Tk Source Code

Changes On Branch core-8-6-branch
Login

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

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

This is equivalent to a diff from 32a9cba038 to 9986fdc267

2025-03-17
10:12
Add [91d0e9d8] to changes Leaf check-in: 9986fdc267 user: oehhar tags: core-8-6-branch
10:04
Ticket [91d0e9d8] MS-Win: Withdrawn Tk transient windows can reappear in Windows taskbar preview check-in: eff58ccd7f user: oehhar tags: core-8-6-branch
2020-10-27
07:08
Rename "trunk" to "main". Add "trunk" propagating tag for backwards compatibility check-in: 0f77b70d50 user: jan.nijtmans tags: trunk, main
01:25
Merge 8.6 Closed-Leaf check-in: 32a9cba038 user: marc_culler tags: trunk
2020-10-26
08:58
Merge 8.6 check-in: 88e0ce578b user: jan.nijtmans tags: trunk
2020-10-25
20:11
Adjustment for Sierra. Closed-Leaf check-in: 77a51c320b user: culler tags: bug-5cc72e002c

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


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


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


>
>







1
2
3
4
5
6
7
8
9
10
11
win/buildall.vc.bat
win/makefile.vc
win/mkd.bat
win/rmd.bat
win/rules-ext.vc
win/rules.vc
win/targets.vc
win/rc/*.bmp
win/rc/*.cur
win/rc/*.ico
win/rc/*.rc
Changes to .fossil-settings/ignore-glob.
16
17
18
19
20
21
22
23
24
25
26
27


28
29
30
31
32
33
34
35
36
37

*/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
40
*/Makefile
*/autom4te.cache
*/config.cache
*/config.log
*/config.status
*/tkConfig.sh
*/wish*
*/tktest
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk*.zip
*/tkUuid.h
doc/man.macros
html
macosx/configure
win/Debug*
win/Release*
win/*.manifest
win/nmhlp-out.txt
win/nmakehlp.out
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
name: Linux
on:
  push:
    branches:
    - "main"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
defaults:
  run:
    shell: bash
    working-directory: tk/unix
env:
  ERROR_ON_FAILURES: 1
jobs:
  build:
    runs-on: ubuntu-22.04
    strategy:
      matrix:
        compiler:
          - "gcc"
          - "clang"
        config:
          - ""
          - "--disable-shared"
          - "--disable-xft"
          - "--disable-xss"
          - "--enable-symbols"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 8.6
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install tcl8.6-dev libxss-dev libxft-dev
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT --with-tcl=/usr/lib/tcl8.6" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
          echo "TOOL_DIR=$(cd tcl/tools;pwd)" >> $GITHUB_ENV
          echo "BUILD_CONFIG_ID=$OPTS" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.config }}
          COMPILER: ${{ matrix.compiler }}
          OPTS: ${{ matrix.compiler }}${{ matrix.config }}
      - name: Configure (opts=${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Build Test Harness
        run: |
          make tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Test-Drive Installation
        run: |
          make install || {
            echo "::error::Failure during Install"
            exit 1
          }
      - name: Create Distribution Package
        run: |
          make dist || {
            echo "::error::Failure during Distribute"
            exit 1
          }
      - name: Convert Documentation to HTML
        run: |
          make html-tk TOOL_DIR=$TOOL_DIR || {
            echo "::error::Failure during Distribute"
            exit 1
          }
      - name: Discover Version ID
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        run: |
          cd /tmp/dist
          echo "VERSION=`ls -d tk* | sed 's/tk//'`" >> $GITHUB_ENV
      - name: Upload Source Distribution
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        uses: actions/upload-artifact@v4
        with:
          name: Tk ${{ env.VERSION }} Source distribution (snapshot)
          path: |
            /tmp/dist/tk*
            !/tmp/dist/tk*/html/**
      - name: Upload Documentation Distribution
        if: ${{ env.BUILD_CONFIG_ID == 'gcc' }}
        uses: actions/upload-artifact@v4
        with:
          name: Tk ${{ env.VERSION }} HTML documentation (snapshot)
          path: /tmp/dist/tk*/html
  test:
    runs-on: ubuntu-20.04
    strategy:
      matrix:
        compiler:
          - "gcc"
        config:
          - ""
          - "--disable-xft"
          - "--enable-symbols"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Setup Environment (compiler=${{ matrix.compiler }})
        run: |
          sudo apt-get install tcl8.6-dev libxss-dev libxft-dev xvfb
          mkdir "$HOME/install dir"
          touch tk/doc/man.macros tk/generic/tkStubInit.c
          echo "CFGOPT=$CFGOPT --with-tcl=/usr/lib/tcl8.6" >> $GITHUB_ENV
          echo "CC=$COMPILER" >> $GITHUB_ENV
        working-directory: "."
        env:
          CFGOPT: ${{ matrix.config }}
          COMPILER: ${{ matrix.compiler }}
      - name: Configure ${{ matrix.config }}
        run: |
          ./configure $CFGOPT "--prefix=$HOME/install dir" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
      - name: Build
        run: |
          make binaries libraries tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tests
        run: |
          xvfb-run --auto-servernum make test-classic | tee out-classic.txt
          xvfb-run --auto-servernum make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 10
Added .github/workflows/mac-build.yml.
























































































































































































































































































































































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




































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
name: Windows
on:
  push:
    branches:
    - "main"
    - "core-8-6-branch"
    tags:
    - "core-**"
permissions:
  contents: read
env:
  ERROR_ON_FAILURES: 1
jobs:
  msvc:
    runs-on: windows-2022
    defaults:
      run:
        shell: powershell
        working-directory: tk/win
    # Using powershell means we need to explicitly stop on failure
    strategy:
      matrix:
        config:
          - ""
          - "OPTS=symbols"
          - "OPTS=static"
          - "OPTS=static,staticpkg"
    steps:
      - name: Checkout Tk
        uses: actions/checkout@v4
        with:
          path: tk
      - name: Checkout Tcl 8.6
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Init MSVC
        uses: ilammy/msvc-dev-cmd@v1
      - name: Make Install Location
        working-directory: tcl
        run: |
          echo "TCLDIR=`pwd`" >> $GITHUB_ENV
          cd ..
          mkdir install
          cd install
          echo "INSTALLDIR=`pwd`" >> $GITHUB_ENV
      - name: Build Tcl (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc release install ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
        working-directory: tcl/win
      - name: Build Tk (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc all ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Build Test Harness (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc tktest ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Run Tk Tests (${{ matrix.config }})
        run: |
          nmake -f makefile.vc test-classic ${{ matrix.config }} | tee out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          nmake -f makefile.vc test-ttk ${{ matrix.config }} | tee out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        env:
          CI_BUILD_WITH_MSVC: 1
        shell: bash
        timeout-minutes: 10
      - name: Build Help (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc htmlhelp ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
      - name: Install (${{ matrix.config }})
        run: |
          &nmake -f makefile.vc install ${{ matrix.config }}
          if ($lastexitcode -ne 0) {
             throw "nmake exit code: $lastexitcode"
          }
  gcc:
    runs-on: windows-2019
    defaults:
      run:
        shell: msys2 {0}
        working-directory: win
    strategy:
      matrix:
        config:
          - ""
          - "--enable-symbols=mem"
          - "--enable-symbols=all"
          - "--disable-shared"
    steps:
      - name: Install MSYS2
        uses: msys2/setup-msys2@v2
        with:
          msystem: MINGW64
          install: git mingw-w64-x86_64-toolchain make
      - name: Checkout Tk
        uses: actions/checkout@v4
      - name: Checkout Tcl 8.6
        uses: actions/checkout@v4
        with:
          repository: tcltk/tcl
          ref: core-8-6-branch
          path: tcl
      - name: Prepare
        run: |
          touch tkStubInit.c
          touch "${HOME}/forWinDialog-5.12.7"
          mkdir "${HOME}/install_dir"
          echo "INSTALL_DIR=${HOME}/install_dir" >> $GITHUB_ENV
        working-directory: generic
      - name: Configure and Build Tcl (${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$INSTALL_DIR" || {
            cat config.log
            echo "::warning::Failure during Tcl Configure"
            exit 1
          }
          make all install  || {
            echo "::warning::Failure during Tcl Build"
            exit 1
          }
          echo "TCL_CONFIG_PATH=`pwd`" >> $GITHUB_ENV
        env:
          CFGOPT: --enable-64bit ${{ matrix.config }}
        working-directory: tcl/win
      - name: Configure Tk (${{ matrix.config }})
        run: |
          ./configure $CFGOPT "--prefix=$HOME/INSTALL_DIR" "--with-tcl=$TCL_CONFIG_PATH" || {
            cat config.log
            echo "::error::Failure during Configure"
            exit 1
          }
        env:
          CFGOPT: --enable-64bit ${{ matrix.config }}
      - name: Build Tk
        run: |
          make all tktest || {
            echo "::error::Failure during Build"
            exit 1
          }
      - name: Run Tk Tests
        run: |
          make test-classic | tee out-classic.txt
          make test-ttk | tee out-ttk.txt
          grep -q "Failed	0" out-classic.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
          grep -q "Failed	0" out-ttk.txt || {
            echo "::error::Failure during Test"
            exit 1
          }
        timeout-minutes: 10
Changes to .gitignore.
12
13
14
15
16
17
18

19
20
21
22
23

24
25
26
27
28
29
30
31
32
33

34
35
36
37
38
39
40
*.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
43
*.res
*.sl
*.so
.fslckout
Makefile
Tk-Info.plist
Wish-Info.plist
Credits.html
autom4te.cache
config.cache
config.log
config.status
config.status.lineno
doc/man.macros
html
manifest.uuid
_FOSSIL_
*/tkConfig.sh
*/wish*
*/tktest
*/versions.vc
*/version.vc
*/libtk.vfs
*/libtk*.zip
*/tkUuid.h
libtommath/bn.ilg
libtommath/bn.ind
libtommath/pretty.build
libtommath/tommath.src
libtommath/*.log
libtommath/*.pdf
libtommath/*.pl
Changes to .project.
1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
	<name>tk8.7</name>
	<comment></comment>
	<projects>
	</projects>
	<buildSpec>
	</buildSpec>
	<natures>
	</natures>


|







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




















































































































































































































































































































































































































































































































































































































Changes to ChangeLog.
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
	* generic/tkObj.c (GetPixelsFromObjEx): [Bug 3431491]: Use a bit of
	type hackery to allow numbers to be interpreted as coordinates (most
	notably on a canvas) without reinterpreting via a string.

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

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

2011-10-13  Jan Nijtmans  <nijtmans@users.sf.net>







|







710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
	* generic/tkObj.c (GetPixelsFromObjEx): [Bug 3431491]: Use a bit of
	type hackery to allow numbers to be interpreted as coordinates (most
	notably on a canvas) without reinterpreting via a string.

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

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

2011-10-13  Jan Nijtmans  <nijtmans@users.sf.net>
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
	* library/demos/mclist.tcl: Added support for arrow indicators to show
	which way a column is being sorted. Corrected determination of which
	fonts to use for measurements.

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

	* doc/wish.1:		Bring doc and demos in line with
	* library/demos/hello:	http://wiki.tcl.tk/812
	* library/demos/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







|







3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
	* library/demos/mclist.tcl: Added support for arrow indicators to show
	which way a column is being sorted. Corrected determination of which
	fonts to use for measurements.

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

	* doc/wish.1:		Bring doc and demos in line with
	* library/demos/hello:	https://wiki.tcl-lang.org/page/exec+magic
	* library/demos/rmt
	* library/demos/square
	* library/demos/tcolor
	* library/demos/timer
	* library/demos/widget
	* win/tkWinMenu.c:	Eliminate a few compiler warnings on mingw
	* win/ttkWinXPTheme.c:	Spacing
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
2008-01-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

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

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

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

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

	* doc/ttk_*.n: [Bug 1876493]: Adjusted handling of the standard
	options part of the Ttk manual pages so that they are documented in
	the correct location.







|







5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
2008-01-30  Donal K. Fellows  <donal.k.fellows@man.ac.uk>

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

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

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

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

	* doc/ttk_*.n: [Bug 1876493]: Adjusted handling of the standard
	options part of the Ttk manual pages so that they are documented in
	the correct location.
Changes to ChangeLog.2002.
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
	Removed setting inputContext to null in Tk_MakeWindowExist as it
	was redundant.

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

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

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

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







|







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

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

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

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

	* win/.cvsignore (new):
	* win/lamp.bmp (new):
	* win/makefile.vc:
	* win/nmakehlp.c (new):
Changes to ChangeLog.2004.
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821

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

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

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

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

	TIP#158 IMPLEMENTATION

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







|







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

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

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

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

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

	TIP#158 IMPLEMENTATION

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

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

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

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

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

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







|







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

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

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

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

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

	* macosx/tkMacOSXCursor.c (TkMacOSXInstallCursor): Set all theme
	cursors using SetThemeCursor or SetAnimatedThemeCursors.
	(TkGetCursorByName): Use the theme cursors for arrow, ibeam, etc. Allow
	animatedCursor{NUM} form for an animated cursor with count.
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
# README:  Tk

This is the **Tk 8.6.17** source distribution.

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

9.0 (production release, daily build)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/linux-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/linux-build.yml?query=branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/win-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/win-build.yml?query=branch%3Amain)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/mac-build.yml/badge.svg?branch=main)](https://github.com/tcltk/tk/actions/workflows/mac-build.yml?query=branch%3Amain)
<br>
8.6 (this release, daily build)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/linux-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/linux-build.yml?query=branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/win-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/win-build.yml?query=branch%3Acore-8-6-branch)
[![Build Status](https://github.com/tcltk/tk/actions/workflows/mac-build.yml/badge.svg?branch=core-8-6-branch)](https://github.com/tcltk/tk/actions/workflows/mac-build.yml?query=branch%3Acore-8-6-branch)

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

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

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

Tk is maintained, enhanced, and distributed freely by the Tcl community.
Source code development and tracking of bug reports and feature requests
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
Changes to changes.
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

10/18/96 (new features) A -menu option has been added to the toplevel
widget command, which allows a menu to operate as a menubar. On the
Macintosh, the menubar is displayed accross the top of the main monitor,
just like with other applications. Under Windows and Unix, the menu is
attached to the toplevel window. Also, changed some semantics.
Tearoff menus will now reflect changes to the menu it was
torn off from, and are deleted when the main menu is
deleted. Tearoffs also reflect more look-and-feel of the
platforms they are running on. (SRP)

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








|







3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498

10/18/96 (new features) A -menu option has been added to the toplevel
widget command, which allows a menu to operate as a menubar. On the
Macintosh, the menubar is displayed accross the top of the main monitor,
just like with other applications. Under Windows and Unix, the menu is
attached to the toplevel window. Also, changed some semantics.
Tearoff menus will now reflect changes to the menu it was
torn off from, and are deleted when the master menu is
deleted. Tearoffs also reflect more look-and-feel of the
platforms they are running on. (SRP)

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

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

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)







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







7412
7413
7414
7415
7416
7417
7418























7419
7420
7421
7422
7423
7424
7425

2017-08-08 (bug)[28d0b8] Follow ICCCM advice on X selection protocol (donchenko)

2017-08-08 (bug)[4966ca] Scidb race in notebook tab selection (cramer)

--- Released 8.6.7, August 9, 2017 --- https://core.tcl-lang.org/tk/ for details
























2017-08-24 (bug)[f1a3ca] Memory leak in [text] B-tree (edhume3)

2017-08-24 (bug)[ee40fd] Report [console] init errors (the)

2017-08-24 (bug)[3295446] Improve history visibility in [console] (goth)

2017-08-24 (bug) canvas closed polylines fully honor -joinstyle (vogel)
7718
7719
7720
7721
7722
7723
7724

7725





































































































































































































































7726

7727




































































































































































































































7728
7729
7730
7731

7732

7733

7734

7735

7736

7737

7738

7739

7740

7741



7742

7743

7744






















7745

7746


7747


7748


7749

7750


7751


7752


7753


7754


7755

7756


7757


7758

7759


7760









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















>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|


>
|
>

>
|
>

>
|
>

>
|
>

>
|
>

>
>
>
|
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

>
|
>
>

>
>
|
>
>

>
|
>
>

>
>
|
>
>

>
>
|
>
>

>
|
>
>

>
>
|
>

>
>
|
>
>
>
>
>
>
>
>
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7709
7710
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7725
7726
7727
7728
7729
7730
7731
7732
7733
7734
7735
7736
7737
7738
7739
7740
7741
7742
7743
7744
7745
7746
7747
7748
7749
7750
7751
7752
7753
7754
7755
7756
7757
7758
7759
7760
7761
7762
7763
7764
7765
7766
7767
7768
7769
7770
7771
7772
7773
7774
7775
7776
7777
7778
7779
7780
7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852
7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888
7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
7995
7996
7997
7998
7999
8000
8001
8002
8003
8004
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015
8016
8017
8018
8019
8020
8021
8022
8023
8024
8025
8026
8027
8028
8029
8030
8031
8032
8033
8034
8035
8036
8037
8038
8039
8040
8041
8042
8043
8044
8045
8046
8047
8048
8049
8050
8051
8052
8053
8054
8055
8056
8057
8058
8059
8060
8061
8062
8063
8064
8065
8066
8067
8068
8069
8070
8071
8072
8073
8074
8075
8076
8077
8078
8079
8080
8081
8082
8083
8084
8085
8086
8087
8088
8089
8090
8091
8092
8093
8094
8095
8096
8097
8098
8099
8100
8101
8102
8103
8104
8105
8106
8107
8108
8109
8110
8111
8112
8113
8114
8115
8116
8117
8118
8119
8120
8121
8122
8123
8124
8125
8126
8127
8128
8129
8130
8131
8132
8133
8134
8135
8136
8137
8138
8139
8140
8141
8142
8143
8144
8145
8146
8147
8148
8149
8150
8151
8152
8153
8154
8155
8156
8157
8158
8159
8160
8161
8162
8163
8164
8165
8166
8167
8168
8169
8170
8171
8172
8173
8174
8175
8176
8177
8178
8179
8180
8181
8182
8183
8184
8185
8186
8187
8188
8189
8190
8191
8192
8193
8194
8195
8196
8197
8198
8199
8200
8201
8202
8203
8204
8205
8206
8207
8208
8209
8210
8211
8212
8213
8214
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267

2019-11-17 [90d555] workaround NSFontManager bad selections (culler)

2019-11-19 (new) Partial Emoji support in text displays (nijtmans,culler)

- Released 8.6.10, Nov 21, 2019 - https://core.tcl-lang.org/tk/ for details

2019-11-25 (bug)[a95373] TkKeyEvent platform variations (werner)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2023-12-03 (bug)[fe9423] Aqua: XPutImage() swap red and blue (chavez)
        *** POTENTIAL INCOMPATIBILITY ***

2023-12-09 (bug)[1d8b71] X: Photo color drawing for 32-bit visuals (warnholz)

2023-12-12 Update to latest X11 headers

2023-12-22 (bug)[9c5742] Fix handling of abbreviated -relief args (nijtmans)

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

2024-01-05 (bug)[a9e637] treeview display partial final line (bron)

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

2024-01-12 (bug)[737abf] text image insertion from O(N^2) to O(N)

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

2024-02-08 (bug)[57b821] see test textIndex-22.16 (vogel)

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

2024-03-15 (bug)[47d4f2] Invoke binding scripts for events with detail field
	NotifyInferior (leunissen, vogel)
	*** POTENTIAL INCOMPATIBILITY ***

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

2024-04-21 (bug) [ab839e] Fix [text undo] clearingdata

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

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

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

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

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

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

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

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

2024-06-11 (bug) [157652] Fix image read with -from option for gif/png
	(vogel)

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

2024-07-06 (bug) [51ece3] Fix crash on [canvas dchars] (vogel)

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

2024-07-31 (bug) [0d4879,089da4,f569b9] Improve focus ring for ttk widgets
	(nemethi)

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

- Released 8.6.15, Sep 13, 2024 - https://core.tcl-lang.org/tk/ for details

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

2024-09-20 (bug) [398109] Segmentation fault with bogus resource value
	(X11) (emiliano)

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

2024-09-27 (bug) [265d4e] macOS Sequoia: warning: 'setShowsResizeIndicator:'
	is deprecated (vogel)

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

2024-10-11 (bug) [f52986] SIGABRT from Tk_DeleteErrorHandler() (vogel)

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

2024-11-25 (bug) [bcbf4c] Tk intialization overwrites thread specific data
	(emiliano)

- Released 8.6.16, Dec 11, 2024 - https://core.tcl-lang.org/tk/ for details

2024-12-19 (bug) [844c0b] Menu entry underline does not consider
	activeborderwidth (vogel)

2025-01-03 (bug) [13ac26] wm iconbitmap does not correctly set the icon
	pixmap hint on macOS (serhiy.storchaka)

2025-03-17 (bug) [159aa5] MS-Win: Incorrect system menu entries for transient
	toplevels (cjmcdonald)

2025-03-17 (bug) [91d0e9] MS-Win: Withdrawn Tk transient windows can reappear in
	Windows taskbar preview (cjmcdonald)
Deleted compat/stdbool.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*===---- stdbool.h - Standard header for booleans -------------------------===
*
* Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
* See https://llvm.org/LICENSE.txt for license information.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*
* Modified for use by pre-C99 compilers. (c) Jan Nijtmans.
*
*===-----------------------------------------------------------------------===
*/

#ifndef __STDBOOL_H
#define __STDBOOL_H

/* Don't define bool, true, and false in C++, except as a GNU extension. */
#ifndef __cplusplus
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#define bool _Bool
#else
#define bool unsigned char
#endif
#define true 1
#define false 0
#elif defined(__GNUC__) && !defined(__STRICT_ANSI__)
/* Define _Bool as a GNU extension. */
#define _Bool bool
#if __cplusplus < 201103L
/* For C++98, define bool, false, true as a GNU extension. */
#define bool  bool
#define false false
#define true  true
#endif
#endif

#define __bool_true_false_are_defined 1

#endif /* __STDBOOL_H */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<










































































Deleted compat/stdint.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
/*  A portable stdint.h
 ****************************************************************************
 *  BSD License:
 ****************************************************************************
 *
 *  Copyright (c) 2005-2016 Paul Hsieh
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *  2. Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *  3. The name of the author may not be used to endorse or promote products
 *     derived from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 *  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 ****************************************************************************
 *
 *  Version 0.1.16.0
 *
 *  The ANSI C standard committee, for the C99 standard, specified the
 *  inclusion of a new standard include file called stdint.h.  This is
 *  a very useful and long desired include file which contains several
 *  very precise definitions for integer scalar types that is critically
 *  important for making several classes of applications portable
 *  including cryptography, hashing, variable length integer libraries
 *  and so on.  But for most developers its likely useful just for
 *  programming sanity.
 *
 *  The problem is that some compiler vendors chose to ignore the C99
 *  standard and some older compilers have no opportunity to be updated.
 *  Because of this situation, simply including stdint.h in your code
 *  makes it unportable.
 *
 *  So that's what this file is all about.  It's an attempt to build a
 *  single universal include file that works on as many platforms as
 *  possible to deliver what stdint.h is supposed to.  Even compilers
 *  that already come with stdint.h can use this file instead without
 *  any loss of functionality.  A few things that should be noted about
 *  this file:
 *
 *    1) It is not guaranteed to be portable and/or present an identical
 *       interface on all platforms.  The extreme variability of the
 *       ANSI C standard makes this an impossibility right from the
 *       very get go. Its really only meant to be useful for the vast
 *       majority of platforms that possess the capability of
 *       implementing usefully and precisely defined, standard sized
 *       integer scalars.  Systems which are not intrinsically 2s
 *       complement may produce invalid constants.
 *
 *    2) There is an unavoidable use of non-reserved symbols.
 *
 *    3) Other standard include files are invoked.
 *
 *    4) This file may come in conflict with future platforms that do
 *       include stdint.h.  The hope is that one or the other can be
 *       used with no real difference.
 *
 *    5) In the current version, if your platform can't represent
 *       int32_t, int16_t and int8_t, it just dumps out with a compiler
 *       error.
 *
 *    6) 64 bit integers may or may not be defined.  Test for their
 *       presence with the test: #ifdef INT64_MAX or #ifdef UINT64_MAX.
 *       Note that this is different from the C99 specification which
 *       requires the existence of 64 bit support in the compiler.  If
 *       this is not defined for your platform, yet it is capable of
 *       dealing with 64 bits then it is because this file has not yet
 *       been extended to cover all of your system's capabilities.
 *
 *    7) (u)intptr_t may or may not be defined.  Test for its presence
 *       with the test: #ifdef PTRDIFF_MAX.  If this is not defined
 *       for your platform, then it is because this file has not yet
 *       been extended to cover all of your system's capabilities, not
 *       because its optional.
 *
 *    8) The following might not been defined even if your platform is
 *       capable of defining it:
 *
 *       WCHAR_MIN
 *       WCHAR_MAX
 *       (u)int64_t
 *       PTRDIFF_MIN
 *       PTRDIFF_MAX
 *       (u)intptr_t
 *
 *    9) The following have not been defined:
 *
 *       WINT_MIN
 *       WINT_MAX
 *
 *   10) The criteria for defining (u)int_least(*)_t isn't clear,
 *       except for systems which don't have a type that precisely
 *       defined 8, 16, or 32 bit types (which this include file does
 *       not support anyways). Default definitions have been given.
 *
 *   11) The criteria for defining (u)int_fast(*)_t isn't something I
 *       would trust to any particular compiler vendor or the ANSI C
 *       committee.  It is well known that "compatible systems" are
 *       commonly created that have very different performance
 *       characteristics from the systems they are compatible with,
 *       especially those whose vendors make both the compiler and the
 *       system.  Default definitions have been given, but its strongly
 *       recommended that users never use these definitions for any
 *       reason (they do *NOT* deliver any serious guarantee of
 *       improved performance -- not in this file, nor any vendor's
 *       stdint.h).
 *
 *   12) The following macros:
 *
 *       PRINTF_INTMAX_MODIFIER
 *       PRINTF_INT64_MODIFIER
 *       PRINTF_INT32_MODIFIER
 *       PRINTF_INT16_MODIFIER
 *       PRINTF_LEAST64_MODIFIER
 *       PRINTF_LEAST32_MODIFIER
 *       PRINTF_LEAST16_MODIFIER
 *       PRINTF_INTPTR_MODIFIER
 *
 *       are strings which have been defined as the modifiers required
 *       for the "d", "u" and "x" printf formats to correctly output
 *       (u)intmax_t, (u)int64_t, (u)int32_t, (u)int16_t, (u)least64_t,
 *       (u)least32_t, (u)least16_t and (u)intptr_t types respectively.
 *       PRINTF_INTPTR_MODIFIER is not defined for some systems which
 *       provide their own stdint.h.  PRINTF_INT64_MODIFIER is not
 *       defined if INT64_MAX is not defined.  These are an extension
 *       beyond what C99 specifies must be in stdint.h.
 *
 *       In addition, the following macros are defined:
 *
 *       PRINTF_INTMAX_HEX_WIDTH
 *       PRINTF_INT64_HEX_WIDTH
 *       PRINTF_INT32_HEX_WIDTH
 *       PRINTF_INT16_HEX_WIDTH
 *       PRINTF_INT8_HEX_WIDTH
 *       PRINTF_INTMAX_DEC_WIDTH
 *       PRINTF_INT64_DEC_WIDTH
 *       PRINTF_INT32_DEC_WIDTH
 *       PRINTF_INT16_DEC_WIDTH
 *       PRINTF_UINT8_DEC_WIDTH
 *       PRINTF_UINTMAX_DEC_WIDTH
 *       PRINTF_UINT64_DEC_WIDTH
 *       PRINTF_UINT32_DEC_WIDTH
 *       PRINTF_UINT16_DEC_WIDTH
 *       PRINTF_UINT8_DEC_WIDTH
 *
 *       Which specifies the maximum number of characters required to
 *       print the number of that type in either hexadecimal or decimal.
 *       These are an extension beyond what C99 specifies must be in
 *       stdint.h.
 *
 *  Compilers tested (all with 0 warnings at their highest respective
 *  settings): Borland Turbo C 2.0, WATCOM C/C++ 11.0 (16 bits and 32
 *  bits), Microsoft Visual C++ 6.0 (32 bit), Microsoft Visual Studio
 *  .net (VC7), Intel C++ 4.0, GNU gcc v3.3.3
 *
 *  This file should be considered a work in progress.  Suggestions for
 *  improvements, especially those which increase coverage are strongly
 *  encouraged.
 *
 *  Acknowledgements
 *
 *  The following people have made significant contributions to the
 *  development and testing of this file:
 *
 *  Chris Howie
 *  John Steele Scott
 *  Dave Thorup
 *  John Dill
 *  Florian Wobbe
 *  Christopher Sean Morrison
 *  Mikkel Fahnoe Jorgensen
 *
 */

#include <stddef.h>
#include <limits.h>
#include <signal.h>

/*
 *  For gcc with _STDINT_H, fill in the PRINTF_INT*_MODIFIER macros, and
 *  do nothing else.  On the Mac OS X version of gcc this is _STDINT_H_.
 */

#if ((defined(__SUNPRO_C) && __SUNPRO_C >= 0x570) || (defined(_MSC_VER) && _MSC_VER >= 1600) || (defined(__STDC__) && __STDC__ && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined (__WATCOMC__) && (defined (_STDINT_H_INCLUDED) || __WATCOMC__ >= 1250)) || (defined(__GNUC__) && (__GNUC__ > 3 || defined(_STDINT_H) || defined(_STDINT_H_) || defined (__UINT_FAST64_TYPE__)) )) && !defined (_PSTDINT_H_INCLUDED)
#include <stdint.h>
#define _PSTDINT_H_INCLUDED
# if defined(__GNUC__) && (defined(__x86_64__) || defined(__ppc64__)) && !(defined(__APPLE__) && defined(__MACH__))
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "l"
#  endif
#  ifndef PRINTF_INT32_MODIFIER
#   define PRINTF_INT32_MODIFIER ""
#  endif
# else
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
#  ifndef PRINTF_INT32_MODIFIER
#   if (UINT_MAX == UINT32_MAX)
#    define PRINTF_INT32_MODIFIER ""
#   else
#    define PRINTF_INT32_MODIFIER "l"
#   endif
#  endif
# endif
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
# ifndef PRINTF_INTMAX_MODIFIER
#  define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INT64_HEX_WIDTH
#  define PRINTF_INT64_HEX_WIDTH "16"
# endif
# ifndef PRINTF_UINT64_HEX_WIDTH
#  define PRINTF_UINT64_HEX_WIDTH "16"
# endif
# ifndef PRINTF_INT32_HEX_WIDTH
#  define PRINTF_INT32_HEX_WIDTH "8"
# endif
# ifndef PRINTF_UINT32_HEX_WIDTH
#  define PRINTF_UINT32_HEX_WIDTH "8"
# endif
# ifndef PRINTF_INT16_HEX_WIDTH
#  define PRINTF_INT16_HEX_WIDTH "4"
# endif
# ifndef PRINTF_UINT16_HEX_WIDTH
#  define PRINTF_UINT16_HEX_WIDTH "4"
# endif
# ifndef PRINTF_INT8_HEX_WIDTH
#  define PRINTF_INT8_HEX_WIDTH "2"
# endif
# ifndef PRINTF_UINT8_HEX_WIDTH
#  define PRINTF_UINT8_HEX_WIDTH "2"
# endif
# ifndef PRINTF_INT64_DEC_WIDTH
#  define PRINTF_INT64_DEC_WIDTH "19"
# endif
# ifndef PRINTF_UINT64_DEC_WIDTH
#  define PRINTF_UINT64_DEC_WIDTH "20"
# endif
# ifndef PRINTF_INT32_DEC_WIDTH
#  define PRINTF_INT32_DEC_WIDTH "10"
# endif
# ifndef PRINTF_UINT32_DEC_WIDTH
#  define PRINTF_UINT32_DEC_WIDTH "10"
# endif
# ifndef PRINTF_INT16_DEC_WIDTH
#  define PRINTF_INT16_DEC_WIDTH "5"
# endif
# ifndef PRINTF_UINT16_DEC_WIDTH
#  define PRINTF_UINT16_DEC_WIDTH "5"
# endif
# ifndef PRINTF_INT8_DEC_WIDTH
#  define PRINTF_INT8_DEC_WIDTH "3"
# endif
# ifndef PRINTF_UINT8_DEC_WIDTH
#  define PRINTF_UINT8_DEC_WIDTH "3"
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
# endif
# ifndef PRINTF_UINTMAX_HEX_WIDTH
#  define PRINTF_UINTMAX_HEX_WIDTH PRINTF_UINT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
# endif
# ifndef PRINTF_UINTMAX_DEC_WIDTH
#  define PRINTF_UINTMAX_DEC_WIDTH PRINTF_UINT64_DEC_WIDTH
# endif

/*
 *  Something really weird is going on with Open Watcom.  Just pull some of
 *  these duplicated definitions from Open Watcom's stdint.h file for now.
 */

# if defined (__WATCOMC__) && __WATCOMC__ >= 1250
#  if !defined (INT64_C)
#   define INT64_C(x)   (x + (INT64_MAX - INT64_MAX))
#  endif
#  if !defined (UINT64_C)
#   define UINT64_C(x)  (x + (UINT64_MAX - UINT64_MAX))
#  endif
#  if !defined (INT32_C)
#   define INT32_C(x)   (x + (INT32_MAX - INT32_MAX))
#  endif
#  if !defined (UINT32_C)
#   define UINT32_C(x)  (x + (UINT32_MAX - UINT32_MAX))
#  endif
#  if !defined (INT16_C)
#   define INT16_C(x)   (x)
#  endif
#  if !defined (UINT16_C)
#   define UINT16_C(x)  (x)
#  endif
#  if !defined (INT8_C)
#   define INT8_C(x)   (x)
#  endif
#  if !defined (UINT8_C)
#   define UINT8_C(x)  (x)
#  endif
#  if !defined (UINT64_MAX)
#   define UINT64_MAX  18446744073709551615ULL
#  endif
#  if !defined (INT64_MAX)
#   define INT64_MAX  9223372036854775807LL
#  endif
#  if !defined (UINT32_MAX)
#   define UINT32_MAX  4294967295UL
#  endif
#  if !defined (INT32_MAX)
#   define INT32_MAX  2147483647L
#  endif
#  if !defined (INTMAX_MAX)
#   define INTMAX_MAX INT64_MAX
#  endif
#  if !defined (INTMAX_MIN)
#   define INTMAX_MIN INT64_MIN
#  endif
# endif
#endif

/*
 *  I have no idea what is the truly correct thing to do on older Solaris.
 *  From some online discussions, this seems to be what is being
 *  recommended.  For people who actually are developing on older Solaris,
 *  what I would like to know is, does this define all of the relevant
 *  macros of a complete stdint.h?  Remember, in pstdint.h 64 bit is
 *  considered optional.
 */

#if (defined(__SUNPRO_C) && __SUNPRO_C >= 0x420) && !defined(_PSTDINT_H_INCLUDED)
#include <sys/inttypes.h>
#define _PSTDINT_H_INCLUDED
#endif

#ifndef _PSTDINT_H_INCLUDED
#define _PSTDINT_H_INCLUDED

#ifndef SIZE_MAX
# define SIZE_MAX ((size_t)-1)
#endif

/*
 *  Deduce the type assignments from limits.h under the assumption that
 *  integer sizes in bits are powers of 2, and follow the ANSI
 *  definitions.
 */

#ifndef UINT8_MAX
# define UINT8_MAX 0xff
#endif
#if !defined(uint8_t) && !defined(_UINT8_T) && !defined(vxWorks)
# if (UCHAR_MAX == UINT8_MAX) || defined (S_SPLINT_S)
    typedef unsigned char uint8_t;
#   define UINT8_C(v) ((uint8_t) v)
# else
#   error "Platform not supported"
# endif
#endif

#ifndef INT8_MAX
# define INT8_MAX 0x7f
#endif
#ifndef INT8_MIN
# define INT8_MIN INT8_C(0x80)
#endif
#if !defined(int8_t) && !defined(_INT8_T) && !defined(vxWorks)
# if (SCHAR_MAX == INT8_MAX) || defined (S_SPLINT_S)
    typedef signed char int8_t;
#   define INT8_C(v) ((int8_t) v)
# else
#   error "Platform not supported"
# endif
#endif

#ifndef UINT16_MAX
# define UINT16_MAX 0xffff
#endif
#if !defined(uint16_t) && !defined(_UINT16_T) && !defined(vxWorks)
#if (UINT_MAX == UINT16_MAX) || defined (S_SPLINT_S)
  typedef unsigned int uint16_t;
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER ""
# endif
# define UINT16_C(v) ((uint16_t) (v))
#elif (USHRT_MAX == UINT16_MAX)
  typedef unsigned short uint16_t;
# define UINT16_C(v) ((uint16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef INT16_MAX
# define INT16_MAX 0x7fff
#endif
#ifndef INT16_MIN
# define INT16_MIN INT16_C(0x8000)
#endif
#if !defined(int16_t) && !defined(_INT16_T) && !defined(vxWorks)
#if (INT_MAX == INT16_MAX) || defined (S_SPLINT_S)
  typedef signed int int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER ""
# endif
#elif (SHRT_MAX == INT16_MAX)
  typedef signed short int16_t;
# define INT16_C(v) ((int16_t) (v))
# ifndef PRINTF_INT16_MODIFIER
#  define PRINTF_INT16_MODIFIER "h"
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef UINT32_MAX
# define UINT32_MAX (0xffffffffUL)
#endif
#if !defined(uint32_t) && !defined(_UINT32_T) && !defined(vxWorks)
#if (ULONG_MAX == UINT32_MAX) || defined (S_SPLINT_S)
  typedef unsigned long uint32_t;
# define UINT32_C(v) v ## UL
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER "l"
# endif
#elif (UINT_MAX == UINT32_MAX)
  typedef unsigned int uint32_t;
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
# define UINT32_C(v) v ## U
#elif (USHRT_MAX == UINT32_MAX)
  typedef unsigned short uint32_t;
# define UINT32_C(v) ((unsigned short) (v))
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif

#ifndef INT32_MAX
# define INT32_MAX (0x7fffffffL)
#endif
#ifndef INT32_MIN
# define INT32_MIN INT32_C(0x80000000)
#endif
#if !defined(int32_t) && !defined(_INT32_T) && !defined(vxWorks)
#if (LONG_MAX == INT32_MAX) || defined (S_SPLINT_S)
  typedef signed long int32_t;
# define INT32_C(v) v ## L
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER "l"
# endif
#elif (INT_MAX == INT32_MAX)
  typedef signed int int32_t;
# define INT32_C(v) v
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#elif (SHRT_MAX == INT32_MAX)
  typedef signed short int32_t;
# define INT32_C(v) ((short) (v))
# ifndef PRINTF_INT32_MODIFIER
#  define PRINTF_INT32_MODIFIER ""
# endif
#else
#error "Platform not supported"
#endif
#endif

/*
 *  The macro stdint_int64_defined is temporarily used to record
 *  whether or not 64 integer support is available.  It must be
 *  defined for any 64 integer extensions for new platforms that are
 *  added.
 */

#undef stdint_int64_defined
#if (defined(__STDC__) && defined(__STDC_VERSION__)) || defined (S_SPLINT_S)
# if (__STDC__ && __STDC_VERSION__ >= 199901L) || defined (S_SPLINT_S)
#  define stdint_int64_defined
   typedef long long int64_t;
   typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# endif
#endif

#if !defined (stdint_int64_defined)
# if defined(__GNUC__) && !defined(vxWorks)
#  define stdint_int64_defined
   __extension__ typedef long long int64_t;
   __extension__ typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# elif defined(__MWERKS__) || defined (__SUNPRO_C) || defined (__SUNPRO_CC) || defined (__APPLE_CC__) || defined (_LONG_LONG) || defined (_CRAYC) || defined (S_SPLINT_S)
#  define stdint_int64_defined
   typedef long long int64_t;
   typedef unsigned long long uint64_t;
#  define UINT64_C(v) v ## ULL
#  define  INT64_C(v) v ## LL
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "ll"
#  endif
# elif (defined(__WATCOMC__) && defined(__WATCOM_INT64__)) || (defined(_MSC_VER) && _INTEGRAL_MAX_BITS >= 64) || (defined (__BORLANDC__) && __BORLANDC__ > 0x460) || defined (__alpha) || defined (__DECC)
#  define stdint_int64_defined
   typedef __int64 int64_t;
   typedef unsigned __int64 uint64_t;
#  define UINT64_C(v) v ## UI64
#  define  INT64_C(v) v ## I64
#  ifndef PRINTF_INT64_MODIFIER
#   define PRINTF_INT64_MODIFIER "I64"
#  endif
# endif
#endif

#if !defined (LONG_LONG_MAX) && defined (INT64_C)
# define LONG_LONG_MAX INT64_C (9223372036854775807)
#endif
#ifndef ULONG_LONG_MAX
# define ULONG_LONG_MAX UINT64_C (18446744073709551615)
#endif

#if !defined (INT64_MAX) && defined (INT64_C)
# define INT64_MAX INT64_C (9223372036854775807)
#endif
#if !defined (INT64_MIN) && defined (INT64_C)
# define INT64_MIN INT64_C (-9223372036854775808)
#endif
#if !defined (UINT64_MAX) && defined (INT64_C)
# define UINT64_MAX UINT64_C (18446744073709551615)
#endif

/*
 *  Width of hexadecimal for number field.
 */

#ifndef PRINTF_INT64_HEX_WIDTH
# define PRINTF_INT64_HEX_WIDTH "16"
#endif
#ifndef PRINTF_INT32_HEX_WIDTH
# define PRINTF_INT32_HEX_WIDTH "8"
#endif
#ifndef PRINTF_INT16_HEX_WIDTH
# define PRINTF_INT16_HEX_WIDTH "4"
#endif
#ifndef PRINTF_INT8_HEX_WIDTH
# define PRINTF_INT8_HEX_WIDTH "2"
#endif
#ifndef PRINTF_INT64_DEC_WIDTH
# define PRINTF_INT64_DEC_WIDTH "19"
#endif
#ifndef PRINTF_INT32_DEC_WIDTH
# define PRINTF_INT32_DEC_WIDTH "10"
#endif
#ifndef PRINTF_INT16_DEC_WIDTH
# define PRINTF_INT16_DEC_WIDTH "5"
#endif
#ifndef PRINTF_INT8_DEC_WIDTH
# define PRINTF_INT8_DEC_WIDTH "3"
#endif
#ifndef PRINTF_UINT64_DEC_WIDTH
# define PRINTF_UINT64_DEC_WIDTH "20"
#endif
#ifndef PRINTF_UINT32_DEC_WIDTH
# define PRINTF_UINT32_DEC_WIDTH "10"
#endif
#ifndef PRINTF_UINT16_DEC_WIDTH
# define PRINTF_UINT16_DEC_WIDTH "5"
#endif
#ifndef PRINTF_UINT8_DEC_WIDTH
# define PRINTF_UINT8_DEC_WIDTH "3"
#endif

/*
 *  Ok, lets not worry about 128 bit integers for now.  Moore's law says
 *  we don't need to worry about that until about 2040 at which point
 *  we'll have bigger things to worry about.
 */

#ifdef stdint_int64_defined
  typedef int64_t intmax_t;
  typedef uint64_t uintmax_t;
# define  INTMAX_MAX   INT64_MAX
# define  INTMAX_MIN   INT64_MIN
# define UINTMAX_MAX  UINT64_MAX
# define UINTMAX_C(v) UINT64_C(v)
# define  INTMAX_C(v)  INT64_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
#   define PRINTF_INTMAX_MODIFIER PRINTF_INT64_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT64_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT64_DEC_WIDTH
# endif
#else
  typedef int32_t intmax_t;
  typedef uint32_t uintmax_t;
# define  INTMAX_MAX   INT32_MAX
# define UINTMAX_MAX  UINT32_MAX
# define UINTMAX_C(v) UINT32_C(v)
# define  INTMAX_C(v)  INT32_C(v)
# ifndef PRINTF_INTMAX_MODIFIER
#   define PRINTF_INTMAX_MODIFIER PRINTF_INT32_MODIFIER
# endif
# ifndef PRINTF_INTMAX_HEX_WIDTH
#  define PRINTF_INTMAX_HEX_WIDTH PRINTF_INT32_HEX_WIDTH
# endif
# ifndef PRINTF_INTMAX_DEC_WIDTH
#  define PRINTF_INTMAX_DEC_WIDTH PRINTF_INT32_DEC_WIDTH
# endif
#endif

/*
 *  Because this file currently only supports platforms which have
 *  precise powers of 2 as bit sizes for the default integers, the
 *  least definitions are all trivial.  Its possible that a future
 *  version of this file could have different definitions.
 */

#ifndef stdint_least_defined
  typedef   int8_t   int_least8_t;
  typedef  uint8_t  uint_least8_t;
  typedef  int16_t  int_least16_t;
  typedef uint16_t uint_least16_t;
  typedef  int32_t  int_least32_t;
  typedef uint32_t uint_least32_t;
# define PRINTF_LEAST32_MODIFIER PRINTF_INT32_MODIFIER
# define PRINTF_LEAST16_MODIFIER PRINTF_INT16_MODIFIER
# define  UINT_LEAST8_MAX  UINT8_MAX
# define   INT_LEAST8_MAX   INT8_MAX
# define UINT_LEAST16_MAX UINT16_MAX
# define  INT_LEAST16_MAX  INT16_MAX
# define UINT_LEAST32_MAX UINT32_MAX
# define  INT_LEAST32_MAX  INT32_MAX
# define   INT_LEAST8_MIN   INT8_MIN
# define  INT_LEAST16_MIN  INT16_MIN
# define  INT_LEAST32_MIN  INT32_MIN
# ifdef stdint_int64_defined
    typedef  int64_t  int_least64_t;
    typedef uint64_t uint_least64_t;
#   define PRINTF_LEAST64_MODIFIER PRINTF_INT64_MODIFIER
#   define UINT_LEAST64_MAX UINT64_MAX
#   define  INT_LEAST64_MAX  INT64_MAX
#   define  INT_LEAST64_MIN  INT64_MIN
# endif
#endif
#undef stdint_least_defined

/*
 *  The ANSI C committee has defined *int*_fast*_t types as well.  This,
 *  of course, defies rationality -- you can't know what will be fast
 *  just from the type itself.  Even for a given architecture, compatible
 *  implementations might have different performance characteristics.
 *  Developers are warned to stay away from these types when using this
 *  or any other stdint.h.
 */

typedef   int_least8_t   int_fast8_t;
typedef  uint_least8_t  uint_fast8_t;
typedef  int_least16_t  int_fast16_t;
typedef uint_least16_t uint_fast16_t;
typedef  int_least32_t  int_fast32_t;
typedef uint_least32_t uint_fast32_t;
#define  UINT_FAST8_MAX  UINT_LEAST8_MAX
#define   INT_FAST8_MAX   INT_LEAST8_MAX
#define UINT_FAST16_MAX UINT_LEAST16_MAX
#define  INT_FAST16_MAX  INT_LEAST16_MAX
#define UINT_FAST32_MAX UINT_LEAST32_MAX
#define  INT_FAST32_MAX  INT_LEAST32_MAX
#define   INT_FAST8_MIN   INT_LEAST8_MIN
#define  INT_FAST16_MIN  INT_LEAST16_MIN
#define  INT_FAST32_MIN  INT_LEAST32_MIN
#ifdef stdint_int64_defined
  typedef  int_least64_t  int_fast64_t;
  typedef uint_least64_t uint_fast64_t;
# define UINT_FAST64_MAX UINT_LEAST64_MAX
# define  INT_FAST64_MAX  INT_LEAST64_MAX
# define  INT_FAST64_MIN  INT_LEAST64_MIN
#endif

#undef stdint_int64_defined

/*
 *  Whatever piecemeal, per compiler thing we can do about the wchar_t
 *  type limits.
 */

#if defined(__WATCOMC__) || defined(_MSC_VER) || defined (__GNUC__) && !defined(vxWorks)
# include <wchar.h>
# ifndef WCHAR_MIN
#  define WCHAR_MIN 0
# endif
# ifndef WCHAR_MAX
#  define WCHAR_MAX ((wchar_t)-1)
# endif
#endif

/*
 *  Whatever piecemeal, per compiler/platform thing we can do about the
 *  (u)intptr_t types and limits.
 */

#if (defined (_MSC_VER) && defined (_UINTPTR_T_DEFINED)) || defined (_UINTPTR_T)
# define STDINT_H_UINTPTR_T_DEFINED
#endif

#ifndef STDINT_H_UINTPTR_T_DEFINED
# if defined (__alpha__) || defined (__ia64__) || defined (__x86_64__) || defined (_WIN64) || defined (__ppc64__)
#  define stdint_intptr_bits 64
# elif defined (__WATCOMC__) || defined (__TURBOC__)
#  if defined(__TINY__) || defined(__SMALL__) || defined(__MEDIUM__)
#    define stdint_intptr_bits 16
#  else
#    define stdint_intptr_bits 32
#  endif
# elif defined (__i386__) || defined (_WIN32) || defined (WIN32) || defined (__ppc64__)
#  define stdint_intptr_bits 32
# elif defined (__INTEL_COMPILER)
/* TODO -- what did Intel do about x86-64? */
# else
/* #error "This platform might not be supported yet" */
# endif

# ifdef stdint_intptr_bits
#  define stdint_intptr_glue3_i(a,b,c)  a##b##c
#  define stdint_intptr_glue3(a,b,c)    stdint_intptr_glue3_i(a,b,c)
#  ifndef PRINTF_INTPTR_MODIFIER
#    define PRINTF_INTPTR_MODIFIER      stdint_intptr_glue3(PRINTF_INT,stdint_intptr_bits,_MODIFIER)
#  endif
#  ifndef PTRDIFF_MAX
#    define PTRDIFF_MAX                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef PTRDIFF_MIN
#    define PTRDIFF_MIN                 stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
#  endif
#  ifndef UINTPTR_MAX
#    define UINTPTR_MAX                 stdint_intptr_glue3(UINT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef INTPTR_MAX
#    define INTPTR_MAX                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MAX)
#  endif
#  ifndef INTPTR_MIN
#    define INTPTR_MIN                  stdint_intptr_glue3(INT,stdint_intptr_bits,_MIN)
#  endif
#  ifndef INTPTR_C
#    define INTPTR_C(x)                 stdint_intptr_glue3(INT,stdint_intptr_bits,_C)(x)
#  endif
#  ifndef UINTPTR_C
#    define UINTPTR_C(x)                stdint_intptr_glue3(UINT,stdint_intptr_bits,_C)(x)
#  endif
  typedef stdint_intptr_glue3(uint,stdint_intptr_bits,_t) uintptr_t;
  typedef stdint_intptr_glue3( int,stdint_intptr_bits,_t)  intptr_t;
# else
/* TODO -- This following is likely wrong for some platforms, and does
   nothing for the definition of uintptr_t. */
  typedef ptrdiff_t intptr_t;
# endif
# define STDINT_H_UINTPTR_T_DEFINED
#endif

/*
 *  Assumes sig_atomic_t is signed and we have a 2s complement machine.
 */

#ifndef SIG_ATOMIC_MAX
# define SIG_ATOMIC_MAX ((((sig_atomic_t) 1) << (sizeof (sig_atomic_t)*CHAR_BIT-1)) - 1)
#endif

#endif

#if defined (__TEST_PSTDINT_FOR_CORRECTNESS)

/*
 *  Please compile with the maximum warning settings to make sure macros are
 *  not defined more than once.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#define glue3_aux(x,y,z) x ## y ## z
#define glue3(x,y,z) glue3_aux(x,y,z)

#define DECLU(bits) glue3(uint,bits,_t) glue3(u,bits,) = glue3(UINT,bits,_C) (0);
#define DECLI(bits) glue3(int,bits,_t) glue3(i,bits,) = glue3(INT,bits,_C) (0);

#define DECL(us,bits) glue3(DECL,us,) (bits)

#define TESTUMAX(bits) glue3(u,bits,) = ~glue3(u,bits,); if (glue3(UINT,bits,_MAX) != glue3(u,bits,)) printf ("Something wrong with UINT%d_MAX\n", bits)

#define REPORTERROR(msg) { err_n++; if (err_first <= 0) err_first = __LINE__; printf msg; }

#define X_SIZE_MAX ((size_t)-1)

int main () {
	int err_n = 0;
	int err_first = 0;
	DECL(I,8)
	DECL(U,8)
	DECL(I,16)
	DECL(U,16)
	DECL(I,32)
	DECL(U,32)
#ifdef INT64_MAX
	DECL(I,64)
	DECL(U,64)
#endif
	intmax_t imax = INTMAX_C(0);
	uintmax_t umax = UINTMAX_C(0);
	char str0[256], str1[256];

	sprintf (str0, "%" PRINTF_INT32_MODIFIER "d", INT32_C(2147483647));
	if (0 != strcmp (str0, "2147483647")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
	if (atoi(PRINTF_INT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_INT32_DEC_WIDTH : %s\n", PRINTF_INT32_DEC_WIDTH));
	sprintf (str0, "%" PRINTF_INT32_MODIFIER "u", UINT32_C(4294967295));
	if (0 != strcmp (str0, "4294967295")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str0));
	if (atoi(PRINTF_UINT32_DEC_WIDTH) != (int) strlen(str0)) REPORTERROR (("Something wrong with PRINTF_UINT32_DEC_WIDTH : %s\n", PRINTF_UINT32_DEC_WIDTH));
#ifdef INT64_MAX
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "d", INT64_C(9223372036854775807));
	if (0 != strcmp (str1, "9223372036854775807")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
	if (atoi(PRINTF_INT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_INT64_DEC_WIDTH : %s, %d\n", PRINTF_INT64_DEC_WIDTH, (int) strlen(str1)));
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "u", UINT64_C(18446744073709550591));
	if (0 != strcmp (str1, "18446744073709550591")) REPORTERROR (("Something wrong with PRINTF_INT32_MODIFIER : %s\n", str1));
	if (atoi(PRINTF_UINT64_DEC_WIDTH) != (int) strlen(str1)) REPORTERROR (("Something wrong with PRINTF_UINT64_DEC_WIDTH : %s, %d\n", PRINTF_UINT64_DEC_WIDTH, (int) strlen(str1)));
#endif

	sprintf (str0, "%d %x\n", 0, ~0);

	sprintf (str1, "%d %x\n",  i8, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i8 : %s\n", str1));
	sprintf (str1, "%u %x\n",  u8, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u8 : %s\n", str1));
	sprintf (str1, "%d %x\n",  i16, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i16 : %s\n", str1));
	sprintf (str1, "%u %x\n",  u16, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u16 : %s\n", str1));
	sprintf (str1, "%" PRINTF_INT32_MODIFIER "d %x\n",  i32, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i32 : %s\n", str1));
	sprintf (str1, "%" PRINTF_INT32_MODIFIER "u %x\n",  u32, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with u32 : %s\n", str1));
#ifdef INT64_MAX
	sprintf (str1, "%" PRINTF_INT64_MODIFIER "d %x\n",  i64, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with i64 : %s\n", str1));
#endif
	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "d %x\n",  imax, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with imax : %s\n", str1));
	sprintf (str1, "%" PRINTF_INTMAX_MODIFIER "u %x\n",  umax, ~0);
	if (0 != strcmp (str0, str1)) REPORTERROR (("Something wrong with umax : %s\n", str1));

	TESTUMAX(8);
	TESTUMAX(16);
	TESTUMAX(32);
#ifdef INT64_MAX
	TESTUMAX(64);
#endif

#define STR(v) #v
#define Q(v) printf ("sizeof " STR(v) " = %u\n", (unsigned) sizeof (v));
	if (err_n) {
		printf ("pstdint.h is not correct.  Please use sizes below to correct it:\n");
	}

	Q(int)
	Q(unsigned)
	Q(long int)
	Q(short int)
	Q(int8_t)
	Q(int16_t)
	Q(int32_t)
#ifdef INT64_MAX
	Q(int64_t)
#endif

#if UINT_MAX < X_SIZE_MAX
	printf ("UINT_MAX < X_SIZE_MAX\n");
#else
	printf ("UINT_MAX >= X_SIZE_MAX\n");
#endif
	printf ("%" PRINTF_INT64_MODIFIER "u vs %" PRINTF_INT64_MODIFIER "u\n", UINT_MAX, X_SIZE_MAX);

	return EXIT_SUCCESS;
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<














































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Added compat/stdlib.h.














































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/*
 * stdlib.h --
 *
 *	Declares facilities exported by the "stdlib" portion of the C library.
 *	This file isn't complete in the ANSI-C sense; it only declares things
 *	that are needed by Tcl. This file is needed even on many systems with
 *	their own stdlib.h (e.g. SunOS) because not all stdlib.h files declare
 *	all the procedures needed here (such as strtol/strtoul).
 *
 * Copyright (c) 1991 The Regents of the University of California.
 * Copyright (c) 1994-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _STDLIB
#define _STDLIB

extern void		abort(void);
extern double		atof(const char *string);
extern int		atoi(const char *string);
extern long		atol(const char *string);
extern void *		calloc(unsigned long numElements, unsigned long size);
extern void		exit(int status);
extern void		free(void *blockPtr);
extern char *		getenv(const char *name);
extern void *		malloc(unsigned long numBytes);
extern void		qsort(void *base, unsigned long n, unsigned long size, int (*compar)(
			    const void *element1, const void *element2));
extern void *		realloc(void *ptr, unsigned long numBytes);
extern char *		realpath(const char *path, char *resolved_path);
extern int		mkstemps(char *templ, int suffixlen);
extern int		mkstemp(char *templ);
extern char *		mkdtemp(char *templ);
extern long		strtol(const char *string, char **endPtr, int base);
extern unsigned long	strtoul(const char *string, char **endPtr, int base);

#endif /* _STDLIB */
Added compat/unistd.h.
























































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
 * unistd.h --
 *
 *      Macros, constants and prototypes for Posix conformance.
 *
 * Copyright 1989 Regents of the University of California Permission to use,
 * copy, modify, and distribute this software and its documentation for any
 * purpose and without fee is hereby granted, provided that the above
 * copyright notice appear in all copies. The University of California makes
 * no representations about the suitability of this software for any purpose.
 * It is provided "as is" without express or implied warranty.
 */

#ifndef _UNISTD
#define _UNISTD

#include <sys/types.h>

#ifndef NULL
#   define NULL    0
#endif

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

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

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

#endif /* _UNISTD */
Changes to doc/3DBorder.3.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
.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).
.AP Tcl_Obj *objPtr in
Pointer to value whose value describes color corresponding to
background (flat areas).  Illuminated edges will be brighter than
this and shadowed edges will be darker than this.
.AP char *colorName in
Same as \fIobjPtr\fR except value is supplied as a string rather
than a value.
.AP Drawable drawable in
X token for window or pixmap;  indicates where graphics are to be drawn.
Must either be the X window for \fItkwin\fR or a pixmap with the
same screen and depth as \fItkwin\fR.
.AP Tk_3DBorder border in







|

|


|


|

<
|

<
|

<
|

<
|

<
|

<
|

<
|


|


|


|

|

|
>











|







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

26
27

28
29

30
31

32
33

34
35

36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
.so man.macros
.BS
.SH NAME
Tk_Alloc3DBorderFromObj, Tk_Get3DBorder, Tk_Get3DBorderFromObj, Tk_Draw3DRectangle, Tk_Fill3DRectangle, Tk_Draw3DPolygon, Tk_Fill3DPolygon, Tk_3DVerticalBevel, Tk_3DHorizontalBevel, Tk_SetBackgroundFromBorder, Tk_NameOf3DBorder, Tk_3DBorderColor, Tk_3DBorderGC, Tk_Free3DBorderFromObj, Tk_Free3DBorder \- draw borders with three-dimensional appearance
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR

Tk_3DBorder
\fBTk_Alloc3DBorderFromObj\fR(\fIinterp, tkwin, objPtr\fR)
.sp
Tk_3DBorder
\fBTk_Get3DBorder\fR(\fIinterp, tkwin, colorName\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).
.AP Tcl_Obj *objPtr in
Pointer to value whose value describes color corresponding to
background (flat areas).  Illuminated edges will be brighter than
this and shadowed edges will be darker than this.
.AP "const char" *colorName in
Same as \fIobjPtr\fR except value is supplied as a string rather
than a value.
.AP Drawable drawable in
X token for window or pixmap;  indicates where graphics are to be drawn.
Must either be the X window for \fItkwin\fR or a pixmap with the
same screen and depth as \fItkwin\fR.
.AP Tk_3DBorder border in
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
\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







|
|







182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
\fIwidth\fR and \fIheight\fR are the dimensions of the window), and
\fIborderWidth\fR specifies the number of pixels actually
occupied by the border.  The \fIrelief\fR argument indicates
which of several three-dimensional effects is desired:
\fBTK_RELIEF_RAISED\fR means that the interior of the rectangle should
appear raised relative to the exterior of the rectangle, and
\fBTK_RELIEF_SUNKEN\fR means that the interior should appear depressed.
\fBTK_RELIEF_GROOVE\fR and \fBTK_RELIEF_RIDGE\fR mean that there should
appear to be a groove or ridge around the exterior of the rectangle.
.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








|
>
281
282
283
284
285
286
287
288
289
with the window and color name used to create the
border; for \fBTk_Free3DBorder\fR the border to release is specified
with the Tk_3DBorder token for the border.
There should be exactly one call to \fBTk_Free3DBorderFromObj\fR or
\fBTk_Free3DBorder\fR for each call to \fBTk_Alloc3DBorderFromObj\fR
or \fBTk_Get3DBorder\fR.
.SH KEYWORDS
3D, background, border, color, depressed, illumination, value, polygon,
raised, shadow, three-dimensional effect
Changes to doc/AddOption.3.
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
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







|
|
|

|

|



|




29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
associated with \fItkwin\fR's main window.  \fIName\fR
contains the option being specified and consists of names and/or
classes separated by asterisks or dots, in the usual X format.
\fIValue\fR contains the text string to associate with \fIname\fR;
this value will be returned in calls to \fBTk_GetOption\fR.
\fIPriority\fR specifies the priority of the value; when options are
queried using \fBTk_GetOption\fR, the value with the highest priority
is returned.  \fIPriority\fR must be between 0 and \fBTK_MAX_PRIO\fR (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.
.SH KEYWORDS
class, name, option, add
Changes to doc/ConfigWidg.3.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30
31
32
33
.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







|


|


|

|
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.SH NAME
Tk_ConfigureWidget, Tk_ConfigureInfo, Tk_ConfigureValue, Tk_FreeOptions \- process configuration options for widgets
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_ConfigureWidget\fR(\fIinterp, tkwin, specs, argc, argv, 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 char *widgRec in/out
.AP Tcl_Interp *interp in
Interpreter to use for returning error messages.
.AP Tk_Window tkwin in
Window used to represent widget (needed to set up X resources).
.AP "const Tk_ConfigSpec" *specs in
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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.







|
|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
options.
.AP Display *display in
Display containing widget whose record is being freed;  needed in
order to free up resources.
.BE
.SH DESCRIPTION
.PP
Note that \fBTk_ConfigureWidget\fR should be replaced with the new
\fBTcl_Obj\fR based API, \fBTk_SetOptions\fR.  The old interface is
retained for backward compatibility.
.PP
\fBTk_ConfigureWidget\fR is called to configure various aspects of a
widget, such as colors, fonts, border width, etc.
It is intended as a convenience procedure to reduce the amount
of code that must be written in individual widget managers to
handle configuration information.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
.CS
typedef struct {
    int \fItype\fR;
    const char *\fIargvName\fR;
    const char *\fIdbName\fR;
    const char *\fIdbClass\fR;
    const char *\fIdefValue\fR;
    size_t \fIoffset\fR;
    int \fIspecFlags\fR;
    const Tk_CustomOption *\fIcustomPtr\fR;
} \fBTk_ConfigSpec\fR;
.CE
The \fItype\fR field indicates what type of configuration option this is
(e.g. \fBTK_CONFIG_COLOR\fR for a color value, or \fBTK_CONFIG_INT\fR for
an integer value).  The \fItype\fR field indicates how to use the







|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
.CS
typedef struct {
    int \fItype\fR;
    const char *\fIargvName\fR;
    const char *\fIdbName\fR;
    const char *\fIdbClass\fR;
    const char *\fIdefValue\fR;
    int \fIoffset\fR;
    int \fIspecFlags\fR;
    const Tk_CustomOption *\fIcustomPtr\fR;
} \fBTk_ConfigSpec\fR;
.CE
The \fItype\fR field indicates what type of configuration option this is
(e.g. \fBTK_CONFIG_COLOR\fR for a color value, or \fBTK_CONFIG_INT\fR for
an integer value).  The \fItype\fR field indicates how to use the
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
172
173

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

188
189
190
191
192
193

194
195
196
197
198
199
200
201
202
203

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

223
224
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
240

241
242
243
244
245
246
247
248
249
250

251
252
253
254

255
256
257
258
259
260

261
262
263
264
265
266

267
268
269
270
271

272
273
274
275
276
277
278
279
280
281

282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299

300
301
302
303
304
305
306

307
308
309
310
311
312

313
314
315
316
317
318

319
320
321
322
323
324
325

326
327
328
329
330
331
332
333
334

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

349
350
351
352
353
354
355

356
357
358
359
360
361
362
form, such as a color if \fItype\fR is \fBTK_CONFIG_COLOR\fR or an integer
if \fItype\fR is \fBTK_CONFIG_INT\fR.  This value is then stored in the
record pointed to by \fIwidgRec\fR.  This record is assumed to
contain information relevant to the manager of the widget;  its exact
type is unknown to \fBTk_ConfigureWidget\fR.  The \fIoffset\fR field
of each \fIspecs\fR entry indicates where in \fIwidgRec\fR to store
the information about this configuration option.  You should use the
\fBoffsetof\fR macro to generate \fIoffset\fR values.  The location

indicated by \fIwidgRec\fR and \fIoffset\fR will be referred to as the
.QW target
in the descriptions below.
.PP
The \fItype\fR field of each entry in \fIspecs\fR determines what
to do with the string value of that configuration option.  The
legal values for \fItype\fR, and the corresponding actions, are:
.TP
\fBTK_CONFIG_ACTIVE_CURSOR\fR

The value
must be an ASCII string identifying a cursor in a form
suitable for passing to \fBTk_GetCursor\fR.
The value is converted to a \fBTk_Cursor\fR by calling
\fBTk_GetCursor\fR and the result is stored in the target.
In addition, the resulting cursor is made the active cursor
for \fItkwin\fR by calling \fBXDefineCursor\fR.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target and \fItkwin\fR's
active cursor will be set to \fBNone\fR.
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







|
>
|








>














>






>










>



















>










>








>










>




>






>






>





>










>










>








>







>






>






>






<
>
|








>














>







>







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

345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
form, such as a color if \fItype\fR is \fBTK_CONFIG_COLOR\fR or an integer
if \fItype\fR is \fBTK_CONFIG_INT\fR.  This value is then stored in the
record pointed to by \fIwidgRec\fR.  This record is assumed to
contain information relevant to the manager of the widget;  its exact
type is unknown to \fBTk_ConfigureWidget\fR.  The \fIoffset\fR field
of each \fIspecs\fR entry indicates where in \fIwidgRec\fR to store
the information about this configuration option.  You should use the
\fBTk_Offset\fR macro to generate \fIoffset\fR values (see below for
a description of \fBTk_Offset\fR).  The location indicated by
\fIwidgRec\fR and \fIoffset\fR will be referred to as the
.QW target
in the descriptions below.
.PP
The \fItype\fR field of each entry in \fIspecs\fR determines what
to do with the string value of that configuration option.  The
legal values for \fItype\fR, and the corresponding actions, are:
.TP
\fBTK_CONFIG_ACTIVE_CURSOR\fR
.
The value
must be an ASCII string identifying a cursor in a form
suitable for passing to \fBTk_GetCursor\fR.
The value is converted to a \fBTk_Cursor\fR by calling
\fBTk_GetCursor\fR and the result is stored in the target.
In addition, the resulting cursor is made the active cursor
for \fItkwin\fR by calling \fBXDefineCursor\fR.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target and \fItkwin\fR's
active cursor will be set to \fBNone\fR.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeCursor\fR.
.TP
\fBTK_CONFIG_ANCHOR\fR
.
The value must be an ASCII string identifying an anchor point in one of the ways
accepted by \fBTk_GetAnchor\fR.
The string is converted to a \fBTk_Anchor\fR by calling
\fBTk_GetAnchor\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_BITMAP\fR
.
The value must be an ASCII string identifying a bitmap in a form
suitable for passing to \fBTk_GetBitmap\fR.  The value is converted
to a \fBPixmap\fR by calling \fBTk_GetBitmap\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target is set to \fBNone\fR.
If the previous value of the target
was not \fBNone\fR, then it is freed by passing it to \fBTk_FreeBitmap\fR.
.TP
\fBTK_CONFIG_BOOLEAN\fR
.
The value must be an ASCII string specifying a boolean value.  Any
of the values
.QW true ,
.QW yes ,
.QW on ,
or
.QW 1 ,
or an abbreviation of one of these values, means true;
any of the values
.QW false ,
.QW no ,
.QW off ,
or
.QW 0 ,
or an abbreviation of one of these values, means false.
The target is expected to be an integer;  for true values it will
be set to 1 and for false values it will be set to 0.
.TP
\fBTK_CONFIG_BORDER\fR
.
The value must be an ASCII string identifying a border color in a form
suitable for passing to \fBTk_Get3DBorder\fR.  The value is converted
to a (\fBTk_3DBorder *\fR) by calling \fBTk_Get3DBorder\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_Free3DBorder\fR.
.TP
\fBTK_CONFIG_CAP_STYLE\fR
.
The value must be
an ASCII string identifying a cap style in one of the ways
accepted by \fBTk_GetCapStyle\fR.
The string is converted to an integer value corresponding
to the cap style by calling
\fBTk_GetCapStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_COLOR\fR
.
The value must be an ASCII string identifying a color in a form
suitable for passing to \fBTk_GetColor\fR.  The value is converted
to an (\fBXColor *\fR) by calling \fBTk_GetColor\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to \fBNone\fR.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeColor\fR.
.TP
\fBTK_CONFIG_CURSOR\fR
.
This option is identical to \fBTK_CONFIG_ACTIVE_CURSOR\fR except
that the new cursor is not made the active one for \fItkwin\fR.
.TP
\fBTK_CONFIG_CUSTOM\fR
.
This option allows applications to define new option types.
The \fIcustomPtr\fR field of the entry points to a structure
defining the new option type.
See the section \fBCUSTOM OPTION TYPES\fR below for details.
.TP
\fBTK_CONFIG_DOUBLE\fR
.
The value must be an ASCII floating-point number in
the format accepted by \fBstrtol\fR.  The string is converted
to a \fBdouble\fR value, and the value is stored in the
target.
.TP
\fBTK_CONFIG_END\fR
.
Marks the end of the table.  The last entry in \fIspecs\fR
must have this type;  all of its other fields are ignored and it
will never match any arguments.
.TP
\fBTK_CONFIG_FONT\fR
.
The value must be an ASCII string identifying a font in a form
suitable for passing to \fBTk_GetFont\fR.  The value is converted
to a \fBTk_Font\fR by calling \fBTk_GetFont\fR and the result
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target
was not NULL, then it is freed by passing it to \fBTk_FreeFont\fR.
.TP
\fBTK_CONFIG_INT\fR
.
The value must be an ASCII integer string
in the format accepted by \fBstrtol\fR (e.g.
.QW 0
and
.QW 0x
prefixes may be used to specify octal or hexadecimal
numbers, respectively).  The string is converted to an integer
value and the integer is stored in the target.
.TP
\fBTK_CONFIG_JOIN_STYLE\fR
.
The value must be
an ASCII string identifying a join style in one of the ways
accepted by \fBTk_GetJoinStyle\fR.
The string is converted to an integer value corresponding
to the join style by calling
\fBTk_GetJoinStyle\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_JUSTIFY\fR
.
The value must be
an ASCII string identifying a justification method in one of the
ways accepted by \fBTk_GetJustify\fR.
The string is converted to a \fBTk_Justify\fR by calling
\fBTk_GetJustify\fR and the result is stored in the target.
.TP
\fBTK_CONFIG_MM\fR
.
The value must specify a screen distance in one of the forms acceptable
to \fBTk_GetScreenMM\fR.
The string is converted to double-precision floating-point distance
in millimeters and the value is stored in the target.
.TP
\fBTK_CONFIG_PIXELS\fR
.
The value must specify screen units in one of the forms acceptable
to \fBTk_GetPixels\fR.
The string is converted to an integer distance in pixels and the
value is stored in the target.
.TP
\fBTK_CONFIG_RELIEF\fR
.
The value must be an ASCII string identifying a relief in a form
suitable for passing to \fBTk_GetRelief\fR.  The value is converted
to an integer relief value by calling \fBTk_GetRelief\fR and the result
is stored in the target.
.TP
\fBTK_CONFIG_STRING\fR

.
A copy of the value is made by allocating memory space with
\fBTcl_Alloc\fR and copying the value into the dynamically-allocated
space.  A pointer to the new string is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR then the value
may be an empty string, in which case the target will be set to NULL.
If the previous value of the target was not NULL, then it is
freed by passing it to \fBTcl_Free\fR.
.TP
\fBTK_CONFIG_SYNONYM\fR
.
This \fItype\fR value identifies special entries in \fIspecs\fR that
are synonyms for other entries.  If an \fIargv\fR value matches the
\fIargvName\fR of a \fBTK_CONFIG_SYNONYM\fR entry, the entry is not used
directly. Instead, \fBTk_ConfigureWidget\fR searches \fIspecs\fR
for another entry whose \fIargvName\fR is the same as the \fIdbName\fR
field in the \fBTK_CONFIG_SYNONYM\fR entry;  this new entry is used just
as if its \fIargvName\fR had matched the \fIargv\fR value.  The
synonym mechanism allows multiple \fIargv\fR values to be used for
a single configuration option, such as
.QW \-background
and
.QW \-bg .
.TP
\fBTK_CONFIG_UID\fR
.
The value is translated to a \fBTk_Uid\fR
(by passing it to \fBTk_GetUid\fR).  The resulting value
is stored in the target.
If \fBTK_CONFIG_NULL_OK\fR is specified in \fIspecFlags\fR and the value
is an empty string then the target will be set to NULL.
.TP
\fBTK_CONFIG_WINDOW\fR
.
The value must be a window path name.  It is translated to a
\fBTk_Window\fR token and the token is stored in the target.
.SH "GROUPED ENTRIES"
.PP
In some cases it is useful to generate multiple resources from
a single configuration value.  For example, a color name might
be used both to generate the background color for a widget (using
377
378
379
380
381
382
383
384

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

398
399
400
401
402

403
404
405
406
407

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

421
422
423
424
425
426
427
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







|
>













>





>





>













>







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







471
472
473
474
475
476
477
for N different widget types, then N of the high-order bits will
be used.  Each \fIspecs\fR entry will have one of more of those
bits set in its \fIspecFlags\fR field to indicate the widget types
for which this entry is valid.  When calling \fBTk_ConfigureWidget\fR,
\fIflags\fR will have a single one of these bits set to select the
entries for the desired widget type.  For a working example of
this feature, see the code in tkButton.c.







.SH TK_CONFIGUREINFO
.PP
The \fBTk_ConfigureInfo\fR procedure may be used to obtain
information about one or all of the options for a given widget.
Given a token for a window (\fItkwin\fR), a table describing the
configuration options for a class of widgets (\fIspecs\fR), a
pointer to a widget record containing the current information for







>
>
>
>
>
>
>







492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
for N different widget types, then N of the high-order bits will
be used.  Each \fIspecs\fR entry will have one of more of those
bits set in its \fIspecFlags\fR field to indicate the widget types
for which this entry is valid.  When calling \fBTk_ConfigureWidget\fR,
\fIflags\fR will have a single one of these bits set to select the
entries for the desired widget type.  For a working example of
this feature, see the code in tkButton.c.
.SH TK_OFFSET
.PP
The \fBTk_Offset\fR macro is provided as a safe way of generating
the \fIoffset\fR values for entries in Tk_ConfigSpec structures.
It takes two arguments:  the name of a type of record, and the
name of a field in that record.  It returns the byte offset of
the named field in records of the given type.
.SH TK_CONFIGUREINFO
.PP
The \fBTk_ConfigureInfo\fR procedure may be used to obtain
information about one or all of the options for a given widget.
Given a token for a window (\fItkwin\fR), a table describing the
configuration options for a class of widgets (\fIspecs\fR), a
pointer to a widget record containing the current information for
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
    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,







|







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
    ClientData \fIclientData\fR;
} \fBTk_CustomOption\fR;

typedef int \fBTk_OptionParseProc\fR(
        ClientData \fIclientData\fR,
        Tcl_Interp *\fIinterp\fR,
        Tk_Window \fItkwin\fR,
        const char *\fIvalue\fR,
        char *\fIwidgRec\fR,
        int \fIoffset\fR);

typedef const char *\fBTk_OptionPrintProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR,
        char *\fIwidgRec\fR,
Changes to doc/CrtImgType.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19




20

21
22
23
24
25
26
27
'\"
'\" 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











|







>
>
>
>

>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
'\"
'\" Copyright (c) 1994 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateImageType, Tk_GetImageMasterData, Tk_GetImageModelData, Tk_InitImageArgs \- define new kind of image
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateImageType\fR(\fItypePtr\fR)
.sp
ClientData
\fBTk_GetImageMasterData\fR(\fIinterp, name, typePtrPtr\fR)
.sp
.VS "TIP 581"
ClientData
\fBTk_GetImageModelData\fR(\fIinterp, name, typePtrPtr\fR)
.VE "TIP 581"
.sp
\fBTk_InitImageArgs\fR(\fIinterp, argc, argvPtr\fR)
.SH ARGUMENTS
.AS "const Tk_ImageType" *typePtrPtr
.AP "const Tk_ImageType" *typePtr in
Structure that defines the new type of image.
For Tk 8.4 and earlier this must be static: a
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
.CS
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIname\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[],
        const Tk_ImageType *\fItypePtr\fR,
        Tk_ImageModel \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the \fBimage\fR
command was invoked, and \fIname\fR is the name for the new image,
which was either specified explicitly in the \fBimage\fR command
or generated automatically by the \fBimage\fR command.
The \fIobjc\fR and \fIobjv\fR arguments describe all the configuration







|







114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
.CS
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        const char *\fIname\fR,
        int \fIobjc\fR,
        Tcl_Obj *const \fIobjv\fR[],
        const Tk_ImageType *\fItypePtr\fR,
        Tk_ImageMaster \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
The \fIinterp\fR argument is the interpreter in which the \fBimage\fR
command was invoked, and \fIname\fR is the name for the new image,
which was either specified explicitly in the \fBimage\fR command
or generated automatically by the \fBimage\fR command.
The \fIobjc\fR and \fIobjv\fR arguments describe all the configuration
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243




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




263
264
265
266
267
268
269
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







|










>
>
>
>











|







>
>
>
>







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
The \fImodelData\fR argument will be the same as the value
stored in \fI*modelDataPtr\fR by \fIcreateProc\fR when the
image was created.
\fIdeleteProc\fR should release any resources associated with
the image.
.SH TK_GETIMAGEMODELDATA
.PP
The procedure \fBTk_GetImageMasterData\fR may be invoked to retrieve
information about an image.  For example, an image manager can use this
procedure to locate its image model data for an image.
If there exists an image named \fIname\fR
in the interpreter given by \fIinterp\fR, then \fI*typePtrPtr\fR is
filled in with type information for the image (the \fItypePtr\fR value
passed to \fBTk_CreateImageType\fR when the image type was registered)
and the return value is the ClientData value returned by the
\fIcreateProc\fR when the image was created (this is typically a
pointer to the image model data structure).  If no such image exists
then NULL is returned and NULL is stored at \fI*typePtrPtr\fR.
.PP
.VS "TIP 581"
\fBTk_GetImageModelData\fR is synonym for \fBTk_GetImageMasterData\fR
.VE "TIP 581"
.SH "LEGACY INTERFACE SUPPORT"
.PP
In Tk 8.2 and earlier, the definition of \fBTk_ImageCreateProc\fR
was incompatibly different, with the following prototype:
.CS
typedef int \fBTk_ImageCreateProc\fR(
        Tcl_Interp *\fIinterp\fR,
        char *\fIname\fR,
        int \fIargc\fR,
        char **\fIargv\fR,
        Tk_ImageType *\fItypePtr\fR,
        Tk_ImageMaster \fImodel\fR,
        ClientData *\fImodelDataPtr\fR);
.CE
Legacy programs and libraries dating from those days may still
contain code that defines extended Tk image types using the old
interface.  The Tk header file will still support this legacy
interface if the code is compiled with the macro \fBUSE_OLD_IMAGE\fR
defined.
.PP
.VS "TIP 581"
\fITk_ImageModel\fR is synonym for \fITk_ImageMaster\fR
.VE "TIP 581"
.PP
When the \fBUSE_OLD_IMAGE\fR legacy support is enabled, you may
see the routine \fBTk_InitImageArgs\fR in use.  This was a migration
tool used to create stub-enabled extensions that could be loaded
into interps containing all versions of Tk 8.1 and later.  Tk 8.5 no longer
provides this routine, but uses a macro to convert any attempted
calls of this routine into an empty comment.  Any stub-enabled
Changes to doc/CrtItemType.3.
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
The first data structure is a Tk_ItemType; it contains
information such as the name of the type and pointers to
the standard procedures implemented by the type manager:
.PP
.CS
typedef struct Tk_ItemType {
    const char *\fIname\fR;
    size_t \fIitemSize\fR;
    Tk_ItemCreateProc *\fIcreateProc\fR;
    const Tk_ConfigSpec *\fIconfigSpecs\fR;
    Tk_ItemConfigureProc *\fIconfigProc\fR;
    Tk_ItemCoordProc *\fIcoordProc\fR;
    Tk_ItemDeleteProc *\fIdeleteProc\fR;
    Tk_ItemDisplayProc *\fIdisplayProc\fR;
    int \fIalwaysRedraw\fR;
    Tk_ItemPointProc *\fIpointProc\fR;
    Tk_ItemAreaProc *\fIareaProc\fR;
    Tk_ItemPostscriptProc *\fIpostscriptProc\fR;
    Tk_ItemScaleProc *\fIscaleProc\fR;
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    Tk_ItemType *\fInextPtr\fR;
.VS "8.7, TIP164"
    Tk_ItemRotateProc *\fIrotateProc\fR;
.VE "8.7, TIP164"
} \fBTk_ItemType\fR;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail
later in this manual entry.
When \fBTk_CreateItemType\fR is called, its \fItypePtr\fR
argument must point to a structure with all of the fields initialized







|


















<
<
<







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



86
87
88
89
90
91
92
The first data structure is a Tk_ItemType; it contains
information such as the name of the type and pointers to
the standard procedures implemented by the type manager:
.PP
.CS
typedef struct Tk_ItemType {
    const char *\fIname\fR;
    int \fIitemSize\fR;
    Tk_ItemCreateProc *\fIcreateProc\fR;
    const Tk_ConfigSpec *\fIconfigSpecs\fR;
    Tk_ItemConfigureProc *\fIconfigProc\fR;
    Tk_ItemCoordProc *\fIcoordProc\fR;
    Tk_ItemDeleteProc *\fIdeleteProc\fR;
    Tk_ItemDisplayProc *\fIdisplayProc\fR;
    int \fIalwaysRedraw\fR;
    Tk_ItemPointProc *\fIpointProc\fR;
    Tk_ItemAreaProc *\fIareaProc\fR;
    Tk_ItemPostscriptProc *\fIpostscriptProc\fR;
    Tk_ItemScaleProc *\fIscaleProc\fR;
    Tk_ItemTranslateProc *\fItranslateProc\fR;
    Tk_ItemIndexProc *\fIindexProc\fR;
    Tk_ItemCursorProc *\fIicursorProc\fR;
    Tk_ItemSelectionProc *\fIselectionProc\fR;
    Tk_ItemInsertProc *\fIinsertProc\fR;
    Tk_ItemDCharsProc *\fIdCharsProc\fR;
    Tk_ItemType *\fInextPtr\fR;



} \fBTk_ItemType\fR;
.CE
.PP
The fields of a Tk_ItemType structure are described in more detail
later in this manual entry.
When \fBTk_CreateItemType\fR is called, its \fItypePtr\fR
argument must point to a structure with all of the fields initialized
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning,
and \fIdeltaX\fR and \fIdeltaY\fR give the amounts that should be
added to each x and y coordinate within the item.
The type manager should adjust the item's coordinates and
update the bounding box in the item's header.
.SS ROTATEPROC
.VS "8.7, TIP164"
.PP
\fItypePtr\->rotateProc\fR is invoked by Tk to rotate a canvas item
during the \fBrotate\fR widget command.
The procedure must match the following prototype:
.PP
.CS
typedef void \fBTk_ItemRotateProc\fR(
        Tk_Canvas \fIcanvas\fR,
        Tk_Item *\fIitemPtr\fR,
        double \fIoriginX\fR,
        double \fIoriginY\fR,
        double \fIangleRad\fR);
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning.
\fIoriginX\fR and \fIoriginY\fR specify an origin relative to which
the item is to be rotated, and \fIangleRad\fR gives the anticlockwise
rotation to be applied in radians.
The item should adjust the coordinates of its control points so that where
they used to have coordinates \fIx\fR and \fIy\fR, they will have new
coordinates \fIx\(fm\fR and \fIy\(fm\fR, where
.PP
.CS
\fIrelX\fR = \fIx\fR - \fIoriginX\fR
\fIrelY\fR = \fIy\fR - \fIoriginY\fR
\fIx\(fm\fR = \fIoriginX\fR + \fIrelX\fR \(mu cos(\fIangleRad\fR) + \fIrelY\fR \(mu sin(\fIangleRad\fR)
\fIy\(fm\fR = \fIoriginY\fR \(mi \fIrelX\fR \(mu sin(\fIangleRad\fR) + \fIrelY\fR \(mu cos(\fIangleRad\fR)
.CE
.PP
The control points for an item are not necessarily the coordinates provided to
the item when it is created (or via the \fItypePtr\->coordProc\fR), but could
instead be derived from them.
\fIrotateProc\fR must also update the bounding box in the item's header.
.PP
Item types do not need to provide a \fItypePtr\->rotateProc\fR. If the
\fItypePtr\->rotateProc\fR is NULL, the \fItypePtr\->coordProc\fR will be
used instead to retrieve and update the list of coordinates.
.VE "8.7, TIP164"
.SS INDEXPROC
.PP
\fItypePtr\->indexProc\fR is invoked by Tk to translate a string
index specification into a numerical index, for example during the
\fBindex\fR widget command.
It is only relevant for item types that support indexable text or coordinates;
\fItypePtr\->indexProc\fR may be specified as NULL for non-textual







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







545
546
547
548
549
550
551








































552
553
554
555
556
557
558
.CE
.PP
The \fIcanvas\fR and \fIitemPtr\fR arguments have the usual meaning,
and \fIdeltaX\fR and \fIdeltaY\fR give the amounts that should be
added to each x and y coordinate within the item.
The type manager should adjust the item's coordinates and
update the bounding box in the item's header.








































.SS INDEXPROC
.PP
\fItypePtr\->indexProc\fR is invoked by Tk to translate a string
index specification into a numerical index, for example during the
\fBindex\fR widget command.
It is only relevant for item types that support indexable text or coordinates;
\fItypePtr\->indexProc\fR may be specified as NULL for non-textual
Changes to doc/EventHndlr.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_CreateEventHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateEventHandler, Tk_DeleteEventHandler, Tk_GetButtonMask, Tk_SendVirtualEvent \- associate procedure callback with an X event
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_DeleteEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_GetButtonMask\fR(\fIbutton\fR)
.sp
\fBTk_SendVirtualEvent\fR(\fItkwin, eventName, detail\fR)
.SH ARGUMENTS
.AS "unsigned long" clientData
.AP unsigned button in
Button number.
.AP "const char" *eventName in
The name of the virtual event.
.AP Tcl_Obj *detail in
Detail information for the virtual event.
.AP Tk_Window tkwin in
Token for window in which events may occur.
.AP "unsigned long" mask in
Bit-mask of events (such as \fBButtonPressMask\fR)
for which \fIproc\fR should be called.
.AP Tk_EventProc *proc in
Procedure to invoke whenever an event in \fImask\fR occurs











|







<
<
<
<


<
<
<
<
<
<







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




20
21






22
23
24
25
26
27
28
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1996 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_CreateEventHandler 3 "" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateEventHandler, Tk_DeleteEventHandler \- associate procedure callback with an X event
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_CreateEventHandler\fR(\fItkwin, mask, proc, clientData\fR)
.sp
\fBTk_DeleteEventHandler\fR(\fItkwin, mask, proc, clientData\fR)




.SH ARGUMENTS
.AS "unsigned long" clientData






.AP Tk_Window tkwin in
Token for window in which events may occur.
.AP "unsigned long" mask in
Bit-mask of events (such as \fBButtonPressMask\fR)
for which \fIproc\fR should be called.
.AP Tk_EventProc *proc in
Procedure to invoke whenever an event in \fImask\fR occurs
77
78
79
80
81
82
83
84
85
86
87
88
89
90
When a window is deleted all of its handlers will be deleted
automatically;  in this case there is no need to call
\fBTk_DeleteEventHandler\fR.
.PP
If multiple handlers are declared for the same type of X event
on the same window, then the handlers will be invoked in the
order they were created.
.PP
\fBTk_GetButtonMask\fR returns the button mask corresponding to
the button. E.g it will return \fIButton1Mask\fR for button \fIButton1\fR.
.PP
\fBTk_SendVirtualEvent\fR sends a virtual event to Tk's event queue.
.SH KEYWORDS
bind, callback, event, handler







<
<
<
<
<


67
68
69
70
71
72
73





74
75
When a window is deleted all of its handlers will be deleted
automatically;  in this case there is no need to call
\fBTk_DeleteEventHandler\fR.
.PP
If multiple handlers are declared for the same type of X event
on the same window, then the handlers will be invoked in the
order they were created.





.SH KEYWORDS
bind, callback, event, handler
Changes to doc/FindPhoto.3.
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
.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







|







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 than or equal to
\fIpixelSize\fR, \fBtk_PhotoPutblock\fR assumes no alpha data is
present and makes the image fully opaque.  This means that for layouts
where the channels are separate (or any other exotic layout where
\fIpixelSize\fR has to be smaller than the alpha offset), the alpha
channel will not be read correctly.  In order to be on the safe side
if this issue will be corrected in a future release, it is strongly
recommended you always provide alpha data - even if the image has no
Changes to doc/FreeXId.3.
21
22
23
24
25
26
27
28


















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







|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Display for which \fIid\fR was allocated.
.AP XID id in
Identifier of X resource (window, font, pixmap, cursor, graphics
context, or colormap) that is no longer in use.
.BE
.SH DESCRIPTION
.PP
The default allocator for resource identifiers provided by Xlib is very
simple-minded and does not allow resource identifiers to be re-used.
If a long-running application reaches the end of the resource id
space, it will generate an X protocol error and crash.
Tk replaces the default id allocator with its own allocator, which
allows identifiers to be reused.
In order for this to work, \fBTk_FreeXId\fR must be called to
tell the allocator about resources that have been freed.
Tk automatically calls \fBTk_FreeXId\fR whenever it frees a
resource, so if you use procedures like \fBTk_GetFont\fR,
\fBTk_GetGC\fR, and \fBTk_GetPixmap\fR then you need not call
\fBTk_FreeXId\fR.
However, if you allocate resources directly from Xlib, for example
by calling \fBXCreatePixmap\fR, then you should call \fBTk_FreeXId\fR
when you call the corresponding Xlib free procedure, such as
\fBXFreePixmap\fR.
If you do not call \fBTk_FreeXId\fR then the resource identifier will
be lost, which could cause problems if the application runs long enough
to lose all of the available identifiers.
.SH KEYWORDS
resource identifier
Changes to doc/GetColor.3.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
.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
String value describes desired color; internal rep will be
modified to cache pointer to corresponding (XColor *).
.AP char *name in
Same as \fIobjPtr\fR except description of color is passed as a string and
resulting (XColor *) is not cached.
.AP XColor *prefPtr in
Indicates red, green, and blue intensities of desired
color.
.AP XColor *colorPtr in
Pointer to X color information.  Must have been allocated by previous







|


|


|


|


|


|

|

|
>









|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
.SH NAME
Tk_AllocColorFromObj, Tk_GetColor, Tk_GetColorFromObj, Tk_GetColorByValue, Tk_NameOfColor, Tk_FreeColorFromObj, Tk_FreeColor \- maintain database of colors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
XColor *
\fBTk_AllocColorFromObj\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
String value describes desired color; internal rep will be
modified to cache pointer to corresponding (XColor *).
.AP "const char" *name in
Same as \fIobjPtr\fR except description of color is passed as a string and
resulting (XColor *) is not cached.
.AP XColor *prefPtr in
Indicates red, green, and blue intensities of desired
color.
.AP XColor *colorPtr in
Pointer to X color information.  Must have been allocated by previous
67
68
69
70
71
72
73

74
75
76
77
78
79
80
81
82
83

84
85
86
87
88
89
90
.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
42
43
44
45
46
47
48
49
50
51
.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
Description of cursor;  see below for possible values.  Internal rep will be
modified to cache pointer to corresponding Tk_Cursor.
.AP char *name in
Same as \fIobjPtr\fR except description of cursor is passed as a string and
resulting Tk_Cursor is not cached.
.AP "const char" *source in
Data for cursor cursor, in standard cursor format.
.AP "const char" *mask in
Data for mask cursor, in standard cursor format.
.AP "int" width in







|


|


|


|


|

|

|
>









|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
.SH NAME
Tk_AllocCursorFromObj, Tk_GetCursor, Tk_GetCursorFromObj, Tk_GetCursorFromData, Tk_NameOfCursor, Tk_FreeCursorFromObj, Tk_FreeCursor \- maintain database of cursors
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Cursor
\fBTk_AllocCursorFromObj\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
Description of cursor;  see below for possible values.  Internal rep will be
modified to cache pointer to corresponding Tk_Cursor.
.AP "const char" *name in
Same as \fIobjPtr\fR except description of cursor is passed as a string and
resulting Tk_Cursor is not cached.
.AP "const char" *source in
Data for cursor cursor, in standard cursor format.
.AP "const char" *mask in
Data for mask cursor, in standard cursor format.
.AP "int" width in
83
84
85
86
87
88
89

90
91
92
93
94
95
96
\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.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_AllocFontFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_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











|













<
<
<







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



26
27
28
29
30
31
32
'\"
'\" Copyright (c) 1990-1992 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_AllocFontFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_AllocFontFromObj, Tk_GetFont, Tk_GetFontFromObj, Tk_NameOfFont, Tk_FreeFontFromObj, Tk_FreeFont \- maintain database of fonts
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_Font
\fBTk_AllocFontFromObj(\fIinterp, tkwin, objPtr\fB)\fR
.sp
Tk_Font
\fBTk_GetFont(\fIinterp, tkwin, string\fB)\fR
.sp
Tk_Font
\fBTk_GetFontFromObj(\fItkwin, objPtr\fB)\fR
.sp



const char *
\fBTk_NameOfFont(\fItkfont\fB)\fR
.sp
Tk_Font
\fBTk_FreeFontFromObj(\fItkwin, objPtr\fB)\fR
.sp
void
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
\fBTk_AllocFontFromObj\fR and \fBTk_GetFont\fR maintain
a database of all fonts they have allocated.  If
the same font is requested multiple times (e.g. by different
windows or for different purposes), then a single Tk_Font will be
shared for all uses.  The underlying resources will be freed automatically
when no-one is using the font anymore.
.PP
The procedure \fBTk_FontGetDescription\fR returns information about the font
description as a Tcl list. One possible result is "{{DejaVu Sans} -16 bold underline}".
.PP
The procedure \fBTk_NameOfFont\fR is roughly the inverse of
\fBTk_GetFont\fR.  Given a \fItkfont\fR that was created by
\fBTk_GetFont\fR (or \fBTk_AllocFontFromObj\fR), the return value is
the \fIstring\fR argument that was
passed to \fBTk_GetFont\fR to create the font.  The string returned by
\fBTk_NameOfFont\fR is only guaranteed to persist until the \fItkfont\fR
is deleted.  The caller must not modify this string.







<
<
<







84
85
86
87
88
89
90



91
92
93
94
95
96
97
\fBTk_AllocFontFromObj\fR and \fBTk_GetFont\fR maintain
a database of all fonts they have allocated.  If
the same font is requested multiple times (e.g. by different
windows or for different purposes), then a single Tk_Font will be
shared for all uses.  The underlying resources will be freed automatically
when no-one is using the font anymore.
.PP



The procedure \fBTk_NameOfFont\fR is roughly the inverse of
\fBTk_GetFont\fR.  Given a \fItkfont\fR that was created by
\fBTk_GetFont\fR (or \fBTk_AllocFontFromObj\fR), the return value is
the \fIstring\fR argument that was
passed to \fBTk_GetFont\fR to create the font.  The string returned by
\fBTk_NameOfFont\fR is only guaranteed to persist until the \fItkfont\fR
is deleted.  The caller must not modify this string.
Changes to doc/GetPixels.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_GetPixelsFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM, Tk_GetDoublePixelsFromObj \- translate between strings and screen units
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetPixelsFromObj(\fIinterp, tkwin, objPtr, intPtr\fB)\fR
.sp
int
\fBTk_GetDoublePixelsFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
\fBTk_GetPixels(\fIinterp, tkwin, string, intPtr\fB)\fR
.sp
int
\fBTk_GetMMFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int











|







<
<
<







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



20
21
22
23
24
25
26
'\"
'\" Copyright (c) 1990 The Regents of the University of California.
'\" Copyright (c) 1994-1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_GetPixelsFromObj 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM \- translate between strings and screen units
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetPixelsFromObj(\fIinterp, tkwin, objPtr, intPtr\fB)\fR
.sp



int
\fBTk_GetPixels(\fIinterp, tkwin, string, intPtr\fB)\fR
.sp
int
\fBTk_GetMMFromObj(\fIinterp, tkwin, objPtr, doublePtr\fB)\fR
.sp
int
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
by a character that is not one of the ones above) then
\fBTCL_ERROR\fR is returned and an error message is left
in \fIinterp\fR's result if \fIinterp\fR is not NULL.
\fBTk_GetPixelsFromObj\fR caches information about the return
value in \fIobjPtr\fR, which speeds up future calls to
\fBTk_GetPixelsFromObj\fR with the same \fIobjPtr\fR.
.PP
\fBTk_GetDoublePixelsFromObj\fR is identical to \fBTk_GetPixelsFromObj\fR
except it returns a double not rounded to the nearest integer.
.PP
\fBTk_GetPixels\fR is identical to \fBTk_GetPixelsFromObj\fR except
that the screen distance is specified with a string instead
of an object.  This prevents \fBTk_GetPixels\fR from caching the
return value, so \fBTk_GetPixels\fR is less efficient than
\fBTk_GetPixelsFromObj\fR.
.PP
\fBTk_GetMMFromObj\fR and \fBTk_GetScreenMM\fR are similar to
\fBTk_GetPixelsFromObj\fR and \fBTk_GetPixels\fR (respectively) except
that they convert the screen distance to millimeters and
store a double-precision floating-point result at \fI*doublePtr\fR.
.SH KEYWORDS
centimeters, convert, inches, millimeters, pixels, points, screen units







<
<
<












77
78
79
80
81
82
83



84
85
86
87
88
89
90
91
92
93
94
95
by a character that is not one of the ones above) then
\fBTCL_ERROR\fR is returned and an error message is left
in \fIinterp\fR's result if \fIinterp\fR is not NULL.
\fBTk_GetPixelsFromObj\fR caches information about the return
value in \fIobjPtr\fR, which speeds up future calls to
\fBTk_GetPixelsFromObj\fR with the same \fIobjPtr\fR.
.PP



\fBTk_GetPixels\fR is identical to \fBTk_GetPixelsFromObj\fR except
that the screen distance is specified with a string instead
of an object.  This prevents \fBTk_GetPixels\fR from caching the
return value, so \fBTk_GetPixels\fR is less efficient than
\fBTk_GetPixelsFromObj\fR.
.PP
\fBTk_GetMMFromObj\fR and \fBTk_GetScreenMM\fR are similar to
\fBTk_GetPixelsFromObj\fR and \fBTk_GetPixels\fR (respectively) except
that they convert the screen distance to millimeters and
store a double-precision floating-point result at \fI*doublePtr\fR.
.SH KEYWORDS
centimeters, convert, inches, millimeters, pixels, points, screen units
Changes to doc/GetRelief.3.
11
12
13
14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
.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 ,
.QW \fBgroove\fR ,
.QW \fBraised\fR ,
.QW \fBridge\fR ,
.QW \fBsolid\fR ,
or
.QW \fBsunken\fR
(or any unique abbreviation thereof on input);
the internal rep will be modified to cache corresponding relief value.
.AP char *string in
Same as \fIobjPtr\fR except description of relief is passed as
a string.
.AP int *reliefPtr out
Pointer to location in which to store relief value corresponding to
\fIobjPtr\fR or \fIname\fR.
.AP "const char" *name
Name of the relief.
.AP int relief in
Relief value (one of \fBTK_RELIEF_FLAT\fR, \fBTK_RELIEF_RAISED\fR,
\fBTK_RELIEF_SUNKEN\fR, \fBTK_RELIEF_GROOVE\fR, \fBTK_RELIEF_SOLID\fR,
or \fBTK_RELIEF_RIDGE\fR).
.BE
.SH DESCRIPTION
.PP







|


|


|
>















|





<
<







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


47
48
49
50
51
52
53
.SH NAME
Tk_GetReliefFromObj, Tk_GetRelief, Tk_NameOfRelief \- translate between strings and relief values
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
int
\fBTk_GetReliefFromObj\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 ,
.QW \fBgroove\fR ,
.QW \fBraised\fR ,
.QW \fBridge\fR ,
.QW \fBsolid\fR ,
or
.QW \fBsunken\fR
(or any unique abbreviation thereof on input);
the internal rep will be modified to cache corresponding relief value.
.AP "const char" *name in
Same as \fIobjPtr\fR except description of relief is passed as
a string.
.AP int *reliefPtr out
Pointer to location in which to store relief value corresponding to
\fIobjPtr\fR or \fIname\fR.


.AP int relief in
Relief value (one of \fBTK_RELIEF_FLAT\fR, \fBTK_RELIEF_RAISED\fR,
\fBTK_RELIEF_SUNKEN\fR, \fBTK_RELIEF_GROOVE\fR, \fBTK_RELIEF_SOLID\fR,
or \fBTK_RELIEF_RIDGE\fR).
.BE
.SH DESCRIPTION
.PP
Changes to doc/GetScroll.3.
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
\fBTk_GetScrollInfoObj\fR parses the arguments expected by widget
scrolling commands such as \fBxview\fR and \fByview\fR.
It receives the entire list of words that make up a widget command
and parses the words starting with \fIobjv\fR[2].
The words starting with \fIobjv\fR[2] must have one of the following forms:
.CS
\fBmoveto \fIfraction\fR
\fBscroll \fInumber\fB pages\fR
\fBscroll \fInumber\fB units\fR
.CE
.LP
Any of the \fBmoveto\fR, \fBscroll\fR, \fBpages\fR, and \fBunits\fR
keywords may be abbreviated.
If \fIobjv\fR has the \fBmoveto\fR form, \fBTK_SCROLL_MOVETO\fR
is returned as result and \fI*fractionPtr\fR is filled in with the
\fIfraction\fR argument to the command, which must be a proper real
value.
If \fIobjv\fR has the \fBscroll\fR form, \fBTK_SCROLL_PAGES\fR
or \fBTK_SCROLL_UNITS\fR is returned and \fI*stepsPtr\fR is filled
in with the \fInumber\fR value, which must be a  integer or a float,
but if it is a float then it is converted to an integer, rounded away from 0.
If an error occurs in parsing the arguments, \fBTK_SCROLL_ERROR\fR
is returned and an error message is left in interpreter
\fIinterp\fR's result.
.PP
\fBTk_GetScrollInfo\fR is identical in function to
\fBTk_GetScrollInfoObj\fR.  However, \fBTk_GetScrollInfo\fR accepts
string arguments, making it more appropriate for use with legacy







|
|


|





|
|
|
<







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

66
67
68
69
70
71
72
\fBTk_GetScrollInfoObj\fR parses the arguments expected by widget
scrolling commands such as \fBxview\fR and \fByview\fR.
It receives the entire list of words that make up a widget command
and parses the words starting with \fIobjv\fR[2].
The words starting with \fIobjv\fR[2] must have one of the following forms:
.CS
\fBmoveto \fIfraction\fR
\fBscroll \fInumber\fB units\fR
\fBscroll \fInumber\fB pages\fR
.CE
.LP
Any of the \fBmoveto\fR, \fBscroll\fR, \fBunits\fR, and \fBpages\fR
keywords may be abbreviated.
If \fIobjv\fR has the \fBmoveto\fR form, \fBTK_SCROLL_MOVETO\fR
is returned as result and \fI*fractionPtr\fR is filled in with the
\fIfraction\fR argument to the command, which must be a proper real
value.
If \fIobjv\fR has the \fBscroll\fR form, \fBTK_SCROLL_UNITS\fR
or \fBTK_SCROLL_PAGES\fR is returned and \fI*stepsPtr\fR is filled
in with the \fInumber\fR value, which must be a proper integer.

If an error occurs in parsing the arguments, \fBTK_SCROLL_ERROR\fR
is returned and an error message is left in interpreter
\fIinterp\fR's result.
.PP
\fBTk_GetScrollInfo\fR is identical in function to
\fBTk_GetScrollInfoObj\fR.  However, \fBTk_GetScrollInfo\fR accepts
string arguments, making it more appropriate for use with legacy
Changes to doc/ImgChanged.3.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Tk_ImageChanged \- notify widgets that image needs to be redrawn
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ImageChanged\fR(\fImodel, x, y, width, height, imageWidth, imageHeight\fR)
.SH ARGUMENTS
.AS Tk_ImageModel imageHeight
.AP Tk_ImageModel model in
Token for image, which was passed to image's \fIcreateProc\fR when
the image was created.
.AP int x in
X-coordinate of upper-left corner of region that needs redisplay (measured
from upper-left corner of image).
.AP int y in
Y-coordinate of upper-left corner of region that needs redisplay (measured







|
|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Tk_ImageChanged \- notify widgets that image needs to be redrawn
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
\fBTk_ImageChanged\fR(\fImodel, x, y, width, height, imageWidth, imageHeight\fR)
.SH ARGUMENTS
.AS Tk_ImageMaster imageHeight
.AP Tk_ImageMaster model in
Token for image, which was passed to image's \fIcreateProc\fR when
the image was created.
.AP int x in
X-coordinate of upper-left corner of region that needs redisplay (measured
from upper-left corner of image).
.AP int y in
Y-coordinate of upper-left corner of region that needs redisplay (measured
43
44
45
46
47
48
49




50
51
52
53
54
55
56
the image are notified so that they can redisplay themselves
appropriately.
The \fImodel\fR argument identifies the image, and
\fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
specify a rectangular region within the image that needs to
be redrawn.
\fIimageWidth\fR and \fIimageHeight\fR specify the image's (new) size.




.PP
An image manager should call \fBTk_ImageChanged\fR during
its \fIcreateProc\fR to specify the image's initial size and to
force redisplay if there are existing instances for the image.
If any of the pixel values in the image should change later on,
\fBTk_ImageChanged\fR should be called again with \fIx\fR, \fIy\fR,
\fIwidth\fR, and \fIheight\fR values that cover all the pixels







>
>
>
>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
the image are notified so that they can redisplay themselves
appropriately.
The \fImodel\fR argument identifies the image, and
\fIx\fR, \fIy\fR, \fIwidth\fR, and \fIheight\fR
specify a rectangular region within the image that needs to
be redrawn.
\fIimageWidth\fR and \fIimageHeight\fR specify the image's (new) size.
.PP
.VS "TIP 581"
\fITk_ImageModel\fR is synonym for \fITk_ImageMaster\fR
.VE "TIP 581"
.PP
An image manager should call \fBTk_ImageChanged\fR during
its \fIcreateProc\fR to specify the image's initial size and to
force redisplay if there are existing instances for the image.
If any of the pixel values in the image should change later on,
\fBTk_ImageChanged\fR should be called again with \fIx\fR, \fIy\fR,
\fIwidth\fR, and \fIheight\fR values that cover all the pixels
Changes to doc/ManageGeom.3.
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
.PP
The structure pointed to by \fImgrPtr\fR contains information about
the geometry manager:
.CS
typedef struct {
    const char *\fIname\fR;
    Tk_GeomRequestProc *\fIrequestProc\fR;
    Tk_GeomLostContentProc *\fIlostContentProc\fR;
} \fBTk_GeomMgr\fR;
.CE
The \fIname\fR field is the textual name for the geometry manager,
such as \fBpack\fR or \fBplace\fR;  this value will be returned
by the command \fBwinfo manager\fR.
.PP
\fIrequestProc\fR is a procedure in the geometry manager that







|







40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
.PP
The structure pointed to by \fImgrPtr\fR contains information about
the geometry manager:
.CS
typedef struct {
    const char *\fIname\fR;
    Tk_GeomRequestProc *\fIrequestProc\fR;
    Tk_GeomLostSlaveProc *\fIlostSlaveProc\fR;
} \fBTk_GeomMgr\fR;
.CE
The \fIname\fR field is the textual name for the geometry manager,
such as \fBpack\fR or \fBplace\fR;  this value will be returned
by the command \fBwinfo manager\fR.
.PP
\fIrequestProc\fR is a procedure in the geometry manager that
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
.CE
The parameters to \fIrequestProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
\fIclientData\fR usually points to a data
structure containing application-specific information about
how to manage \fItkwin\fR's geometry.
.PP
The \fIlostContentProc\fR field of \fImgrPtr\fR points to another
procedure in the geometry manager.
Tk will invoke \fIlostContentProc\fR if some other manager
calls \fBTk_ManageGeometry\fR to claim
\fItkwin\fR away from the current geometry manager.
\fIlostContentProc\fR is not invoked if \fBTk_ManageGeometry\fR is
called with a NULL value for \fImgrPtr\fR (presumably the current
geometry manager has made this call, so it already knows that the
window is no longer managed), nor is it called if \fImgrPtr\fR
is the same as the window's current geometry manager.
\fIlostContentProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void \fBTk_GeomLostContentProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostContentProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
.SH KEYWORDS
callback, geometry, managed, request, unmanaged







|

|


|




|


|



|



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
.CE
The parameters to \fIrequestProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
\fIclientData\fR usually points to a data
structure containing application-specific information about
how to manage \fItkwin\fR's geometry.
.PP
The \fIlostSlaveProc\fR field of \fImgrPtr\fR points to another
procedure in the geometry manager.
Tk will invoke \fIlostSlaveProc\fR if some other manager
calls \fBTk_ManageGeometry\fR to claim
\fItkwin\fR away from the current geometry manager.
\fIlostSlaveProc\fR is not invoked if \fBTk_ManageGeometry\fR is
called with a NULL value for \fImgrPtr\fR (presumably the current
geometry manager has made this call, so it already knows that the
window is no longer managed), nor is it called if \fImgrPtr\fR
is the same as the window's current geometry manager.
\fIlostSlaveProc\fR should have
arguments and results that match the following prototype:
.CS
typedef void \fBTk_GeomLostSlaveProc\fR(
        ClientData \fIclientData\fR,
        Tk_Window \fItkwin\fR);
.CE
The parameters to \fIlostSlaveProc\fR will be identical to the
corresponding parameters passed to \fBTk_ManageGeometry\fR.
.SH KEYWORDS
callback, geometry, managed, request, unmanaged
Changes to doc/NameOfImg.3.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28




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




.SH KEYWORDS
image manager, image name







|

|
|








>
>
>
>


10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.SH NAME
Tk_NameOfImage \- Return name of image.
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
const char *
\fBTk_NameOfImage\fR(\fIimageMaster\fR)
.SH ARGUMENTS
.AS Tk_ImageMaster imageMaster
.AP Tk_ImageMaster imageMaster in
Token for image, which was passed to image manager's \fIcreateProc\fR when
the image was created.
.BE
.SH DESCRIPTION
.PP
This procedure is invoked by image managers to find out the name
of an image.  Given the token for the image, it returns the
string name for the image.
.PP
.VS "TIP 581"
\fITk_ImageModel\fR is synonym for \fITk_ImageMaster\fR
.VE "TIP 581"
.SH KEYWORDS
image manager, image name
Changes to doc/ParseArgv.3.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
.PP
The \fIargTable\fR array specifies the kinds of arguments that are
expected;  each of its entries has the following structure:
.CS
typedef struct {
    const char *\fIkey\fR;
    int \fItype\fR;
    void *\fIsrc\fR;
    void *\fIdst\fR;
    const char *\fIhelp\fR;
} \fBTk_ArgvInfo\fR;
.CE
The \fIkey\fR field is a string such as
.QW \-display
or
.QW \-bg







|
|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
.PP
The \fIargTable\fR array specifies the kinds of arguments that are
expected;  each of its entries has the following structure:
.CS
typedef struct {
    const char *\fIkey\fR;
    int \fItype\fR;
    char *\fIsrc\fR;
    char *\fIdst\fR;
    const char *\fIhelp\fR;
} \fBTk_ArgvInfo\fR;
.CE
The \fIkey\fR field is a string such as
.QW \-display
or
.QW \-bg
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
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;







|

|

|

|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
char *fileName = defaultFileName;
Boolean exec = FALSE;

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

main(argc, argv)
    int argc;
Changes to doc/SetClassProcs.3.
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
.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.







|







29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
.PP
\fBTk_SetClassProcs\fR is called to register a set of procedures that
are used as callbacks in different places.
.PP
The structure pointed to by \fIprocs\fR contains the following:
.CS
typedef struct Tk_ClassProcs {
    unsigned int \fIsize\fR;
    Tk_ClassWorldChangedProc *\fIworldChangedProc\fR;
    Tk_ClassCreateProc *\fIcreateProc\fR;
    Tk_ClassModalProc *\fImodalProc\fR;
} \fBTk_ClassProcs\fR;
.CE
The \fIsize\fR field is used to simplify future expansion of the
structure. It should always be set to (literally) \fBsizeof(Tk_ClassProcs)\fR.
Changes to doc/SetOptions.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37




38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
'\"
'\" Copyright (c) 1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_SetOptions 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateOptionTable, Tk_DeleteOptionTable, Tk_InitOptions, Tk_SetOptions, Tk_FreeSavedOptions, Tk_RestoreSavedOptions, Tk_GetOptionValue,  Tk_GetOptionInfo, Tk_FreeConfigOptions \- process configuration options
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Tk_OptionTable
\fBTk_CreateOptionTable(\fIinterp, templatePtr\fB)\fR
.sp
\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.
.AP "const Tk_OptionSpec" *templatePtr in
Points to an array of static information that describes the configuration
options that are supported.  Used to build a Tk_OptionTable.  The information
pointed to by this argument must exist for the lifetime of the Tk_OptionTable.
.AP Tk_OptionTable optionTable in
Token for an option table.  Must have been returned by a previous call
to \fBTk_CreateOptionTable\fR.
.AP void *recordPtr in/out
Points to structure in which values of configuration options are stored;
fields of this record are modified by procedures such as \fBTk_SetOptions\fR
and read by procedures such as \fBTk_GetOptionValue\fR.
.AP Tk_Window tkwin in
For options such as \fBTK_OPTION_COLOR\fR, this argument indicates
the window in which the option will be used.  If \fIoptionTable\fR uses
no window-dependent options, then a NULL value may be supplied for










|





|

|


|


|

|

|


|


|

|
>
>
>
>














|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
'\"
'\" Copyright (c) 1998 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_SetOptions 3 8.1 Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_CreateOptionTable, Tk_DeleteOptionTable, Tk_InitOptions, Tk_SetOptions, Tk_FreeSavedOptions, Tk_RestoreSavedOptions, Tk_GetOptionValue,  Tk_GetOptionInfo, Tk_FreeConfigOptions, Tk_Offset \- 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)
.sp
int
\fBTk_Offset(\fItype, field\fB)\fR
.fi
.SH ARGUMENTS
.AS Tk_SavedOptions "*const objv[]" in/out
.AP Tcl_Interp *interp in
A Tcl interpreter.  Most procedures use this only for returning error
messages; if it is NULL then no error messages are returned.  For
\fBTk_CreateOptionTable\fR the value cannot be NULL; it gives the
interpreter in which the option table will be used.
.AP "const Tk_OptionSpec" *templatePtr in
Points to an array of static information that describes the configuration
options that are supported.  Used to build a Tk_OptionTable.  The information
pointed to by this argument must exist for the lifetime of the Tk_OptionTable.
.AP Tk_OptionTable optionTable in
Token for an option table.  Must have been returned by a previous call
to \fBTk_CreateOptionTable\fR.
.AP char *recordPtr in/out
Points to structure in which values of configuration options are stored;
fields of this record are modified by procedures such as \fBTk_SetOptions\fR
and read by procedures such as \fBTk_GetOptionValue\fR.
.AP Tk_Window tkwin in
For options such as \fBTK_OPTION_COLOR\fR, this argument indicates
the window in which the option will be used.  If \fIoptionTable\fR uses
no window-dependent options, then a NULL value may be supplied for
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
.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







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
.QW widget
will be used to refer to the object whose options are being managed; in
practice the object may not actually be a widget.  The term
.QW "widget record"
is used to refer to the C-level structure in
which information about a particular widget or object is stored.
.PP
Note 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







|
<




|
<





|
>
>







127
128
129
130
131
132
133
134

135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
class.  A Tk_OptionTable may be used only in a single interpreter, given
by the \fIinterp\fR argument to \fBTk_CreateOptionTable\fR.  When an
option table is no longer needed \fBTk_DeleteOptionTable\fR should be
called to free all of its resources.  All of the option tables
for a Tcl interpreter are freed automatically if the interpreter is deleted.
.PP
\fBTk_InitOptions\fR is invoked when a new widget is created to set the
default values.

\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
232
233
234
235
236
237
238






239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
(e.g., because \fInamePtr\fR contains an unknown option name) then NULL
is returned and an error message is left in \fIinterp\fR's result unless
\fIinterp\fR is NULL.
.PP
\fBTk_FreeConfigOptions\fR must be invoked when a widget is deleted.
It frees all of the resources associated with any of the configuration
options defined in \fIrecordPtr\fR by \fIoptionTable\fR.






.SH "TEMPLATES"
.PP
The array of Tk_OptionSpec structures passed to \fBTk_CreateOptionTable\fR
via its \fItemplatePtr\fR argument describes the configuration options
supported by a particular class of widgets.  Each structure specifies
one configuration option and has the following fields:
.CS
typedef struct {
    Tk_OptionType \fItype\fR;
    const char *\fIoptionName\fR;
    const char *\fIdbName\fR;
    const char *\fIdbClass\fR;
    const char *\fIdefValue\fR;
    size_t \fIobjOffset\fR;
    size_t \fIinternalOffset\fR;
    int \fIflags\fR;
    const void *\fIclientData\fR;
    int \fItypeMask\fR;
} \fBTk_OptionSpec\fR;
.CE
The \fItype\fR field indicates what kind of configuration option this is
(e.g. \fBTK_OPTION_COLOR\fR for a color value, or \fBTK_OPTION_INT\fR for







>
>
>
>
>
>













|
|







236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
(e.g., because \fInamePtr\fR contains an unknown option name) then NULL
is returned and an error message is left in \fIinterp\fR's result unless
\fIinterp\fR is NULL.
.PP
\fBTk_FreeConfigOptions\fR must be invoked when a widget is deleted.
It frees all of the resources associated with any of the configuration
options defined in \fIrecordPtr\fR by \fIoptionTable\fR.
.PP
The \fBTk_Offset\fR macro is provided as a safe way of generating the
\fIobjOffset\fR and \fIinternalOffset\fR values for entries in
Tk_OptionSpec structures.  It takes two arguments: the name of a type
of record, and the name of a field in that record. It returns the byte
offset of the named field in records of the given type.
.SH "TEMPLATES"
.PP
The array of Tk_OptionSpec structures passed to \fBTk_CreateOptionTable\fR
via its \fItemplatePtr\fR argument describes the configuration options
supported by a particular class of widgets.  Each structure specifies
one configuration option and has the following fields:
.CS
typedef struct {
    Tk_OptionType \fItype\fR;
    const char *\fIoptionName\fR;
    const char *\fIdbName\fR;
    const char *\fIdbClass\fR;
    const char *\fIdefValue\fR;
    int \fIobjOffset\fR;
    int \fIinternalOffset\fR;
    int \fIflags\fR;
    const void *\fIclientData\fR;
    int \fItypeMask\fR;
} \fBTk_OptionSpec\fR;
.CE
The \fItype\fR field indicates what kind of configuration option this is
(e.g. \fBTK_OPTION_COLOR\fR for a color value, or \fBTK_OPTION_INT\fR for
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
\fIdbName\fR is NULL then the option database is not used by
\fBTk_InitOptions\fR for this option.  The \fIdefValue\fR field
specifies a default value for this configuration option if no
value is specified in the option database.  The \fIobjOffset\fR and
\fIinternalOffset\fR fields indicate where to store the value of this
option in widget records (more on this below); values for the \fIobjOffset\fR
and \fIinternalOffset\fR fields should always be generated with the
\fBoffsetof\fR macro.
The \fIflags\fR field contains additional information
to control the processing of this configuration option (see below
for details).
\fIClientData\fR provides additional type-specific data needed
by certain types.  For instance, for \fBTK_OPTION_COLOR\fR types,
\fIclientData\fR is a string giving the default value to use on
monochrome displays.  See the descriptions of the different types







|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
\fIdbName\fR is NULL then the option database is not used by
\fBTk_InitOptions\fR for this option.  The \fIdefValue\fR field
specifies a default value for this configuration option if no
value is specified in the option database.  The \fIobjOffset\fR and
\fIinternalOffset\fR fields indicate where to store the value of this
option in widget records (more on this below); values for the \fIobjOffset\fR
and \fIinternalOffset\fR fields should always be generated with the
\fBTk_Offset\fR macro.
The \fIflags\fR field contains additional information
to control the processing of this configuration option (see below
for details).
\fIClientData\fR provides additional type-specific data needed
by certain types.  For instance, for \fBTK_OPTION_COLOR\fR types,
\fIclientData\fR is a string giving the default value to use on
monochrome displays.  See the descriptions of the different types
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322

323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347


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







<
|










<
|





>









|
|



<
|




<
|

|
<
>
>
|





<
|





<
|







<
|



<
|




<
|







<
|





<
|


|
|
<
|



<
|



|
|


|
<
|



|
|
<
|



<
|








<
|





<
|







307
308
309
310
311
312
313

314
315
316
317
318
319
320
321
322
323
324

325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345

346
347
348
349
350

351
352
353

354
355
356
357
358
359
360
361

362
363
364
365
366
367

368
369
370
371
372
373
374
375

376
377
378
379

380
381
382
383
384

385
386
387
388
389
390
391
392

393
394
395
396
397
398

399
400
401
402
403

404
405
406
407

408
409
410
411
412
413
414
415
416

417
418
419
420
421
422

423
424
425
426

427
428
429
430
431
432
433
434
435

436
437
438
439
440
441

442
443
444
445
446
447
448
449
\fBTK_OPTION_INT\fR then the internal form is an integer.  If the
\fIobjOffset\fR or \fIinternalOffset\fR field is negative then the
value is not stored in that form.  At least one of the offsets must be
greater than or equal to zero.
.PP
The \fIflags\fR field consists of one or more bits ORed together. The
following flags are supported:

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

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

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

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

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








|
|







>
>
>
>








|







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

557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
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







<
|


<
|

<
|

<
|









<
|

<
|


<
|





<
|







555
556
557
558
559
560
561

562
563
564

565
566

567
568

569
570
571
572
573
574
575
576
577
578

579
580

581
582
583

584
585
586
587
588
589

590
591
592
593
594
595
596
597
may be NULL, indicating that no function should be called for those
operations.
.PP
The \fIsetProc\fR procedure is invoked by \fBTk_SetOptions\fR to
convert a Tcl_Obj into an internal representation and store the
resulting value in the widget record.  The arguments are:
.RS

.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/WindowId.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
'\"
'\" Copyright (c) 1990-1993 The Regents of the University of California.
'\" Copyright (c) 1994-1997 Sun Microsystems, Inc.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH Tk_WindowId 3 "8.4" Tk "Tk Library Procedures"
.so man.macros
.BS
.SH NAME
Tk_WindowId, Tk_Parent, Tk_Display, Tk_DisplayName, Tk_ScreenNumber, Tk_AlwaysShowSelection, Tk_Screen, Tk_X, Tk_Y, Tk_Width, Tk_Height, Tk_Changes, Tk_Attributes, Tk_IsContainer, Tk_IsEmbedded, Tk_IsMapped, Tk_IsTopLevel, Tk_ReqWidth, Tk_ReqHeight, Tk_MinReqWidth, Tk_MinReqHeight, Tk_InternalBorderLeft, Tk_InternalBorderRight, Tk_InternalBorderTop, Tk_InternalBorderBottom, Tk_Visual, Tk_Depth, Tk_Colormap, Tk_Interp, Tk_NewWindowObj  \- retrieve information from Tk's local data structure
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
Window
\fBTk_WindowId\fR(\fItkwin\fR)
.sp
Tk_Window
\fBTk_Parent\fR(\fItkwin\fR)
.sp
Display *
\fBTk_Display\fR(\fItkwin\fR)
.sp
const char *
\fBTk_DisplayName\fR(\fItkwin\fR)
.sp
int
\fBTk_ScreenNumber\fR(\fItkwin\fR)
.sp
int
\fBTk_AlwaysShowSelection\fR(\fItkwin\fR)
.sp
Screen *
\fBTk_Screen\fR(\fItkwin\fR)
.sp
int
\fBTk_X\fR(\fItkwin\fR)
.sp
int











|



















<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31



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



Screen *
\fBTk_Screen\fR(\fItkwin\fR)
.sp
int
\fBTk_X\fR(\fItkwin\fR)
.sp
int
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
\fBTk_Depth\fR(\fItkwin\fR)
.sp
Colormap
\fBTk_Colormap\fR(\fItkwin\fR)
.sp
Tcl_Interp *
\fBTk_Interp\fR(\fItkwin\fR)
.sp
Tcl_Obj *
\fBTk_NewWindowObj\fR(\fItkwin\fR)
.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE
.SH DESCRIPTION
.PP







<
<
<







93
94
95
96
97
98
99



100
101
102
103
104
105
106
\fBTk_Depth\fR(\fItkwin\fR)
.sp
Colormap
\fBTk_Colormap\fR(\fItkwin\fR)
.sp
Tcl_Interp *
\fBTk_Interp\fR(\fItkwin\fR)



.SH ARGUMENTS
.AS Tk_Window tkwin
.AP Tk_Window tkwin in
Token for window.
.BE
.SH DESCRIPTION
.PP
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
.PP
\fBTk_Display\fR returns a pointer to the Xlib display structure
corresponding to \fItkwin\fR.  \fBTk_DisplayName\fR returns an
ASCII string identifying \fItkwin\fR's display.  \fBTk_ScreenNumber\fR
returns the index of \fItkwin\fR's screen among all the screens
of \fItkwin\fR's display.  \fBTk_Screen\fR returns a pointer to
the Xlib structure corresponding to \fItkwin\fR's screen.
\fBTk_AlwaysShowSelection\fR indicates whether text/entry widgets
should always display their selection, regardless of window focus.
.PP
\fBTk_X\fR, \fBTk_Y\fR, \fBTk_Width\fR, and \fBTk_Height\fR
return information about \fItkwin's\fR location within its
parent and its size.  The location information refers to the
upper-left pixel in the window, or its border if there is one.
The width and height information refers to the interior size
of the window, not including any border.  \fBTk_Changes\fR







<
<







123
124
125
126
127
128
129


130
131
132
133
134
135
136
.PP
\fBTk_Display\fR returns a pointer to the Xlib display structure
corresponding to \fItkwin\fR.  \fBTk_DisplayName\fR returns an
ASCII string identifying \fItkwin\fR's display.  \fBTk_ScreenNumber\fR
returns the index of \fItkwin\fR's screen among all the screens
of \fItkwin\fR's display.  \fBTk_Screen\fR returns a pointer to
the Xlib structure corresponding to \fItkwin\fR's screen.


.PP
\fBTk_X\fR, \fBTk_Y\fR, \fBTk_Width\fR, and \fBTk_Height\fR
return information about \fItkwin's\fR location within its
parent and its size.  The location information refers to the
upper-left pixel in the window, or its border if there is one.
The width and height information refers to the interior size
of the window, not including any border.  \fBTk_Changes\fR
186
187
188
189
190
191
192
193
194
195
196
197
198
information about the visual characteristics of a window.
\fBTk_Visual\fR returns the visual type for
the window, \fBTk_Depth\fR returns the number of bits per pixel,
and \fBTk_Colormap\fR returns the current
colormap for the window.  The visual characteristics are
normally set from the defaults for the window's screen, but
they may be overridden by calling \fBTk_SetWindowVisual\fR.
.PP
\fBTk_NewWindowObj\fR creates a new \fBTcl_Obj\fR from the window.
.SH KEYWORDS
attributes, colormap, depth, display, height, geometry manager,
identifier, mapped, requested size, screen, top-level,
visual, width, window, x, y







<
<




178
179
180
181
182
183
184


185
186
187
188
information about the visual characteristics of a window.
\fBTk_Visual\fR returns the visual type for
the window, \fBTk_Depth\fR returns the number of bits per pixel,
and \fBTk_Colormap\fR returns the current
colormap for the window.  The visual characteristics are
normally set from the defaults for the window's screen, but
they may be overridden by calling \fBTk_SetWindowVisual\fR.


.SH KEYWORDS
attributes, colormap, depth, display, height, geometry manager,
identifier, mapped, requested size, screen, top-level,
visual, width, window, x, y
Changes to doc/bind.n.
49
50
51
52
53
54
55



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
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
take one of three forms.  In the simplest case it is a single
printing ASCII character, such as \fBa\fR or \fB[\fR.  The character
may not be a space character or the character \fB<\fR.  This form of
pattern matches a \fBKey\fR event for the particular
character.  The second form of pattern is longer but more general.
It has the following syntax:
.CS
\fB<\fImodifier\-modifier\-type\-detail\fB>\fR
.CE
The entire event pattern is surrounded by angle brackets.
Inside the angle brackets are zero or more modifiers, an event







>
>
>




<
<
<










|







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



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
the window.
Although the \fBbindtags\fR command may be used to assign an
arbitrary set of binding tags to a window, the default binding
tags provide the following behavior:
.IP \(bu 3
If a tag is the name of an internal window the binding applies
to that window.
.IP \(bu 3
If the tag is the name of a class of widgets, such as \fBButton\fR,
the binding applies to all widgets in that class.
.IP \(bu 3
If the tag is the name of a toplevel window the binding applies
to the toplevel window and all its internal windows.
.IP \(bu 3



If \fItag\fR has the value \fBall\fR,
the binding applies to all windows in the application.
.SH "EVENT PATTERNS"
.PP
The \fIsequence\fR argument specifies a sequence of one or more
event patterns, with optional white space between the patterns.  Each
event pattern may
take one of three forms.  In the simplest case it is a single
printing ASCII character, such as \fBa\fR or \fB[\fR.  The character
may not be a space character or the character \fB<\fR.  This form of
pattern matches a \fBKeyPress\fR event for the particular
character.  The second form of pattern is longer but more general.
It has the following syntax:
.CS
\fB<\fImodifier\-modifier\-type\-detail\fB>\fR
.CE
The entire event pattern is surrounded by angle brackets.
Inside the angle brackets are zero or more modifiers, an event
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
.PP
The \fItype\fR field may be any of the standard X event types, with a
few extra abbreviations.  The \fItype\fR field will also accept a
couple non-standard X event types that were added to better support
the Macintosh and Windows platforms.  Below is a list of all the valid
types; where two names appear together, they are synonyms.
.DS
.ta \w'\fBButton, ButtonPress\0\0\0\fR'u +\w'\fBKey, KeyPress\0\0\0\fR'u
\fBActivate\fR	\fBDestroy\fR	\fBMap\fR
\fBButton\fR, \fBButtonPress\fR	\fBEnter\fR	\fBMapRequest\fR
\fBButtonRelease\fR	\fBExpose\fR	\fBMotion\fR
\fBCirculate\fR	\fBFocusIn\fR	\fBMouseWheel\fR
\fBCirculateRequest\fR	\fBFocusOut\fR	\fBProperty\fR
\fBColormap\fR	\fBGravity\fR	\fBReparent\fR
\fBConfigure\fR	\fBKey\fR, \fBKeyPress\fR	\fBResizeRequest\fR
\fBConfigureRequest\fR	\fBKeyRelease\fR	\fBUnmap\fR
\fBCreate\fR	\fBLeave\fR	\fBVisibility\fR
\fBDeactivate\fR
.DE
Most of the above events have the same fields and behaviors as events
in the X Windowing system.  You can find more detailed descriptions of
these events in any X window programming book.  A couple of the events







|

|




|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
.PP
The \fItype\fR field may be any of the standard X event types, with a
few extra abbreviations.  The \fItype\fR field will also accept a
couple non-standard X event types that were added to better support
the Macintosh and Windows platforms.  Below is a list of all the valid
types; where two names appear together, they are synonyms.
.DS
.ta \w'\fBButtonPress, Button\0\0\0\fR'u +\w'\fBKeyPress, Key\0\0\0\fR'u
\fBActivate\fR	\fBDestroy\fR	\fBMap\fR
\fBButtonPress\fR, \fBButton\fR	\fBEnter\fR	\fBMapRequest\fR
\fBButtonRelease\fR	\fBExpose\fR	\fBMotion\fR
\fBCirculate\fR	\fBFocusIn\fR	\fBMouseWheel\fR
\fBCirculateRequest\fR	\fBFocusOut\fR	\fBProperty\fR
\fBColormap\fR	\fBGravity\fR	\fBReparent\fR
\fBConfigure\fR	\fBKeyPress\fR, \fBKey\fR	\fBResizeRequest\fR
\fBConfigureRequest\fR	\fBKeyRelease\fR	\fBUnmap\fR
\fBCreate\fR	\fBLeave\fR	\fBVisibility\fR
\fBDeactivate\fR
.DE
Most of the above events have the same fields and behaviors as events
in the X Windowing system.  You can find more detailed descriptions of
these events in any X window programming book.  A couple of the events
210
211
212
213
214
215
216




217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
value determines which direction your widget should scroll.  Positive
values should scroll up and negative values should scroll down.
.RS
.PP
Horizontal scrolling uses \fBShift-MouseWheel\fR events, with positive
\fB%D\fR \fIdelta\fR substitution indicating left scrolling and negative
right scrolling.




Horizontal scrolling events may fire from
many different hardware units such as tilt wheels or touchpads.  Horizontal
scrolling can also be emulated by holding Shift and scrolling vertically.
.RE
.IP "\fBKeyPress\fR, \fBKeyRelease\fR" 5
The \fBKeyPress\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKeyPress\fR and \fBKeyRelease\fR
.IP "\fBKey\fR, \fBKeyRelease\fR" 5
The \fBKey\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKey\fR and \fBKeyRelease\fR
events are sent to the window which currently has the keyboard focus.
.IP "\fBButton\fR, \fBButtonRelease\fR, \fBMotion\fR" 5
The \fBButton\fR and \fBButtonRelease\fR events
are generated when the user presses or releases a mouse button.
\fBMotion\fR events are generated whenever the pointer is moved.
\fBButton\fR, \fBButtonRelease\fR, and \fBMotion\fR events are
normally sent to the window containing the pointer.
.RS
.PP
When a mouse button is pressed, the window containing the pointer
automatically obtains a temporary pointer grab.
Subsequent \fBButton\fR, \fBButtonRelease\fR, and \fBMotion\fR
events will be sent to that window,
regardless of which window contains the pointer,
until all buttons have been released.
.RE
.IP \fBConfigure\fR 5
A \fBConfigure\fR event is sent to a window whenever its
size, position, or border width changes, and sometimes







>
>
>
>
|






<
<
<

|
|


|





|







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



228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
value determines which direction your widget should scroll.  Positive
values should scroll up and negative values should scroll down.
.RS
.PP
Horizontal scrolling uses \fBShift-MouseWheel\fR events, with positive
\fB%D\fR \fIdelta\fR substitution indicating left scrolling and negative
right scrolling.
Only Windows and macOS Aqua typically fire \fBMouseWheel\fR and
\fBShift-MouseWheel\fR events.  On
X11 vertical scrolling is rather supported through \fBButton-4\fR and
\fBButton-5\fR events, and horizontal scrolling through \fBShift-Button-4\fR
and \fBShift-Button-5\fR events.  Horizontal scrolling events may fire from
many different hardware units such as tilt wheels or touchpads.  Horizontal
scrolling can also be emulated by holding Shift and scrolling vertically.
.RE
.IP "\fBKeyPress\fR, \fBKeyRelease\fR" 5
The \fBKeyPress\fR and \fBKeyRelease\fR events are generated
whenever a key is pressed or released.  \fBKeyPress\fR and \fBKeyRelease\fR



events are sent to the window which currently has the keyboard focus.
.IP "\fBButtonPress\fR, \fBButtonRelease\fR, \fBMotion\fR" 5
The \fBButtonPress\fR and \fBButtonRelease\fR events
are generated when the user presses or releases a mouse button.
\fBMotion\fR events are generated whenever the pointer is moved.
\fBButtonPress\fR, \fBButtonRelease\fR, and \fBMotion\fR events are
normally sent to the window containing the pointer.
.RS
.PP
When a mouse button is pressed, the window containing the pointer
automatically obtains a temporary pointer grab.
Subsequent \fBButtonPress\fR, \fBButtonRelease\fR, and \fBMotion\fR
events will be sent to that window,
regardless of which window contains the pointer,
until all buttons have been released.
.RE
.IP \fBConfigure\fR 5
A \fBConfigure\fR event is sent to a window whenever its
size, position, or border width changes, and sometimes
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
This event type is included only for completeness;
there is no reliable way to track changes to a window's
position in the stacking order.
.RE
.SS "EVENT DETAILS"
.PP
The last part of a long event specification is \fIdetail\fR.  In the
case of a \fBButton\fR or \fBButtonRelease\fR event, it is the
number of a button (1\-9).  If a button number is given, then only an
event on that particular button will match;  if no button number is
given, then an event on any button will match.  Note:  giving a
specific button number is different than specifying a button modifier;
in the first case, it refers to a button being pressed or released,
while in the second it refers to some other button that is already
depressed when the matching event occurs.  If a button
number is given then \fItype\fR may be omitted:  if will default
to \fBButton\fR.  For example, the specifier \fB<1>\fR
is equivalent to \fB<Button\-1>\fR.
.PP
If the event type is \fBKey\fR or \fBKeyRelease\fR, then
\fIdetail\fR may be specified in the form of an X keysym.  Keysyms
are textual specifications for particular keys on the keyboard;
they include all the alphanumeric ASCII characters (e.g.
.QW a
is the keysym for the ASCII character
.QW a ),
plus descriptions for non-alphanumeric characters
.PQ comma "is the keysym for the comma character" ,
plus descriptions for all the non-ASCII keys on the keyboard (e.g.
.QW Shift_L
is the keysym for the left shift key, and
.QW F1
is the keysym for the F1 function key, if it exists).  The
complete list of keysyms is not presented here;  it is
available in other X documentation and may vary from system to
system.
If necessary, you can use the \fB%K\fR notation described below
to print out the keysym name for a particular key.
If a keysym \fIdetail\fR is given, then the
\fItype\fR field may be omitted;  it will default to \fBKey\fR.
For example, \fB<Control\-comma>\fR is equivalent to
\fB<Control\-Key\-comma>\fR.
.SH "BINDING SCRIPTS AND SUBSTITUTIONS"
.PP
The \fIscript\fR argument to \fBbind\fR is a Tcl script, called the
.QW "binding script",
which will be executed whenever the given event sequence occurs.
\fICommand\fR will be executed in the same interpreter that the
\fBbind\fR command was executed in, and it will run at global







|
|







|
|

|



















|

|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
This event type is included only for completeness;
there is no reliable way to track changes to a window's
position in the stacking order.
.RE
.SS "EVENT DETAILS"
.PP
The last part of a long event specification is \fIdetail\fR.  In the
case of a \fBButtonPress\fR or \fBButtonRelease\fR event, it is the
number of a button (1\-5).  If a button number is given, then only an
event on that particular button will match;  if no button number is
given, then an event on any button will match.  Note:  giving a
specific button number is different than specifying a button modifier;
in the first case, it refers to a button being pressed or released,
while in the second it refers to some other button that is already
depressed when the matching event occurs.  If a button
number is given then \fItype\fR may be omitted:  if will default
to \fBButtonPress\fR.  For example, the specifier \fB<1>\fR
is equivalent to \fB<ButtonPress\-1>\fR.
.PP
If the event type is \fBKeyPress\fR or \fBKeyRelease\fR, then
\fIdetail\fR may be specified in the form of an X keysym.  Keysyms
are textual specifications for particular keys on the keyboard;
they include all the alphanumeric ASCII characters (e.g.
.QW a
is the keysym for the ASCII character
.QW a ),
plus descriptions for non-alphanumeric characters
.PQ comma "is the keysym for the comma character" ,
plus descriptions for all the non-ASCII keys on the keyboard (e.g.
.QW Shift_L
is the keysym for the left shift key, and
.QW F1
is the keysym for the F1 function key, if it exists).  The
complete list of keysyms is not presented here;  it is
available in other X documentation and may vary from system to
system.
If necessary, you can use the \fB%K\fR notation described below
to print out the keysym name for a particular key.
If a keysym \fIdetail\fR is given, then the
\fItype\fR field may be omitted;  it will default to \fBKeyPress\fR.
For example, \fB<Control\-comma>\fR is equivalent to
\fB<Control\-KeyPress\-comma>\fR.
.SH "BINDING SCRIPTS AND SUBSTITUTIONS"
.PP
The \fIscript\fR argument to \fBbind\fR is a Tcl script, called the
.QW "binding script",
which will be executed whenever the given event sequence occurs.
\fICommand\fR will be executed in the same interpreter that the
\fBbind\fR command was executed in, and it will run at global
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
formatted as a hexadecimal number.
Valid only for \fBConfigure\fR events.
Indicates the sibling window immediately below the receiving window
in the stacking order, or \fB0\fR if the receiving window is at the
bottom.
.IP \fB%b\fR 5
The number of the button that was pressed or released.  Valid only
for \fBButton\fR and \fBButtonRelease\fR events.
.IP \fB%c\fR 5
The \fIcount\fR field from the event.  Valid only for \fBExpose\fR events.
Indicates that there are \fIcount\fR pending \fBExpose\fR events which have not
yet been delivered to the window.
.IP \fB%d\fR 5
The \fIdetail\fR or \fIuser_data\fR
field from the event.  The \fB%d\fR is replaced by







|







431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
formatted as a hexadecimal number.
Valid only for \fBConfigure\fR events.
Indicates the sibling window immediately below the receiving window
in the stacking order, or \fB0\fR if the receiving window is at the
bottom.
.IP \fB%b\fR 5
The number of the button that was pressed or released.  Valid only
for \fBButtonPress\fR and \fBButtonRelease\fR events.
.IP \fB%c\fR 5
The \fIcount\fR field from the event.  Valid only for \fBExpose\fR events.
Indicates that there are \fIcount\fR pending \fBExpose\fR events which have not
yet been delivered to the window.
.IP \fB%d\fR 5
The \fIdetail\fR or \fIuser_data\fR
field from the event.  The \fB%d\fR is replaced by
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
\fBConfigureRequest\fR, \fBCreate\fR, \fBResizeRequest\fR, and
\fBExpose\fR events.
Indicates the new or requested height of the window.
.IP \fB%i\fR 5
The \fIwindow\fR field from the event, represented as a hexadecimal
integer.  Valid for all event types.
.IP \fB%k\fR 5
The \fIkeycode\fR field from the event.  Valid only for \fBKey\fR
and \fBKeyRelease\fR events.
.IP \fB%m\fR 5
The \fImode\fR field from the event.  The substituted string is one of
\fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.  Valid only for \fBEnter\fR,
\fBFocusIn\fR, \fBFocusOut\fR, and \fBLeave\fR events.
.IP \fB%o\fR 5
The \fIoverride_redirect\fR field from the event.  Valid only for
\fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
.IP \fB%p\fR 5
The \fIplace\fR field from the event, substituted as one of the
strings \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.  Valid only
for \fBCirculate\fR and \fBCirculateRequest\fR events.
.IP \fB%s\fR 5
The \fIstate\fR field from the event.  For \fBButton\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBKey\fR, \fBKeyRelease\fR,
\fBLeave\fR, and \fBMotion\fR events, a decimal string
is substituted.  For \fBVisibility\fR, one of the strings
\fBVisibilityUnobscured\fR, \fBVisibilityPartiallyObscured\fR,
and \fBVisibilityFullyObscured\fR is substituted.
For \fBProperty\fR events, substituted with
either the string \fBNewValue\fR (indicating that the property
has been created or modified) or \fBDelete\fR (indicating that







|














|
|







478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
\fBConfigureRequest\fR, \fBCreate\fR, \fBResizeRequest\fR, and
\fBExpose\fR events.
Indicates the new or requested height of the window.
.IP \fB%i\fR 5
The \fIwindow\fR field from the event, represented as a hexadecimal
integer.  Valid for all event types.
.IP \fB%k\fR 5
The \fIkeycode\fR field from the event.  Valid only for \fBKeyPress\fR
and \fBKeyRelease\fR events.
.IP \fB%m\fR 5
The \fImode\fR field from the event.  The substituted string is one of
\fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.  Valid only for \fBEnter\fR,
\fBFocusIn\fR, \fBFocusOut\fR, and \fBLeave\fR events.
.IP \fB%o\fR 5
The \fIoverride_redirect\fR field from the event.  Valid only for
\fBMap\fR, \fBReparent\fR, and \fBConfigure\fR events.
.IP \fB%p\fR 5
The \fIplace\fR field from the event, substituted as one of the
strings \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.  Valid only
for \fBCirculate\fR and \fBCirculateRequest\fR events.
.IP \fB%s\fR 5
The \fIstate\fR field from the event.  For \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBKeyPress\fR, \fBKeyRelease\fR,
\fBLeave\fR, and \fBMotion\fR events, a decimal string
is substituted.  For \fBVisibility\fR, one of the strings
\fBVisibilityUnobscured\fR, \fBVisibilityPartiallyObscured\fR,
and \fBVisibilityFullyObscured\fR is substituted.
For \fBProperty\fR events, substituted with
either the string \fBNewValue\fR (indicating that the property
has been created or modified) or \fBDelete\fR (indicating that
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
The \fIwidth\fR field from the event.
Indicates the new or requested width of the window.
Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, \fBCreate\fR,
\fBResizeRequest\fR, and \fBExpose\fR events.
.IP "\fB%x\fR, \fB%y\fR" 5
The \fIx\fR and \fIy\fR fields from the event.
For \fBButton\fR, \fBButtonRelease\fR, \fBMotion\fR,
\fBKey\fR, \fBKeyRelease\fR, and \fBMouseWheel\fR events,
\fB%x\fR and \fB%y\fR indicate the position of the mouse pointer
relative to the receiving window.
For key events on the Macintosh these are the coordinates of the
mouse at the moment when an X11 KeyEvent is sent to Tk, which could
be slightly later than the time of the physical press or release.
For \fBEnter\fR and \fBLeave\fR events, the position where the
mouse pointer crossed the window, relative to the receiving window.
For \fBConfigure\fR and \fBCreate\fR requests, the \fIx\fR and \fIy\fR
coordinates of the window relative to its parent window.
.IP \fB%A\fR 5
Substitutes the UNICODE character corresponding to the event, or
the empty string if the event does not correspond to a UNICODE character
(e.g. the shift key was pressed). On X11, \fBXmbLookupString\fR (or
\fBXLookupString\fR when input method support is turned off) does all
the work of translating from the event to a UNICODE character.
On X11, valid only for \fBKey\fR event. On Windows and macOS/aqua,
valid only for \fBKey\fR and \fBKeyRelease\fR events.
.IP \fB%B\fR 5
The \fIborder_width\fR field from the event.  Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, and \fBCreate\fR events.
.IP \fB%D\fR 5
This reports the \fIdelta\fR value of a \fBMouseWheel\fR event.  The
\fIdelta\fR value represents the rotation units the mouse wheel has
been moved. The sign of the value represents the direction the mouse
wheel was scrolled.
.IP \fB%E\fR 5
The \fIsend_event\fR field from the event.  Valid for all event types.
\fB0\fR indicates that this is a
.QW normal
event, \fB1\fR indicates that it is a
.QW synthetic
event generated by \fBSendEvent\fR.
.IP \fB%K\fR 5
The keysym corresponding to the event, substituted as a textual
string.  Valid only for \fBKey\fR and \fBKeyRelease\fR events.
.IP \fB%M\fR 5
The number of script-based binding patterns matched so far for the
event.  Valid for all event types.
.IP \fB%N\fR 5
The keysym corresponding to the event, substituted as a decimal
number.  Valid only for \fBKey\fR and \fBKeyRelease\fR events.
.IP \fB%P\fR 5
The name of the property being updated or deleted (which
may be converted to an XAtom using \fBwinfo atom\fR.) Valid
only for \fBProperty\fR events.
.IP \fB%R\fR 5
The \fIroot\fR window identifier from the event.  Valid only for
events containing a \fIroot\fR field.







|
|















|
|

















|





|







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
The \fIwidth\fR field from the event.
Indicates the new or requested width of the window.
Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, \fBCreate\fR,
\fBResizeRequest\fR, and \fBExpose\fR events.
.IP "\fB%x\fR, \fB%y\fR" 5
The \fIx\fR and \fIy\fR fields from the event.
For \fBButtonPress\fR, \fBButtonRelease\fR, \fBMotion\fR,
\fBKeyPress\fR, \fBKeyRelease\fR, and \fBMouseWheel\fR events,
\fB%x\fR and \fB%y\fR indicate the position of the mouse pointer
relative to the receiving window.
For key events on the Macintosh these are the coordinates of the
mouse at the moment when an X11 KeyEvent is sent to Tk, which could
be slightly later than the time of the physical press or release.
For \fBEnter\fR and \fBLeave\fR events, the position where the
mouse pointer crossed the window, relative to the receiving window.
For \fBConfigure\fR and \fBCreate\fR requests, the \fIx\fR and \fIy\fR
coordinates of the window relative to its parent window.
.IP \fB%A\fR 5
Substitutes the UNICODE character corresponding to the event, or
the empty string if the event does not correspond to a UNICODE character
(e.g. the shift key was pressed). On X11, \fBXmbLookupString\fR (or
\fBXLookupString\fR when input method support is turned off) does all
the work of translating from the event to a UNICODE character.
On X11, valid only for \fBKeyPress\fR event. On Windows and macOS/aqua,
valid only for \fBKeyPress\fR and \fBKeyRelease\fR events.
.IP \fB%B\fR 5
The \fIborder_width\fR field from the event.  Valid only for
\fBConfigure\fR, \fBConfigureRequest\fR, and \fBCreate\fR events.
.IP \fB%D\fR 5
This reports the \fIdelta\fR value of a \fBMouseWheel\fR event.  The
\fIdelta\fR value represents the rotation units the mouse wheel has
been moved. The sign of the value represents the direction the mouse
wheel was scrolled.
.IP \fB%E\fR 5
The \fIsend_event\fR field from the event.  Valid for all event types.
\fB0\fR indicates that this is a
.QW normal
event, \fB1\fR indicates that it is a
.QW synthetic
event generated by \fBSendEvent\fR.
.IP \fB%K\fR 5
The keysym corresponding to the event, substituted as a textual
string.  Valid only for \fBKeyPress\fR and \fBKeyRelease\fR events.
.IP \fB%M\fR 5
The number of script-based binding patterns matched so far for the
event.  Valid for all event types.
.IP \fB%N\fR 5
The keysym corresponding to the event, substituted as a decimal
number.  Valid only for \fBKeyPress\fR and \fBKeyRelease\fR events.
.IP \fB%P\fR 5
The name of the property being updated or deleted (which
may be converted to an XAtom using \fBwinfo atom\fR.) Valid
only for \fBProperty\fR events.
.IP \fB%R\fR 5
The \fIroot\fR window identifier from the event.  Valid only for
events containing a \fIroot\fR field.
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
The path name of the window to which the event was reported (the
\fIwindow\fR field from the event).  Valid for all event types.
.IP "\fB%X\fR, \fB%Y\fR" 5
The \fIx_root\fR and  \fIy_root\fR fields from the event.
If a virtual-root window manager is being used then the substituted
values are the corresponding x-coordinate and y-coordinate in the virtual root.
Valid only for
\fBButton\fR, \fBButtonRelease\fR, \fBEnter\fR, \fBKey\fR,
\fBKeyRelease\fR, \fBLeave\fR and \fBMotion\fR events.
Same meaning as \fB%x\fR and \fB%y\fR, except relative to the (virtual) root
window.
.LP
The replacement string for a %-replacement is formatted as a proper
Tcl list element.
This means that spaces or special characters such as \fB$\fR and







|







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
The path name of the window to which the event was reported (the
\fIwindow\fR field from the event).  Valid for all event types.
.IP "\fB%X\fR, \fB%Y\fR" 5
The \fIx_root\fR and  \fIy_root\fR fields from the event.
If a virtual-root window manager is being used then the substituted
values are the corresponding x-coordinate and y-coordinate in the virtual root.
Valid only for
\fBButtonPress\fR, \fBButtonRelease\fR, \fBEnter\fR, \fBKeyPress\fR,
\fBKeyRelease\fR, \fBLeave\fR and \fBMotion\fR events.
Same meaning as \fB%x\fR and \fB%y\fR, except relative to the (virtual) root
window.
.LP
The replacement string for a %-replacement is formatted as a proper
Tcl list element.
This means that spaces or special characters such as \fB$\fR and
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
The following tests are applied, in order, to determine which of
several matching sequences is more specific:
.RS
.IP (a)
an event pattern that specifies a specific button or key is more specific
than one that does not;
.IP (b)
a sequence with the most highest-ordered patterns (in term of highest
repetition count) is more specific than a sequence with less
highest-ordered patterns;
.IP (c)
if the modifiers specified in one pattern are a subset of the
modifiers in another pattern, then the pattern with more modifiers
is more specific;
.IP (d)
a virtual event whose physical pattern matches the sequence is less
specific than the same physical pattern that is not associated with a







|
|
<







647
648
649
650
651
652
653
654
655

656
657
658
659
660
661
662
The following tests are applied, in order, to determine which of
several matching sequences is more specific:
.RS
.IP (a)
an event pattern that specifies a specific button or key is more specific
than one that does not;
.IP (b)
a longer sequence (in terms of number
of events matched) is more specific than a shorter sequence;

.IP (c)
if the modifiers specified in one pattern are a subset of the
modifiers in another pattern, then the pattern with more modifiers
is more specific;
.IP (d)
a virtual event whose physical pattern matches the sequence is less
specific than the same physical pattern that is not associated with a
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
An unbound event is not considered to be an error.
.SH "MULTI-EVENT SEQUENCES AND IGNORED EVENTS"
.PP
When a \fIsequence\fR specified in a \fBbind\fR command contains
more than one event pattern, then its script is executed whenever
the recent events (leading up to and including the current event)
match the given sequence.  This means, for example, that if button 1 is
clicked repeatedly the sequence \fB<Double\-Button\-1>\fR will match
each button press but the first.
If extraneous events that would prevent a match occur in the middle
of an event sequence then the extraneous events are
ignored unless they are \fBKey\fR or \fBButton\fR events.
For example, \fB<Double\-Button\-1>\fR will match a sequence of
presses of button 1, even though there will be \fBButtonRelease\fR
events (and possibly \fBMotion\fR events) between the
\fBButton\fR events.
Furthermore, a \fBKey\fR event may be preceded by any number
of other \fBKey\fR events for modifier keys without the
modifier keys preventing a match.
For example, the event sequence \fBaB\fR will match a press of the
\fBa\fR key, a release of the \fBa\fR key, a press of the \fBShift\fR
key, and a press of the \fBb\fR key:  the press of \fBShift\fR is
ignored because it is a modifier key.
Finally, if several \fBMotion\fR events occur in a row, only
the last one is used for purposes of matching binding sequences.







|



|
|


|
|
|







692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
An unbound event is not considered to be an error.
.SH "MULTI-EVENT SEQUENCES AND IGNORED EVENTS"
.PP
When a \fIsequence\fR specified in a \fBbind\fR command contains
more than one event pattern, then its script is executed whenever
the recent events (leading up to and including the current event)
match the given sequence.  This means, for example, that if button 1 is
clicked repeatedly the sequence \fB<Double\-ButtonPress\-1>\fR will match
each button press but the first.
If extraneous events that would prevent a match occur in the middle
of an event sequence then the extraneous events are
ignored unless they are \fBKeyPress\fR or \fBButtonPress\fR events.
For example, \fB<Double\-ButtonPress\-1>\fR will match a sequence of
presses of button 1, even though there will be \fBButtonRelease\fR
events (and possibly \fBMotion\fR events) between the
\fBButtonPress\fR events.
Furthermore, a \fBKeyPress\fR event may be preceded by any number
of other \fBKeyPress\fR events for modifier keys without the
modifier keys preventing a match.
For example, the event sequence \fBaB\fR will match a press of the
\fBa\fR key, a release of the \fBa\fR key, a press of the \fBShift\fR
key, and a press of the \fBb\fR key:  the press of \fBShift\fR is
ignored because it is a modifier key.
Finally, if several \fBMotion\fR events occur in a row, only
the last one is used for purposes of matching binding sequences.
Changes to doc/bitmap.n.
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
.PP
When a bitmap image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg ...\fR?
.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
.







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
.PP
When a bitmap image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for bitmap images:
.TP
\fIimageName \fBcget\fR \fIoption\fR
.
Changes to doc/busy.n.
26
27
28
29
30
31
32

33
34
35
36
37
38
39
40
41
42
43
44
45

46
47
48
49
50
51
52
.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
.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 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







|












<
<
|
<
<
<

|






>







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


127



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
\fBtk busy\fR forget .top
.CE
.PP
The busy window has a configurable cursor. You can change the busy cursor
using the \fBconfigure\fR operation.
.PP
.CS
\fBtk busy\fR configure .top -cursor "watch"
.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: 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
214
215
216
217
218
219
220
221
222
223
224
225
226

227













228
229
230
231
232
233
234
235
236
237
specified for it by either \fBoption\fR command:
.PP
.CS
option add *frame.busyCursor gumby
option add *Frame.BusyCursor gumby
.CE
.RE

.TP
\fBtk busy current \fR?\fIpattern\fR?
.
Returns the pathnames of all widgets that are currently busy. If a
\fIpattern\fR is given, only the path names of busy widgets matching
\fIpattern\fR are returned.

.TP
\fBtk busy forget \fIwindow\fR ?\fIwindow\fR?...
.
Releases resources allocated by the \fBtk busy\fR command for \fIwindow\fR,
including the transparent window. User events will again be received by
\fIwindow\fR. Resources are also released when \fIwindow\fR is destroyed.
\fIWindow\fR must be the name of a widget specified in the \fBhold\fR
operation, otherwise an error is reported.

.TP
\fBtk busy hold \fIwindow\fR ?\fIoption value\fR?...
.
Makes the specified \fIwindow\fR (and its descendants in the Tk window
hierarchy) appear busy. \fIWindow\fR must be a valid path name of a Tk widget.
A transparent window is put in front of the specified window. This transparent
window is mapped the next time idle tasks are processed, and the specified
window and its descendants will be blocked from user interactions. Normally
\fBupdate\fR should be called immediately afterward to insure that the hold
operation is in effect before the application starts its processing. The
command returns the pathname of the busy window that was created (i.e. the
transparent window shielding the window appearing busy). The following
configuration options are valid:
.RS

.TP
\fB\-cursor \fIcursorName\fR
.
Specifies the cursor to be displayed when the widget is made busy.
\fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The
default cursor is \fBwait\fR on Windows and \fBwatch\fR on other platforms.
.RE

.TP
\fBtk busy status \fIwindow\fR
.
Returns the status of a widget \fIwindow\fR. If \fIwindow\fR presently can not
receive user interactions, \fB1\fR is returned, otherwise \fB0\fR.
.SH "EVENT HANDLING"
.SS BINDINGS
.PP
The event blocking feature is implemented by creating and mapping a
transparent window that completely covers the widget. When the busy window is
mapped, it invisibly shields the widget and its hierarchy from all events that
may be sent. Like Tk widgets, busy windows have widget names in the Tk window
hierarchy. This means that you can use the \fBbind\fR command to handle
events in the busy window:
.PP
.CS
\fBtk busy\fR hold .frame.canvas
bind [\fBtk busy\fR busywindow .frame.canvas] <Enter> { ... }
.CE
.PP

or













.CS
set busyWin [\fBtk busy\fR hold .frame.canvas]
bind $busyWin <Enter> { ... }
.CE
.SS "ENTER/LEAVE EVENTS"
.PP
Mapping and unmapping busy windows generates Enter/Leave events for all
widgets they cover. Please note this if you are tracking Enter/Leave events in
widgets.
.SS "KEYBOARD EVENTS"







>






>








>










<
<
|

>







>

















|


>
|
>
>
>
>
>
>
>
>
>
>
>
>
>

|
|







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


190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
specified for it by either \fBoption\fR command:
.PP
.CS
option add *frame.busyCursor gumby
option add *Frame.BusyCursor gumby
.CE
.RE
.\" METHOD: current
.TP
\fBtk busy current \fR?\fIpattern\fR?
.
Returns the pathnames of all widgets that are currently busy. If a
\fIpattern\fR is given, only the path names of busy widgets matching
\fIpattern\fR are returned.
.\" METHOD: forget
.TP
\fBtk busy forget \fIwindow\fR ?\fIwindow\fR?...
.
Releases resources allocated by the \fBtk busy\fR command for \fIwindow\fR,
including the transparent window. User events will again be received by
\fIwindow\fR. Resources are also released when \fIwindow\fR is destroyed.
\fIWindow\fR must be the name of a widget specified in the \fBhold\fR
operation, otherwise an error is reported.
.\" METHOD: hold
.TP
\fBtk busy hold \fIwindow\fR ?\fIoption value\fR?...
.
Makes the specified \fIwindow\fR (and its descendants in the Tk window
hierarchy) appear busy. \fIWindow\fR must be a valid path name of a Tk widget.
A transparent window is put in front of the specified window. This transparent
window is mapped the next time idle tasks are processed, and the specified
window and its descendants will be blocked from user interactions. Normally
\fBupdate\fR should be called immediately afterward to insure that the hold
operation is in effect before the application starts its processing. The


following configuration options are valid:
.RS
.\" OPTION: -cursor
.TP
\fB\-cursor \fIcursorName\fR
.
Specifies the cursor to be displayed when the widget is made busy.
\fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The
default cursor is \fBwait\fR on Windows and \fBwatch\fR on other platforms.
.RE
.\" METHOD: status
.TP
\fBtk busy status \fIwindow\fR
.
Returns the status of a widget \fIwindow\fR. If \fIwindow\fR presently can not
receive user interactions, \fB1\fR is returned, otherwise \fB0\fR.
.SH "EVENT HANDLING"
.SS BINDINGS
.PP
The event blocking feature is implemented by creating and mapping a
transparent window that completely covers the widget. When the busy window is
mapped, it invisibly shields the widget and its hierarchy from all events that
may be sent. Like Tk widgets, busy windows have widget names in the Tk window
hierarchy. This means that you can use the \fBbind\fR command to handle
events in the busy window:
.PP
.CS
\fBtk busy\fR hold .frame.canvas
bind .frame.canvas_Busy <Enter> { ... }
.CE
.PP
Normally the busy window is a sibling of the widget. The name of the busy
window is
.QW \fIwidget\fB_Busy\fR
where \fIwidget\fR is the name of the widget to be made busy. In the previous
example, the pathname of the busy window is
.QW \fB.frame.canvas_Busy\fR .
The exception is when the widget is a toplevel widget (such as
.QW . )
where the busy window can't be made a sibling. The busy window is then a child
of the widget named
.QW \fIwidget\fB._Busy\fR
where \fIwidget\fR is the name of the toplevel widget. In the following
example, the pathname of the busy window is
.QW \fB._Busy\fR .
.PP
.CS
\fBtk busy\fR hold .
bind ._Busy <Enter> { ... }
.CE
.SS "ENTER/LEAVE EVENTS"
.PP
Mapping and unmapping busy windows generates Enter/Leave events for all
widgets they cover. Please note this if you are tracking Enter/Leave events in
widgets.
.SS "KEYBOARD EVENTS"
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
.PP
The above example moves the focus from .frame immediately after invoking the
\fBhold\fR so that no keyboard events will be sent to \fB.frame\fR or any of
its descendants. It also makes sure it's not possible to leave button
\fB.cancel\fR using the keyboard.
.SH PORTABILITY
.PP
Note that the \fBtk busy\fR command does not currently have any effect on OSX
when Tk is built using Aqua support.
.SH "SEE ALSO"
grab(n)
.SH KEYWORDS
busy, keyboard events, pointer events, window
'\" Local Variables:
'\" mode: nroff
'\" End:







|








264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
.PP
The above example moves the focus from .frame immediately after invoking the
\fBhold\fR so that no keyboard events will be sent to \fB.frame\fR or any of
its descendants. It also makes sure it's not possible to leave button
\fB.cancel\fR using the keyboard.
.SH PORTABILITY
.PP
Note that the \fBtk busy\fR command does not currently have any effect on macOS
when Tk is built using Aqua support.
.SH "SEE ALSO"
grab(n)
.SH KEYWORDS
busy, keyboard events, pointer events, window
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/button.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.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
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
If the button's state is \fBdisabled\fR then none of the above
actions occur:  the button is completely non-responsive.
.PP
The behavior of buttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "PLATFORM NOTES"
.PP
On Aqua/Mac OS X, some configuration options are ignored for the purpose of
drawing of the widget because they would otherwise conflict with platform
guidelines. The \fBconfigure\fR and \fBcget\fR subcommands can still
manipulate the values, but do not cause any variation to the look of the
widget. The options affected notably include \fB\-background\fR and
\fB\-relief\fR.
.SH EXAMPLES
.PP
This is the classic Tk
.QW "Hello, World!"
demonstration:
.PP
.CS
\fBbutton\fR .b \-text "Hello, World!" \-command exit
pack .b
.CE
.PP
This example demonstrates how to handle button accelerators:
.PP
.CS
\fBbutton\fR .b1 \-text Hello \-underline 0
\fBbutton\fR .b2 \-text World \-underline 0
bind . <Key\-h> {.b1 flash; .b1 invoke}
bind . <Key\-w> {.b2 flash; .b2 invoke}
pack .b1 .b2
.CE
.SH "SEE ALSO"
ttk::button(n)
.SH KEYWORDS
button, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







|












|






|
|
|
|









179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
If the button's state is \fBdisabled\fR then none of the above
actions occur:  the button is completely non-responsive.
.PP
The behavior of buttons can be changed by defining new bindings for
individual widgets or by redefining the class bindings.
.SH "PLATFORM NOTES"
.PP
On Aqua/macOS, some configuration options are ignored for the purpose of
drawing of the widget because they would otherwise conflict with platform
guidelines. The \fBconfigure\fR and \fBcget\fR subcommands can still
manipulate the values, but do not cause any variation to the look of the
widget. The options affected notably include \fB\-background\fR and
\fB\-relief\fR.
.SH EXAMPLES
.PP
This is the classic Tk
.QW "Hello, World!"
demonstration:
.PP
.CS
\fBbutton\fR .b -text "Hello, World!" -command exit
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.
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
It is possible to adjust the origin of the canvas
coordinate system relative to the origin of the window using the
\fBxview\fR and \fByview\fR widget commands; this is typically used
for scrolling.
Canvases do not support scaling or rotation of the canvas coordinate
system relative to the window coordinate system.
.PP
Individual items may be moved, scaled
.VS "8.7, TIP164"
or rotated
.VE "8.7, TIP164"
using widget commands
described below.
.PP
Note that the default origin of the canvas's visible area is
coincident with the origin for the whole window as that makes bindings
using the mouse position easier to work with; you only need to use the
\fBcanvasx\fR and \fBcanvasy\fR widget commands if you adjust the
origin of the visible area. However, this also means that any focus
ring (as controlled by the \fB\-highlightthickness\fR option) and







|
<
<
<
<
|







216
217
218
219
220
221
222
223




224
225
226
227
228
229
230
231
It is possible to adjust the origin of the canvas
coordinate system relative to the origin of the window using the
\fBxview\fR and \fByview\fR widget commands; this is typically used
for scrolling.
Canvases do not support scaling or rotation of the canvas coordinate
system relative to the window coordinate system.
.PP
Individual items may be moved or scaled using widget commands




described below, but they may not be rotated.
.PP
Note that the default origin of the canvas's visible area is
coincident with the origin for the whole window as that makes bindings
using the mouse position easier to work with; you only need to use the
\fBcanvasx\fR and \fBcanvasy\fR widget commands if you adjust the
origin of the visible area. However, this also means that any focus
ring (as controlled by the \fB\-highlightthickness\fR option) and
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,-_ \fR" .
The space can be used
to enlarge the space between other line elements, and cannot
occur as the first position in the string. Some examples:
.PP
.CS
\-dash .     \(-> \-dash {2 4}
\-dash -     \(-> \-dash {6 4}
\-dash -.    \(-> \-dash {6 4 2 4}
\-dash -..   \(-> \-dash {6 4 2 4 2 4}
\-dash {. }  \(-> \-dash {2 8}
\-dash ,     \(-> \-dash {4 4}







<







309
310
311
312
313
314
315

316
317
318
319
320
321
322
.PP
The second possible syntax is a character list containing only
5 possible characters
.QW "\fB.,-_ \fR" .
The space can be used
to enlarge the space between other line elements, and cannot
occur as the first position in the string. Some examples:

.CS
\-dash .     \(-> \-dash {2 4}
\-dash -     \(-> \-dash {6 4}
\-dash -.    \(-> \-dash {6 4 2 4}
\-dash -..   \(-> \-dash {6 4 2 4 2 4}
\-dash {. }  \(-> \-dash {2 8}
\-dash ,     \(-> \-dash {4 4}
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
.SH "WIDGET COMMAND"
.PP
The \fBcanvas\fR command creates a new Tcl command whose
name is \fIpathName\fR. This
command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
The following widget commands are possible for canvas widgets:
.TP
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg ...\fR?
.
For each item that meets the constraints specified by
\fIsearchSpec\fR and the \fIarg\fRs, add
\fItag\fR to the list of tags associated with the item if it
is not already present on that list.
It is possible that no items will satisfy the constraints
given by \fIsearchSpec\fR and \fIarg\fRs, in which case the







|





|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
.SH "WIDGET COMMAND"
.PP
The \fBcanvas\fR command creates a new Tcl command whose
name is \fIpathName\fR. This
command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
The following widget commands are possible for canvas widgets:
.TP
\fIpathName \fBaddtag \fItag searchSpec \fR?\fIarg arg ...\fR?
.
For each item that meets the constraints specified by
\fIsearchSpec\fR and the \fIarg\fRs, add
\fItag\fR to the list of tags associated with the item if it
is not already present on that list.
It is possible that no items will satisfy the constraints
given by \fIsearchSpec\fR and \fIarg\fRs, in which case the
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
If both \fIcommand\fR and \fIsequence\fR are omitted then the command
returns a list of all the sequences for which bindings have been
defined for \fItagOrId\fR.
.RS
.PP
The only events for which bindings may be specified are those related to
the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR,
\fBButton\fR, \fBMotion\fR, and \fBKey\fR) or virtual events.
The handling of events in canvases uses the current item defined in
\fBITEM IDS AND TAGS\fR above. \fBEnter\fR and \fBLeave\fR events
trigger for an
item when it becomes the current item or ceases to be the current item;
note that these events are different than \fBEnter\fR and \fBLeave\fR
events for windows. Mouse-related events are directed to the current
item, if any. Keyboard-related events are directed to the focus item, if







|







461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
If both \fIcommand\fR and \fIsequence\fR are omitted then the command
returns a list of all the sequences for which bindings have been
defined for \fItagOrId\fR.
.RS
.PP
The only events for which bindings may be specified are those related to
the mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR,
\fBButtonPress\fR, \fBMotion\fR, and \fBKeyPress\fR) or virtual events.
The handling of events in canvases uses the current item defined in
\fBITEM IDS AND TAGS\fR above. \fBEnter\fR and \fBLeave\fR events
trigger for an
item when it becomes the current item or ceases to be the current item;
note that these events are different than \fBEnter\fR and \fBLeave\fR
events for windows. Mouse-related events are directed to the current
item, if any. Keyboard-related events are directed to the focus item, if
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
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.







|







593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
tag given by \fItagToDelete\fR from the list of those
associated with the item.
If an item does not have the tag \fItagToDelete\fR then
the item is unaffected by the command.
If \fItagToDelete\fR is omitted then it defaults to \fItagOrId\fR.
This command returns an empty string.
.TP
\fIpathName \fBfind \fIsearchCommand \fR?\fIarg arg ...\fR?
.
This command returns a list consisting of all the items that
meet the constraints specified by \fIsearchCommand\fR and
\fIarg\fR's.
\fISearchCommand\fR and \fIargs\fR have any of the forms
accepted by the \fBaddtag\fR command.
The items are returned in stacking order, with the lowest item first.
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686

687
688
689
690
691
692
693
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.







<
<
<
<
<
<
<
<
<
<
<
<
<
<

|





>







654
655
656
657
658
659
660














661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
legal forms for \fIindex\fR.
Note: the insertion cursor is only displayed in an item if
that item currently has the keyboard focus (see the \fBfocus\fR widget
command, above), but the cursor position may
be set even when the item does not have the focus.
This command returns an empty string.
.TP














\fIpathName \fBimove \fItagOrId index x y\fR
.VS 8.6
This command causes the \fIindex\fR'th coordinate of each of the items
indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR).
Each item interprets \fIindex\fR independently according to the rules
described in \fBINDICES\fR above. Out of the standard set of items, only line
and polygon items may have their coordinates relocated this way.
.VE 8.6
.TP
\fIpathName \fBindex \fItagOrId index\fR
.
This command returns a decimal string giving the numerical index
within \fItagOrId\fR corresponding to \fIindex\fR.
\fIIndex\fR gives a textual description of the desired position
as described in \fBINDICES\fR above.
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781

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







|









>







747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
Move each of the items given by \fItagOrId\fR in the canvas coordinate
space by adding \fIxAmount\fR to the x-coordinate of each point
associated with the item and \fIyAmount\fR to the y-coordinate of
each point associated with the item.
This command returns an empty string.
.TP
\fIpathName \fBmoveto \fItagOrId xPos yPos\fR
.VS 8.6
Move the items given by \fItagOrId\fR in the canvas coordinate
space so that the first coordinate pair (the upper-left corner of the
bounding box) of the first item (the lowest in the display list) with
tag \fItagOrId\fR is located at
position (\fIxPos\fR,\fIyPos\fR). \fIxPos\fR and \fIyPos\fR may be
the empty string, in which case the corresponding coordinate
will be unchanged. All items matching
\fItagOrId\fR remain in the same positions relative to each other.
This command returns an empty string.
.VE 8.6
.TP
\fIpathName \fBpostscript \fR?\fIoption value option value ...\fR?
.
Generate a Postscript representation for part or all of the canvas.
If the \fB\-file\fR option is specified then the Postscript is written
to a file and an empty string is returned; otherwise the Postscript
is returned as the result of the command.
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
.RE
.TP
\fIpathName \fBrchars \fItagOrId first last string\fR
.
This command causes the text or coordinates between \fIfirst\fR and \fIlast\fR
for each of the items indicated by \fItagOrId\fR to be replaced by
\fIstring\fR. Each item interprets \fIfirst\fR and \fIlast\fR independently
according to the rules described in \fBINDICES\fR above. Out of the standard
set of items, text items support this operation by altering their text as
directed, and line and polygon items support this operation by altering their
coordinate list (in which case \fIstring\fR should be a list of coordinates to
use as a replacement). The other items ignore this operation.
.TP
\fIpathName \fBrotate \fItagOrId xOrigin yOrigin angle\fR
.VS "8.7, TIP164"
Rotate the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the rotation
operation and \fIangle\fR identifies the amount to rotate the coordinates
anticlockwise, in degrees. (Negative values rotate clockwise.)
This command returns an empty string.
.RS
.PP
Implementation note: not all item types work the same with rotations. In
particular,\fB bitmap\fR,\fB image\fR,\fB text\fR and\fB window\fR items only
rotate their anchor points and do not rotate the items themselves about those
points, and the \fBarc\fR, \fBoval\fR and \fBrectangle\fR types rotate about a
computed center point instead of moving the bounding box coordinates directly.
.PP
Some items (currently \fBarc\fR and\fB text\fR) have angles in their options;
this command \fIdoes not\fR affect those options.
.RE
.VE "8.7, TIP164"
.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
.
Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale







|








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|







943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958




















959
960
961
962
963
964
965
966
Note: this command has no effect on window items. Window items always
obscure other item types, and the stacking order of window items is
determined by the \fBraise\fR command and \fBlower\fR command, not the
\fBraise\fR widget command and \fBlower\fR widget command for canvases.
.RE
.TP
\fIpathName \fBrchars \fItagOrId first last string\fR
.VS 8.6
This command causes the text or coordinates between \fIfirst\fR and \fIlast\fR
for each of the items indicated by \fItagOrId\fR to be replaced by
\fIstring\fR. Each item interprets \fIfirst\fR and \fIlast\fR independently
according to the rules described in \fBINDICES\fR above. Out of the standard
set of items, text items support this operation by altering their text as
directed, and line and polygon items support this operation by altering their
coordinate list (in which case \fIstring\fR should be a list of coordinates to
use as a replacement). The other items ignore this operation.




















.VE 8.6
.TP
\fIpathName \fBscale \fItagOrId xOrigin yOrigin xScale yScale\fR
.
Rescale the coordinates of all of the items given by \fItagOrId\fR in canvas
coordinate space.
\fIXOrigin\fR and \fIyOrigin\fR identify the origin for the scaling
operation and \fIxScale\fR and \fIyScale\fR identify the scale
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153



1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
total width of the canvas is off-screen to the left.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.



If \fIwhat is \fBpages\fR then the view
adjusts in units of nine-tenths the window's width.
If \fInumber\fR is negative then information farther to the left
becomes visible; if it is positive then information farther to the right
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right in units
of the \fBxScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's width otherwise.
.RE
.TP
\fIpathName \fByview ?\fIargs\fR?
.
This command is used to query and change the vertical position of the
information displayed in the canvas's window.
It can take any of the following forms:







|
<
|

>
>
>





<
<
<







1106
1107
1108
1109
1110
1111
1112
1113

1114
1115
1116
1117
1118
1119
1120
1121
1122
1123



1124
1125
1126
1127
1128
1129
1130
total width of the canvas is off-screen to the left.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right in units
of the \fBxScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's width otherwise.
If \fIwhat is \fBpages\fR then the view
adjusts in units of nine-tenths the window's width.
If \fInumber\fR is negative then information farther to the left
becomes visible; if it is positive then information farther to the right
becomes visible.



.RE
.TP
\fIpathName \fByview ?\fIargs\fR?
.
This command is used to query and change the vertical position of the
information displayed in the canvas's window.
It can take any of the following forms:
1186
1187
1188
1189
1190
1191
1192
1193



1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
\fIFraction\fR is a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.



If \fIwhat\fR is \fBpages\fR then
the view adjusts in units of nine-tenths the window's height.
If \fInumber\fR is negative then higher information becomes
visible; if it is positive then lower information
becomes visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down in units
of the \fByScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's height otherwise.
.RE
.SH "OVERVIEW OF ITEM TYPES"
.PP
The sections below describe the various types of items supported
by canvas widgets. Each item type is characterized by two things:
first, the form of the \fBcreate\fR command used to create
instances of the type; and second, a set of configuration options







|
>
>
>





<
<
<







1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163



1164
1165
1166
1167
1168
1169
1170
\fIFraction\fR is a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBunits\fR or \fBpages\fR.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down in units
of the \fByScrollIncrement\fR option, if it is greater than zero,
or in units of one-tenth the window's height otherwise.
If \fIwhat\fR is \fBpages\fR then
the view adjusts in units of nine-tenths the window's height.
If \fInumber\fR is negative then higher information becomes
visible; if it is positive then lower information
becomes visible.



.RE
.SH "OVERVIEW OF ITEM TYPES"
.PP
The sections below describe the various types of items supported
by canvas widgets. Each item type is characterized by two things:
first, the form of the \fBcreate\fR command used to create
instances of the type; and second, a set of configuration options
1252
1253
1254
1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
\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







|
>







1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
\fB\-fill \fIcolor\fR
.TP
\fB\-activefill \fIcolor\fR
.TP
\fB\-disabledfill \fIcolor\fR
.
Specifies the color to be used to fill item's area.
in its normal, active, and disabled states.
The even-odd fill rule is used.
\fIColor\fR may have any of the forms accepted by \fBTk_GetColor\fR.
For the line item, it specifies the color of the line drawn.
For the text item, it specifies the foreground color of the text.
If \fIcolor\fR is an empty string (the default for all canvas items
except line and text), then the item will not be filled.
.TP
\fB\-outline \fIcolor\fR
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.
.SH "STANDARD ITEM TYPES"
.SS "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by either the \fB\-start\fR and \fB\-extent\fR options or the \fB\-height\fR option)
and displayed in one of several ways (specified by the \fB\-style\fR option).
Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval that defines the arc (except when
\fB\-height\fR is specified - see below).
.
After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An arc item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.







|
|







|
<
<







1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337


1338
1339
1340
1341
1342
1343
1344
For arcs, wide outlines will be drawn centered on the edges of the
arc's region.
.SH "STANDARD ITEM TYPES"
.SS "ARC ITEMS"
.PP
Items of type \fBarc\fR appear on the display as arc-shaped regions.
An arc is a section of an oval delimited by two angles (specified
by the \fB\-start\fR and \fB\-extent\fR options) and displayed in
one of several ways (specified by the \fB\-style\fR option).
Arcs are created with widget commands of the following form:
.CS
\fIpathName \fBcreate arc \fIx1 y1 x2 y2 \fR?\fIoption value ...\fR?
\fIpathName \fBcreate arc \fIcoordList\fR ?\fIoption value ...\fR?
.CE
The arguments \fIx1\fR, \fIy1\fR, \fIx2\fR, and \fIy2\fR or \fIcoordList\fR give
the coordinates of two diagonally opposite corners of a
rectangular region enclosing the oval that defines the arc.


After the coordinates there may be any number of \fIoption\fR\-\fIvalue\fR
pairs, each of which sets one of the configuration options
for the item. These same \fIoption\fR\-\fIvalue\fR pairs may be
used in \fBitemconfigure\fR widget commands to change the item's
configuration. An arc item becomes the current item when the mouse pointer is
over any part that is painted or (when fully transparent) that would be
painted if both the \fB\-fill\fR and \fB\-outline\fR options were non-empty.
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
modulo 360 is used as the extent.
.TP
\fB\-start \fIdegrees\fR
Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position; it may be either positive or negative.
.TP
\fB\-height \fIdistance\fR
Provides a shortcut for creating a circular arc segment by defining the
distance of the mid-point of the arc from its chord. When this option
is used the coordinates are interpreted as the start and end coordinates
of the chord, and the options \fB\-start\fR and \fB-extent\fR are ignored.
The value of \fIdistance\fR has the following meaning:
.RS
.PP
.RS
\fIdistance\fR > 0 creates a clockwise arc
.br
\fIdistance\fR < 0 creates an counter-clockwise arc
.br
\fIdistance\fR = 0 creates an arc as if this option had not been specified
.RE
.PP
If you want the arc to have a specific radius, \fIr\fR, use the formula:
.PP
.RS
\fIdistance\fR = \fIr\fR \(+- sqrt(\fIr\fR**2 - (chordLength / 2)**2)
.RE
.PP
choosing the minus sign for the minor arc and the plus sign for the major arc.
.PP
Note that \fBitemcget \-height\fR always returns 0 so that introspection code
can be kept simple.
.RE
.TP
\fB\-style \fItype\fR
Specifies how to draw the arc. If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1370
1371
1372
1373
1374
1375
1376




























1377
1378
1379
1380
1381
1382
1383
modulo 360 is used as the extent.
.TP
\fB\-start \fIdegrees\fR
Specifies the beginning of the angular range occupied by the
arc.
\fIDegrees\fR is given in units of degrees measured counter-clockwise
from the 3-o'clock position; it may be either positive or negative.




























.TP
\fB\-style \fItype\fR
Specifies how to draw the arc. If \fItype\fR is \fBpieslice\fR
(the default) then the arc's region is defined by a section
of the oval's perimeter plus two line segments, one between the center
of the oval and each end of the perimeter section.
If \fItype\fR is \fBchord\fR then the arc's region is defined
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
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







|







1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
and third, and so on. Straight-line segments can be generated within
a curve by duplicating the end-points of the desired line segment.
If the smoothing method is \fBraw\fR, this indicates that the polygon
should also be drawn as a curve but where the list of coordinates is
such that the first coordinate pair (and every third coordinate pair
thereafter) is a knot point on a cubic Bezier curve, and the other
coordinates are control points on the cubic Bezier curve. Straight
line segments can be generated within a curve by making control points
equal to their neighbouring knot points. If the last point is not the
second point of a pair of control points, the point is repeated (one or two
times) so that it also becomes the second point of a pair of control
points (the associated knot point will be the first control point).
.TP
\fB\-splinesteps \fInumber\fR
Specifies the degree of smoothness desired for curves: each spline
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871

1872
1873
1874
1875
1876
1877
1878
\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







|





>







1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
\fB\-stipple\fR	\fB\-activestipple\fR
\fB\-disabledstipple\fR	\fB\-state\fR
\fB\-tags\fR
.DE
The following extra options are supported for text items:
.TP
\fB\-angle \fIrotationDegrees\fR
.VS 8.6
\fIRotationDegrees\fR tells how many degrees to rotate the text anticlockwise
about the positioning point for the text; it may have any floating-point value
from 0.0 to 360.0. For example, if \fIrotationDegrees\fR is \fB90\fR, then the
text will be drawn vertically from bottom to top.
This option defaults to \fB0.0\fR.
.VE 8.6
.TP
\fB\-font \fIfontName\fR
Specifies the font to use for the text item.
\fIFontName\fR may be any string acceptable to \fBTk_GetFont\fR.
If this option is not specified, it defaults to a system-dependent
font.
.TP
Changes to doc/checkbutton.n.
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
.SH "WIDGET COMMAND"
.PP
The \fBcheckbutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for checkbutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given







|







188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
.SH "WIDGET COMMAND"
.PP
The \fBcheckbutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for checkbutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
Changes to doc/chooseDirectory.n.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

19
20

21
22
23
24
25

26
27

28
29
30
31
32
33
34
35

36
37

38
39

40
41

42
43
44

45
46

47
48
49

50
51

52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
'\"
'\" 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 macOS.
.\" 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 macOS.
.\" 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 macOS, 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.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH clipboard n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
clipboard \- Manipulate Tk clipboard
.SH SYNOPSIS
\fBclipboard \fIoption\fR ?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a Tcl interface to the Tk clipboard,
which stores data for later retrieval using the selection mechanism
(via the \fB\-selection CLIPBOARD\fR option).
In order to copy data into the clipboard, \fBclipboard clear\fR must







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH clipboard n 8.4 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
clipboard \- Manipulate Tk clipboard
.SH SYNOPSIS
\fBclipboard \fIoption\fR ?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a Tcl interface to the Tk clipboard,
which stores data for later retrieval using the selection mechanism
(via the \fB\-selection CLIPBOARD\fR option).
In order to copy data into the clipboard, \fBclipboard clear\fR must
Changes to doc/colors.n.
1
2
3
4
5
6
7
8
9
'\"
'\" Copyright (c) 1998-2000 by Scriptics Corporation.
'\" Copyright (c) 2003 ActiveState Corporation.
'\" Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
'\" Copyright (c) 2008 Donal K. Fellows
'\"
.TH colors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS

|







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 <das@users.sourceforge.net>
'\" Copyright (c) 2008 Donal K. Fellows
'\"
.TH colors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
yellow2	238	238 	0
yellow3	205	205 	0
yellow4	139	139 	0
YellowGreen	154	205 	50
.DE
.SH "PORTABILITY ISSUES"
.TP
\fBMac OS X\fR
.
On macOS, the following additional system colors are available.  This
first group contains all of the HIBrush colors available in the
HIToolbox library. Note that on macOS 10.14 (Mojave) and later these
colors are unlikely to match the color actually used for the purpose
suggested by the color name.
.RS







|







778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
yellow2	238	238 	0
yellow3	205	205 	0
yellow4	139	139 	0
YellowGreen	154	205 	50
.DE
.SH "PORTABILITY ISSUES"
.TP
\fBmacOS\fR
.
On macOS, the following additional system colors are available.  This
first group contains all of the HIBrush colors available in the
HIToolbox library. Note that on macOS 10.14 (Mojave) and later these
colors are unlikely to match the color actually used for the purpose
suggested by the color name.
.RS
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
systemWhite
systemWindowBody
.DE
.RE
.
Tk supports all of the NSColors in the macOS System ColorList.  The
convention for naming these colors is that the Tk name is generated by
capitalizing the macOS name and adding the prefix "system".  On OSX
10.14 (Mojave) and later many of these "semantic" colors will appear
differently depending on whether the NSWindow in which they are used has
the Aqua or DarkAqua appearance.  The System ColorList differs between
releases of macOS and some colors, such as systemLinkColor and
systemControlAccentColor, are simulated on older systems which did not
provide them.  All of the colors below are available on all supported
macOS releases, but newer systems will support additional colors.







|







866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
systemWhite
systemWindowBody
.DE
.RE
.
Tk supports all of the NSColors in the macOS System ColorList.  The
convention for naming these colors is that the Tk name is generated by
capitalizing the macOS name and adding the prefix "system".  On macOS
10.14 (Mojave) and later many of these "semantic" colors will appear
differently depending on whether the NSWindow in which they are used has
the Aqua or DarkAqua appearance.  The System ColorList differs between
releases of macOS and some colors, such as systemLinkColor and
systemControlAccentColor, are simulated on older systems which did not
provide them.  All of the colors below are available on all supported
macOS releases, but newer systems will support additional colors.
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
systemTextBackgroundColor
systemTextColor
.DE
.RE
.
The numbered systemWindowBackgroundColors below
are used in the \fBttk::notebook\fR and \fBttk::labelframe\fR widgets
to provide a contrasting background.  Each numbered color constrasts
with its predecessor.
.RS
.DS
systemWindowBackgroundColor
systemWindowBackgroundColor1
systemWindowBackgroundColor2
systemWindowBackgroundColor3
systemWindowBackgroundColor4
systemWindowBackgroundColor5
systemWindowBackgroundColor6
systemWindowBackgroundColor7
.DE
.RE
.TP

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







|














<







|
|
|
|
|
|
|
|
|




<









892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913

914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933

934
935
936
937
938
939
940
941
942
systemTextBackgroundColor
systemTextColor
.DE
.RE
.
The numbered systemWindowBackgroundColors below
are used in the \fBttk::notebook\fR and \fBttk::labelframe\fR widgets
to provide a contrasting background.  Each numbered color contrasts
with its predecessor.
.RS
.DS
systemWindowBackgroundColor
systemWindowBackgroundColor1
systemWindowBackgroundColor2
systemWindowBackgroundColor3
systemWindowBackgroundColor4
systemWindowBackgroundColor5
systemWindowBackgroundColor6
systemWindowBackgroundColor7
.DE
.RE
.TP

\fBWindows\fR
.
On Windows, the following additional system colors are available
(note that the actual color values depend on the currently active OS theme):
.RS
.DS
.ta 6c
system3dDarkShadow	systemHighlight
system3dLight	systemHighlightText
systemActiveBorder	systemInactiveBorder
systemActiveCaption	systemInactiveCaption
systemAppWorkspace	systemInactiveCaptionText
systemBackground	systemInfoBackground
systemButtonFace	systemInfoText
systemButtonHighlight	systemMenu
systemButtonShadow	systemMenuText
systemButtonText	systemScrollbar
systemCaptionText	systemWindow
systemDisabledText	systemWindowFrame
systemGrayText	systemWindowText

.DE
.RE
.SH "SEE ALSO"
options(n), Tk_GetColor(3)
.SH KEYWORDS
color, option
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/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 <das@users.sourceforge.net>
'\"
.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 <das@users.sourceforge.net>
'\"
.TH cursors n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
97
98
99
100
101
102
103

104
105
106
107
108
109
110
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
126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
141
size_nw_se
size_we
uparrow
wait
.CE
.RE
.TP
\fBMac OS X\fR

On Mac OS X systems, the following cursors are mapped to native cursors:
.RS
.CS
arrow
top_left_arrow
left_ptr
cross
crosshair







|
>
|







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
size_nw_se
size_we
uparrow
wait
.CE
.RE
.TP
\fBmacOS\fR
.
On macOS, the following cursors are mapped to native cursors:
.RS
.CS
arrow
top_left_arrow
left_ptr
cross
crosshair
Changes to doc/entry.n.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
\-borderwidth	\-insertbackground	\-selectborderwidth
\-cursor	\-insertborderwidth	\-selectforeground
\-exportselection	\-insertofftime	\-takefocus
\-font	\-insertontime	\-textvariable
\-foreground	\-insertwidth	\-xscrollcommand
\-highlightbackground	\-justify
\-highlightcolor	\-relief
\-placeholder	\-placeholderforeground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-disabledbackground disabledBackground DisabledBackground
Specifies the background color to use when the entry is disabled.  If
this option is the empty string, the normal background color is used.
.OP \-disabledforeground disabledForeground DisabledForeground
Specifies the foreground color to use when the entry is disabled.  If







<







19
20
21
22
23
24
25

26
27
28
29
30
31
32
\-borderwidth	\-insertbackground	\-selectborderwidth
\-cursor	\-insertborderwidth	\-selectforeground
\-exportselection	\-insertofftime	\-takefocus
\-font	\-insertontime	\-textvariable
\-foreground	\-insertwidth	\-xscrollcommand
\-highlightbackground	\-justify
\-highlightcolor	\-relief

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-disabledbackground disabledBackground DisabledBackground
Specifies the background color to use when the entry is disabled.  If
this option is the empty string, the normal background color is used.
.OP \-disabledforeground disabledForeground DisabledForeground
Specifies the foreground color to use when the entry is disabled.  If
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
entry widget to become out of sync with the \fB\-textvariable\fR.
.SH "WIDGET COMMAND"
.PP
The \fBentry\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName subcommand \fR?\fIarg ...\fR?
.CE
\fISubcommand\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for entries take one or more indices as
arguments.  An index specifies a particular character in the entry's







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
entry widget to become out of sync with the \fB\-textvariable\fR.
.SH "WIDGET COMMAND"
.PP
The \fBentry\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName subcommand \fR?\fIarg arg ...\fR?
.CE
\fISubcommand\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for entries take one or more indices as
arguments.  An index specifies a particular character in the entry's
399
400
401
402
403
404
405
406
407
408
409


410
411
412
413
414
415
416
417
418
419
420
421
422
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.


If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left become
visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for entries that give them
the following default behavior. In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or







|
<
|

>
>
|
|
|

<
<







398
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413


414
415
416
417
418
419
420
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display;  if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.


.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for entries that give them
the following default behavior. In the descriptions below,
.QW word
refers to a contiguous group of letters, digits, or
Changes to doc/event.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH event n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
event \- Miscellaneous event facilities: define virtual events and generate events
.SH SYNOPSIS
\fBevent\fI option \fR?\fIarg ...\fR?
.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:







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH event n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
event \- Miscellaneous event facilities: define virtual events and generate events
.SH SYNOPSIS
\fBevent\fI option \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBevent\fR command provides several facilities for dealing with
window system events, such as defining virtual events and synthesizing
events.  The command has several different forms, determined by the
first argument.  The following forms are currently supported:
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
\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.







|







96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
\fISize\fR must be a screen distance;  it specifies the
\fIborder_width\fR field for the event.
Valid for \fBConfigure\fR events.
Corresponds to the \fB%B\fR substitution for binding scripts.
.TP
\fB\-button\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIdetail\fR field
for a \fBButtonPress\fR or \fBButtonRelease\fR event, overriding
any button  number provided in the base \fIevent\fR argument.
Corresponds to the \fB%b\fR substitution for binding scripts.
.TP
\fB\-count\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIcount\fR field
for the event.  Valid for \fBExpose\fR events.
Corresponds to the \fB%c\fR substitution for binding scripts.
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
\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







|







|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
\fISize\fR must be a screen distance;  it specifies the \fIheight\fR
field for the event.  Valid for \fBConfigure\fR events.
Corresponds to the \fB%h\fR substitution for binding scripts.
.TP
\fB\-keycode\fI number\fR
\fINumber\fR  must be an integer;  it specifies the \fIkeycode\fR
field for the event.
Valid for \fBKeyPress\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%k\fR substitution for binding scripts.
.TP
\fB\-keysym\fI name\fR
\fIName\fR must be the name of a valid keysym, such as \fBg\fR,
\fBspace\fR, or \fBReturn\fR;  its corresponding
keycode value is used as the \fIkeycode\fR field for event, overriding
any detail specified in the base \fIevent\fR argument.
Valid for \fBKeyPress\fR and \fBKeyRelease\fR events.
Corresponds to the \fB%K\fR substitution for binding scripts.
.TP
\fB\-mode\fI notify\fR
\fINotify\fR specifies the \fImode\fR field for the event and must be
one of \fBNotifyNormal\fR, \fBNotifyGrab\fR, \fBNotifyUngrab\fR, or
\fBNotifyWhileGrabbed\fR.
Valid for \fBEnter\fR, \fBLeave\fR, \fBFocusIn\fR, and
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
either \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.
Valid for \fBCirculate\fR events.
Corresponds to the \fB%p\fR substitution for binding scripts.
.TP
\fB\-root\fI window\fR
\fIWindow\fR must be either a window path name or an integer window
identifier;  it specifies the \fIroot\fR field for the event.
Valid for \fBKey\fR, \fBKeyRelease\fR, \fBButton\fR,
\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.







|







|






|
















|











|







|







|







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
either \fBPlaceOnTop\fR or \fBPlaceOnBottom\fR.
Valid for \fBCirculate\fR events.
Corresponds to the \fB%p\fR substitution for binding scripts.
.TP
\fB\-root\fI window\fR
\fIWindow\fR must be either a window path name or an integer window
identifier;  it specifies the \fIroot\fR field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%R\fR substitution for binding scripts.
.TP
\fB\-rootx\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIx_root\fR
field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.  Corresponds to the \fB%X\fR substitution for binding scripts.
.TP
\fB\-rooty\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIy_root\fR
field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR
events.
Corresponds to the \fB%Y\fR substitution for binding scripts.
.TP
\fB\-sendevent\fI boolean\fR
\fIBoolean\fR must be a boolean value;  it specifies the \fIsend_event\fR
field for the event.  Valid for all events.  Corresponds to the
\fB%E\fR substitution for binding scripts.
.TP
\fB\-serial\fI number\fR
\fINumber\fR must be an integer;  it specifies the \fIserial\fR field
for the event.  Valid for all events.
Corresponds to the \fB%#\fR substitution for binding scripts.
.TP
\fB\-state\fI state\fR
\fIState\fR specifies the \fIstate\fR field for the event.
For \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events
it must be an integer value.
For \fBVisibility\fR events it must be one of \fBVisibilityUnobscured\fR,
\fBVisibilityPartiallyObscured\fR, or \fBVisibilityFullyObscured\fR.
This option overrides any modifiers such as \fBMeta\fR or \fBControl\fR
specified in the base \fIevent\fR.
Corresponds to the \fB%s\fR substitution for binding scripts.
.TP
\fB\-subwindow\fI window\fR
\fIWindow\fR specifies the \fIsubwindow\fR field for the event, either
as a path name for a Tk widget or as an integer window identifier.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, and \fBMotion\fR events.
Similar to \fB%S\fR substitution for binding scripts.
.TP
\fB\-time\fI integer\fR
\fIInteger\fR must be an integer value;  it specifies the \fItime\fR field
for the event. Additonally the special value \fBcurrent\fR is allowed,
this value will be substituted by the current event time.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBEnter\fR, \fBLeave\fR, \fBMotion\fR,
and \fBProperty\fR events.
Corresponds to the \fB%t\fR substitution for binding scripts.
.TP
\fB\-warp\fI boolean\fR
\fIboolean\fR must be a boolean value;  it specifies whether
the screen pointer should be warped as well.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, and \fBMotion\fR events.  The pointer will
only warp to a window if it is mapped.
.TP
\fB\-width\fI size\fR
\fISize\fR must be a screen distance;  it specifies the \fIwidth\fR field
for the event.
Valid for \fBConfigure\fR events.
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
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.







|











|







278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
This option is useful when generating a series of events that should
be processed in order but at the front of the queue.
.RE
.TP
\fB\-x\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIx\fR field
for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%x\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%X\fR substitution
for binding scripts.
.TP
\fB\-y\fI coord\fR
\fICoord\fR must be a screen distance;  it specifies the \fIy\fR
field for the event.
Valid for \fBKeyPress\fR, \fBKeyRelease\fR, \fBButtonPress\fR,
\fBButtonRelease\fR, \fBMotion\fR, \fBEnter\fR, \fBLeave\fR,
\fBExpose\fR, \fBConfigure\fR, \fBGravity\fR, and \fBReparent\fR
events.
Corresponds to the \fB%y\fR substitution for binding scripts.
If \fIWindow\fR is empty the coordinate is relative to the
screen, and this option corresponds to the \fB%Y\fR substitution
for binding scripts.
338
339
340
341
342
343
344









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







>
>
>
>
>
>
>
>
>







338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
This is sent to a text widget when the selection in the widget is
changed.
.TP
\fB<<ThemeChanged>>\fR
This is sent to all widgets when the ttk theme changed. The ttk
widgets listen to this event and redisplay themselves when it fires.
The legacy widgets ignore this event.
.TP
\fB<<TkWorldChanged>>\fR
.
This event is sent to all widgets when a font is changed, for example,
by the use of [font configure].  The user_data field (%d) will have the
value "FontChanged".  For other system wide changes, this event will
be sent to all widgets, and the user_data field will indicate the
cause of the change.  NOTE: all tk and ttk widgets already handle this
event internally.
.TP
\fB<<TraverseIn>>\fR
This is sent to a widget when the focus enters the widget because of a
user-driven
.QW "tab to widget"
action.
.TP
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
.PP
When a definition of a virtual event changes at run time, all windows
will respond immediately to the new definition.
Starting from the preceding example, if the following code is executed:
.PP
.CS
bind Entry <Control-y> {}
\fBevent add\fR <<Paste>> <F6>
.CE
.PP
the behavior will change such in two ways.  First, the shadowed
\fB<<Paste>>\fR binding will emerge.
Typing Control-y will no longer invoke the \fB<Control-y>\fR binding,
but instead invoke the virtual event \fB<<Paste>>\fR.  Second,
pressing the F6 key will now also invoke the \fB<<Paste>>\fR binding.







|







573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
.PP
When a definition of a virtual event changes at run time, all windows
will respond immediately to the new definition.
Starting from the preceding example, if the following code is executed:
.PP
.CS
bind Entry <Control-y> {}
\fBevent add\fR <<Paste>> <Key-F6>
.CE
.PP
the behavior will change such in two ways.  First, the shadowed
\fB<<Paste>>\fR binding will emerge.
Typing Control-y will no longer invoke the \fB<Control-y>\fR binding,
but instead invoke the virtual event \fB<<Paste>>\fR.  Second,
pressing the F6 key will now also invoke the \fB<<Paste>>\fR binding.
Changes to doc/focus.n.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
focus \- Manage the input focus
.SH SYNOPSIS
.nf
\fBfocus\fR
\fBfocus \fIwindow\fR
\fBfocus \fIoption\fR ?\fIarg ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
The \fBfocus\fR command is used to manage the Tk input focus.
At any given time, one window on each display is designated as
the \fIfocus window\fR;  any key press or key release events for the







|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
focus \- Manage the input focus
.SH SYNOPSIS
.nf
\fBfocus\fR
\fBfocus \fIwindow\fR
\fBfocus \fIoption\fR ?\fIarg arg ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
The \fBfocus\fR command is used to manage the Tk input focus.
At any given time, one window on each display is designated as
the \fIfocus window\fR;  any key press or key release events for the
Changes to doc/font.n.
16
17
18
19
20
21
22

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

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

61
62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78

79
80
81
82
83
84

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

99
100
101
102
103
104
105
106
107
108
109

110
111

112
113
114
115
116
117
118
.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/macOS, the system fonts (see
\fBPLATFORM SPECIFIC FONTS\fR below) may not be actually altered because they
are implemented by the system theme. To achieve the effect of modification,
use \fBfont actual\fR to get their configuration and \fBfont create\fR to
synthesize a copy of the font which can be modified.
.RE
.\" METHOD: create
.TP
\fBfont create\fR ?\fIfontname\fR? ?\fIoption value ...\fR?
.
Creates a new named font and returns its name.  \fIfontname\fR specifies the
name for the font; if it is omitted, then Tk generates a new name of the
form \fBfont\fIx\fR, where \fIx\fR is an integer.  There may be any number
of \fIoption\fR\-\fIvalue\fR pairs, which provide the desired attributes for
the new named font.  See \fBFONT OPTIONS\fR below for a list of the possible
attributes.
.\" METHOD: delete
.TP
\fBfont delete\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
\fBmacOS\fR
.
The following fonts are supported, and are mapped to the user's
style defaults.
.RS
.DS
.ta 3c 6c
\fBsystem\fR	\fBapplication\fR	\fBmenu\fR
.DE
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
.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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
'\"
'\" Copyright (c) 2008 Daniel A. Steffen <das@users.sourceforge.net>
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH fontchooser n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fontchooser \- control font selection dialog
.SH SYNOPSIS

\fBtk fontchooser\fR \fBconfigure\fR ?\fI\-option value ...\fR?
.sp
\fBtk fontchooser\fR \fBshow\fR
.sp
\fBtk fontchooser\fR \fBhide\fR

.BE
.SH DESCRIPTION
.PP
The \fBtk fontchooser\fR command controls the Tk font selection dialog. It uses
the native platform font selection dialog where available, or a dialog
implemented in Tcl otherwise.
.PP
Unlike most of the other Tk dialog commands, \fBtk fontchooser\fR does not
return an immediate result, as on some platforms (Mac OS X) the standard font
dialog is modeless while on others (Windows) it is modal. To accommodate this
difference, all user interaction with the dialog will be communicated to the
caller via callbacks or virtual events.
.PP
The \fBtk fontchooser\fR command can have one of the following forms:

.TP
\fBtk fontchooser\fR \fBconfigure \fR?\fI\-option value ...\fR?
.
Set or query one or more of the configurations options below (analogous to Tk
widget configuration).

.TP
\fBtk fontchooser\fR \fBshow\fR
.
Show the font selection dialog. Depending on the platform, may return
immediately or only once the dialog has been withdrawn.

.TP
\fBtk fontchooser\fR \fBhide\fR
.
Hide the font selection dialog if it is visible and cause any pending
\fBtk fontchooser\fR \fBshow\fR command to return.
.PP
.SH "CONFIGURATION OPTIONS"

.TP
\fB\-parent\fR

Specifies/returns the logical parent window of the font selection dialog
(similar to the \fB\-parent\fR option to other dialogs). The font selection
dialog is hidden if it is visible when the parent window is destroyed.

.TP
\fB\-title\fR

Specifies/returns the title of the dialog. Has no effect on platforms where the
font selection dialog does not support titles.

.TP
\fB\-font\fR

Specifies/returns the font that is currently selected in the dialog if it is
visible, or that will be initially selected when the dialog is shown (if
supported by the platform). Can be set to the empty string to indicate that no
font should be selected. Fonts can be specified in any form given by the "FONT
DESCRIPTION" section in the \fBfont\fR manual page.

.TP
\fB\-command\fR

Specifies/returns the command prefix to be called when a font selection has
been made by the user. The command prefix is evaluated at the global level
after having the specification of the selected font appended. On platforms
where the font selection dialog offers the user control of further font
attributes (such as color), additional key/value pairs may be appended before
evaluation. Can be set to the empty string to indicate that no callback should
be invoked. Fonts are specified by a list of form [3] of the "FONT DESCRIPTION"
section in the \fBfont\fR manual page (i.e. a list of the form
\fI{family size style ?style ...?}\fR).

.TP
\fB\-visible\fR

Read-only option that returns a boolean indicating whether the font selection
dialog is currently visible. Attempting to set this option results in an error.

.PP
.SH "VIRTUAL EVENTS"
.TP
\fB<<TkFontchooserVisibility>>\fR

Sent to the dialog parent whenever the visibility of the font selection dialog
changes, both as a result of user action (e.g. disposing of the dialog via
OK/Cancel button or close box) and of the \fBtk fontchooser\fR
\fBshow\fR/\fBhide\fR commands being called. Binding scripts can determine the
current visibility of the dialog by querying the \fB\-visible\fR configuration
option.
.TP
\fB<<TkFontchooserFontChanged>>\fR

Sent to the dialog parent whenever the font selection dialog is visible and the
selected font changes, both as a result of user action and of the \fB\-font\fR
configuration option being set. Binding scripts can determine the currently
selected font by querying the \fB\-font\fR configuration option.
.PP
.SH NOTES
.PP
Callers should not expect a result from \fBtk fontchooser\fR \fBshow\fR and may
not assume that the dialog has been withdrawn or closed when the command
returns. All user interaction with the dialog is communicated to the caller via
the \fB\-command\fR callback and the \fB<<TkFontchooser*>>\fR virtual events.
It is implementation dependent which exact user actions result in the callback
being called resp. the virtual events being sent. Where an Apply or OK button
is present in the dialog, that button will trigger the \fB\-command\fR callback
and \fB<<TkFontchooserFontChanged>>\fR virtual event. On some implementations
other user actions may also have that effect; on Mac OS X for instance, the
standard font selection dialog immediately reflects all user choices to the
caller.
.PP
In the presence of multiple widgets intended to be influenced by the font
selection dialog, care needs to be taken to correctly handle focus changes: the
font selected in the dialog should always match the current font of the widget
with the focus, and the \fB\-command\fR callback should only act on the widget













>

<

<

>








|





>





>





>







>


>



>


>


>


>





>


>









>


>







>








>















|







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

16

17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
'\"
'\" Copyright (c) 2008 Daniel A. Steffen <das@users.sourceforge.net>
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH fontchooser n "" Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
fontchooser \- control font selection dialog
.SH SYNOPSIS
.nf
\fBtk fontchooser\fR \fBconfigure\fR ?\fI\-option value ...\fR?

\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 (macOS) the standard font
dialog is modeless while on others (Windows) it is modal. To accommodate this
difference, all user interaction with the dialog will be communicated to the
caller via callbacks or virtual events.
.PP
The \fBtk fontchooser\fR command can have one of the following forms:
.\" METHOD: configure
.TP
\fBtk fontchooser\fR \fBconfigure \fR?\fI\-option value ...\fR?
.
Set or query one or more of the configurations options below (analogous to Tk
widget configuration).
.\" METHOD: show
.TP
\fBtk fontchooser\fR \fBshow\fR
.
Show the font selection dialog. Depending on the platform, may return
immediately or only once the dialog has been withdrawn.
.\" METHOD: hide
.TP
\fBtk fontchooser\fR \fBhide\fR
.
Hide the font selection dialog if it is visible and cause any pending
\fBtk fontchooser\fR \fBshow\fR command to return.
.PP
.SH "CONFIGURATION OPTIONS"
.\" OPTION: -parent
.TP
\fB\-parent\fR
.
Specifies/returns the logical parent window of the font selection dialog
(similar to the \fB\-parent\fR option to other dialogs). The font selection
dialog is hidden if it is visible when the parent window is destroyed.
.\" OPTION: -title
.TP
\fB\-title\fR
.
Specifies/returns the title of the dialog. Has no effect on platforms where the
font selection dialog does not support titles.
.\" OPTION: -font
.TP
\fB\-font\fR
.
Specifies/returns the font that is currently selected in the dialog if it is
visible, or that will be initially selected when the dialog is shown (if
supported by the platform). Can be set to the empty string to indicate that no
font should be selected. Fonts can be specified in any form given by the "FONT
DESCRIPTION" section in the \fBfont\fR manual page.
.\" OPTION: -command
.TP
\fB\-command\fR
.
Specifies/returns the command prefix to be called when a font selection has
been made by the user. The command prefix is evaluated at the global level
after having the specification of the selected font appended. On platforms
where the font selection dialog offers the user control of further font
attributes (such as color), additional key/value pairs may be appended before
evaluation. Can be set to the empty string to indicate that no callback should
be invoked. Fonts are specified by a list of form [3] of the "FONT DESCRIPTION"
section in the \fBfont\fR manual page (i.e. a list of the form
\fI{family size style ?style ...?}\fR).
.\" OPTION: -visible
.TP
\fB\-visible\fR
.
Read-only option that returns a boolean indicating whether the font selection
dialog is currently visible. Attempting to set this option results in an error.

.PP
.SH "VIRTUAL EVENTS"
.TP
\fB<<TkFontchooserVisibility>>\fR
.
Sent to the dialog parent whenever the visibility of the font selection dialog
changes, both as a result of user action (e.g. disposing of the dialog via
OK/Cancel button or close box) and of the \fBtk fontchooser\fR
\fBshow\fR/\fBhide\fR commands being called. Binding scripts can determine the
current visibility of the dialog by querying the \fB\-visible\fR configuration
option.
.TP
\fB<<TkFontchooserFontChanged>>\fR
.
Sent to the dialog parent whenever the font selection dialog is visible and the
selected font changes, both as a result of user action and of the \fB\-font\fR
configuration option being set. Binding scripts can determine the currently
selected font by querying the \fB\-font\fR configuration option.
.PP
.SH NOTES
.PP
Callers should not expect a result from \fBtk fontchooser\fR \fBshow\fR and may
not assume that the dialog has been withdrawn or closed when the command
returns. All user interaction with the dialog is communicated to the caller via
the \fB\-command\fR callback and the \fB<<TkFontchooser*>>\fR virtual events.
It is implementation dependent which exact user actions result in the callback
being called resp. the virtual events being sent. Where an Apply or OK button
is present in the dialog, that button will trigger the \fB\-command\fR callback
and \fB<<TkFontchooserFontChanged>>\fR virtual event. On some implementations
other user actions may also have that effect; on macOS for instance, the
standard font selection dialog immediately reflects all user choices to the
caller.
.PP
In the presence of multiple widgets intended to be influenced by the font
selection dialog, care needs to be taken to correctly handle focus changes: the
font selected in the dialog should always match the current font of the widget
with the focus, and the \fB\-command\fR callback should only act on the widget
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
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.
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 "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fB\-background\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.
.VS "8.7, TIP262"
An empty background will disable drawing the background image.
.OP \-backgroundimage backgroundImage BackgroundImage
This specifies an image to display on the frame's background within
the border of the frame (i.e., the image will be clipped by the
frame's highlight ring and border, if either are present); subwidgets
of the frame will be drawn on top. The image must have been created
with the \fBimage create\fR command. If specified as the empty string,
no image will be displayed.
.VE "8.7, TIP262"
.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.
The \fB\-class\fR option may not be changed with the \fBconfigure\fR
widget command.







<
<
<
<
<
<
<
<
<
<







21
22
23
24
25
26
27










28
29
30
31
32
33
34
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fB\-background\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.










.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.
The \fB\-class\fR option may not be changed with the \fBconfigure\fR
widget command.
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
Specifies the desired height for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.  If this option is less than or equal
to zero then the window will not request any size at all.  Note that this
sets the total height of the frame, any \fB\-borderwidth\fR or similar is
not added.  Normally \fB\-height\fR should not be used if a propagating
geometry manager, such as \fBgrid\fR or \fBpack\fR, is used within the
frame since the geometry manager will override the height of the frame.
.OP \-tile tile Tile
.VS "8.7, TIP262"
This specifies how to draw the background image (see
\fB\-backgroundimage\fR) on the frame.
If true (according to \fBTcl_GetBoolean\fR), the image will be tiled
to fill the whole frame, with the origin of the first copy of the
image being the top left of the interior of the frame.
If false (the default), the image will be centered within the frame.
.VE "8.7, TIP262"
.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the same
visual as its parent.
The \fB\-visual\fR option may not be modified with the \fBconfigure\fR
widget command.







<
<
<
<
<
<
<
<
<







58
59
60
61
62
63
64









65
66
67
68
69
70
71
Specifies the desired height for the window in any of the forms
acceptable to \fBTk_GetPixels\fR.  If this option is less than or equal
to zero then the window will not request any size at all.  Note that this
sets the total height of the frame, any \fB\-borderwidth\fR or similar is
not added.  Normally \fB\-height\fR should not be used if a propagating
geometry manager, such as \fBgrid\fR or \fBpack\fR, is used within the
frame since the geometry manager will override the height of the frame.









.OP \-visual visual Visual
Specifies visual information for the new window in any of the
forms accepted by \fBTk_GetVisual\fR.
If this option is not specified, the new window will use the same
visual as its parent.
The \fB\-visual\fR option may not be modified with the \fBconfigure\fR
widget command.
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
or in the option database
to configure aspects of the frame such as its background color
and relief.  The \fBframe\fR command returns the
path name of the new window.
.PP
A frame is a simple widget.  Its primary purpose is to act as a
spacer or container for complex window layouts.  The only features
of a frame are its background and an optional 3-D border to make the
frame appear raised or sunken.
.SH "WIDGET COMMAND"
.PP
The \fBframe\fR command creates a new Tcl command whose
name is the same as the path name of the frame's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.PP
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the frame widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP







|









|







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
or in the option database
to configure aspects of the frame such as its background color
and relief.  The \fBframe\fR command returns the
path name of the new window.
.PP
A frame is a simple widget.  Its primary purpose is to act as a
spacer or container for complex window layouts.  The only features
of a frame are its background color and an optional 3-D border to make the
frame appear raised or sunken.
.SH "WIDGET COMMAND"
.PP
The \fBframe\fR command creates a new Tcl command whose
name is the same as the path name of the frame's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.PP
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the frame widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
Changes to doc/getOpenFile.n.
30
31
32
33
34
35
36

37
38

39
40
41
42
43

44
45

46
47
48
49

50
51
52
53
54
55
56
57
58
59

60
61
62
63
64
65
66
67
68
69
70

71
72
73
74
75
76
77
78
79
80
81

82
83
84
85

86
87
88
89
90

91
92
93
94

95
96
97
98
99
100

101
102
103
104
105

106
107
108
109
110
111
112
113
114
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 macOS.
.\" 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 macOS, which
does not require extensions to filenames,
and the UNIX implementation guesses reasonable values for this from
the \fB\-filetypes\fR option when this is not supplied.
.\" OPTION: -filetypes
.TP
\fB\-filetypes\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 macOS.
.\" 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 macOS, 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.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grab \- Confine pointer and keyboard events to a window sub-tree
.SH SYNOPSIS
\fBgrab \fR?\fB\-global\fR? \fIwindow\fR
.sp
\fBgrab \fIoption \fR?\fIarg \fR...?
.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







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
grab \- Confine pointer and keyboard events to a window sub-tree
.SH SYNOPSIS
\fBgrab \fR?\fB\-global\fR? \fIwindow\fR
.sp
\fBgrab \fIoption \fR?\fIarg arg \fR...?
.BE
.SH DESCRIPTION
.PP
This command implements simple pointer and keyboard grabs for Tk.
Tk's grabs are different than the grabs
described in the Xlib documentation.
When a grab is set for a particular window, Tk restricts all pointer
Changes to doc/grid.n.
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
.TP
\fB\-sticky \fIstyle\fR
.
If a content's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the content within its cell.
\fIStyle\fR  is a string that contains zero or more of the characters
\fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.
The string can optionally contain spaces or
commas, but they are ignored.  Each letter refers to a side (north, south,
east, or west) that the content will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR) are
specified, the content will be stretched to fill the entire
height (or width) of its cavity.  The \fB\-sticky\fR option subsumes the
combination of \fB\-anchor\fR and \fB\-fill\fR that is used by \fBpack\fR.







|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
.TP
\fB\-sticky \fIstyle\fR
.
If a content's cell is larger than its requested dimensions, this
option may be used to position (or stretch) the content within its cell.
\fIStyle\fR  is a string that contains zero or more of the characters
\fBn\fR, \fBs\fR, \fBe\fR or \fBw\fR.
The string can optionally contains spaces or
commas, but they are ignored.  Each letter refers to a side (north, south,
east, or west) that the content will
.QW stick
to.  If both \fBn\fR and \fBs\fR (or \fBe\fR and \fBw\fR) are
specified, the content will be stretched to fill the entire
height (or width) of its cavity.  The \fB\-sticky\fR option subsumes the
combination of \fB\-anchor\fR and \fB\-fill\fR that is used by \fBpack\fR.
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
.
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







<
<
<
<
<
<
<
<







198
199
200
201
202
203
204








205
206
207
208
209
210
211
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
The configuration options for that window are forgotten, so that if the
window is managed once more by the grid geometry manager, the initial
default settings are used.








.TP
\fBgrid info \fIwindow\fR
.
Returns a list whose elements are the current configuration state of
the content given by \fIwindow\fR in the same option-value form that
might be specified to \fBgrid configure\fR.
The first two elements of the list are
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
\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







|







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
\fB1\fR to indicate whether propagation is currently enabled
for \fIwindow\fR.
Propagation is enabled by default.
.TP
\fBgrid rowconfigure \fIwindow index \fR?\fI\-option value...\fR?
.
Query or set the row properties of the \fIindex\fR row of the
geometry window, \fIwindow\fR.
The valid options are \fB\-minsize\fR, \fB\-weight\fR, \fB\-uniform\fR
and \fB\-pad\fR.
If one or more options are provided, then \fIindex\fR may be given as
a list of row indices to which the configuration options will operate on.
Indices may be integers, window names or the keyword \fIall\fR. For \fIall\fR
the options apply to all rows currently occupied by content windows. For
a window name, that window must be a content window of this container and the options
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314

315
316
317
318
319
320
321
.
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.







<
<
<
<
<
<
<
<








|


|



>

|

|
>







273
274
275
276
277
278
279








280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
.
Removes each of the \fIwindow\fRs from grid for its
container and unmaps their windows.
The content will no longer be managed by the grid geometry manager.
However, the configuration options for that window are remembered,
so that if the content window is managed once more by the grid
geometry manager, the previous values are retained.








.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 slaves \fIwindow\fR ?\fI\-option value\fR?
.
If no options are supplied, a list of all of the content in \fIwindow\fR
are returned, most recently managed first.
\fIOption\fR can be either \fB\-row\fR or \fB\-column\fR which
causes only the content in the row (or column) specified by \fIvalue\fR
to be returned.
.VS "TIP 581"
.TP
\fBgrid content \fIwindow\fR ?\fI\-option value\fR?
.
Synonym for \fBgrid slaves \fIwindow\fR ?\fI\-option value\fR?.
.VE "TIP 581"
.SH "RELATIVE PLACEMENT"
.PP
The \fBgrid\fR command contains a limited set of capabilities that
permit layouts to be created without specifying the row and column
information for each content.  This permits content to be rearranged,
added, or removed without the need to explicitly specify row and
column information.
Changes to doc/image.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.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







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH image n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
image \- Create and manipulate images
.SH SYNOPSIS
\fBimage\fR \fIoption \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBimage\fR command is used to create, delete, and query images.
It can take several different forms, depending on the
\fIoption\fR argument.  The legal forms are:
.TP
Changes to doc/keysyms.n.
1
2
3
4
5
6
7
8
9
'\"
'\" 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

|







1
2
3
4
5
6
7
8
9
'\"
'\" Copyright (c) 1998-2000 Scriptics Corporation.
'\" All rights reserved.
'\"
.TH keysyms n 8.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
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







|














|
|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
currency                           164     0xA4
yen                                165     0xA5
brokenbar                          166     0xA6
section                            167     0xA7
diaeresis                          168     0xA8
copyright                          169     0xA9
ordfeminine                        170     0xAA
guillemetleft                      171     0xAB
notsign                            172     0xAC
hyphen                             173     0xAD
registered                         174     0xAE
macron                             175     0xAF
degree                             176     0xB0
plusminus                          177     0xB1
twosuperior                        178     0xB2
threesuperior                      179     0xB3
acute                              180     0xB4
mu                                 181     0xB5
paragraph                          182     0xB6
periodcentered                     183     0xB7
cedilla                            184     0xB8
onesuperior                        185     0xB9
ordmasculine                       186     0xBA
guillemetright                     187     0xBB
onequarter                         188     0xBC
onehalf                            189     0xBD
threequarters                      190     0xBE
questiondown                       191     0xBF
Agrave                             192     0xC0
Aacute                             193     0xC1
Acircumflex                        194     0xC2
210
211
212
213
214
215
216


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


397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546

547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612


613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818


819
820
821
822
823
824
825
ugrave                             249     0xF9
uacute                             250     0xFA
ucircumflex                        251     0xFB
udiaeresis                         252     0xFC
yacute                             253     0xFD
thorn                              254     0xFE
ydiaeresis                         255     0xFF


Aogonek                            417     0x1A1
breve                              418     0x1A2
Lstroke                            419     0x1A3
Lcaron                             421     0x1A5
Sacute                             422     0x1A6
Scaron                             425     0x1A9
Scedilla                           426     0x1AA
Tcaron                             427     0x1AB
Zacute                             428     0x1AC
.CE
.CS
Zcaron                             430     0x1AE
Zabovedot                          431     0x1AF
aogonek                            433     0x1B1
ogonek                             434     0x1B2
lstroke                            435     0x1B3
lcaron                             437     0x1B5
sacute                             438     0x1B6
caron                              439     0x1B7
scaron                             441     0x1B9
scedilla                           442     0x1BA
tcaron                             443     0x1BB
zacute                             444     0x1BC
doubleacute                        445     0x1BD
zcaron                             446     0x1BE
zabovedot                          447     0x1BF
Racute                             448     0x1C0
Abreve                             451     0x1C3
Lacute                             453     0x1C5
Cacute                             454     0x1C6
Ccaron                             456     0x1C8
Eogonek                            458     0x1CA
Ecaron                             460     0x1CC
Dcaron                             463     0x1CF
Dstroke                            464     0x1D0
Nacute                             465     0x1D1
Ncaron                             466     0x1D2
Odoubleacute                       469     0x1D5
Rcaron                             472     0x1D8
Uring                              473     0x1D9
Udoubleacute                       475     0x1DB
Tcedilla                           478     0x1DE
racute                             480     0x1E0
abreve                             483     0x1E3
lacute                             485     0x1E5
cacute                             486     0x1E6
ccaron                             488     0x1E8
eogonek                            490     0x1EA
ecaron                             492     0x1EC
dcaron                             495     0x1EF
dstroke                            496     0x1F0
nacute                             497     0x1F1
ncaron                             498     0x1F2
odoubleacute                       501     0x1F5
rcaron                             504     0x1F8
uring                              505     0x1F9
udoubleacute                       507     0x1FB
tcedilla                           510     0x1FE
abovedot                           511     0x1FF
Hstroke                            673     0x2A1
Hcircumflex                        678     0x2A6
Iabovedot                          681     0x2A9
Gbreve                             683     0x2AB
Jcircumflex                        684     0x2AC
hstroke                            689     0x2B1
hcircumflex                        694     0x2B6
idotless                           697     0x2B9
gbreve                             699     0x2BB
jcircumflex                        700     0x2BC
Cabovedot                          709     0x2C5
Ccircumflex                        710     0x2C6
Gabovedot                          725     0x2D5
Gcircumflex                        728     0x2D8
Ubreve                             733     0x2DD
Scircumflex                        734     0x2DE
cabovedot                          741     0x2E5
ccircumflex                        742     0x2E6
gabovedot                          757     0x2F5
gcircumflex                        760     0x2F8
ubreve                             765     0x2FD
scircumflex                        766     0x2FE
kra                                930     0x3A2
Rcedilla                           931     0x3A3
Itilde                             933     0x3A5
Lcedilla                           934     0x3A6
Emacron                            938     0x3AA
Gcedilla                           939     0x3AB
Tslash                             940     0x3AC
rcedilla                           947     0x3B3
itilde                             949     0x3B5
lcedilla                           950     0x3B6
emacron                            954     0x3BA
gcedilla                           955     0x3BB
tslash                             956     0x3BC
ENG                                957     0x3BD
eng                                959     0x3BF
Amacron                            960     0x3C0
Iogonek                            967     0x3C7
Eabovedot                          972     0x3CC
Imacron                            975     0x3CF
Ncedilla                           977     0x3D1
Omacron                            978     0x3D2
Kcedilla                           979     0x3D3
Uogonek                            985     0x3D9
Utilde                             989     0x3DD
Umacron                            990     0x3DE
amacron                            992     0x3E0
iogonek                            999     0x3E7
eabovedot                         1004     0x3EC
imacron                           1007     0x3EF
ncedilla                          1009     0x3F1
omacron                           1010     0x3F2
kcedilla                          1011     0x3F3
uogonek                           1017     0x3F9
utilde                            1021     0x3FD
umacron                           1022     0x3FE
overline                          1150     0x47E
kana_fullstop                     1185     0x4A1
kana_openingbracket               1186     0x4A2
kana_closingbracket               1187     0x4A3
kana_comma                        1188     0x4A4
kana_conjunctive                  1189     0x4A5
kana_WO                           1190     0x4A6
kana_a                            1191     0x4A7
kana_i                            1192     0x4A8
kana_u                            1193     0x4A9
kana_e                            1194     0x4AA
kana_o                            1195     0x4AB
kana_ya                           1196     0x4AC
kana_yu                           1197     0x4AD
kana_yo                           1198     0x4AE
kana_tsu                          1199     0x4AF
prolongedsound                    1200     0x4B0
kana_A                            1201     0x4B1
kana_I                            1202     0x4B2
kana_U                            1203     0x4B3
kana_E                            1204     0x4B4
kana_O                            1205     0x4B5
kana_KA                           1206     0x4B6
kana_KI                           1207     0x4B7
kana_KU                           1208     0x4B8
kana_KE                           1209     0x4B9
kana_KO                           1210     0x4BA
kana_SA                           1211     0x4BB
kana_SHI                          1212     0x4BC
kana_SU                           1213     0x4BD
kana_SE                           1214     0x4BE
kana_SO                           1215     0x4BF
kana_TA                           1216     0x4C0
kana_CHI                          1217     0x4C1
kana_TSU                          1218     0x4C2
kana_TE                           1219     0x4C3
kana_TO                           1220     0x4C4
kana_NA                           1221     0x4C5
kana_NI                           1222     0x4C6
kana_NU                           1223     0x4C7
kana_NE                           1224     0x4C8
kana_NO                           1225     0x4C9
kana_HA                           1226     0x4CA
kana_HI                           1227     0x4CB
kana_FU                           1228     0x4CC
kana_HE                           1229     0x4CD
kana_HO                           1230     0x4CE
kana_MA                           1231     0x4CF
kana_MI                           1232     0x4D0
kana_MU                           1233     0x4D1
kana_ME                           1234     0x4D2
kana_MO                           1235     0x4D3
kana_YA                           1236     0x4D4
kana_YU                           1237     0x4D5
kana_YO                           1238     0x4D6
kana_RA                           1239     0x4D7
kana_RI                           1240     0x4D8
kana_RU                           1241     0x4D9
kana_RE                           1242     0x4DA
kana_RO                           1243     0x4DB
kana_WA                           1244     0x4DC
kana_N                            1245     0x4DD
voicedsound                       1246     0x4DE
semivoicedsound                   1247     0x4DF


Arabic_comma                      1452     0x5AC
Arabic_semicolon                  1467     0x5BB
Arabic_question_mark              1471     0x5BF
Arabic_hamza                      1473     0x5C1
Arabic_maddaonalef                1474     0x5C2
Arabic_hamzaonalef                1475     0x5C3
Arabic_hamzaonwaw                 1476     0x5C4
Arabic_hamzaunderalef             1477     0x5C5
Arabic_hamzaonyeh                 1478     0x5C6
Arabic_alef                       1479     0x5C7
Arabic_beh                        1480     0x5C8
Arabic_tehmarbuta                 1481     0x5C9
Arabic_teh                        1482     0x5CA
Arabic_theh                       1483     0x5CB
Arabic_jeem                       1484     0x5CC
Arabic_hah                        1485     0x5CD
Arabic_khah                       1486     0x5CE
Arabic_dal                        1487     0x5CF
Arabic_thal                       1488     0x5D0
Arabic_ra                         1489     0x5D1
Arabic_zain                       1490     0x5D2
Arabic_seen                       1491     0x5D3
Arabic_sheen                      1492     0x5D4
Arabic_sad                        1493     0x5D5
Arabic_dad                        1494     0x5D6
Arabic_tah                        1495     0x5D7
Arabic_zah                        1496     0x5D8
Arabic_ain                        1497     0x5D9
Arabic_ghain                      1498     0x5DA
Arabic_tatweel                    1504     0x5E0
Arabic_feh                        1505     0x5E1
Arabic_qaf                        1506     0x5E2
Arabic_kaf                        1507     0x5E3
Arabic_lam                        1508     0x5E4
Arabic_meem                       1509     0x5E5
.CE
.CS
Arabic_noon                       1510     0x5E6
Arabic_ha                         1511     0x5E7
Arabic_waw                        1512     0x5E8
Arabic_alefmaksura                1513     0x5E9
Arabic_yeh                        1514     0x5EA
Arabic_fathatan                   1515     0x5EB
Arabic_dammatan                   1516     0x5EC
Arabic_kasratan                   1517     0x5ED
Arabic_fatha                      1518     0x5EE
Arabic_damma                      1519     0x5EF
Arabic_kasra                      1520     0x5F0
Arabic_shadda                     1521     0x5F1
Arabic_sukun                      1522     0x5F2
Serbian_dje                       1697     0x6A1
Macedonia_gje                     1698     0x6A2
Cyrillic_io                       1699     0x6A3
Ukrainian_ie                      1700     0x6A4
Macedonia_dse                     1701     0x6A5
Ukrainian_i                       1702     0x6A6
Ukrainian_yi                      1703     0x6A7
Cyrillic_je                       1704     0x6A8
Cyrillic_lje                      1705     0x6A9
Cyrillic_nje                      1706     0x6AA
Serbian_tshe                      1707     0x6AB
Macedonia_kje                     1708     0x6AC
Ukrainian_ghe_with_upturn         1709     0x6AD
Byelorussian_shortu               1710     0x6AE
Cyrillic_dzhe                     1711     0x6AF
numerosign                        1712     0x6B0
Serbian_DJE                       1713     0x6B1
Macedonia_GJE                     1714     0x6B2
Cyrillic_IO                       1715     0x6B3
Ukrainian_IE                      1716     0x6B4
Macedonia_DSE                     1717     0x6B5
Ukrainian_I                       1718     0x6B6
Ukrainian_YI                      1719     0x6B7
Cyrillic_JE                       1720     0x6B8
Cyrillic_LJE                      1721     0x6B9
Cyrillic_NJE                      1722     0x6BA
Serbian_TSHE                      1723     0x6BB
Macedonia_KJE                     1724     0x6BC
Ukrainian_GHE_WITH_UPTURN         1725     0x6BD
Byelorussian_SHORTU               1726     0x6BE
Cyrillic_DZHE                     1727     0x6BF
Cyrillic_yu                       1728     0x6C0
Cyrillic_a                        1729     0x6C1
Cyrillic_be                       1730     0x6C2
Cyrillic_tse                      1731     0x6C3
Cyrillic_de                       1732     0x6C4
Cyrillic_ie                       1733     0x6C5
Cyrillic_ef                       1734     0x6C6
Cyrillic_ghe                      1735     0x6C7
Cyrillic_ha                       1736     0x6C8
Cyrillic_i                        1737     0x6C9
Cyrillic_shorti                   1738     0x6CA
Cyrillic_ka                       1739     0x6CB
Cyrillic_el                       1740     0x6CC
Cyrillic_em                       1741     0x6CD
Cyrillic_en                       1742     0x6CE
Cyrillic_o                        1743     0x6CF
Cyrillic_pe                       1744     0x6D0
Cyrillic_ya                       1745     0x6D1
Cyrillic_er                       1746     0x6D2
Cyrillic_es                       1747     0x6D3
Cyrillic_te                       1748     0x6D4
Cyrillic_u                        1749     0x6D5
Cyrillic_zhe                      1750     0x6D6
Cyrillic_ve                       1751     0x6D7
Cyrillic_softsign                 1752     0x6D8
Cyrillic_yeru                     1753     0x6D9
Cyrillic_ze                       1754     0x6DA
Cyrillic_sha                      1755     0x6DB
Cyrillic_e                        1756     0x6DC
Cyrillic_shcha                    1757     0x6DD
Cyrillic_che                      1758     0x6DE
Cyrillic_hardsign                 1759     0x6DF
Cyrillic_YU                       1760     0x6E0
Cyrillic_A                        1761     0x6E1
Cyrillic_BE                       1762     0x6E2
Cyrillic_TSE                      1763     0x6E3
Cyrillic_DE                       1764     0x6E4
Cyrillic_IE                       1765     0x6E5
Cyrillic_EF                       1766     0x6E6
Cyrillic_GHE                      1767     0x6E7
Cyrillic_HA                       1768     0x6E8
Cyrillic_I                        1769     0x6E9
Cyrillic_SHORTI                   1770     0x6EA
Cyrillic_KA                       1771     0x6EB
Cyrillic_EL                       1772     0x6EC
Cyrillic_EM                       1773     0x6ED
Cyrillic_EN                       1774     0x6EE
Cyrillic_O                        1775     0x6EF
Cyrillic_PE                       1776     0x6F0
Cyrillic_YA                       1777     0x6F1
Cyrillic_ER                       1778     0x6F2
Cyrillic_ES                       1779     0x6F3
Cyrillic_TE                       1780     0x6F4
Cyrillic_U                        1781     0x6F5
Cyrillic_ZHE                      1782     0x6F6
Cyrillic_VE                       1783     0x6F7
Cyrillic_SOFTSIGN                 1784     0x6F8
Cyrillic_YERU                     1785     0x6F9
Cyrillic_ZE                       1786     0x6FA
Cyrillic_SHA                      1787     0x6FB
Cyrillic_E                        1788     0x6FC
Cyrillic_SHCHA                    1789     0x6FD
Cyrillic_CHE                      1790     0x6FE
Cyrillic_HARDSIGN                 1791     0x6FF
Greek_ALPHAaccent                 1953     0x7A1
Greek_EPSILONaccent               1954     0x7A2
Greek_ETAaccent                   1955     0x7A3
Greek_IOTAaccent                  1956     0x7A4
Greek_IOTAdieresis                1957     0x7A5

Greek_OMICRONaccent               1959     0x7A7
Greek_UPSILONaccent               1960     0x7A8
Greek_UPSILONdieresis             1961     0x7A9

Greek_OMEGAaccent                 1963     0x7AB
Greek_accentdieresis              1966     0x7AE
Greek_horizbar                    1967     0x7AF
Greek_alphaaccent                 1969     0x7B1
Greek_epsilonaccent               1970     0x7B2
Greek_etaaccent                   1971     0x7B3
Greek_iotaaccent                  1972     0x7B4
Greek_iotadieresis                1973     0x7B5
Greek_iotaaccentdieresis          1974     0x7B6
Greek_omicronaccent               1975     0x7B7
Greek_upsilonaccent               1976     0x7B8
Greek_upsilondieresis             1977     0x7B9
Greek_upsilonaccentdieresis       1978     0x7BA
Greek_omegaaccent                 1979     0x7BB
Greek_ALPHA                       1985     0x7C1
Greek_BETA                        1986     0x7C2
Greek_GAMMA                       1987     0x7C3
Greek_DELTA                       1988     0x7C4
Greek_EPSILON                     1989     0x7C5
Greek_ZETA                        1990     0x7C6
Greek_ETA                         1991     0x7C7
Greek_THETA                       1992     0x7C8
Greek_IOTA                        1993     0x7C9
Greek_KAPPA                       1994     0x7CA
Greek_LAMDA                       1995     0x7CB
Greek_MU                          1996     0x7CC
Greek_NU                          1997     0x7CD
Greek_XI                          1998     0x7CE
Greek_OMICRON                     1999     0x7CF
Greek_PI                          2000     0x7D0
Greek_RHO                         2001     0x7D1
Greek_SIGMA                       2002     0x7D2
Greek_TAU                         2004     0x7D4
Greek_UPSILON                     2005     0x7D5
Greek_PHI                         2006     0x7D6
Greek_CHI                         2007     0x7D7
Greek_PSI                         2008     0x7D8
Greek_OMEGA                       2009     0x7D9
Greek_alpha                       2017     0x7E1
Greek_beta                        2018     0x7E2
Greek_gamma                       2019     0x7E3
Greek_delta                       2020     0x7E4
Greek_epsilon                     2021     0x7E5
Greek_zeta                        2022     0x7E6
Greek_eta                         2023     0x7E7
Greek_theta                       2024     0x7E8
Greek_iota                        2025     0x7E9
Greek_kappa                       2026     0x7EA
Greek_lamda                       2027     0x7EB
Greek_mu                          2028     0x7EC
Greek_nu                          2029     0x7ED
Greek_xi                          2030     0x7EE
Greek_omicron                     2031     0x7EF
Greek_pi                          2032     0x7F0
Greek_rho                         2033     0x7F1
Greek_sigma                       2034     0x7F2
Greek_finalsmallsigma             2035     0x7F3
Greek_tau                         2036     0x7F4
Greek_upsilon                     2037     0x7F5
Greek_phi                         2038     0x7F6
Greek_chi                         2039     0x7F7
Greek_psi                         2040     0x7F8
Greek_omega                       2041     0x7F9


leftradical                       2209     0x8A1
topleftradical                    2210     0x8A2
horizconnector                    2211     0x8A3
topintegral                       2212     0x8A4
botintegral                       2213     0x8A5
vertconnector                     2214     0x8A6
topleftsqbracket                  2215     0x8A7
botleftsqbracket                  2216     0x8A8
toprightsqbracket                 2217     0x8A9
botrightsqbracket                 2218     0x8AA
topleftparens                     2219     0x8AB
botleftparens                     2220     0x8AC
toprightparens                    2221     0x8AD
botrightparens                    2222     0x8AE
leftmiddlecurlybrace              2223     0x8AF
rightmiddlecurlybrace             2224     0x8B0
topleftsummation                  2225     0x8B1
botleftsummation                  2226     0x8B2
topvertsummationconnector         2227     0x8B3
botvertsummationconnector         2228     0x8B4
toprightsummation                 2229     0x8B5
botrightsummation                 2230     0x8B6
rightmiddlesummation              2231     0x8B7
.CE
.CS
lessthanequal                     2236     0x8BC
notequal                          2237     0x8BD
greaterthanequal                  2238     0x8BE
integral                          2239     0x8BF
therefore                         2240     0x8C0
variation                         2241     0x8C1
infinity                          2242     0x8C2
nabla                             2245     0x8C5
approximate                       2248     0x8C8
similarequal                      2249     0x8C9
ifonlyif                          2253     0x8CD
implies                           2254     0x8CE
identical                         2255     0x8CF
radical                           2262     0x8D6
includedin                        2266     0x8DA
includes                          2267     0x8DB
intersection                      2268     0x8DC
union                             2269     0x8DD
logicaland                        2270     0x8DE
logicalor                         2271     0x8DF
partialderivative                 2287     0x8EF
function                          2294     0x8F6
leftarrow                         2299     0x8FB
uparrow                           2300     0x8FC
rightarrow                        2301     0x8FD
downarrow                         2302     0x8FE
blank                             2527     0x9DF
soliddiamond                      2528     0x9E0
checkerboard                      2529     0x9E1
ht                                2530     0x9E2
ff                                2531     0x9E3
cr                                2532     0x9E4
lf                                2533     0x9E5
nl                                2536     0x9E8
vt                                2537     0x9E9
lowrightcorner                    2538     0x9EA
uprightcorner                     2539     0x9EB
upleftcorner                      2540     0x9EC
lowleftcorner                     2541     0x9ED
crossinglines                     2542     0x9EE
horizlinescan1                    2543     0x9EF
horizlinescan3                    2544     0x9F0
horizlinescan5                    2545     0x9F1
horizlinescan7                    2546     0x9F2
horizlinescan9                    2547     0x9F3
leftt                             2548     0x9F4
rightt                            2549     0x9F5
bott                              2550     0x9F6
topt                              2551     0x9F7
vertbar                           2552     0x9F8
emspace                           2721     0xAA1
enspace                           2722     0xAA2
em3space                          2723     0xAA3
em4space                          2724     0xAA4
digitspace                        2725     0xAA5
punctspace                        2726     0xAA6
thinspace                         2727     0xAA7
hairspace                         2728     0xAA8
emdash                            2729     0xAA9
endash                            2730     0xAAA
signifblank                       2732     0xAAC
ellipsis                          2734     0xAAE
doubbaselinedot                   2735     0xAAF
onethird                          2736     0xAB0
twothirds                         2737     0xAB1
onefifth                          2738     0xAB2
twofifths                         2739     0xAB3
threefifths                       2740     0xAB4
fourfifths                        2741     0xAB5
onesixth                          2742     0xAB6
fivesixths                        2743     0xAB7
careof                            2744     0xAB8
figdash                           2747     0xABB
leftanglebracket                  2748     0xABC
decimalpoint                      2749     0xABD
rightanglebracket                 2750     0xABE
marker                            2751     0xABF
oneeighth                         2755     0xAC3
threeeighths                      2756     0xAC4
fiveeighths                       2757     0xAC5
seveneighths                      2758     0xAC6
trademark                         2761     0xAC9
signaturemark                     2762     0xACA
trademarkincircle                 2763     0xACB
leftopentriangle                  2764     0xACC
rightopentriangle                 2765     0xACD
emopencircle                      2766     0xACE
emopenrectangle                   2767     0xACF
leftsinglequotemark               2768     0xAD0
rightsinglequotemark              2769     0xAD1
leftdoublequotemark               2770     0xAD2
rightdoublequotemark              2771     0xAD3
prescription                      2772     0xAD4
permille                          2773     0xAD5
minutes                           2774     0xAD6
seconds                           2775     0xAD7
latincross                        2777     0xAD9
hexagram                          2778     0xADA
filledrectbullet                  2779     0xADB
filledlefttribullet               2780     0xADC
filledrighttribullet              2781     0xADD
emfilledcircle                    2782     0xADE
emfilledrect                      2783     0xADF
enopencircbullet                  2784     0xAE0
enopensquarebullet                2785     0xAE1
openrectbullet                    2786     0xAE2
opentribulletup                   2787     0xAE3
opentribulletdown                 2788     0xAE4
openstar                          2789     0xAE5
enfilledcircbullet                2790     0xAE6
enfilledsqbullet                  2791     0xAE7
filledtribulletup                 2792     0xAE8
filledtribulletdown               2793     0xAE9
leftpointer                       2794     0xAEA
rightpointer                      2795     0xAEB
club                              2796     0xAEC
diamond                           2797     0xAED
heart                             2798     0xAEE
maltesecross                      2800     0xAF0
dagger                            2801     0xAF1
doubledagger                      2802     0xAF2
checkmark                         2803     0xAF3
ballotcross                       2804     0xAF4
musicalsharp                      2805     0xAF5
musicalflat                       2806     0xAF6
malesymbol                        2807     0xAF7
femalesymbol                      2808     0xAF8
telephone                         2809     0xAF9
telephonerecorder                 2810     0xAFA
phonographcopyright               2811     0xAFB
caret                             2812     0xAFC
singlelowquotemark                2813     0xAFD
doublelowquotemark                2814     0xAFE
cursor                            2815     0xAFF
leftcaret                         2979     0xBA3
rightcaret                        2982     0xBA6
downcaret                         2984     0xBA8
upcaret                           2985     0xBA9
overbar                           3008     0xBC0
downtack                          3010     0xBC2
upshoe                            3011     0xBC3
downstile                         3012     0xBC4
underbar                          3014     0xBC6
jot                               3018     0xBCA
quad                              3020     0xBCC
uptack                            3022     0xBCE
circle                            3023     0xBCF
upstile                           3027     0xBD3
downshoe                          3030     0xBD6
rightshoe                         3032     0xBD8
leftshoe                          3034     0xBDA
lefttack                          3036     0xBDC
righttack                         3068     0xBFC
hebrew_doublelowline              3295     0xCDF
hebrew_aleph                      3296     0xCE0
hebrew_bet                        3297     0xCE1
hebrew_gimel                      3298     0xCE2
hebrew_dalet                      3299     0xCE3
hebrew_he                         3300     0xCE4
hebrew_waw                        3301     0xCE5
hebrew_zain                       3302     0xCE6
hebrew_chet                       3303     0xCE7
hebrew_tet                        3304     0xCE8
hebrew_yod                        3305     0xCE9
hebrew_finalkaph                  3306     0xCEA
hebrew_kaph                       3307     0xCEB
hebrew_lamed                      3308     0xCEC
hebrew_finalmem                   3309     0xCED
hebrew_mem                        3310     0xCEE
hebrew_finalnun                   3311     0xCEF
hebrew_nun                        3312     0xCF0
hebrew_samech                     3313     0xCF1
hebrew_ayin                       3314     0xCF2
hebrew_finalpe                    3315     0xCF3
hebrew_pe                         3316     0xCF4
hebrew_finalzade                  3317     0xCF5
hebrew_zade                       3318     0xCF6
hebrew_qoph                       3319     0xCF7
hebrew_resh                       3320     0xCF8
hebrew_shin                       3321     0xCF9
hebrew_taw                        3322     0xCFA


Thai_kokai                        3489     0xDA1
Thai_khokhai                      3490     0xDA2
Thai_khokhuat                     3491     0xDA3
Thai_khokhwai                     3492     0xDA4
Thai_khokhon                      3493     0xDA5
Thai_khorakhang                   3494     0xDA6
Thai_ngongu                       3495     0xDA7







>
>









<
<









































































































































































>
>



































<
<

















































































































>



>































































>
>























<
<





















































































































































































>
>







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


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


434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639


640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
ugrave                             249     0xF9
uacute                             250     0xFA
ucircumflex                        251     0xFB
udiaeresis                         252     0xFC
yacute                             253     0xFD
thorn                              254     0xFE
ydiaeresis                         255     0xFF
.CE
.CS
Aogonek                            417     0x1A1
breve                              418     0x1A2
Lstroke                            419     0x1A3
Lcaron                             421     0x1A5
Sacute                             422     0x1A6
Scaron                             425     0x1A9
Scedilla                           426     0x1AA
Tcaron                             427     0x1AB
Zacute                             428     0x1AC


Zcaron                             430     0x1AE
Zabovedot                          431     0x1AF
aogonek                            433     0x1B1
ogonek                             434     0x1B2
lstroke                            435     0x1B3
lcaron                             437     0x1B5
sacute                             438     0x1B6
caron                              439     0x1B7
scaron                             441     0x1B9
scedilla                           442     0x1BA
tcaron                             443     0x1BB
zacute                             444     0x1BC
doubleacute                        445     0x1BD
zcaron                             446     0x1BE
zabovedot                          447     0x1BF
Racute                             448     0x1C0
Abreve                             451     0x1C3
Lacute                             453     0x1C5
Cacute                             454     0x1C6
Ccaron                             456     0x1C8
Eogonek                            458     0x1CA
Ecaron                             460     0x1CC
Dcaron                             463     0x1CF
Dstroke                            464     0x1D0
Nacute                             465     0x1D1
Ncaron                             466     0x1D2
Odoubleacute                       469     0x1D5
Rcaron                             472     0x1D8
Uring                              473     0x1D9
Udoubleacute                       475     0x1DB
Tcedilla                           478     0x1DE
racute                             480     0x1E0
abreve                             483     0x1E3
lacute                             485     0x1E5
cacute                             486     0x1E6
ccaron                             488     0x1E8
eogonek                            490     0x1EA
ecaron                             492     0x1EC
dcaron                             495     0x1EF
dstroke                            496     0x1F0
nacute                             497     0x1F1
ncaron                             498     0x1F2
odoubleacute                       501     0x1F5
rcaron                             504     0x1F8
uring                              505     0x1F9
udoubleacute                       507     0x1FB
tcedilla                           510     0x1FE
abovedot                           511     0x1FF
Hstroke                            673     0x2A1
Hcircumflex                        678     0x2A6
Iabovedot                          681     0x2A9
Gbreve                             683     0x2AB
Jcircumflex                        684     0x2AC
hstroke                            689     0x2B1
hcircumflex                        694     0x2B6
idotless                           697     0x2B9
gbreve                             699     0x2BB
jcircumflex                        700     0x2BC
Cabovedot                          709     0x2C5
Ccircumflex                        710     0x2C6
Gabovedot                          725     0x2D5
Gcircumflex                        728     0x2D8
Ubreve                             733     0x2DD
Scircumflex                        734     0x2DE
cabovedot                          741     0x2E5
ccircumflex                        742     0x2E6
gabovedot                          757     0x2F5
gcircumflex                        760     0x2F8
ubreve                             765     0x2FD
scircumflex                        766     0x2FE
kra                                930     0x3A2
Rcedilla                           931     0x3A3
Itilde                             933     0x3A5
Lcedilla                           934     0x3A6
Emacron                            938     0x3AA
Gcedilla                           939     0x3AB
Tslash                             940     0x3AC
rcedilla                           947     0x3B3
itilde                             949     0x3B5
lcedilla                           950     0x3B6
emacron                            954     0x3BA
gcedilla                           955     0x3BB
tslash                             956     0x3BC
ENG                                957     0x3BD
eng                                959     0x3BF
Amacron                            960     0x3C0
Iogonek                            967     0x3C7
Eabovedot                          972     0x3CC
Imacron                            975     0x3CF
Ncedilla                           977     0x3D1
Omacron                            978     0x3D2
Kcedilla                           979     0x3D3
Uogonek                            985     0x3D9
Utilde                             989     0x3DD
Umacron                            990     0x3DE
amacron                            992     0x3E0
iogonek                            999     0x3E7
eabovedot                         1004     0x3EC
imacron                           1007     0x3EF
ncedilla                          1009     0x3F1
omacron                           1010     0x3F2
kcedilla                          1011     0x3F3
uogonek                           1017     0x3F9
utilde                            1021     0x3FD
umacron                           1022     0x3FE
overline                          1150     0x47E
kana_fullstop                     1185     0x4A1
kana_openingbracket               1186     0x4A2
kana_closingbracket               1187     0x4A3
kana_comma                        1188     0x4A4
kana_conjunctive                  1189     0x4A5
kana_WO                           1190     0x4A6
kana_a                            1191     0x4A7
kana_i                            1192     0x4A8
kana_u                            1193     0x4A9
kana_e                            1194     0x4AA
kana_o                            1195     0x4AB
kana_ya                           1196     0x4AC
kana_yu                           1197     0x4AD
kana_yo                           1198     0x4AE
kana_tsu                          1199     0x4AF
prolongedsound                    1200     0x4B0
kana_A                            1201     0x4B1
kana_I                            1202     0x4B2
kana_U                            1203     0x4B3
kana_E                            1204     0x4B4
kana_O                            1205     0x4B5
kana_KA                           1206     0x4B6
kana_KI                           1207     0x4B7
kana_KU                           1208     0x4B8
kana_KE                           1209     0x4B9
kana_KO                           1210     0x4BA
kana_SA                           1211     0x4BB
kana_SHI                          1212     0x4BC
kana_SU                           1213     0x4BD
kana_SE                           1214     0x4BE
kana_SO                           1215     0x4BF
kana_TA                           1216     0x4C0
kana_CHI                          1217     0x4C1
kana_TSU                          1218     0x4C2
kana_TE                           1219     0x4C3
kana_TO                           1220     0x4C4
kana_NA                           1221     0x4C5
kana_NI                           1222     0x4C6
kana_NU                           1223     0x4C7
kana_NE                           1224     0x4C8
kana_NO                           1225     0x4C9
kana_HA                           1226     0x4CA
kana_HI                           1227     0x4CB
kana_FU                           1228     0x4CC
kana_HE                           1229     0x4CD
kana_HO                           1230     0x4CE
kana_MA                           1231     0x4CF
kana_MI                           1232     0x4D0
kana_MU                           1233     0x4D1
kana_ME                           1234     0x4D2
kana_MO                           1235     0x4D3
kana_YA                           1236     0x4D4
kana_YU                           1237     0x4D5
kana_YO                           1238     0x4D6
kana_RA                           1239     0x4D7
kana_RI                           1240     0x4D8
kana_RU                           1241     0x4D9
kana_RE                           1242     0x4DA
kana_RO                           1243     0x4DB
kana_WA                           1244     0x4DC
kana_N                            1245     0x4DD
voicedsound                       1246     0x4DE
semivoicedsound                   1247     0x4DF
.CE
.CS
Arabic_comma                      1452     0x5AC
Arabic_semicolon                  1467     0x5BB
Arabic_question_mark              1471     0x5BF
Arabic_hamza                      1473     0x5C1
Arabic_maddaonalef                1474     0x5C2
Arabic_hamzaonalef                1475     0x5C3
Arabic_hamzaonwaw                 1476     0x5C4
Arabic_hamzaunderalef             1477     0x5C5
Arabic_hamzaonyeh                 1478     0x5C6
Arabic_alef                       1479     0x5C7
Arabic_beh                        1480     0x5C8
Arabic_tehmarbuta                 1481     0x5C9
Arabic_teh                        1482     0x5CA
Arabic_theh                       1483     0x5CB
Arabic_jeem                       1484     0x5CC
Arabic_hah                        1485     0x5CD
Arabic_khah                       1486     0x5CE
Arabic_dal                        1487     0x5CF
Arabic_thal                       1488     0x5D0
Arabic_ra                         1489     0x5D1
Arabic_zain                       1490     0x5D2
Arabic_seen                       1491     0x5D3
Arabic_sheen                      1492     0x5D4
Arabic_sad                        1493     0x5D5
Arabic_dad                        1494     0x5D6
Arabic_tah                        1495     0x5D7
Arabic_zah                        1496     0x5D8
Arabic_ain                        1497     0x5D9
Arabic_ghain                      1498     0x5DA
Arabic_tatweel                    1504     0x5E0
Arabic_feh                        1505     0x5E1
Arabic_qaf                        1506     0x5E2
Arabic_kaf                        1507     0x5E3
Arabic_lam                        1508     0x5E4
Arabic_meem                       1509     0x5E5


Arabic_noon                       1510     0x5E6
Arabic_ha                         1511     0x5E7
Arabic_waw                        1512     0x5E8
Arabic_alefmaksura                1513     0x5E9
Arabic_yeh                        1514     0x5EA
Arabic_fathatan                   1515     0x5EB
Arabic_dammatan                   1516     0x5EC
Arabic_kasratan                   1517     0x5ED
Arabic_fatha                      1518     0x5EE
Arabic_damma                      1519     0x5EF
Arabic_kasra                      1520     0x5F0
Arabic_shadda                     1521     0x5F1
Arabic_sukun                      1522     0x5F2
Serbian_dje                       1697     0x6A1
Macedonia_gje                     1698     0x6A2
Cyrillic_io                       1699     0x6A3
Ukrainian_ie                      1700     0x6A4
Macedonia_dse                     1701     0x6A5
Ukrainian_i                       1702     0x6A6
Ukrainian_yi                      1703     0x6A7
Cyrillic_je                       1704     0x6A8
Cyrillic_lje                      1705     0x6A9
Cyrillic_nje                      1706     0x6AA
Serbian_tshe                      1707     0x6AB
Macedonia_kje                     1708     0x6AC
Ukrainian_ghe_with_upturn         1709     0x6AD
Byelorussian_shortu               1710     0x6AE
Cyrillic_dzhe                     1711     0x6AF
numerosign                        1712     0x6B0
Serbian_DJE                       1713     0x6B1
Macedonia_GJE                     1714     0x6B2
Cyrillic_IO                       1715     0x6B3
Ukrainian_IE                      1716     0x6B4
Macedonia_DSE                     1717     0x6B5
Ukrainian_I                       1718     0x6B6
Ukrainian_YI                      1719     0x6B7
Cyrillic_JE                       1720     0x6B8
Cyrillic_LJE                      1721     0x6B9
Cyrillic_NJE                      1722     0x6BA
Serbian_TSHE                      1723     0x6BB
Macedonia_KJE                     1724     0x6BC
Ukrainian_GHE_WITH_UPTURN         1725     0x6BD
Byelorussian_SHORTU               1726     0x6BE
Cyrillic_DZHE                     1727     0x6BF
Cyrillic_yu                       1728     0x6C0
Cyrillic_a                        1729     0x6C1
Cyrillic_be                       1730     0x6C2
Cyrillic_tse                      1731     0x6C3
Cyrillic_de                       1732     0x6C4
Cyrillic_ie                       1733     0x6C5
Cyrillic_ef                       1734     0x6C6
Cyrillic_ghe                      1735     0x6C7
Cyrillic_ha                       1736     0x6C8
Cyrillic_i                        1737     0x6C9
Cyrillic_shorti                   1738     0x6CA
Cyrillic_ka                       1739     0x6CB
Cyrillic_el                       1740     0x6CC
Cyrillic_em                       1741     0x6CD
Cyrillic_en                       1742     0x6CE
Cyrillic_o                        1743     0x6CF
Cyrillic_pe                       1744     0x6D0
Cyrillic_ya                       1745     0x6D1
Cyrillic_er                       1746     0x6D2
Cyrillic_es                       1747     0x6D3
Cyrillic_te                       1748     0x6D4
Cyrillic_u                        1749     0x6D5
Cyrillic_zhe                      1750     0x6D6
Cyrillic_ve                       1751     0x6D7
Cyrillic_softsign                 1752     0x6D8
Cyrillic_yeru                     1753     0x6D9
Cyrillic_ze                       1754     0x6DA
Cyrillic_sha                      1755     0x6DB
Cyrillic_e                        1756     0x6DC
Cyrillic_shcha                    1757     0x6DD
Cyrillic_che                      1758     0x6DE
Cyrillic_hardsign                 1759     0x6DF
Cyrillic_YU                       1760     0x6E0
Cyrillic_A                        1761     0x6E1
Cyrillic_BE                       1762     0x6E2
Cyrillic_TSE                      1763     0x6E3
Cyrillic_DE                       1764     0x6E4
Cyrillic_IE                       1765     0x6E5
Cyrillic_EF                       1766     0x6E6
Cyrillic_GHE                      1767     0x6E7
Cyrillic_HA                       1768     0x6E8
Cyrillic_I                        1769     0x6E9
Cyrillic_SHORTI                   1770     0x6EA
Cyrillic_KA                       1771     0x6EB
Cyrillic_EL                       1772     0x6EC
Cyrillic_EM                       1773     0x6ED
Cyrillic_EN                       1774     0x6EE
Cyrillic_O                        1775     0x6EF
Cyrillic_PE                       1776     0x6F0
Cyrillic_YA                       1777     0x6F1
Cyrillic_ER                       1778     0x6F2
Cyrillic_ES                       1779     0x6F3
Cyrillic_TE                       1780     0x6F4
Cyrillic_U                        1781     0x6F5
Cyrillic_ZHE                      1782     0x6F6
Cyrillic_VE                       1783     0x6F7
Cyrillic_SOFTSIGN                 1784     0x6F8
Cyrillic_YERU                     1785     0x6F9
Cyrillic_ZE                       1786     0x6FA
Cyrillic_SHA                      1787     0x6FB
Cyrillic_E                        1788     0x6FC
Cyrillic_SHCHA                    1789     0x6FD
Cyrillic_CHE                      1790     0x6FE
Cyrillic_HARDSIGN                 1791     0x6FF
Greek_ALPHAaccent                 1953     0x7A1
Greek_EPSILONaccent               1954     0x7A2
Greek_ETAaccent                   1955     0x7A3
Greek_IOTAaccent                  1956     0x7A4
Greek_IOTAdieresis                1957     0x7A5
Greek_IOTAaccentdiaeresis         1958     0x7A6
Greek_OMICRONaccent               1959     0x7A7
Greek_UPSILONaccent               1960     0x7A8
Greek_UPSILONdieresis             1961     0x7A9
Greek_UPSILONaccentdieresis       1962     0x7AA
Greek_OMEGAaccent                 1963     0x7AB
Greek_accentdieresis              1966     0x7AE
Greek_horizbar                    1967     0x7AF
Greek_alphaaccent                 1969     0x7B1
Greek_epsilonaccent               1970     0x7B2
Greek_etaaccent                   1971     0x7B3
Greek_iotaaccent                  1972     0x7B4
Greek_iotadieresis                1973     0x7B5
Greek_iotaaccentdieresis          1974     0x7B6
Greek_omicronaccent               1975     0x7B7
Greek_upsilonaccent               1976     0x7B8
Greek_upsilondieresis             1977     0x7B9
Greek_upsilonaccentdieresis       1978     0x7BA
Greek_omegaaccent                 1979     0x7BB
Greek_ALPHA                       1985     0x7C1
Greek_BETA                        1986     0x7C2
Greek_GAMMA                       1987     0x7C3
Greek_DELTA                       1988     0x7C4
Greek_EPSILON                     1989     0x7C5
Greek_ZETA                        1990     0x7C6
Greek_ETA                         1991     0x7C7
Greek_THETA                       1992     0x7C8
Greek_IOTA                        1993     0x7C9
Greek_KAPPA                       1994     0x7CA
Greek_LAMDA                       1995     0x7CB
Greek_MU                          1996     0x7CC
Greek_NU                          1997     0x7CD
Greek_XI                          1998     0x7CE
Greek_OMICRON                     1999     0x7CF
Greek_PI                          2000     0x7D0
Greek_RHO                         2001     0x7D1
Greek_SIGMA                       2002     0x7D2
Greek_TAU                         2004     0x7D4
Greek_UPSILON                     2005     0x7D5
Greek_PHI                         2006     0x7D6
Greek_CHI                         2007     0x7D7
Greek_PSI                         2008     0x7D8
Greek_OMEGA                       2009     0x7D9
Greek_alpha                       2017     0x7E1
Greek_beta                        2018     0x7E2
Greek_gamma                       2019     0x7E3
Greek_delta                       2020     0x7E4
Greek_epsilon                     2021     0x7E5
Greek_zeta                        2022     0x7E6
Greek_eta                         2023     0x7E7
Greek_theta                       2024     0x7E8
Greek_iota                        2025     0x7E9
Greek_kappa                       2026     0x7EA
Greek_lamda                       2027     0x7EB
Greek_mu                          2028     0x7EC
Greek_nu                          2029     0x7ED
Greek_xi                          2030     0x7EE
Greek_omicron                     2031     0x7EF
Greek_pi                          2032     0x7F0
Greek_rho                         2033     0x7F1
Greek_sigma                       2034     0x7F2
Greek_finalsmallsigma             2035     0x7F3
Greek_tau                         2036     0x7F4
Greek_upsilon                     2037     0x7F5
Greek_phi                         2038     0x7F6
Greek_chi                         2039     0x7F7
Greek_psi                         2040     0x7F8
Greek_omega                       2041     0x7F9
.CE
.CS
leftradical                       2209     0x8A1
topleftradical                    2210     0x8A2
horizconnector                    2211     0x8A3
topintegral                       2212     0x8A4
botintegral                       2213     0x8A5
vertconnector                     2214     0x8A6
topleftsqbracket                  2215     0x8A7
botleftsqbracket                  2216     0x8A8
toprightsqbracket                 2217     0x8A9
botrightsqbracket                 2218     0x8AA
topleftparens                     2219     0x8AB
botleftparens                     2220     0x8AC
toprightparens                    2221     0x8AD
botrightparens                    2222     0x8AE
leftmiddlecurlybrace              2223     0x8AF
rightmiddlecurlybrace             2224     0x8B0
topleftsummation                  2225     0x8B1
botleftsummation                  2226     0x8B2
topvertsummationconnector         2227     0x8B3
botvertsummationconnector         2228     0x8B4
toprightsummation                 2229     0x8B5
botrightsummation                 2230     0x8B6
rightmiddlesummation              2231     0x8B7


lessthanequal                     2236     0x8BC
notequal                          2237     0x8BD
greaterthanequal                  2238     0x8BE
integral                          2239     0x8BF
therefore                         2240     0x8C0
variation                         2241     0x8C1
infinity                          2242     0x8C2
nabla                             2245     0x8C5
approximate                       2248     0x8C8
similarequal                      2249     0x8C9
ifonlyif                          2253     0x8CD
implies                           2254     0x8CE
identical                         2255     0x8CF
radical                           2262     0x8D6
includedin                        2266     0x8DA
includes                          2267     0x8DB
intersection                      2268     0x8DC
union                             2269     0x8DD
logicaland                        2270     0x8DE
logicalor                         2271     0x8DF
partialderivative                 2287     0x8EF
function                          2294     0x8F6
leftarrow                         2299     0x8FB
uparrow                           2300     0x8FC
rightarrow                        2301     0x8FD
downarrow                         2302     0x8FE
blank                             2527     0x9DF
soliddiamond                      2528     0x9E0
checkerboard                      2529     0x9E1
ht                                2530     0x9E2
ff                                2531     0x9E3
cr                                2532     0x9E4
lf                                2533     0x9E5
nl                                2536     0x9E8
vt                                2537     0x9E9
lowrightcorner                    2538     0x9EA
uprightcorner                     2539     0x9EB
upleftcorner                      2540     0x9EC
lowleftcorner                     2541     0x9ED
crossinglines                     2542     0x9EE
horizlinescan1                    2543     0x9EF
horizlinescan3                    2544     0x9F0
horizlinescan5                    2545     0x9F1
horizlinescan7                    2546     0x9F2
horizlinescan9                    2547     0x9F3
leftt                             2548     0x9F4
rightt                            2549     0x9F5
bott                              2550     0x9F6
topt                              2551     0x9F7
vertbar                           2552     0x9F8
emspace                           2721     0xAA1
enspace                           2722     0xAA2
em3space                          2723     0xAA3
em4space                          2724     0xAA4
digitspace                        2725     0xAA5
punctspace                        2726     0xAA6
thinspace                         2727     0xAA7
hairspace                         2728     0xAA8
emdash                            2729     0xAA9
endash                            2730     0xAAA
signifblank                       2732     0xAAC
ellipsis                          2734     0xAAE
doubbaselinedot                   2735     0xAAF
onethird                          2736     0xAB0
twothirds                         2737     0xAB1
onefifth                          2738     0xAB2
twofifths                         2739     0xAB3
threefifths                       2740     0xAB4
fourfifths                        2741     0xAB5
onesixth                          2742     0xAB6
fivesixths                        2743     0xAB7
careof                            2744     0xAB8
figdash                           2747     0xABB
leftanglebracket                  2748     0xABC
decimalpoint                      2749     0xABD
rightanglebracket                 2750     0xABE
marker                            2751     0xABF
oneeighth                         2755     0xAC3
threeeighths                      2756     0xAC4
fiveeighths                       2757     0xAC5
seveneighths                      2758     0xAC6
trademark                         2761     0xAC9
signaturemark                     2762     0xACA
trademarkincircle                 2763     0xACB
leftopentriangle                  2764     0xACC
rightopentriangle                 2765     0xACD
emopencircle                      2766     0xACE
emopenrectangle                   2767     0xACF
leftsinglequotemark               2768     0xAD0
rightsinglequotemark              2769     0xAD1
leftdoublequotemark               2770     0xAD2
rightdoublequotemark              2771     0xAD3
prescription                      2772     0xAD4
permille                          2773     0xAD5
minutes                           2774     0xAD6
seconds                           2775     0xAD7
latincross                        2777     0xAD9
hexagram                          2778     0xADA
filledrectbullet                  2779     0xADB
filledlefttribullet               2780     0xADC
filledrighttribullet              2781     0xADD
emfilledcircle                    2782     0xADE
emfilledrect                      2783     0xADF
enopencircbullet                  2784     0xAE0
enopensquarebullet                2785     0xAE1
openrectbullet                    2786     0xAE2
opentribulletup                   2787     0xAE3
opentribulletdown                 2788     0xAE4
openstar                          2789     0xAE5
enfilledcircbullet                2790     0xAE6
enfilledsqbullet                  2791     0xAE7
filledtribulletup                 2792     0xAE8
filledtribulletdown               2793     0xAE9
leftpointer                       2794     0xAEA
rightpointer                      2795     0xAEB
club                              2796     0xAEC
diamond                           2797     0xAED
heart                             2798     0xAEE
maltesecross                      2800     0xAF0
dagger                            2801     0xAF1
doubledagger                      2802     0xAF2
checkmark                         2803     0xAF3
ballotcross                       2804     0xAF4
musicalsharp                      2805     0xAF5
musicalflat                       2806     0xAF6
malesymbol                        2807     0xAF7
femalesymbol                      2808     0xAF8
telephone                         2809     0xAF9
telephonerecorder                 2810     0xAFA
phonographcopyright               2811     0xAFB
caret                             2812     0xAFC
singlelowquotemark                2813     0xAFD
doublelowquotemark                2814     0xAFE
cursor                            2815     0xAFF
leftcaret                         2979     0xBA3
rightcaret                        2982     0xBA6
downcaret                         2984     0xBA8
upcaret                           2985     0xBA9
overbar                           3008     0xBC0
downtack                          3010     0xBC2
upshoe                            3011     0xBC3
downstile                         3012     0xBC4
underbar                          3014     0xBC6
jot                               3018     0xBCA
quad                              3020     0xBCC
uptack                            3022     0xBCE
circle                            3023     0xBCF
upstile                           3027     0xBD3
downshoe                          3030     0xBD6
rightshoe                         3032     0xBD8
leftshoe                          3034     0xBDA
lefttack                          3036     0xBDC
righttack                         3068     0xBFC
hebrew_doublelowline              3295     0xCDF
hebrew_aleph                      3296     0xCE0
hebrew_bet                        3297     0xCE1
hebrew_gimel                      3298     0xCE2
hebrew_dalet                      3299     0xCE3
hebrew_he                         3300     0xCE4
hebrew_waw                        3301     0xCE5
hebrew_zain                       3302     0xCE6
hebrew_chet                       3303     0xCE7
hebrew_tet                        3304     0xCE8
hebrew_yod                        3305     0xCE9
hebrew_finalkaph                  3306     0xCEA
hebrew_kaph                       3307     0xCEB
hebrew_lamed                      3308     0xCEC
hebrew_finalmem                   3309     0xCED
hebrew_mem                        3310     0xCEE
hebrew_finalnun                   3311     0xCEF
hebrew_nun                        3312     0xCF0
hebrew_samech                     3313     0xCF1
hebrew_ayin                       3314     0xCF2
hebrew_finalpe                    3315     0xCF3
hebrew_pe                         3316     0xCF4
hebrew_finalzade                  3317     0xCF5
hebrew_zade                       3318     0xCF6
hebrew_qoph                       3319     0xCF7
hebrew_resh                       3320     0xCF8
hebrew_shin                       3321     0xCF9
hebrew_taw                        3322     0xCFA
.CE
.CS
Thai_kokai                        3489     0xDA1
Thai_khokhai                      3490     0xDA2
Thai_khokhuat                     3491     0xDA3
Thai_khokhwai                     3492     0xDA4
Thai_khokhon                      3493     0xDA5
Thai_khorakhang                   3494     0xDA6
Thai_ngongu                       3495     0xDA7
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027

1028
1029
1030
1031
1032
1033
1034
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
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
.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
1129
dead_E                           65155     0xFE83
dead_i                           65156     0xFE84
dead_I                           65157     0xFE85
dead_o                           65158     0xFE86
dead_O                           65159     0xFE87
dead_u                           65160     0xFE88
dead_U                           65161     0xFE89
dead_small_schwa                 65162     0xFE8A
dead_capital_schwa               65163     0xFE8B
dead_greek                       65164     0xFE8C

dead_lowline                     65168     0xFE90
dead_aboveverticalline           65169     0xFE91
dead_belowverticalline           65170     0xFE92
dead_longsolidusoverlay          65171     0xFE93
ch                               65184     0xFEA0
Ch                               65185     0xFEA1
CH                               65186     0xFEA2







|
|

>







1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
dead_E                           65155     0xFE83
dead_i                           65156     0xFE84
dead_I                           65157     0xFE85
dead_o                           65158     0xFE86
dead_O                           65159     0xFE87
dead_u                           65160     0xFE88
dead_U                           65161     0xFE89
dead_schwa                       65162     0xFE8A
dead_SCHWA                       65163     0xFE8B
dead_greek                       65164     0xFE8C
dead_hamza                       65165     0xFE8D
dead_lowline                     65168     0xFE90
dead_aboveverticalline           65169     0xFE91
dead_belowverticalline           65170     0xFE92
dead_longsolidusoverlay          65171     0xFE93
ch                               65184     0xFEA0
Ch                               65185     0xFEA1
CH                               65186     0xFEA2
1161
1162
1163
1164
1165
1166
1167


1168
1169
1170
1171
1172
1173
1174
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
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
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







<
<







1191
1192
1193
1194
1195
1196
1197


1198
1199
1200
1201
1202
1203
1204
Down                             65364     0xFF54
Prior                            65365     0xFF55
Next                             65366     0xFF56
End                              65367     0xFF57
Begin                            65368     0xFF58
Win_L                            65371     0xFF5B
Win_R                            65372     0xFF5C


App                              65373     0xFF5D
Select                           65376     0xFF60
Print                            65377     0xFF61
Execute                          65378     0xFF62
Insert                           65379     0xFF63
Undo                             65381     0xFF65
Redo                             65382     0xFF66
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
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







|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1300
1301
1302
1303
1304
1305
1306
1307

































































































































































































































































































































































1308


































































































































































































































































































































































1309
1310
1311
1312
1313
1314
1315
braille_dot_5                    65525     0xFFF5
braille_dot_6                    65526     0xFFF6
braille_dot_7                    65527     0xFFF7
braille_dot_8                    65528     0xFFF8
braille_dot_9                    65529     0xFFF9
braille_dot_10                   65530     0xFFFA
Delete                           65535     0xFFFF
.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







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>












>
>







1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
SunAudioLowerVolume          268828535     0x1005FF77
SunAudioMute                 268828536     0x1005FF78
SunAudioRaiseVolume          268828537     0x1005FF79
SunVideoDegauss              268828538     0x1005FF7A
SunVideoLowerBrightness      268828539     0x1005FF7B
SunVideoRaiseBrightness      268828540     0x1005FF7C
SunPowerSwitchShift          268828541     0x1005FF7D
XF86BrightnessAuto           268964084     0x100810F4
XF86DisplayOff               268964085     0x100810F5
XF86Info                     268964198     0x10081166
XF86AspectRatio              268964215     0x10081177
XF86DVD                      268964229     0x10081185
XF86Audio                    268964232     0x10081188
XF86ChannelUp                268964242     0x10081192
XF86ChannelDown              268964243     0x10081193
XF86Break                    268964251     0x1008119B
XF86VideoPhone               268964256     0x100811A0
XF86ZoomReset                268964260     0x100811A4
XF86Editor                   268964262     0x100811A6
XF86GraphicsEditor           268964264     0x100811A8
XF86Presentation             268964265     0x100811A9
XF86Database                 268964266     0x100811AA
XF86Voicemail                268964268     0x100811AC
XF86Addressbook              268964269     0x100811AD
XF86DisplayToggle            268964271     0x100811AF
XF86SpellCheck               268964272     0x100811B0
XF86ContextMenu              268964278     0x100811B6
XF86MediaRepeat              268964279     0x100811B7
XF8610ChannelsUp             268964280     0x100811B8
XF8610ChannelsDown           268964281     0x100811B9
XF86Images                   268964282     0x100811BA
XF86NotificationCenter       268964284     0x100811BC
XF86PickupPhone              268964285     0x100811BD
XF86HangupPhone              268964286     0x100811BE
XF86Fn                       268964304     0x100811D0
XF86Fn_Esc                   268964305     0x100811D1
XF86FnRightShift             268964325     0x100811E5
XF86Numeric0                 268964352     0x10081200
XF86Numeric1                 268964353     0x10081201
XF86Numeric2                 268964354     0x10081202
XF86Numeric3                 268964355     0x10081203
XF86Numeric4                 268964356     0x10081204
XF86Numeric5                 268964357     0x10081205
XF86Numeric6                 268964358     0x10081206
XF86Numeric7                 268964359     0x10081207
XF86Numeric8                 268964360     0x10081208
XF86Numeric9                 268964361     0x10081209
XF86NumericStar              268964362     0x1008120A
XF86NumericPound             268964363     0x1008120B
XF86NumericA                 268964364     0x1008120C
XF86NumericB                 268964365     0x1008120D
XF86NumericC                 268964366     0x1008120E
XF86NumericD                 268964367     0x1008120F
XF86CameraFocus              268964368     0x10081210
XF86WPSButton                268964369     0x10081211
XF86CameraZoomIn             268964373     0x10081215
XF86CameraZoomOut            268964374     0x10081216
XF86CameraUp                 268964375     0x10081217
XF86CameraDown               268964376     0x10081218
XF86CameraLeft               268964377     0x10081219
XF86CameraRight              268964378     0x1008121A
XF86AttendantOn              268964379     0x1008121B
XF86AttendantOff             268964380     0x1008121C
XF86AttendantToggle          268964381     0x1008121D
XF86LightsToggle             268964382     0x1008121E
XF86ALSToggle                268964400     0x10081230
XF86Buttonconfig             268964416     0x10081240
XF86Taskmanager              268964417     0x10081241
XF86Journal                  268964418     0x10081242
XF86ControlPanel             268964419     0x10081243
XF86AppSelect                268964420     0x10081244
XF86Screensaver              268964421     0x10081245
XF86VoiceCommand             268964422     0x10081246
XF86Assistant                268964423     0x10081247
XF86EmojiPicker              268964425     0x10081249
XF86Dictate                  268964426     0x1008124A
XF86BrightnessMin            268964432     0x10081250
XF86BrightnessMax            268964433     0x10081251
XF86KbdInputAssistPrev       268964448     0x10081260
XF86KbdInputAssistNext       268964449     0x10081261
XF86KbdInputAssistPrevgroup  268964450     0x10081262
XF86KbdInputAssistNextgroup  268964451     0x10081263
XF86KbdInputAssistAccept     268964452     0x10081264
XF86KbdInputAssistCancel     268964453     0x10081265
XF86RightUp                  268964454     0x10081266
XF86RightDown                268964455     0x10081267
XF86LeftUp                   268964456     0x10081268
XF86LeftDown                 268964457     0x10081269
XF86RootMenu                 268964458     0x1008126A
XF86MediaTopMenu             268964459     0x1008126B
XF86Numeric11                268964460     0x1008126C
XF86Numeric12                268964461     0x1008126D
XF86AudioDesc                268964462     0x1008126E
XF863DMode                   268964463     0x1008126F
XF86NextFavorite             268964464     0x10081270
XF86StopRecord               268964465     0x10081271
XF86PauseRecord              268964466     0x10081272
XF86VOD                      268964467     0x10081273
XF86Unmute                   268964468     0x10081274
XF86FastReverse              268964469     0x10081275
XF86SlowReverse              268964470     0x10081276
XF86Data                     268964471     0x10081277
XF86OnScreenKeyboard         268964472     0x10081278
XF86PrivacyScreenToggle      268964473     0x10081279
XF86SelectiveScreenshot      268964474     0x1008127A
XF86Macro1                   268964496     0x10081290
XF86Macro2                   268964497     0x10081291
XF86Macro3                   268964498     0x10081292
XF86Macro4                   268964499     0x10081293
XF86Macro5                   268964500     0x10081294
XF86Macro6                   268964501     0x10081295
XF86Macro7                   268964502     0x10081296
XF86Macro8                   268964503     0x10081297
XF86Macro9                   268964504     0x10081298
XF86Macro10                  268964505     0x10081299
XF86Macro11                  268964506     0x1008129A
XF86Macro12                  268964507     0x1008129B
XF86Macro13                  268964508     0x1008129C
XF86Macro14                  268964509     0x1008129D
XF86Macro15                  268964510     0x1008129E
XF86Macro16                  268964511     0x1008129F
XF86Macro17                  268964512     0x100812A0
XF86Macro18                  268964513     0x100812A1
XF86Macro19                  268964514     0x100812A2
XF86Macro20                  268964515     0x100812A3
XF86Macro21                  268964516     0x100812A4
XF86Macro22                  268964517     0x100812A5
XF86Macro23                  268964518     0x100812A6
XF86Macro24                  268964519     0x100812A7
XF86Macro25                  268964520     0x100812A8
XF86Macro26                  268964521     0x100812A9
XF86Macro27                  268964522     0x100812AA
XF86Macro28                  268964523     0x100812AB
XF86Macro29                  268964524     0x100812AC
XF86Macro30                  268964525     0x100812AD
XF86MacroRecordStart         268964528     0x100812B0
XF86MacroRecordStop          268964529     0x100812B1
XF86MacroPresetCycle         268964530     0x100812B2
XF86MacroPreset1             268964531     0x100812B3
XF86MacroPreset2             268964532     0x100812B4
XF86MacroPreset3             268964533     0x100812B5
XF86KbdLcdMenu1              268964536     0x100812B8
XF86KbdLcdMenu2              268964537     0x100812B9
XF86KbdLcdMenu3              268964538     0x100812BA
XF86KbdLcdMenu4              268964539     0x100812BB
XF86KbdLcdMenu5              268964540     0x100812BC
XF86Switch_VT_1              269024769     0x1008FE01
XF86Switch_VT_2              269024770     0x1008FE02
XF86Switch_VT_3              269024771     0x1008FE03
XF86Switch_VT_4              269024772     0x1008FE04
XF86Switch_VT_5              269024773     0x1008FE05
XF86Switch_VT_6              269024774     0x1008FE06
XF86Switch_VT_7              269024775     0x1008FE07
XF86Switch_VT_8              269024776     0x1008FE08
XF86Switch_VT_9              269024777     0x1008FE09
XF86Switch_VT_10             269024778     0x1008FE0A
XF86Switch_VT_11             269024779     0x1008FE0B
XF86Switch_VT_12             269024780     0x1008FE0C
.CE
.CS
XF86Ungrab                   269024800     0x1008FE20
XF86ClearGrab                269024801     0x1008FE21
XF86Next_VMode               269024802     0x1008FE22
XF86Prev_VMode               269024803     0x1008FE23
XF86LogWindowTree            269024804     0x1008FE24
XF86LogGrabInfo              269024805     0x1008FE25
XF86ModeLock                 269025025     0x1008FF01
2239
2240
2241
2242
2243
2244
2245

2246
2247
2248
2249
2250
2251
2252
2253
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:







>








1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
XF86TouchpadOff              269025201     0x1008FFB1
XF86AudioMicMute             269025202     0x1008FFB2
XF86Keyboard                 269025203     0x1008FFB3
XF86WWAN                     269025204     0x1008FFB4
XF86RFKill                   269025205     0x1008FFB5
XF86AudioPreset              269025206     0x1008FFB6
XF86RotationLockToggle       269025207     0x1008FFB7
XF86FullScreen               269025208     0x1008FFB8
.CE
.SH "SEE ALSO"
bind(n), event(n)
.SH KEYWORDS
bind, binding, event, keysym
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/label.n.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
.SH "WIDGET COMMAND"
.PP
The \fBlabel\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for label widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given







|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
.SH "WIDGET COMMAND"
.PP
The \fBlabel\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for label widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Returns the current value of the configuration option given
Changes to doc/labelframe.n.
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
.SH "WIDGET COMMAND"
.PP
The \fBlabelframe\fR command creates a new Tcl command whose
name is the same as the path name of the labelframe's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the labelframe widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
.SH "WIDGET COMMAND"
.PP
The \fBlabelframe\fR command creates a new Tcl command whose
name is the same as the path name of the labelframe's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the labelframe widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for frame widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
Changes to doc/listbox.n.
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
.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
.







|







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
.SH "WIDGET COMMAND"
.PP
The \fBlistbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for listbox widgets:
.TP
\fIpathName \fBactivate\fR \fIindex\fR
.
379
380
381
382
383
384
385
386
387
388
389


390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
total width of the listbox text is off-screen to the left.
\fIfraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.


If \fIwhat\fR is \fBpages\fR then the view adjusts by
\fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR character units (the width of the \fB0\fR character)
on the display.
.RE
.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the
text in the widget's window.
It can take any of the following forms:







|
<
|

>
>
|




<
<
<







379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394
395



396
397
398
399
400
401
402
total width of the listbox text is off-screen to the left.
\fIfraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR character units (the width of the \fB0\fR character)
on the display;  if it is \fBpages\fR then the view adjusts by
\fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.



.RE
.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the
text in the widget's window.
It can take any of the following forms:
429
430
431
432
433
434
435
436
437

438
439
440
441
442
443
444
445
446
447
448
449
450
way through the listbox, and so on.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
If \fIwhat\fR is \fBpages\fR then

the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then earlier elements
become visible;  if it is positive then later elements
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR lines.
.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for listboxes that give them
Motif-like behavior.  Much of the behavior of a listbox is determined
by its \fB\-selectmode\fR option, which selects one of four ways
of dealing with the selection.







|
|
>




<
<







427
428
429
430
431
432
433
434
435
436
437
438
439
440


441
442
443
444
445
446
447
way through the listbox, and so on.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjusts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBunits\fR or \fBpages\fR.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR lines;  if it is \fBpages\fR then
the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then earlier elements
become visible;  if it is positive then later elements
become visible.


.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for listboxes that give them
Motif-like behavior.  Much of the behavior of a listbox is determined
by its \fB\-selectmode\fR option, which selects one of four ways
of dealing with the selection.
Deleted doc/man.macros.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
.\" The -*- nroff -*- definitions below are for supplemental macros used
.\" in Tcl/Tk manual entries.
.\"
.\" .AP type name in/out ?indent?
.\"	Start paragraph describing an argument to a library procedure.
.\"	type is type of argument (int, etc.), in/out is either "in", "out",
.\"	or "in/out" to describe whether procedure reads or modifies arg,
.\"	and indent is equivalent to second arg of .IP (shouldn't ever be
.\"	needed;  use .AS below instead)
.\"
.\" .AS ?type? ?name?
.\"	Give maximum sizes of arguments for setting tab stops.  Type and
.\"	name are examples of largest possible arguments that will be passed
.\"	to .AP later.  If args are omitted, default tab stops are used.
.\"
.\" .BS
.\"	Start box enclosure.  From here until next .BE, everything will be
.\"	enclosed in one large box.
.\"
.\" .BE
.\"	End of box enclosure.
.\"
.\" .CS
.\"	Begin code excerpt.
.\"
.\" .CE
.\"	End code excerpt.
.\"
.\" .VS ?version? ?br?
.\"	Begin vertical sidebar, for use in marking newly-changed parts
.\"	of man pages.  The first argument is ignored and used for recording
.\"	the version when the .VS was added, so that the sidebars can be
.\"	found and removed when they reach a certain age.  If another argument
.\"	is present, then a line break is forced before starting the sidebar.
.\"
.\" .VE
.\"	End of vertical sidebar.
.\"
.\" .DS
.\"	Begin an indented unfilled display.
.\"
.\" .DE
.\"	End of indented unfilled display.
.\"
.\" .SO ?manpage?
.\"	Start of list of standard options for a Tk widget. The manpage
.\"	argument defines where to look up the standard options; if
.\"	omitted, defaults to "options". The options follow on successive
.\"	lines, in three columns separated by tabs.
.\"
.\" .SE
.\"	End of list of standard options for a Tk widget.
.\"
.\" .OP cmdName dbName dbClass
.\"	Start of description of a specific option.  cmdName gives the
.\"	option's name as specified in the class command, dbName gives
.\"	the option's name in the option database, and dbClass gives
.\"	the option's class in the option database.
.\"
.\" .UL arg1 arg2
.\"	Print arg1 underlined, then print arg2 normally.
.\"
.\" .QW arg1 ?arg2?
.\"	Print arg1 in quotes, then arg2 normally (for trailing punctuation).
.\"
.\" .PQ arg1 ?arg2?
.\"	Print an open parenthesis, arg1 in quotes, then arg2 normally
.\"	(for trailing punctuation) and then a closing parenthesis.
.\"
.\"	# Set up traps and other miscellaneous stuff for Tcl/Tk man pages.
.if t .wh -1.3i ^B
.nr ^l \n(.l
.ad b
.\"	# Start an argument description
.de AP
.ie !"\\$4"" .TP \\$4
.el \{\
.   ie !"\\$2"" .TP \\n()Cu
.   el          .TP 15
.\}
.ta \\n()Au \\n()Bu
.ie !"\\$3"" \{\
\&\\$1 \\fI\\$2\\fP (\\$3)
.\".b
.\}
.el \{\
.br
.ie !"\\$2"" \{\
\&\\$1	\\fI\\$2\\fP
.\}
.el \{\
\&\\fI\\$1\\fP
.\}
.\}
..
.\"	# define tabbing values for .AP
.de AS
.nr )A 10n
.if !"\\$1"" .nr )A \\w'\\$1'u+3n
.nr )B \\n()Au+15n
.\"
.if !"\\$2"" .nr )B \\w'\\$2'u+\\n()Au+3n
.nr )C \\n()Bu+\\w'(in/out)'u+2n
..
.AS Tcl_Interp Tcl_CreateInterp in/out
.\"	# BS - start boxed text
.\"	# ^y = starting y location
.\"	# ^b = 1
.de BS
.br
.mk ^y
.nr ^b 1u
.if n .nf
.if n .ti 0
.if n \l'\\n(.lu\(ul'
.if n .fi
..
.\"	# BE - end boxed text (draw box now)
.de BE
.nf
.ti 0
.mk ^t
.ie n \l'\\n(^lu\(ul'
.el \{\
.\"	Draw four-sided box normally, but don't draw top of
.\"	box if the box started on an earlier page.
.ie !\\n(^b-1 \{\
\h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.el \}\
\h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\l'|0u-1.5n\(ul'
.\}
.\}
.fi
.br
.nr ^b 0
..
.\"	# VS - start vertical sidebar
.\"	# ^Y = starting y location
.\"	# ^v = 1 (for troff;  for nroff this doesn't matter)
.de VS
.if !"\\$2"" .br
.mk ^Y
.ie n 'mc \s12\(br\s0
.el .nr ^v 1u
..
.\"	# VE - end of vertical sidebar
.de VE
.ie n 'mc
.el \{\
.ev 2
.nf
.ti 0
.mk ^t
\h'|\\n(^lu+3n'\L'|\\n(^Yu-1v\(bv'\v'\\n(^tu+1v-\\n(^Yu'\h'-|\\n(^lu+3n'
.sp -1
.fi
.ev
.\}
.nr ^v 0
..
.\"	# Special macro to handle page bottom:  finish off current
.\"	# box/sidebar if in box/sidebar mode, then invoked standard
.\"	# page bottom macro.
.de ^B
.ev 2
'ti 0
'nf
.mk ^t
.if \\n(^b \{\
.\"	Draw three-sided box if this is the box's first page,
.\"	draw two sides but no top otherwise.
.ie !\\n(^b-1 \h'-1.5n'\L'|\\n(^yu-1v'\l'\\n(^lu+3n\(ul'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.el \h'-1.5n'\L'|\\n(^yu-1v'\h'\\n(^lu+3n'\L'\\n(^tu+1v-\\n(^yu'\h'|0u'\c
.\}
.if \\n(^v \{\
.nr ^x \\n(^tu+1v-\\n(^Yu
\kx\h'-\\nxu'\h'|\\n(^lu+3n'\ky\L'-\\n(^xu'\v'\\n(^xu'\h'|0u'\c
.\}
.bp
'fi
.ev
.if \\n(^b \{\
.mk ^y
.nr ^b 2
.\}
.if \\n(^v \{\
.mk ^Y
.\}
..
.\"	# DS - begin display
.de DS
.RS
.nf
.sp
..
.\"	# DE - end display
.de DE
.fi
.RE
.sp
..
.\"	# SO - start of list of standard options
.de SO
'ie '\\$1'' .ds So \\fBoptions\\fR
'el .ds So \\fB\\$1\\fR
.SH "STANDARD OPTIONS"
.LP
.nf
.ta 5.5c 11c
.ft B
..
.\"	# SE - end of list of standard options
.de SE
.fi
.ft R
.LP
See the \\*(So manual entry for details on the standard options.
..
.\"	# OP - start of full description for a single option
.de OP
.LP
.nf
.ta 4c
Command-Line Name:	\\fB\\$1\\fR
Database Name:	\\fB\\$2\\fR
Database Class:	\\fB\\$3\\fR
.fi
.IP
..
.\"	# CS - begin code excerpt
.de CS
.RS
.nf
.ta .25i .5i .75i 1i
..
.\"	# CE - end code excerpt
.de CE
.fi
.RE
..
.\"	# UL - underline word
.de UL
\\$1\l'|0\(ul'\\$2
..
.\"	# QW - apply quotation marks to word
.de QW
.ie '\\*(lq'"' ``\\$1''\\$2
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\$2
..
.\"	# PQ - apply parens and quotation marks to word
.de PQ
.ie '\\*(lq'"' (``\\$1''\\$2)\\$3
.\"" fix emacs highlighting
.el (\\*(lq\\$1\\*(rq\\$2)\\$3
..
.\"	# QR - quoted range
.de QR
.ie '\\*(lq'"' ``\\$1''\\-``\\$2''\\$3
.\"" fix emacs highlighting
.el \\*(lq\\$1\\*(rq\\-\\*(lq\\$2\\*(rq\\$3
..
.\"	# MT - "empty" string
.de MT
.QW ""
..
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































Changes to doc/menu.n.
9
10
11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menu, tk_menuSetFocus \- Create and manipulate 'menu' widgets and menubars
.SH SYNOPSIS
.nf
\fBmenu\fR \fIpathName \fR?\fIoptions\fR?
\fBtk_menuSetFocus\fR \fIpathName\fR

.SO
\-activebackground	\-borderwidth	\-foreground
\-activeborderwidth	\-cursor	\-relief
\-activeforeground	\-disabledforeground	\-takefocus
\-background	\-font	\-activerelief
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-postcommand postCommand Command
If this option is specified then it provides a Tcl command to execute
each time the menu is posted.  The command is invoked by the \fBpost\fR
widget command before posting the menu. Note that in Tk 8.0 on Macintosh
and Windows, all post-commands in a system of menus are executed before any
of those menus are posted.
This is due to the limitations in the individual platforms' menu managers.
.OP \-selectcolor selectColor Background
For menu entries that are check buttons or radio buttons, this option
specifies the color to display in the indicator when the check button
or radio button is selected.
.OP \-tearoff tearOff TearOff
This option must have a proper boolean value (default is false),
which specifies whether or not the menu should include a tear-off
entry at the top.  If so, it will exist as entry 0 of the menu and
the other entries will number starting at 1.  The default menu
bindings arrange for the menu to be torn off when the tear-off entry
is invoked.
This option is ignored under Aqua/Mac OS X, where menus cannot
be torn off.
.OP \-tearoffcommand tearOffCommand TearOffCommand
If this option has a non-empty value, then it specifies a Tcl command
to invoke whenever the menu is torn off.  The actual command will
consist of the value of this option, followed by a space, followed
by the name of the menu window, followed by a space, followed by
the name of the name of the torn off menu window.  For example, if
the option's value is
.QW "\fBa b\fR"
and menu \fB.x.y\fR is torn off to
create a new menu \fB.x.tearoff1\fR, then the command
.QW "\fBa b .x.y .x.tearoff1\fR"
will be invoked.
This option is ignored under Aqua/Mac OS X, where menus cannot
be torn off.
.OP \-title title Title
The string will be used to title the window created when this menu is
torn off. If the title is NULL, then the window will have the title
of the menubutton or the text of the cascade item from which this menu
was invoked.
.OP \-type type Type







|
|
>




|














|
|
|
|
|
|
|













|







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
menu, tk_menuSetFocus \- Create and manipulate 'menu' widgets and menubars
.SH SYNOPSIS
.nf
\fBmenu\fI pathName \fR?\fIoptions\fR?
\fBtk_menuSetFocus\fI pathName\fR
.fi
.SO
\-activebackground	\-borderwidth	\-foreground
\-activeborderwidth	\-cursor	\-relief
\-activeforeground	\-disabledforeground	\-takefocus
\-background	\-font
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-postcommand postCommand Command
If this option is specified then it provides a Tcl command to execute
each time the menu is posted.  The command is invoked by the \fBpost\fR
widget command before posting the menu. Note that in Tk 8.0 on Macintosh
and Windows, all post-commands in a system of menus are executed before any
of those menus are posted.
This is due to the limitations in the individual platforms' menu managers.
.OP \-selectcolor selectColor Background
For menu entries that are check buttons or radio buttons, this option
specifies the color to display in the indicator when the check button
or radio button is selected.
.OP \-tearoff tearOff TearOff
This option must have a proper boolean value, which specifies
whether or not the menu should include a tear-off entry at the
top.  If so, it will exist as entry 0 of the menu and the other
entries will number starting at 1.  The default
menu bindings arrange for the menu to be torn off when the tear-off
entry is invoked.
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
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
(hidden from Tk) will be inserted into the menubar at that time and
subsequent addition of a .apple menu will no longer result in it
becoming the Application menu.
.PP
When Tk sees a .menubar.window menu on the Macintosh, the menu's
contents are inserted into the standard Window menu of the user's
menubar whenever the window's menubar is in front. The first items in
the menu are provided by Mac OS X, and the names of the current
toplevels are automatically appended after all the Tk-defined items and
a separator. The Window menu on the Mac also allows toggling the
window into a fullscreen state, and managing a tabbed window interface
(multiple windows grouped into a single window) if supported by that
version of the operating system.
.PP
When Tk sees a .menubar.help menu on the Macintosh, the menu's contents
are appended to the standard Help menu of the user's menubar whenever
the window's menubar is in front. The first items in the menu
are provided by Mac OS X.
.PP
When Tk sees a System menu on Windows, its items are appended to the
system menu that the menubar is attached to. This menu is tied to the
application icon and can be invoked with the mouse or by typing
Alt+Spacebar.  Due to limitations in the Windows API, any font changes,
colors, images, bitmaps, or tearoff images will not appear in the
system menu.







|









|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
(hidden from Tk) will be inserted into the menubar at that time and
subsequent addition of a .apple menu will no longer result in it
becoming the Application menu.
.PP
When Tk sees a .menubar.window menu on the Macintosh, the menu's
contents are inserted into the standard Window menu of the user's
menubar whenever the window's menubar is in front. The first items in
the menu are provided by macOS, and the names of the current
toplevels are automatically appended after all the Tk-defined items and
a separator. The Window menu on the Mac also allows toggling the
window into a fullscreen state, and managing a tabbed window interface
(multiple windows grouped into a single window) if supported by that
version of the operating system.
.PP
When Tk sees a .menubar.help menu on the Macintosh, the menu's contents
are appended to the standard Help menu of the user's menubar whenever
the window's menubar is in front. The first items in the menu
are provided by macOS.
.PP
When Tk sees a System menu on Windows, its items are appended to the
system menu that the menubar is attached to. This menu is tied to the
application icon and can be invoked with the mouse or by typing
Alt+Spacebar.  Due to limitations in the Windows API, any font changes,
colors, images, bitmaps, or tearoff images will not appear in the
system menu.
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349

350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368
369
370
371
372
373
374
375
376

377
378
379
380
381
382
383
384
385
386

387
388
389
390
391
392
393

394
395
396
397
398
399
400
401
402

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

418
419
420
421
422
423
424
425

426
427
428
429
430
431
432

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

446
447
448
449
450

451
452
453
454
455
456
457
458
459

460
461
462
463
464
465
466
467
468
469
470
471

472
473
474
475
476
477
478
479
480
481
482
483
484
485

486
487
488
489
490
491
492
493
494

495
496
497
498
499
500
501

502
503
504
505
506
507
508

509
510
511
512
513

514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529
530
531
532

533
534
535
536
537
538
539
540

541
542
543
544
545
546
547
548
549

550
551
552
553
554

555
556
557

558
559
560
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
577

578
579
580
581
582

583
584
585
586
587
588
589
590
591
592

593
594
595
596
597
598
599
600

601
602
603
604
605

606
607
608

609
610
611
612
613
614
615

616
617
618
619
620
621
622
623
624
625
626
627

628
629
630
631
632
633

634
635
636
637
638

639
640
641
642
643
644

645
646
647
648
649
650

651
652
653
654
655

656
657
658
659
660
661
662
663

664
665
666
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690

691
692
693
694
695
696
697
698
699
700

701
702
703
704
705
706
707

708
709
710
711
712
713
714
.SH "WIDGET COMMAND"
.PP
The \fBmenu\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Many of the widget commands for a menu take as one argument an
indicator of which entry of the menu to operate on. These
indicators are called \fIindex\fRes and may be specified in
any of the following forms:
.TP 12
\fBactive\fR
.
Indicates the entry that is currently active.  If no entry is
active then this form is equivalent to \fBnone\fR.  This form may
not be abbreviated.
.TP 12
\fBend\fR
.
Indicates the bottommost entry in the menu.  If there are no
entries in the menu then this form is equivalent to \fBnone\fR.
This form may not be abbreviated.
.TP 12
\fBlast\fR
.
Same as \fBend\fR.
.TP 12
\fBnone\fR
.
Indicates
.QW "no entry at all" ;
this is used most commonly with
the \fBactivate\fR option to deactivate all the entries in the
menu.  In most cases the specification of \fBnone\fR causes
nothing to happen in the widget command.
This form may not be abbreviated.
.TP 12
\fB@\fInumber\fR
.
In this form, \fInumber\fR is treated as a y-coordinate in the
menu's window;  the entry closest to that y-coordinate is used.
For example,
.QW \fB@0\fR
indicates the top-most entry in the window.
.TP 12

\fInumber\fR
.
Specifies the entry numerically, where 0 corresponds
to the top-most entry of the menu, 1 to the entry below it, and
so on.
.TP 12
\fIpattern\fR
.
If the index does not satisfy one of the above forms then this
form is used.  \fIPattern\fR is pattern-matched against the label of
each entry in the menu, in order from the top down, until a
matching entry is found.  The rules of \fBstring match\fR
are used.
.PP
If the index could match more than one of the above forms, then
the form earlier in the above list takes precedence.
.PP
The following widget commands are possible for menu widgets:

.TP
\fIpathName \fBactivate \fIindex\fR
.
Change the state of the entry indicated by \fIindex\fR to \fBactive\fR
and redisplay it using its active colors.
Any previously-active entry is deactivated.  If \fIindex\fR
is specified as \fBnone\fR, or if the specified entry is
disabled, then the menu ends up with no active entry.
Returns an empty string.

.TP
\fIpathName \fBadd \fItype \fR?\fIoption value option value ...\fR?
.
Add a new entry to the bottom of the menu.  The new entry's type
is given by \fItype\fR and must be one of \fBcascade\fR,
\fBcheckbutton\fR, \fBcommand\fR, \fBradiobutton\fR, or \fBseparator\fR,
or a unique abbreviation of one of the above.  If additional arguments
are present, they specify the options listed in the \fBMENU ENTRY OPTIONS\fR
section below.
The \fBadd\fR widget command returns an empty string.

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.

.TP
\fIpathName \fBclone \fInewPathname\fR ?\fIcloneType\fR?
.
Makes a clone of the current menu named \fInewPathName\fR. This clone
is a menu in its own right, but any changes to the clone are
propagated to the original menu and vice versa. \fIcloneType\fR can be
\fBnormal\fR, \fBmenubar\fR, or \fBtearoff\fR. Should not normally be
called outside of the Tk library. See the \fBCLONES\fR section for
more information.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.

.TP
\fIpathName \fBdelete \fIindex1\fR ?\fIindex2\fR?
.
Delete all of the menu entries between \fIindex1\fR and
\fIindex2\fR inclusive.
If \fIindex2\fR is omitted then it defaults to \fIindex1\fR.
Attempts to delete a tear-off menu entry are ignored (instead, you
should change the \fB\-tearoff\fR option to remove the tear-off entry).

.TP
\fIpathName \fBentrycget \fIindex option\fR
.
Returns the current value of a configuration option for
the entry given by \fIindex\fR.
\fIOption\fR may have any of the names described in the
\fBMENU ENTRY OPTIONS\fR section below.

.TP
\fIpathName \fBentryconfigure \fIindex \fR?\fIoptions...\fR?
.
This command is similar to the \fBconfigure\fR command, except that
it applies to the options for an individual entry, whereas \fBconfigure\fR
applies to the options for the menu as a whole.
\fIOptions\fR may have any of the values described in the
\fBMENU ENTRY OPTIONS\fR
section below.  If \fIoptions\fR are specified, options are
modified as indicated in the command and the command returns an empty string.
If no \fIoptions\fR are specified, returns a list describing
the current options for entry \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).

.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the numerical index corresponding to \fIindex\fR, or
\fBnone\fR if \fIindex\fR was specified as \fBnone\fR.

.TP
\fIpathName \fBinsert \fIindex type \fR?\fIoption value option value ...\fR?
.
Same as the \fBadd\fR widget command except that it inserts the new
entry just before the entry given by \fIindex\fR, instead of appending
to the end of the menu.  The \fItype\fR, \fIoption\fR, and \fIvalue\fR
arguments have the same interpretation as for the \fBadd\fR widget
command.  It is not possible to insert new menu entries before the
tear-off entry, if the menu has one.

.TP
\fIpathName \fBinvoke \fIindex\fR
.
Invoke the action of the menu entry.  See the sections on the
individual entries above for details on what happens.  If the
menu entry is disabled then nothing happens.  If the
entry has a command associated with it then the result of that
command is returned as the result of the \fBinvoke\fR widget
command.  Otherwise the result is an empty string.  Note:  invoking
a menu entry does not automatically unpost the menu;  the default
bindings normally take care of this before invoking the \fBinvoke\fR
widget command.

.TP
\fIpathName \fBpost \fIx y\fR ?\fIindex\fR?
.
Arrange for the menu to be displayed on the screen at the root-window
coordinates given by \fIx\fR and \fIy\fR.  If an index is specified
the menu will be located so that the entry with that index is
displayed at the point.  These coordinates are adjusted if necessary to
guarantee that the entire menu is visible on the screen.  This command
normally returns an empty string.  If the \fB\-postcommand\fR option
has been specified, then its value is executed as a Tcl script before
posting the menu and the result of that script is returned as the
result of the \fBpost\fR widget command.  If an error returns while
executing the command, then the error is returned without posting the
menu.

.TP
\fIpathName \fBpostcascade \fIindex\fR
.
Posts the submenu associated with the cascade entry given by
\fIindex\fR, and unposts any previously posted submenu.
If \fIindex\fR does not correspond to a cascade entry,
or if \fIpathName\fR is not posted,
the command has no effect except to unpost any currently posted
submenu.

.TP
\fIpathName \fBtype \fIindex\fR
.
Returns the type of the menu entry given by \fIindex\fR.
This is the \fItype\fR argument passed to the \fBadd\fR or \fBinsert\fR widget
command when the entry was created, such as \fBcommand\fR
or \fBseparator\fR, or \fBtearoff\fR for a tear-off entry.

.TP
\fIpathName \fBunpost\fR
.
Unmap the window so that it is no longer displayed.  If a
lower-level cascaded menu is posted, unpost that menu.  Returns an
empty string. This subcommand does not work on Windows and the
Macintosh, as those platforms have their own way of unposting menus.

.TP
\fIpathName \fBxposition \fIindex\fR
.
Returns a decimal string giving the x-coordinate within the menu
window of the leftmost pixel in the entry specified by \fIindex\fR.

.TP
\fIpathName \fByposition \fIindex\fR
.
Returns a decimal string giving the y-coordinate within the menu
window of the topmost pixel in the entry specified by \fIindex\fR.
.SH "MENU ENTRY OPTIONS"
The following options are allowed on menu entries. Most options are not
supported by all entry types.

.TP
\fB\-activebackground \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fB\-activebackground\fR option for the overall menu is used.
If the \fBtk_strictMotif\fR variable has been set to request strict
Motif compliance, then this option is ignored and the \fB\-background\fR
option is used in its place.
This option is not available for separator or tear-off entries.

.TP
\fB\-activeforeground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is active.
If this option is specified as an empty string (the default), then the
\fB\-activeforeground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.

.TP
\fB\-accelerator \fIvalue\fR
.
Specifies a string to display at the right side of the menu entry.
Normally describes an accelerator keystroke sequence that may be
used to invoke the same function as the menu entry. This is a display
option, it does not actually set the corresponding binding (which can
be achieved using the \fBbind\fR command). This option is not available
for separator or tear-off entries.

.TP
\fB\-background \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is in the normal state (neither active nor disabled).

If this option is specified as an empty string (the default), then the
\fB\-background\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.

.TP
\fB\-bitmap \fIvalue\fR
.
Specifies a bitmap to display in the menu instead of a textual
label, in any of the forms accepted by \fBTk_GetBitmap\fR.
This option overrides the \fB\-label\fR option
(as controlled by the \fB\-compound\fR option)
but may be reset
to an empty string to enable a textual label to be displayed.
If a \fB\-image\fR option has been specified, it overrides
\fB\-bitmap\fR.
This option is not available for separator or tear-off entries.

.TP
\fB\-columnbreak \fIvalue\fR
.
When this option is zero, the entry appears below the previous entry. When
this option is one, the entry appears at the top of a new column in the
menu.
This option is ignored on Aqua/Mac OS X, where menus are always a single
column.

.TP
\fB\-command \fIvalue\fR
.
Specifies a Tcl command to execute when the menu entry is invoked.
Not available for separator or tear-off entries.

.TP
\fB\-compound \fIvalue\fR
.
Specifies whether the menu entry should display both an image and text,
and if so, where the image should be placed relative to the text.
Valid values for this option are \fBbottom\fR, \fBcenter\fR,
\fBleft\fR, \fBnone\fR, \fBright\fR and \fBtop\fR.  The default value
is \fBnone\fR, meaning that the button will display either an image or
text, depending on the values of the \fB\-image\fR and \fB\-bitmap\fR
options.

.TP
\fB\-font \fIvalue\fR
.
Specifies the font to use when drawing the label or accelerator
string in this entry.
If this option is specified as an empty string (the default) then
the \fB\-font\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.

.TP
\fB\-foreground \fIvalue\fR
.
Specifies a foreground color to use for displaying this entry when it
is in the normal state (neither active nor disabled).

If this option is specified as an empty string (the default), then the
\fB\-foreground\fR option for the overall menu is used.
This option is not available for separator or tear-off entries.

.TP
\fB\-hidemargin \fIvalue\fR
.
Specifies whether the standard margins should be drawn for this menu
entry. This is useful when creating palette with images in them, i.e.,
color palettes, pattern palettes, etc. 1 indicates that the margin for
the entry is hidden; 0 means that the margin is used.

.TP
\fB\-image \fIvalue\fR
.
Specifies an image to display in the menu instead of a text string
or bitmap.
The image must have been created by some previous invocation of
\fBimage create\fR.
This option overrides the \fB\-label\fR and \fB\-bitmap\fR options
(as controlled by the \fB\-compound\fR option)
but may be reset to an empty string to enable a textual or
bitmap label to be displayed.
This option is not available for separator or tear-off entries.

.TP
\fB\-indicatoron \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
\fIValue\fR is a boolean that determines whether or not the
indicator should be displayed.

.TP
\fB\-label \fIvalue\fR
.
Specifies a string to display as an identifying label in the menu
entry.  Not available for separator or tear-off entries.

.TP
\fB\-menu \fIvalue\fR
.
Available only for cascade entries.  Specifies the path name of
the submenu associated with this entry.
The submenu must be a child of the menu.

.TP
\fB\-offvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is
deselected.

.TP
\fB\-onvalue \fIvalue\fR
.
Available only for checkbutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.

.TP
\fB\-selectcolor \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies the color to display in the indicator when the entry is
selected.
If the value is an empty string (the default) then the \fB\-selectcolor\fR
option for the menu determines the indicator color.

.TP
\fB\-selectimage \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.
Specifies an image to display in the entry (in place of
the \fB\-image\fR option) when it is selected.
\fIValue\fR is the name of an image, which must have been created
by some previous invocation of \fBimage create\fR.
This option is ignored unless the \fB\-image\fR option has
been specified.

.TP
\fB\-state \fIvalue\fR
.
Specifies one of three states for the entry:  \fBnormal\fR, \fBactive\fR,
or \fBdisabled\fR.  In normal state the entry is displayed using the
\fB\-foreground\fR option for the menu and the \fB\-background\fR
option from the entry or the menu.
The active state is typically used when the pointer is over the entry.
In active state the entry is displayed using the \fB\-activeforeground\fR
option for the menu along with the \fB\-activebackground\fR option from
the entry.  Disabled state means that the entry
should be insensitive:  the default bindings will refuse to activate
or invoke the entry.
In this state the entry is displayed according to the
\fB\-disabledforeground\fR option for the menu and the
\fB\-background\fR option from the entry.
This option is not available for separator entries.

.TP
\fB\-underline \fIvalue\fR
.
Specifies the integer index of a character to underline in the entry.
This option is also queried by the default bindings and used to
implement keyboard traversal.
0 corresponds to the first character of the text displayed in the entry,
1 to the next character, and so on.
If a bitmap or image is displayed in the entry then this option is ignored.
This option is not available for separator or tear-off entries.

.TP
\fB\-value \fIvalue\fR
.
Available only for radiobutton entries.  Specifies the value to
store in the entry's associated variable when the entry is selected.
If an empty string is specified, then the \fB\-label\fR option
for the entry as the value to store in the variable.

.TP
\fB\-variable \fIvalue\fR
.
Available only for checkbutton and radiobutton entries.  Specifies
the name of a global variable to set when the entry is selected.
For checkbutton entries the variable is also set when the entry
is deselected.  For radiobutton entries, changing the variable







|








<
|
<



<
|
<



<
|
<

<
|
<







<
|
<
<
|
<
|
|
<
>
|
<



<
|
<










>









>










>







>









>















>








>







>













>





>









>












>














>









>







>







>





>








>




|
|





>




|



>









>





>
|


>












>






|

>





>










>








>





>
|


>







>












>






>





>






>






>





>








>










>

















>










>







>







300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315

316

317
318
319

320

321
322
323

324

325

326

327
328
329
330
331
332
333

334


335

336
337

338
339

340
341
342

343

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
.SH "WIDGET COMMAND"
.PP
The \fBmenu\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Many of the widget commands for a menu take as one argument an
indicator of which entry of the menu to operate on. These
indicators are called \fIindex\fRes and may be specified in
any of the following forms:

.IP \fBactive\fR 12

Indicates the entry that is currently active.  If no entry is
active then this form is equivalent to \fBnone\fR.  This form may
not be abbreviated.

.IP \fBend\fR 12

Indicates the bottommost entry in the menu.  If there are no
entries in the menu then this form is equivalent to \fBnone\fR.
This form may not be abbreviated.

.IP \fBlast\fR 12

Same as \fBend\fR.

.IP \fBnone\fR 12

Indicates
.QW "no entry at all" ;
this is used most commonly with
the \fBactivate\fR option to deactivate all the entries in the
menu.  In most cases the specification of \fBnone\fR causes
nothing to happen in the widget command.
This form may not be abbreviated.

.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 \fBnone\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 \fIpattern\fR 12

If the index does not satisfy one of the above forms then this
form is used.  \fIPattern\fR is pattern-matched against the label of
each entry in the menu, in order from the top down, until a
matching entry is found.  The rules of \fBstring match\fR
are used.
.PP
If the index could match more than one of the above forms, then
the form earlier in the above list takes precedence.
.PP
The following widget commands are possible for menu widgets:
.\" METHOD: activate
.TP
\fIpathName \fBactivate \fIindex\fR
.
Change the state of the entry indicated by \fIindex\fR to \fBactive\fR
and redisplay it using its active colors.
Any previously-active entry is deactivated.  If \fIindex\fR
is specified as \fBnone\fR, or if the specified entry is
disabled, then the menu ends up with no active entry.
Returns an empty string.
.\" METHOD: add
.TP
\fIpathName \fBadd \fItype \fR?\fIoption value option value ...\fR?
.
Add a new entry to the bottom of the menu.  The new entry's type
is given by \fItype\fR and must be one of \fBcascade\fR,
\fBcheckbutton\fR, \fBcommand\fR, \fBradiobutton\fR, or \fBseparator\fR,
or a unique abbreviation of one of the above.  If additional arguments
are present, they specify the options listed in the \fBMENU ENTRY OPTIONS\fR
section below.
The \fBadd\fR widget command returns an empty string.
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.\" METHOD: clone
.TP
\fIpathName \fBclone \fInewPathname\fR ?\fIcloneType\fR?
.
Makes a clone of the current menu named \fInewPathName\fR. This clone
is a menu in its own right, but any changes to the clone are
propagated to the original menu and vice versa. \fIcloneType\fR can be
\fBnormal\fR, \fBmenubar\fR, or \fBtearoff\fR. Should not normally be
called outside of the Tk library. See the \fBCLONES\fR section for
more information.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).  If \fIoption\fR is specified
with no \fIvalue\fR, then the command returns a list describing the
one named option (this list will be identical to the corresponding
sublist of the value returned if no \fIoption\fR is specified).  If
one or more \fIoption\-value\fR pairs are specified, then the command
modifies the given widget option(s) to have the given value(s);  in
this case the command returns an empty string.
\fIOption\fR may have any of the values accepted by the \fBmenu\fR
command.
.\" METHOD: delete
.TP
\fIpathName \fBdelete \fIindex1\fR ?\fIindex2\fR?
.
Delete all of the menu entries between \fIindex1\fR and
\fIindex2\fR inclusive.
If \fIindex2\fR is omitted then it defaults to \fIindex1\fR.
Attempts to delete a tear-off menu entry are ignored (instead, you
should change the \fB\-tearoff\fR option to remove the tear-off entry).
.\" METHOD: entrycget
.TP
\fIpathName \fBentrycget \fIindex option\fR
.
Returns the current value of a configuration option for
the entry given by \fIindex\fR.
\fIOption\fR may have any of the names described in the
\fBMENU ENTRY OPTIONS\fR section below.
.\" METHOD: entryconfigure
.TP
\fIpathName \fBentryconfigure \fIindex \fR?\fIoptions...\fR?
.
This command is similar to the \fBconfigure\fR command, except that
it applies to the options for an individual entry, whereas \fBconfigure\fR
applies to the options for the menu as a whole.
\fIOptions\fR may have any of the values described in the
\fBMENU ENTRY OPTIONS\fR
section below.  If \fIoptions\fR are specified, options are
modified as indicated in the command and the command returns an empty string.
If no \fIoptions\fR are specified, returns a list describing
the current options for entry \fIindex\fR (see \fBTk_ConfigureInfo\fR for
information on the format of this list).
.\" METHOD: index
.TP
\fIpathName \fBindex \fIindex\fR
.
Returns the numerical index corresponding to \fIindex\fR, or
\fBnone\fR if \fIindex\fR was specified as \fBnone\fR.
.\" METHOD: insert
.TP
\fIpathName \fBinsert \fIindex type \fR?\fIoption value option value ...\fR?
.
Same as the \fBadd\fR widget command except that it inserts the new
entry just before the entry given by \fIindex\fR, instead of appending
to the end of the menu.  The \fItype\fR, \fIoption\fR, and \fIvalue\fR
arguments have the same interpretation as for the \fBadd\fR widget
command.  It is not possible to insert new menu entries before the
tear-off entry, if the menu has one.
.\" METHOD: invoke
.TP
\fIpathName \fBinvoke \fIindex\fR
.
Invoke the action of the menu entry.  See the sections on the
individual entries above for details on what happens.  If the
menu entry is disabled then nothing happens.  If the
entry has a command associated with it then the result of that
command is returned as the result of the \fBinvoke\fR widget
command.  Otherwise the result is an empty string.  Note:  invoking
a menu entry does not automatically unpost the menu;  the default
bindings normally take care of this before invoking the \fBinvoke\fR
widget command.
.\" METHOD: post
.TP
\fIpathName \fBpost \fIx y\fR ?\fIindex\fR?
.
Arrange for the menu to be displayed on the screen at the root-window
coordinates given by \fIx\fR and \fIy\fR.  If an index is specified
the menu will be located so that the entry with that index is
displayed at the point.  These coordinates are adjusted if necessary to
guarantee that the entire menu is visible on the screen.  This command
normally returns an empty string.  If the \fB\-postcommand\fR option
has been specified, then its value is executed as a Tcl script before
posting the menu and the result of that script is returned as the
result of the \fBpost\fR widget command.  If an error returns while
executing the command, then the error is returned without posting the
menu.
.\" METHOD: postcascade
.TP
\fIpathName \fBpostcascade \fIindex\fR
.
Posts the submenu associated with the cascade entry given by
\fIindex\fR, and unposts any previously posted submenu.
If \fIindex\fR does not correspond to a cascade entry,
or if \fIpathName\fR is not posted,
the command has no effect except to unpost any currently posted
submenu.
.\" METHOD: type
.TP
\fIpathName \fBtype \fIindex\fR
.
Returns the type of the menu entry given by \fIindex\fR.
This is the \fItype\fR argument passed to the \fBadd\fR or \fBinsert\fR widget
command when the entry was created, such as \fBcommand\fR
or \fBseparator\fR, or \fBtearoff\fR for a tear-off entry.
.\" METHOD: unpost
.TP
\fIpathName \fBunpost\fR
.
Unmap the window so that it is no longer displayed.  If a
lower-level cascaded menu is posted, unpost that menu.  Returns an
empty string. This subcommand does not work on Windows and the
Macintosh, as those platforms have their own way of unposting menus.
.\" METHOD: xposition
.TP
\fIpathName \fBxposition \fIindex\fR
.
Returns a decimal string giving the x-coordinate within the menu
window of the leftmost pixel in the entry specified by \fIindex\fR.
.\" METHOD: yposition
.TP
\fIpathName \fByposition \fIindex\fR
.
Returns a decimal string giving the y-coordinate within the menu
window of the topmost pixel in the entry specified by \fIindex\fR.
.SH "MENU ENTRY OPTIONS"
The following options are allowed on menu entries. Most options are not
supported by all entry types.
.\" OPTION: -activebackground
.TP
\fB\-activebackground \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is active. 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.
This option is not available for separator or tear-off entries.
.\" OPTION: -accelerator
.TP
\fB\-accelerator \fIvalue\fR
.
Specifies a string to display at the right side of the menu entry.
Normally describes an accelerator keystroke sequence that may be
used to invoke the same function as the menu entry. This is a display
option, it does not actually set the corresponding binding (which can
be achieved using the \fBbind\fR command). This option is not available
for separator or tear-off entries.
.\" OPTION: -background
.TP
\fB\-background \fIvalue\fR
.
Specifies a background color to use for displaying this entry when it
is in the normal state (neither active nor disabled).
This option is ignored on Aqua/macOS.
If 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
Changes to doc/menubar.n.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_menuBar, tk_bindForTraversal \- Obsolete support for menu bars
.SH SYNOPSIS
\fBtk_menuBar \fIframe \fR?\fImenu menu ...\fR?
.sp
\fBtk_bindForTraversal \fIarg ... \fR
.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







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk_menuBar, tk_bindForTraversal \- Obsolete support for menu bars
.SH SYNOPSIS
\fBtk_menuBar \fIframe \fR?\fImenu menu ...\fR?
.sp
\fBtk_bindForTraversal \fIarg arg ... \fR
.BE
.SH DESCRIPTION
.PP
These procedures were used in Tk 3.6 and earlier releases to help
manage pulldown menus and to implement keyboard traversal of menus.
In Tk 4.0 and later releases they are no
longer needed.  Stubs for these procedures have been retained for
Changes to doc/menubutton.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.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.
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
be posted just underneath the menubutton.  If the mouse is moved over
the menu before releasing the mouse button, the button release
causes the underlying menu entry to be invoked.  When the button
is released, the menu is unposted.
.PP
Menubuttons are used to construct a \fBtk_optionMenu\fR, which is the
preferred mechanism for allowing a user to select one item from a list
on Mac OS X.
.PP
Menubuttons were also typically organized into groups called menu bars
that allow scanning:
if the mouse button is pressed over one menubutton (causing it
to post its menu) and the mouse is moved over another menubutton
in the same menu bar without releasing the mouse button, then the
menu of the first menubutton is unposted and the menu of the







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
be posted just underneath the menubutton.  If the mouse is moved over
the menu before releasing the mouse button, the button release
causes the underlying menu entry to be invoked.  When the button
is released, the menu is unposted.
.PP
Menubuttons are used to construct a \fBtk_optionMenu\fR, which is the
preferred mechanism for allowing a user to select one item from a list
on macOS.
.PP
Menubuttons were also typically organized into groups called menu bars
that allow scanning:
if the mouse button is pressed over one menubutton (causing it
to post its menu) and the mouse is moved over another menubutton
in the same menu bar without releasing the mouse button, then the
menu of the first menubutton is unposted and the menu of the
118
119
120
121
122
123
124

125
126
127
128
129
130
131

132
133
134
135
136
137
138
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.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
.SH "WIDGET COMMAND"
.PP
The \fBmessage\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.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
.







|







102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
.SH "WIDGET COMMAND"
.PP
The \fBmessage\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for message widgets:
.TP
\fIpathName \fBcget \fIoption\fR
.
Changes to doc/messageBox.n.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.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 ,







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.PP
The following option-value pairs are supported:
.TP
\fB\-command\fR \fIstring\fR
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog. The actual command consists of \fIstring\fR followed by a space
and the name of the button clicked by the user to close the dialog. This
is only available on macOS.
.TP
\fB\-default\fR \fIname\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
\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
.







|
<
|














|







62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
\fB\-parent\fR \fIwindow\fR
.
Makes \fIwindow\fR the logical parent of the message box. The message
box is displayed on top of its parent window.
.TP
\fB\-title\fR \fItitleString\fR
.
Specifies a string to display as the title of the message box. The

default value is an empty string.
.TP
\fB\-type\fR \fIpredefinedType\fR
.
Arranges for a predefined set of buttons to be displayed. The
following values are possible for \fIpredefinedType\fR:
.RS
.TP 18
\fBabortretryignore\fR
.
Displays three buttons whose symbolic names are \fBabort\fR,
\fBretry\fR and \fBignore\fR.
.TP 18
\fBok\fR
.
Displays one button whose symbolic name is \fBok\fR. This is the default.
.TP 18
\fBokcancel\fR
.
Displays two buttons whose symbolic names are \fBok\fR and \fBcancel\fR.
.TP 18
\fBretrycancel\fR
.
Changes to doc/options.n.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
definition of active elements.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
This option is typically only available in widgets displaying more
than one element at a time (e.g. menus but not buttons).
.OP \-activeforeground activeForeground Background
Specifies foreground color to use when drawing active elements.
See above for definition of active elements.
.OP \-activerelief activeRelief Relief
Specifies the 3-D effect desired for the active item of the widget.
See the \fB-relief\fR option for details.
.OP \-anchor anchor Anchor
Specifies how the information in a widget (e.g. text or a bitmap)
is to be displayed in the widget.
Must be one of the values \fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
For example, \fBnw\fR means display the information such that its
top-left corner is at the top-left corner of the widget.







<
<
<







54
55
56
57
58
59
60



61
62
63
64
65
66
67
definition of active elements.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
This option is typically only available in widgets displaying more
than one element at a time (e.g. menus but not buttons).
.OP \-activeforeground activeForeground Background
Specifies foreground color to use when drawing active elements.
See above for definition of active elements.



.OP \-anchor anchor Anchor
Specifies how the information in a widget (e.g. text or a bitmap)
is to be displayed in the widget.
Must be one of the values \fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR.
For example, \fBnw\fR means display the information such that its
top-left corner is at the top-left corner of the widget.
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
all the time.
.OP \-insertontime insertOnTime OnTime
Specifies a non-negative integer value indicating the number of
milliseconds the insertion cursor should remain
.QW on
in each blink cycle.
.OP \-insertwidth insertWidth InsertWidth
Specifies a  value indicating the total width of the insertion cursor.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If a border has been specified for the insertion
cursor (using the \fB\-insertborderwidth\fR option), the border
will be drawn inside the width specified by the \fB\-insertwidth\fR
option.
.OP \-jump jump Jump
For widgets with a slider that can be dragged to adjust a value,







|







162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
all the time.
.OP \-insertontime insertOnTime OnTime
Specifies a non-negative integer value indicating the number of
milliseconds the insertion cursor should remain
.QW on
in each blink cycle.
.OP \-insertwidth insertWidth InsertWidth
Specifies a non-negative value indicating the total width of the insertion cursor.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If a border has been specified for the insertion
cursor (using the \fB\-insertborderwidth\fR option), the border
will be drawn inside the width specified by the \fB\-insertwidth\fR
option.
.OP \-jump jump Jump
For widgets with a slider that can be dragged to adjust a value,
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
this amount to the height it would normally need (as determined by
the height of the things displayed in the widget);  if the geometry
manager can satisfy this request, the widget will end up with extra
internal space above and/or below what it displays inside.
Most widgets only use this option for padding text:  if they are
displaying a bitmap or image, then they usually ignore padding
options.
.OP \-placeholder placeHolder PlaceHolder
Specifies a help text string to display if no text is otherwise displayed,
that is when the widget is empty. The placeholder text is displayed using
the values of the \fB\-font\fR and \fB\-justify\fR options.
.OP \-placeholderforeground placeholderForeground PlaceholderForeground
Specifies the foreground color to use when the placeholder text is
displayed. The default color is platform-specific.
.OP \-relief relief Relief
Specifies the 3-D effect desired for the widget.  Acceptable
values are \fBraised\fR, \fBsunken\fR, \fBflat\fR, \fBridge\fR,
\fBsolid\fR, and \fBgroove\fR.
The value
indicates how the interior of the widget should appear relative
to its exterior;  for example, \fBraised\fR means the interior of







<
<
<
<
<
<
<







217
218
219
220
221
222
223







224
225
226
227
228
229
230
this amount to the height it would normally need (as determined by
the height of the things displayed in the widget);  if the geometry
manager can satisfy this request, the widget will end up with extra
internal space above and/or below what it displays inside.
Most widgets only use this option for padding text:  if they are
displaying a bitmap or image, then they usually ignore padding
options.







.OP \-relief relief Relief
Specifies the 3-D effect desired for the widget.  Acceptable
values are \fBraised\fR, \fBsunken\fR, \fBflat\fR, \fBridge\fR,
\fBsolid\fR, and \fBgroove\fR.
The value
indicates how the interior of the widget should appear relative
to its exterior;  for example, \fBraised\fR means the interior of
Changes to doc/pack.n.
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
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"







<
<
<
<
<
<
<
<







125
126
127
128
129
130
131








132
133
134
135
136
137
138
than receiving default values.
.RE
.TP
\fBpack forget \fIwindow \fR?\fIwindow ...\fR?
Removes each of the \fIwindow\fRs from the packing order for its
container and unmaps their windows.
The content will no longer be managed by the packer.








.TP
\fBpack info \fIwindow\fR
Returns a list whose elements are the current configuration state of
the window given by \fIwindow\fR in the same option-value form that
might be specified to \fBpack configure\fR.
The first two elements of the list are
.QW "\fB\-in \fIcontainer\fR"
154
155
156
157
158
159
160
161
162
163
164
165

166
167
168
169

170
171
172
173
174
175
176
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.







|




>

|

|
>







146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
disabled for \fIcontainer\fR.
In either of these cases an empty string is returned.
If \fIboolean\fR is omitted then the command returns \fB0\fR or
\fB1\fR to indicate whether propagation is currently enabled
for \fIcontainer\fR.
Propagation is enabled by default.
.TP
\fBpack slaves \fIwindow\fR
Returns a list of all of the content windows in the packing order for \fIwindow\fR.
The order of the content windows in the list is the same as their order in
the packing order.
If \fIwindow\fR has no content then an empty string is returned.
.VS "TIP 581"
.TP
\fBpack content \fIwindow\fR
.
Synonym for \fBpack slaves \fIwindow\fR.
.VE "TIP 581"
.SH "THE PACKER ALGORITHM"
.PP
For each container the packer maintains an ordered list of content
windows called the \fIpacking list\fR.
The \fB\-in\fR, \fB\-after\fR, and \fB\-before\fR configuration
options are used to specify the container for each content and the content's
position in the packing list.
Changes to doc/panedwindow.n.
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
.SH "WIDGET COMMAND"
.PP
The \fBpanedwindow\fR command creates a new Tcl command whose name is
the same as the path name of the panedwindow's window.  This command
may be used to invoke various operations on the widget.  It has the
following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the panedwindow widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for panedwindow widgets:
.TP
\fIpathName \fBadd \fIwindow \fR?\fIwindow ...\fR? ?\fIoption value ...\fR?







|







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
.SH "WIDGET COMMAND"
.PP
The \fBpanedwindow\fR command creates a new Tcl command whose name is
the same as the path name of the panedwindow's window.  This command
may be used to invoke various operations on the widget.  It has the
following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as
the panedwindow widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for panedwindow widgets:
.TP
\fIpathName \fBadd \fIwindow \fR?\fIwindow ...\fR? ?\fIoption value ...\fR?
Changes to doc/photo.n.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

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

67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
\fBimage create photo \fR?\fIname\fR? ?\fIoptions\fR?

\fIimageName \fBblank\fR
\fIimageName \fBcget \fIoption\fR
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
\fIimageName \fBcopy \fIsourceImage\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBget \fIx y\fR ?\fIoption\fR?
\fIimageName \fBput \fIdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBread \fIfilename\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBredither\fR
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg ...\fR?
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
A photo is an image whose pixels can display any color with a varying
degree of transparency (the alpha channel). A photo image is stored
internally in full color (32 bits per pixel), and is displayed using
dithering if necessary.  Image data for a photo image can be obtained
from a file or a string, or it can be supplied from C code through a
procedural interface.  At present, only
.VS 8.6
PNG,
.VE 8.6

GIF and PPM/PGM formats are supported, but an interface exists to
allow additional image file formats to be added easily.  A photo image
is (semi)transparent if the image data it was obtained from had
transparency informaton. In regions where no image data has been
supplied, it is fully transparent. Transparency may also be modified
with the \fBtransparency set\fR subcommand.
.SH "CREATING PHOTOS"
.PP
Like all images, photos are created using the \fBimage create\fR
command.
Photos support the following \fIoptions\fR:
.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the image as a string.
.VS 8.7
The string should
contain data in the default list-of-lists form,
.VE 8.7
binary data or, for some formats, base64-encoded data (this is
currently guaranteed to be supported for PNG and GIF images). The

format of the string must be one of those for which there is an image
file format handler that will accept string data.  If both the
\fB\-data\fR and \fB\-file\fR options are specified, the \fB\-file\fR
option takes precedence.
.TP
\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?}
.
Specifies the name of the file format for the data specified with the
\fB\-data\fR or \fB\-file\fR option and optional arguments passed to
the format handler. Note: the value of this option must be a Tcl list.
This means that the braces may be omitted if the argument has only one
word. Also, instead of braces, double quotes may be used for quoting.
.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file that is to be read to supply data
for the photo image.  The file format must be one of those for which
there is an image file format handler that can read data.
.TP







|



|





|
|
|
|
|
|



>
|
|
<
|
|
|








|
<
<
<
<
|

>
|
|
|
|

|


|
<
<
<







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

49
50
51
52
53
54
55
56
57
58
59
60




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



73
74
75
76
77
78
79
\fBimage create photo \fR?\fIname\fR? ?\fIoptions\fR?

\fIimageName \fBblank\fR
\fIimageName \fBcget \fIoption\fR
\fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
\fIimageName \fBcopy \fIsourceImage\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBget \fIx y\fR
\fIimageName \fBput \fIdata\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBread \fIfilename\fR ?\fIoption value(s) ...\fR?
\fIimageName \fBredither\fR
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg arg ...\fR?
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.fi
.BE
.SH DESCRIPTION
.PP
A photo is an image whose pixels can display any color or be
transparent.  A photo image is stored internally in full color (32
bits per pixel), and is displayed using dithering if necessary.  Image
data for a photo image can be obtained from a file or a string, or it
can be supplied from
C code through a procedural interface.  At present, only
.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 transparent

in regions where no image data has been supplied
or where it has been set transparent by the \fBtransparency set\fR
subcommand.
.SH "CREATING PHOTOS"
.PP
Like all images, photos are created using the \fBimage create\fR
command.
Photos support the following \fIoptions\fR:
.TP
\fB\-data \fIstring\fR
.
Specifies the contents of the image as a string.  The string should




contain binary data or, for some formats, base64-encoded data (this is
currently guaranteed to be supported for 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 \fIformat-name\fR
.
Specifies the name of the file format for the data specified with the
\fB\-data\fR or \fB\-file\fR option.



.TP
\fB\-file \fIname\fR
.
\fIname\fR gives the name of a file that is to be read to supply data
for the photo image.  The file format must be one of those for which
there is an image file format handler that can read data.
.TP
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
.PP
When a photo image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Those options that write data to the image generally expand the size
of the image, if necessary, to accommodate the data written to the
image, unless the user has specified non-zero values for the







|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
.PP
When a photo image is created, Tk also creates a new command
whose name is the same as the image.
This command may be used to invoke various operations
on the image.
It has the following general form:
.CS
\fIimageName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.PP
Those options that write data to the image generally expand the size
of the image, if necessary, to accommodate the data written to the
image, unless the user has specified non-zero values for the
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274

275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309

310
311



312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
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







|
<
<
<
<
<
<
|








|

|
|
|
|
|
<
|
|
|

|
<
<
<
<
>
















<

|



|
<
<
<
<




<
|


>
|
|
>
>
>
|


|

|
<



<
<
<








<
<
|














|

|
<



<
<
<







229
230
231
232
233
234
235
236






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

253
254
255
256
257




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

275
276
277
278
279
280




281
282
283
284

285
286
287
288
289
290
291
292
293
294
295
296
297
298
299

300
301
302



303
304
305
306
307
308
309
310


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

329
330
331



332
333
334
335
336
337
338
is set, the old contents of the destination image are discarded and
the source image is used as-is.  The default compositing rule is
\fIoverlay\fR.
.RE
.TP
\fIimageName \fBdata\fR ?\fIoption value(s) ...\fR?
.
Returns image data in the form of a string. The following options






may be specified:
.RS
.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.TP
\fB\-format\fI format-name\fR
.
Specifies the name of the image file format handler to be used.
Specifically, this subcommand searches
for the first handler whose name matches an initial substring of
\fIformat-name\fR and which has the capability to write a string
containing this image data.

If this option is not given, this subcommand uses a format that
consists of a list (one element per row) of lists (one element per
pixel/column) of colors in
.QW \fB#\fIrrggbb\fR
format (where \fIrr\fR is a pair of hexadecimal digits for the red




channel, \fIgg\fR for green, and \fIbb\fR for blue).
.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be returned.
If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
diagonally opposite corners of the rectangular region, including x1,y1
and excluding x2,y2.  The default, if this option is not given, is the
whole image.
.TP
\fB\-grayscale\fR
.
If this options is specified, the data will not contain color
information. All pixel data will be transformed into grayscale.
.RE

.TP
\fIimageName \fBget\fR \fIx y\fR
.
Returns the color of the pixel at coordinates (\fIx\fR,\fIy\fR) in the
image as a list of three integers between 0 and 255, representing the
red, green and blue components respectively.




.TP
\fIimageName \fBput\fR \fIdata\fR ?\fIoption value(s) ...\fR?
.
Sets pixels in \fI imageName\fR to the data specified in \fIdata\fR.

This command first searches the list of image file format handlers for
a handler that can interpret the data in \fIdata\fR, and then reads
the image encoded within into \fIimageName\fR (the destination image).
If \fIdata\fR does not match any known format, an attempt to interpret
it as a (top-to-bottom) list of scan-lines is made, with each
scan-line being a (left-to-right) list of pixel colors (see
\fBTk_GetColor\fR for a description of valid colors.)  Every scan-line
must be of the same length.  Note that when \fIdata\fR is a single
color name, you are instructing Tk to fill a rectangular region with
that color.  The following options may be specified:
.RS
.TP
\fB\-format \fIformat-name\fR
.
Specifies the format of the image data in \fIdata\fR.

Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.



.TP
\fB\-to \fIx1 y1\fR ?\fIx2 y2\fR?
.
Specifies the coordinates of the top-left corner (\fIx1\fR,\fIy1\fR)
of the region of \fIimageName\fR into which the image data will be
copied.  The default position is (0,0).  If \fIx2\fR,\fIy2\fR is given
and \fIdata\fR is not large enough to cover the rectangle specified by
this option, the image data extracted will be tiled so it covers the


entire destination rectangle.  Note that if \fIdata\fR specifies a
single color value, then a region extending to the bottom-right corner
represented by (\fIx2\fR,\fIy2\fR) will be filled with that color.
.RE
.TP
\fIimageName \fBread\fR \fIfilename\fR ?\fIoption value(s) ...\fR?
.
Reads image data from the file named \fIfilename\fR into the image.
This command first searches the list of
image file format handlers for a handler that can interpret the data
in \fIfilename\fR, and then reads the image in \fIfilename\fR into
\fIimageName\fR (the destination image).  The following options may be
specified:
.RS
.TP
\fB\-format \fIformat-name\fR
.
Specifies the format of the image data in \fIfilename\fR.

Specifically, only image file format handlers whose names begin with
\fIformat-name\fR will be used while searching for an image data
format handler to read the data.



.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular sub-region of the image file data to be copied
to the destination image.  If only \fIx1\fR and \fIy1\fR are
specified, the region extends from (\fIx1,y1\fR) to the bottom-right
corner of the image in the image file.  If all four coordinates are
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
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







|




<

|

|
<
<
<
|
<

|

|
<
<
|
<
<
<














|


<
|
|
|
|
|
|
<
<
<







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

374
375
376
377



378

379
380
381
382


383



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

401
402
403
404
405
406



407
408
409
410
411
412
413
quantization errors from one pixel to its neighbors.
If the image data for \fIimageName\fR is supplied in pieces, the
dithered image may not be exactly correct.  Normally the difference is
not noticeable, but if it is a problem, this command can be used to
recalculate the dithered image in each window where the image is
displayed.
.TP
\fIimageName \fBtransparency \fIsubcommand \fR?\fIarg arg ...\fR?
.
Allows examination and manipulation of the transparency information in
the photo image.  Several subcommands are available:
.RS

.TP
\fIimageName \fBtransparency get \fIx y\fR
.
Returns a boolean indicating if the pixel at (\fIx\fR,\fIy\fR) is



transparent.

.TP
\fIimageName \fBtransparency set \fIx y boolean\fR
.
Makes the pixel at (\fIx\fR,\fIy\fR) transparent if \fIboolean\fR is


true, and makes that pixel opaque otherwise.



.RE
.TP
\fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR?
.
Writes image data from \fIimageName\fR to a file named \fIfilename\fR.
The following options may be specified:
.RS
.TP
\fB\-background\fI color\fR
.
If the color is specified, the data will not contain any transparency
information. In all transparent pixels the color will be replaced by
the specified color.
.TP
\fB\-format\fI format-name\fR
.
Specifies the name of the image file format handler to be used to

write the data to the file.  Specifically, this subcommand searches
for the first handler whose name matches an initial substring of
\fIformat-name\fR and which has the capability to write an image
file.  If this option is not given, 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.



.TP
\fB\-from \fIx1 y1 x2 y2\fR
.
Specifies a rectangular region of \fIimageName\fR to be written to the
image file.  If only \fIx1\fR and \fIy1\fR are specified, the region
extends from \fI(x1,y1)\fR to the bottom-right corner of
\fIimageName\fR.  If all four coordinates are given, they specify
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
.SH "IMAGE FORMATS"
.PP
The photo image code is structured to allow handlers for additional
image file formats to be added easily.  The photo image code maintains
a list of these handlers.  Handlers are added to the list by
registering them with a call to \fBTk_CreatePhotoImageFormat\fR.  The
standard Tk distribution comes with handlers for PPM/PGM, PNG and GIF
formats,
.VS 8.7
as well as the \fBdefault\fR handler to encode/decode image
data in a human readable form.
.VE 8.7
These handlers are automatically registered on initialization.
.PP
When reading an image file or processing string data specified with
the \fB\-data\fR configuration option, the photo image code invokes

each handler in turn until one is found that claims to be able to read
the data in the file or string.  Usually this will find the correct
handler, but if it does not, the user may give a format name with the
\fB\-format\fR option to specify which handler to use.  In this case,
the photo image code will try those handlers whose names begin with
the string specified for the \fB\-format\fR option (the comparison is
case-insensitive).  For example, if the user specifies \fB\-format
gif\fR, then a handler named GIF87 or GIF89 may be invoked, but a
handler named JPEG may not (assuming that such handlers had been
registered).
.PP
When writing image data to a file, the processing of the
\fB\-format\fR option is slightly different: the string value given
for the \fB\-format\fR option must begin with the complete name of the
requested handler, and may contain additional information following
that, which the handler can use, for example, to specify which variant
to use of the formats supported by the handler.
Note that not all image handlers may support writing transparency data
to a file, even where the target image format does.
.VS 8.7
.SS "THE DEFAULT IMAGE HANDLER"
.PP
The \fBdefault\fR image handler cannot be used to read or write data
from/to a file. Its sole purpose is to encode and decode image data in
string form in a clear text, human readable, form. The \fIimageName\fR
\fBdata\fR subcommand uses this handler when no other format is
specified. When reading image data from a string with \fIimageName\fR
\fBput\fR or the \fB-data\fR option, the default handler is treated
as the other handlers.
.PP
Image data in the \fBdefault\fR string format is a (top-to-bottom)
list of scan-lines, with each scan-line being a (left-to-right) list
of pixel data. Every scan-line has the same length. The color
and, optionally, alpha value of each pixel is specified in any of
the forms described in the \fBCOLOR FORMATS\fR section below.
.VE 8.7

.SS "FORMAT SUBOPTIONS"
.PP
.VS 8.6
Image formats may support sub-options, wich ahre specified using
additional words in the value to the \fB\-format\fR option. These
suboptions can affect how image data is read or written to file or
string. The nature and values of these options is up to the format
handler.
The built-in handlers support these suboptions:
.VS 8.7
.TP
\fBdefault \-colorformat\fI formatType\fR
.
The option is allowed when writing image data to a string with
\fIimageName\fR \fBdata\fR. Specifies the format to use for the color
string of each pixel. \fIformatType\fR may be one of: \fBrgb\fR to
encode pixel data in the form \fB#\fIRRGGBB\fR, \fBrgba\fR to encode
pixel data in the form \fB#\fIRRGGBBAA\fR or \fBlist\fR to encode
pixel data as a list with four elements. See \fBCOLOR FORMATS\fR
below for details. The default is \fBrgb\fR.
.VE 8.7
.TP
\fBgif \-index\fI indexValue\fR
.
The option has effect when reading image data from a file. When
parsing a multi-part GIF image, Tk normally only accesses the first
image. By giving the \fB\-index\fR sub-option, the \fIindexValue\fR'th
value may be used instead. The \fIindexValue\fR must be an integer
from 0 up to the number of image parts in the GIF data.
.TP
\fBpng \-alpha\fI alphaValue\fR
.
The option has effect when reading image data from a file. Specifies
an additional alpha filtering for the overall image, which allows the
background on which the image is displayed to show through.  This
usually also has the effect of desaturating the image.  The
\fIalphaValue\fR must be between 0.0 and 1.0.
.TP
\fBsvg \-dpi\fI dpiValue\fB \-scale\fI scaleValue\fB \-scaletowidth \fI width\fB \-scaletoheight\fI height\fR
.
\fIdpiValue\fR is used in conversion between given coordinates and
screen resolution. The value must be greater than 0 and the default
value is 96.
\fIscaleValue\fR is used to scale the resulting image. The value must
be greater than 0 and the default value is 1.
\fIwidth\fR and \fIheight\fR are the width or height that the image
will be adjusted to. Only one parameter among \fB\-scale\fR,
\fB\-scaletowidth\fR and \fB\-scaletoheight\fR can be given at a time
and the aspect ratio of the original image is always preserved.
The svg format supports a wide range of SVG features, but the
full SVG standard is not available, for instance the 'text' feature
is missing and silently ignored when reading the SVG data.
The supported SVG features are:
.
.RS
\fB elements:\fR g, path, rect, circle, ellipse, line, polyline, polygon,
linearGradient, radialGradient, stop, defs, svg, style
.PP
\fB attributes:\fR width, height, viewBox,
preserveAspectRatio with none, xMin, xMid, xMax, yMin, yMid, yMax, slice
.PP
\fB gradient attributes:\fR gradientUnits with objectBoundingBox,
gradientTransform, cx, cy, r fx, fy x1, y1, x2, y2
spreadMethod with pad, reflect or repeat,
xlink:href
.PP
\fB poly attributes: \fR points
.PP
\fB line attributes: \fR x1, y1, x2, y2
.PP
\fB ellipse attributes: \fR cx, cy, rx, ry
.PP
\fB circle attributes: \fR cx, cy, r
.PP
\fB rectangle attributes: \fR x, y, width, height, rx, ry
.PP
\fB path attributes: \fR d with m, M, l, L, h, H, v, V, c, C, s, S, q, Q, t, T, a, A, z, Z
.PP
\fB style attributes: \fR display with none, visibility, hidden, visible,
fill with nonzero and evenodd, opacity, fill-opacity,
stroke, stroke-width, stroke-dasharray, stroke-dashoffset, stroke-opacity,
stroke-linecap with butt, round and square,
stroke-linejoin with miter, round and  bevel, stroke-miterlimit
fill-rule, font-size,
transform with matrix, translate, scale, rotate, skewX and  skewY,
stop-color, stop-opacity, offset, id, class
.RE
.
Currently only SVG images reading and conversion into (pixel-based
format) photos is supported: Tk does not (yet) support bundling photo
images in SVG vector graphics.
.VE 8.6
.VS 8.7
.SH "COLOR FORMATS"
.PP
The default image handler can represent/parse color and alpha values
of a pixel in one of the formats listed below. If a color format does
not contain transparency information, full opacity is assumed.  The
available color formats are:
.IP \(bu 3
The empty string - interpreted as full transparency, the color value
is undefined.
.IP \(bu 3
Any value accepted by \fBTk_GetColor\fR, optionally followed by an
alpha suffix. The alpha suffix may be one of:
.RS
.TP
\fB@\fR\fIA\fR
.
The alpha value \fIA\fR must be a fractional value in the range  0.0
(fully transparent) to 1.0 (fully opaque).
.TP
\fB#\fR\fIX\fR
.
The alpha value \fIX\fR is a hexadecimal digit that specifies an integer
alpha value in the range 0 (fully transparent) to 255 (fully opaque).
This is expanded in range from 4 bits wide to 8 bits wide by
multiplication by 0x11.
.TP
\fB#\fR\fIXX\fR
.
The alpha value \fIXX\fR is passed as two hexadecimal digits that
specify an integer alpha value in the range 0 (fully transparent) to 255
(fully opaque).
.RE
.IP \(bu 3
A Tcl list with three or four integers in the range 0 to 255,
specifying the values for the red, green, blue and (optionally)
alpha channels respectively.
.IP \(bu 3
\fB#\fR\fIRGBA\fR format: a \fB#\fR followed by four hexadecimal digits,
where each digit is the value for the red, green, blue and alpha
channels respectively. Each digit will be expanded internally to
8 bits by multiplication by 0x11.
.IP \(bu 3
\fB#\fR\fIRRGGBBAA\fR format: \fB#\fR followed by eight hexadecimal digits,
where each pair of  subsequent digits represents the value for the red,
green, blue and alpha channels respectively.
.VE 8.7
.SH "COLOR ALLOCATION"
.PP
When a photo image is displayed in a window, the photo image code
allocates colors to use to display the image and dithers the image, if
necessary, to display a reasonable approximation to the image using
the colors that are available.  The colors are allocated as a color
cube, that is, the number of colors allocated is the product of the







<
<
<
<
<
|

|
|
>
|
|
|
|
|
|
|
|
|










<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<



|
|
<
<
<
|
<

<
<
<
<
<
<
<
<
<
<
<


<
|
|
|
|



<
|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







422
423
424
425
426
427
428





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


















453
454
455
456
457



458

459











460
461

462
463
464
465
466
467
468

469
470
471
472






















































473















































474
475
476
477
478
479
480
.SH "IMAGE FORMATS"
.PP
The photo image code is structured to allow handlers for additional
image file formats to be added easily.  The photo image code maintains
a list of these handlers.  Handlers are added to the list by
registering them with a call to \fBTk_CreatePhotoImageFormat\fR.  The
standard Tk distribution comes with handlers for PPM/PGM, PNG and GIF





formats, which are automatically registered on initialization.
.PP
When reading an image file or processing
string data specified with the \fB\-data\fR configuration option, the
photo image code invokes each handler in turn until one is
found that claims to be able to read the data in the file or string.
Usually this will find the correct handler, but if it does not, the
user may give a format name with the \fB\-format\fR option to specify
which handler to use.  In fact the photo image code will try those
handlers whose names begin with the string specified for the
\fB\-format\fR option (the comparison is case-insensitive).  For
example, if the user specifies \fB\-format gif\fR, then a handler
named GIF87 or GIF89 may be invoked, but a handler
named JPEG may not (assuming that such handlers had been
registered).
.PP
When writing image data to a file, the processing of the
\fB\-format\fR option is slightly different: the string value given
for the \fB\-format\fR option must begin with the complete name of the
requested handler, and may contain additional information following
that, which the handler can use, for example, to specify which variant
to use of the formats supported by the handler.
Note that not all image handlers may support writing transparency data
to a file, even where the target image format does.


















.SS "FORMAT SUBOPTIONS"
.PP
.VS 8.6
Some image formats support sub-options, which are specified at the time that
the image is loaded using additional words in the \fB\-format\fR option. At



the time of writing, the following are supported:

.TP











\fBgif \-index\fI indexValue\fR
.

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
.

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.






















































.VE 8.6















































.SH "COLOR ALLOCATION"
.PP
When a photo image is displayed in a window, the photo image code
allocates colors to use to display the image and dithers the image, if
necessary, to display a reasonable approximation to the image using
the colors that are available.  The colors are allocated as a color
cube, that is, the number of colors allocated is the product of the
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
.CS
\fBimage create photo\fR icon \-file "icon.png"
\fBimage create photo\fR iconDisabled \-file "icon.png" \e
        \-format "png \-alpha 0.5"
button .b \-image icon \-disabledimage iconDisabled
.CE
.VE 8.6
.PP
.VS 8.7
Create a green box with a simple shadow effect
.PP
.CS
\fBimage create photo\fR foo

# Make a simple graduated fill varying in alpha for the shadow
for {set i 14} {$i > 0} {incr i -1} {
   set i2 [expr {$i + 30}]
   foo \fBput\fR [format black#%x [expr {15-$i}]] -to $i $i $i2 $i2
}

# Put a solid green rectangle on top
foo \fBput\fR #F080 -to 0 0 30 30
.VE 8.7
.CE
.SH "SEE ALSO"
image(n)
.SH KEYWORDS
photo, image, color
'\" Local Variables:
'\" mode: nroff
'\" End:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







530
531
532
533
534
535
536

















537
538
539
540
541
542
543
.CS
\fBimage create photo\fR icon \-file "icon.png"
\fBimage create photo\fR iconDisabled \-file "icon.png" \e
        \-format "png \-alpha 0.5"
button .b \-image icon \-disabledimage iconDisabled
.CE
.VE 8.6

















.SH "SEE ALSO"
image(n)
.SH KEYWORDS
photo, image, color
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/place.n.
187
188
189
190
191
192
193
194
195
196

197
198
199
200

201
202
203
204
205
206
207
.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"







|


>

|

|
>







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
.TP
\fBplace info \fIwindow\fR
Returns a list giving the current configuration of \fIwindow\fR.
The list consists of \fIoption\-value\fR pairs in exactly the
same form as might be specified to the \fBplace configure\fR
command.
.TP
\fBplace slaves \fIwindow\fR
Returns a list of all the content windows for which \fIwindow\fR is the container.
If there is no content for \fIwindow\fR then an empty string is returned.
.VS "TIP 581"
.TP
\fBplace content \fIwindow\fR
.
Synonym for \fBplace slaves \fIwindow\fR.
.VE "TIP 581"
.PP
If the configuration of a window has been retrieved with
\fBplace info\fR, that configuration can be restored later by
first using \fBplace forget\fR to erase any existing information
for the window and then invoking \fBplace configure\fR with
the saved information.
.SH "FINE POINTS"
Changes to doc/popup.n.
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$m add command \-label "Example 1" \-command bell
$m add command \-label "Example 2" \-command bell

# Create something to attach it to
pack [label .l \-text "Click me!"]

# Arrange for the menu to pop up when the label is clicked
bind .l <Button-1> {\fBtk_popup\fR .popupMenu %X %Y}
.CE
.SH "SEE ALSO"
bind(n), menu(n), tk_optionMenu(n)
.SH KEYWORDS
menu, popup
'\" Local Variables:
'\" mode: nroff







|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
$m add command \-label "Example 1" \-command bell
$m add command \-label "Example 2" \-command bell

# Create something to attach it to
pack [label .l \-text "Click me!"]

# Arrange for the menu to pop up when the label is clicked
bind .l <1> {\fBtk_popup\fR .popupMenu %X %Y}
.CE
.SH "SEE ALSO"
bind(n), menu(n), tk_optionMenu(n)
.SH KEYWORDS
menu, popup
'\" Local Variables:
'\" mode: nroff
Changes to doc/radiobutton.n.
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
.SH "WIDGET COMMAND"
.PP
The \fBradiobutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for radiobutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.







|







172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
.SH "WIDGET COMMAND"
.PP
The \fBradiobutton\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for radiobutton widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Changes to doc/scale.n.
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
.SH "WIDGET COMMAND"
.PP
The \fBscale\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scale widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.







|







134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
.SH "WIDGET COMMAND"
.PP
The \fBscale\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for scale widgets:
.TP
\fIpathName \fBcget\fR \fIoption\fR
.
Changes to doc/scrollbar.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.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
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







|
>










>
>
>
>
>
>
>
>
>
>









|
<
<
<
<
<
<
<
<
<
<
<
<







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












241
242
243
244
245
246
247
the slider, the scrollbar notifies the associated widget that it
must change its view.
The scrollbar makes the notification by evaluating a Tcl command
generated from the scrollbar's \fB\-command\fR option.
The command may take any of the following forms.
In each case, \fIprefix\fR is the contents of the
\fB\-command\fR option, which usually has a form like
.QW "\fB.t yview\fR" .
.\" METHOD: moveto
.TP
\fIprefix \fBmoveto \fIfraction\fR
.
\fIFraction\fR is a real number between 0 and 1.
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.\" METHOD: scroll
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
.
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR
.
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible.












.SH "OLD COMMAND SYNTAX"
.PP
In versions of Tk before 4.0, the \fBset\fR and \fBget\fR widget
commands used a different form.
This form is still supported for backward compatibility, but it
is deprecated.
In the old command syntax, the \fBset\fR widget command has the
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
.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:







|
|
|
|
|


|





346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
.IP [14]
The End key adjusts the view to the bottom (right edge) of the document.
.SH EXAMPLE
.PP
Create a window with a scrollable \fBtext\fR widget:
.CS
toplevel .tl
text .tl.t -yscrollcommand {.tl.s set}
\fBscrollbar\fR .tl.s -command {.tl.t yview}
grid .tl.t .tl.s -sticky nsew
grid columnconfigure .tl 0 -weight 1
grid rowconfigure .tl 0 -weight 1
.CE
.SH "SEE ALSO"
ttk::scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/selection.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH selection n 8.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
selection \- Manipulate the X selection
.SH SYNOPSIS
\fBselection \fIoption\fR ?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a Tcl interface to the X selection mechanism and
implements the full selection functionality described in the
X Inter-Client Communication Conventions Manual (ICCCM).
.PP







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH selection n 8.1 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
selection \- Manipulate the X selection
.SH SYNOPSIS
\fBselection \fIoption\fR ?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command provides a Tcl interface to the X selection mechanism and
implements the full selection functionality described in the
X Inter-Client Communication Conventions Manual (ICCCM).
.PP
Changes to doc/send.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH send n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
send \- Execute a command in a different application
.SH SYNOPSIS
\fBsend ?\fIoptions\fR? \fIapp cmd \fR?\fIarg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command arranges for \fIcmd\fR (and \fIarg\fRs) to be executed in the
application named by \fIapp\fR.  It returns the result or
error from that command execution.
\fIApp\fR may be the name of any application whose main window is







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH send n 4.0 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
send \- Execute a command in a different application
.SH SYNOPSIS
\fBsend ?\fIoptions\fR? \fIapp cmd \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
This command arranges for \fIcmd\fR (and \fIarg\fRs) to be executed in the
application named by \fIapp\fR.  It returns the result or
error from that command execution.
\fIApp\fR may be the name of any application whose main window is
Changes to doc/spinbox.n.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
\-borderwidth	\-insertborderwidth	\-selectborderwidth
\-cursor	\-insertontime	\-selectforeground
\-exportselection	\-insertwidth	\-takefocus
\-font	\-insertofftime	\-textvariable
\-foreground	\-justify	\-xscrollcommand
\-highlightbackground	\-relief
\-highlightcolor	\-repeatdelay
\-placeholder	\-placeholderforeground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-buttonbackground buttonBackground Background
The background color to be used for the spin buttons.
.OP \-buttoncursor buttonCursor Cursor
The cursor to be used when over the spin buttons.  If this is empty
(the default), a default cursor will be used.







<







19
20
21
22
23
24
25

26
27
28
29
30
31
32
\-borderwidth	\-insertborderwidth	\-selectborderwidth
\-cursor	\-insertontime	\-selectforeground
\-exportselection	\-insertwidth	\-takefocus
\-font	\-insertofftime	\-textvariable
\-foreground	\-justify	\-xscrollcommand
\-highlightbackground	\-relief
\-highlightcolor	\-repeatdelay

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-buttonbackground buttonBackground Background
The background color to be used for the spin buttons.
.OP \-buttoncursor buttonCursor Cursor
The cursor to be used when over the spin buttons.  If this is empty
(the default), a default cursor will be used.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-from from From
A floating-point value corresponding to the lowest value for a spinbox, to
be used in conjunction with \fB\-to\fR and \fB\-increment\fR.  When all
are specified correctly, the spinbox will use these values to control its
contents. If this value is greater than the \fB\-to\fR option, then
\fB\-from\fR and \fB\-to\fR values are automatically swapped.
If \fB\-values\fR is specified, it supersedes this option.
.OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand
Specifies a script to eval when \fB\-validatecommand\fR returns 0.  Setting
it to an empty string disables this feature (the default).  The best use of
this option is to set it to \fIbell\fR.  See \fBVALIDATION\fR below for
more information.
.OP \-increment increment Increment







|
<







50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
when using the \fB\-from\fR and \fB\-to\fR range.
This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
as it will format a floating-point number.
.OP \-from from From
A floating-point value corresponding to the lowest value for a spinbox, to
be used in conjunction with \fB\-to\fR and \fB\-increment\fR.  When all
are specified correctly, the spinbox will use these values to control its
contents.  This value must be less than the \fB\-to\fR option.

If \fB\-values\fR is specified, it supersedes this option.
.OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand
Specifies a script to eval when \fB\-validatecommand\fR returns 0.  Setting
it to an empty string disables this feature (the default).  The best use of
this option is to set it to \fIbell\fR.  See \fBVALIDATION\fR below for
more information.
.OP \-increment increment Increment
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
displayed, the contents will not be selectable, and the spinbox may
be displayed in a different color, depending on the values of the
\fB\-disabledforeground\fR and \fB\-disabledbackground\fR options.
.OP \-to to To
A floating-point value corresponding to the highest value for the spinbox,
to be used in conjunction with \fB\-from\fR and \fB\-increment\fR.  When
all are specified correctly, the spinbox will use these values to control
its contents. If this value is less than the \fB\-from\fR option, then
\fB\-from\fR and \fB\-to\fR values are automatically swapped.
If \fB\-values\fR is specified, it supersedes this option.
.OP \-validate validate Validate
Specifies the mode in which validation should operate: \fBnone\fR,
\fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
It defaults to \fBnone\fR.  When you want validation, you must explicitly
state which mode you wish to use.  See \fBVALIDATION\fR below for more.
.OP "\-validatecommand or \-vcmd" validateCommand ValidateCommand







|
<







79
80
81
82
83
84
85
86

87
88
89
90
91
92
93
displayed, the contents will not be selectable, and the spinbox may
be displayed in a different color, depending on the values of the
\fB\-disabledforeground\fR and \fB\-disabledbackground\fR options.
.OP \-to to To
A floating-point value corresponding to the highest value for the spinbox,
to be used in conjunction with \fB\-from\fR and \fB\-increment\fR.  When
all are specified correctly, the spinbox will use these values to control
its contents.  This value must be greater than the \fB\-from\fR option.

If \fB\-values\fR is specified, it supersedes this option.
.OP \-validate validate Validate
Specifies the mode in which validation should operate: \fBnone\fR,
\fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR.
It defaults to \fBnone\fR.  When you want validation, you must explicitly
state which mode you wish to use.  See \fBVALIDATION\fR below for more.
.OP "\-validatecommand or \-vcmd" validateCommand ValidateCommand
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
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







|







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
then the \fB-validate\fR option will be automatically set to \fBnone\fR.
.SH "WIDGET COMMAND"
.PP
The \fBspinbox\fR command creates a new Tcl command whose
name is \fIpathName\fR.  This command may be used to invoke various
operations on the widget.  It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.
.SS INDICES
.PP
Many of the widget commands for spinboxes take one or more indices as
arguments.  An index specifies a particular character in the spinbox's
466
467
468
469
470
471
472
473
474
475
476


477
478
479
480
481
482
483
484
485
486
487
488
489
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR or an abbreviation
of one of these.


If \fIwhat\fR is \fBpages\fR then the view adjusts by \fInumber\fR
screenfuls. If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for spinboxes that give them
the following default behavior.
In the descriptions below,
.QW word







|
<
|

>
>
|
|


<
<







463
464
465
466
467
468
469
470

471
472
473
474
475
476
477
478


479
480
481
482
483
484
485
Adjusts the view in the window so that the character \fIfraction\fR of the
way through the text appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR or an abbreviation
of one of these.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display;  if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.


.RE
.SH "DEFAULT BINDINGS"
.PP
Tk automatically creates class bindings for spinboxes that give them
the following default behavior.
In the descriptions below,
.QW word
Changes to doc/text.n.
225
226
227
228
229
230
231
232

233
234
235
236
237
238
239
.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







|
>







225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
.TP 12
\fBend\fR
.
Indicates the end of the text (the character just after the last newline).
.TP 12
\fImark\fR
.
Indicates the character just after the mark whose name is \fImark\fR (see
\fBMARKS\fR for details).
.TP 12
\fItag\fB.first\fR
.
Indicates the first character in the text that has been tagged with \fItag\fR.
This form generates an error if no characters are currently tagged with
\fItag\fR.
.TP 12
843
844
845
846
847
848
849



850
851
852
853
854
855
856
.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







>
>
>







844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
.IP [3]
If the selection is claimed away by another application or by another window
within this application, then the \fBsel\fR tag will be removed from all
characters in the text.
.IP [4]
Whenever the \fBsel\fR tag range changes a virtual event \fB<<Selection>>\fR
is generated.
It might also be generated when selection is affected but not actually changed.
Further, multiple selection changes could happen before events can be processed
leading to multiple events with the same visible selection.
.PP
The \fBsel\fR tag is automatically defined when a text widget is created, and
it may not be deleted with the
.QW "\fIpathName \fBtag delete\fR"
widget command. Furthermore, the \fB\-selectbackground\fR,
\fB\-selectborderwidth\fR, and \fB\-selectforeground\fR options for the text
widget are tied to the \fB\-background\fR, \fB\-borderwidth\fR, and
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
.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
.







|







1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
.CE
.SH "WIDGET COMMAND"
.PP
The \fBtext\fR command creates a new Tcl command whose name is the same as the
path name of the text's window. This command may be used to invoke various
operations on the widget. It has the following general form:
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
\fIPathName\fR is the name of the command, which is the same as the text
widget's path name. \fIOption\fR and the \fIarg\fRs determine the exact
behavior of the command. The following commands are possible for text widgets:
.TP
\fIpathName \fBbbox \fIindex\fR
.
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
.
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







|







1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
.
Include information about embedded windows in the dump results. The value of a
window is its Tk pathname, unless the window has not been created yet. (It
must have a create script.) In this case an empty string is returned, and you
must query the window by its index position to get more information.
.RE
.TP
\fIpathName \fBedit \fIoption \fR?\fIarg arg ...\fR?
.
This command controls the undo mechanism and the modified flag. The exact
behavior of the command depends on the \fIoption\fR argument that follows the
\fBedit\fR argument. The following forms of the command are currently
supported:
.RS
.TP
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
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







|
<
|












|
<
|
|







1309
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330

1331
1332
1333
1334
1335
1336
1337
1338
1339
The insert, delete, edit undo and edit redo commands or the user can set or
clear the modified flag. If \fIboolean\fR is specified, sets the modified flag
of the widget to \fIboolean\fR.
.TP
\fIpathName \fBedit redo\fR
.
When the \fB\-undo\fR option is true, reapplies the last undone edits provided
no other edits were done since then. Generates an error when the redo stack is

empty. Does nothing when the \fB\-undo\fR option is false.
.TP
\fIpathName \fBedit reset\fR
.
Clears the undo and redo stacks.
.TP
\fIpathName \fBedit separator\fR
.
Inserts a separator (boundary) on the undo stack. Does nothing when the
\fB\-undo\fR option is false.
.TP
\fIpathName \fBedit undo\fR
.
Undoes the last edit action when the \fB\-undo\fR option is true. An edit

action is defined as all the insert and delete commands that are recorded on
the undo stack in between two separators. Generates an error when the undo
stack is empty. Does nothing when the \fB\-undo\fR option is false.
.RE
.TP
\fIpathName \fBget\fR ?\fB\-displaychars\fR? ?\fB\-\-\fR? \fIindex1\fR ?\fIindex2 ...\fR?
.
Return a range of characters from the text. The return value will be all the
characters in the text starting with the one whose index is \fIindex1\fR and
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
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







|


|







1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
ranges of text will be returned in a list. Invalid ranges will not be
represented with empty strings in the list. The ranges are returned in the
order passed to \fIpathName \fBget\fR. If the \fB\-displaychars\fR option is
given, then, within each range, only those characters which are not elided
will be returned. This may have the effect that some of the returned ranges
are empty strings.
.TP
\fIpathName \fBimage \fIoption \fR?\fIarg arg ...\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
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
characters will receive all of the tags in this list and no others, regardless
of the tags present around the insertion point. If multiple
\fIchars\fR\-\fItagList\fR argument pairs are present, they produce the same
effect as if a separate \fIpathName \fBinsert\fR widget command had been
issued for each pair, in order. The last \fItagList\fR argument may be
omitted.
.TP
\fIpathName \fBmark \fIoption \fR?\fIarg ...\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?







|







1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
characters will receive all of the tags in this list and no others, regardless
of the tags present around the insertion point. If multiple
\fIchars\fR\-\fItagList\fR argument pairs are present, they produce the same
effect as if a separate \fIpathName \fBinsert\fR widget command had been
issued for each pair, in order. The last \fItagList\fR argument may be
omitted.
.TP
\fIpathName \fBmark \fIoption \fR?\fIarg arg ...\fR?
.
This command is used to manipulate marks. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBmark\fR argument. The
following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBmark gravity \fImarkName\fR ?\fIdirection\fR?
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
\fIpathName \fBsync -command \fIcommand\fR
Schedules \fIcommand\fR to be executed (by the event loop) exactly once as soon
as all line heights are up-to-date. If there are no pending line metrics
calculations, the scheduling is immediate. The command returns the empty
string. \fBbgerror\fR is called on \fIcommand\fR failure.
.RE
.TP
\fIpathName \fBtag \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate tags. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBtag\fR argument. The
following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBtag add \fItagName index1 \fR?\fIindex2 index1 index2 ...\fR?







|







1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
\fIpathName \fBsync -command \fIcommand\fR
Schedules \fIcommand\fR to be executed (by the event loop) exactly once as soon
as all line heights are up-to-date. If there are no pending line metrics
calculations, the scheduling is immediate. The command returns the empty
string. \fBbgerror\fR is called on \fIcommand\fR failure.
.RE
.TP
\fIpathName \fBtag \fIoption \fR?\fIarg arg ...\fR?
.
This command is used to manipulate tags. The exact behavior of the command
depends on the \fIoption\fR argument that follows the \fBtag\fR argument. The
following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBtag add \fItagName index1 \fR?\fIindex2 index1 index2 ...\fR?
1729
1730
1731
1732
1733
1734
1735
1736
1737

1738
1739
1740
1741
1742
1743
1744

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







|
|
>
|





|
>
|







1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
the command returns the \fIscript\fR associated with \fItagName\fR and
\fIsequence\fR (an error occurs if there is no such binding). If both
\fIscript\fR and \fIsequence\fR are omitted then the command returns a list of
all the sequences for which bindings have been defined for \fItagName\fR.
.RS
.PP
The only events for which bindings may be specified are those related to the
mouse and keyboard (such as \fBEnter\fR, \fBLeave\fR, \fBButtonPress\fR,
\fBMotion\fR, and \fBKeyPress\fR) or virtual events. Mouse and keyboard event
bindings for a text widget respectively use the \fBcurrent\fR and \fBinsert\fR
marks described under \fBMARKS\fR above. An
\fBEnter\fR event triggers for a tag when the tag first becomes present on the
current character, and a \fBLeave\fR event triggers for a tag when it ceases
to be present on the current character. \fBEnter\fR and \fBLeave\fR events can
happen either because the \fBcurrent\fR mark moved or because the character at
that position changed. Note that these events are different than \fBEnter\fR
and \fBLeave\fR events for windows. Mouse events are directed to the current
character, while keyboard events are directed to the insert character.
If a virtual event is used in a binding, that binding
can trigger only if the virtual event is defined by an underlying
mouse-related or keyboard-related event.
.PP
It is possible for the current character to have multiple tags, and for each
of them to have a binding for a particular event sequence. When this occurs,
one binding is invoked for each tag, in order from lowest-priority to highest
priority. If there are multiple matching bindings for a single tag, then the
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
\fIindex1\fR\-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then the
tag is removed from the single character at \fIindex1\fR. If there are no
characters in the specified range (e.g. \fIindex1\fR is past the end of the
file or \fIindex2\fR is less than or equal to \fIindex1\fR) then the command
has no effect. This command returns an empty string.
.RE
.TP
\fIpathName \fBwindow \fIoption \fR?\fIarg ...\fR?
.
This command is used to manipulate embedded windows. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBwindow\fR
argument. The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBwindow cget \fIindex option\fR







|







1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
\fIindex1\fR\-\fIindex2\fR pairs. If the last \fIindex2\fR is omitted then the
tag is removed from the single character at \fIindex1\fR. If there are no
characters in the specified range (e.g. \fIindex1\fR is past the end of the
file or \fIindex2\fR is less than or equal to \fIindex1\fR) then the command
has no effect. This command returns an empty string.
.RE
.TP
\fIpathName \fBwindow \fIoption \fR?\fIarg arg ...\fR?
.
This command is used to manipulate embedded windows. The behavior of the
command depends on the \fIoption\fR argument that follows the \fBwindow\fR
argument. The following forms of the command are currently supported:
.RS
.TP
\fIpathName \fBwindow cget \fIindex option\fR
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944


1945
1946
1947
1948
1949
1950
1951
Adjusts the view in the window so that \fIfraction\fR of the horizontal span
of the text is off-screen to the left. \fIFraction\fR is a fraction between 0
and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBpages\fR,
\fBpixels\fR, or \fBunits\fR. If \fIwhat\fR is \fBpages\fR or
\fBunits\fR then \fInumber\fR must be an integer, otherwise number may be
specified in any of the forms acceptable to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded to the nearest integer value. If no units are given,
pixels are assumed). If \fIwhat\fR is \fBpages\fR then the view adjusts by
\fInumber\fR screenfuls; if it is \fBpixels\fR then the view adjusts by
\fInumber\fR pixels; if it is \fBunits\fR, the view adjusts left or
right by \fInumber\fR average-width characters on the display. If \fInumber\fR is


negative then characters farther to the left become visible; if it is positive
then characters farther to the right become visible.
.RE
.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the text in







|
|
|
|




|
<
<
|
>
>







1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945


1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
Adjusts the view in the window so that \fIfraction\fR of the horizontal span
of the text is off-screen to the left. \fIFraction\fR is a fraction between 0
and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR
.
This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBunits\fR, \fBpages\fR or
\fBpixels\fR. If \fIwhat\fR is \fBunits\fR or \fBpages\fR then \fInumber\fR
must be an integer, otherwise number may be specified in any of the forms
acceptable to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded to the nearest integer value. If no units are given,
pixels are assumed). If \fIwhat\fR is \fBunits\fR, the view adjusts left or


right by \fInumber\fR average-width characters on the display; if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls; if it is
\fBpixels\fR then the view adjusts by \fInumber\fR pixels. If \fInumber\fR is
negative then characters farther to the left become visible; if it is positive
then characters farther to the right become visible.
.RE
.TP
\fIpathName \fByview \fR?\fIargs\fR?
.
This command is used to query and change the vertical position of the text in
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
the widget will never scroll beyond the last pixel, and so a value of 1 will
effectively be rounded back to whatever fraction ensures the last pixel is at
the bottom of the window, and some other pixel is at the top.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjust the view in the window up or down according to
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBpages\fR,
\fBpixels\fR, or \fBunits\fR. If \fIwhat\fR is \fBunits\fR or \fBpages\fR then
\fInumber\fR must be an integer, otherwise number may be specified in any of
the forms acceptable to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded to the nearest integer value. If no units are given,
pixels are assumed). If \fIwhat\fR is \fBunits\fR, the view adjusts up or down
by \fInumber\fR lines on the display; if it is \fBpages\fR then the view
adjusts by \fInumber\fR screenfuls; if it is \fBpixels\fR then the view







|
|
|
|







1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
the widget will never scroll beyond the last pixel, and so a value of 1 will
effectively be rounded back to whatever fraction ensures the last pixel is at
the bottom of the window, and some other pixel is at the top.
.TP
\fIpathName \fByview scroll \fInumber what\fR
.
This command adjust the view in the window up or down according to
\fInumber\fR and \fIwhat\fR. \fIWhat\fR must be \fBunits\fR, \fBpages\fR or
\fBpixels\fR. If \fIwhat\fR is \fBunits\fR or \fBpages\fR then \fInumber\fR
must be an integer, otherwise number may be specified in any of the forms
acceptable to \fBTk_GetPixels\fR, such as
.QW 2.0c
or
.QW 1i
(the result is rounded to the nearest integer value. If no units are given,
pixels are assumed). If \fIwhat\fR is \fBunits\fR, the view adjusts up or down
by \fInumber\fR lines on the display; if it is \fBpages\fR then the view
adjusts by \fInumber\fR screenfuls; if it is \fBpixels\fR then the view
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
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







|







2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
Tk automatically creates class bindings for texts that give them the following
default behavior.
In the descriptions below,
.QW word
is dependent on the value of
the \fBtcl_wordchars\fR variable.  See \fBtclvars\fR(n).
.IP [1]
Clicking mouse button 1 positions the insertion cursor at the closest edge of the
character underneath the mouse cursor, sets the input focus to this widget,
and clears any selection in the widget. Dragging with mouse button 1 strokes
out a selection between the insertion cursor and the character under the
mouse.
.IP [2]
Double-clicking with mouse button 1 selects the word under the mouse and
positions the insertion cursor at the start of the word. Dragging after a
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166



2167
2168
2169
2170
2171
2172
2173
.IP [28]
Control-o opens a new line by inserting a newline character in front of the
insertion cursor without moving the insertion cursor.
.IP [29]
Meta-backspace and Meta-Delete delete the word to the left of the insertion
cursor.
.IP [30]
Control-t reverses the order of the two characters to the right of the
insertion cursor.
.IP [31]
Control-x deletes whatever is selected in the text widget after copying it to
the clipboard.



.IP [32]
Control-z undoes the last edit action if the \fB\-undo\fR option is true.
Does nothing otherwise.
.IP [33]
Control-Z (or Control-y on Windows) reapplies the last undone edit action if
the \fB\-undo\fR option is true. Does nothing otherwise.
.PP







<
<
<


>
>
>







2159
2160
2161
2162
2163
2164
2165



2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
.IP [28]
Control-o opens a new line by inserting a newline character in front of the
insertion cursor without moving the insertion cursor.
.IP [29]
Meta-backspace and Meta-Delete delete the word to the left of the insertion
cursor.
.IP [30]



Control-x deletes whatever is selected in the text widget after copying it to
the clipboard.
.IP [31]
Control-t reverses the order of the two characters to the right of the
insertion cursor.
.IP [32]
Control-z undoes the last edit action if the \fB\-undo\fR option is true.
Does nothing otherwise.
.IP [33]
Control-Z (or Control-y on Windows) reapplies the last undone edit action if
the \fB\-undo\fR option is true. Does nothing otherwise.
.PP
Changes to doc/tk.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
.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
\fInewName\fR should not start with a capital letter.
This will interfere with option processing, since names starting with
capitals are assumed to be classes;  as a result, Tk may not
be able to find some options for the application.
If sends have been disabled by deleting the \fBsend\fR command,
this command will reenable them and recreate the \fBsend\fR
command.
.\" METHOD: busy
.TP
\fBtk busy \fIsubcommand\fR ...
.
This command controls the marking of window hierarchies as
.QW busy ,
rendering them non-interactive while some other operation is proceeding. For
more details see the \fBbusy\fR manual page.
.\" METHOD: caret
.TP
\fBtk caret \fIwindow \fR?\fB\-x \fIx\fR? ?\fB\-y \fIy\fR? ?\fB\-height \fIheight\fR?
.
Sets and queries the caret location for the display of the specified
Tk window \fIwindow\fR.  The caret is the per-display cursor location
used for indicating global focus (e.g. to comply with Microsoft
Accessibility guidelines), as well as for location of the over-the-spot
XIM (X Input Methods) or Windows IME windows.  If no options are specified,
the last values used for setting the caret are return in option-value pair
format.  \fB\-x\fR and \fB\-y\fR represent window-relative coordinates, and
\fB\-height\fR is the height of the current cursor location, or the height
of the specified \fIwindow\fR if none is given.
.\" METHOD: inactive
.TP
\fBtk inactive \fR?\fB\-displayof \fIwindow\fR? ?\fBreset\fR?
.
Returns a positive integer, the number of milliseconds since the last
time the user interacted with the system. If the \fB\-displayof\fR
option is given then the return value refers to the display of
\fIwindow\fR; otherwise it refers to the display of the application's
main window.
.RS
.PP
\fBtk inactive\fR will return \-1, if querying the user inactive time
is not supported by the system, and in safe interpreters.
.PP
If the literal string \fBreset\fR is given as an additional argument,
the timer is reset and an empty string is returned. Resetting the
inactivity time is forbidden in safe interpreters and will throw an
error if tried.
.RE
.\" METHOD: fontchooser
.TP
\fBtk fontchooser \fIsubcommand\fR ...
.
Controls the Tk font selection dialog. For more details see the
\fBfontchooser\fR manual page.
.\" METHOD: scaling
.TP
\fBtk scaling \fR?\fB\-displayof \fIwindow\fR? ?\fInumber\fR?
.
Sets and queries the current scaling factor used by Tk to convert between
physical units (for example, points, inches, or millimeters) and pixels.  The
\fInumber\fR argument is a floating point number that specifies the number of
pixels per point on \fIwindow\fR's display.  If the \fIwindow\fR argument is
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122

123
124
125
126
127
128
129
130
131
132
133
134
135
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:







>










>





|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
displayed 1.25 times as large as normal.  The initial value for the scaling
factor is set when the application starts, based on properties of the
installed monitor, but it can be changed at any time.  Measurements made
after the scaling factor is changed will use the new scaling factor, but it
is undefined whether existing widgets will resize themselves dynamically to
accommodate the new scaling factor.
.RE
.\" METHOD: useinputmethods
.TP
\fBtk useinputmethods \fR?\fB\-displayof \fIwindow\fR? ?\fIboolean\fR?
.
Sets and queries the state of whether Tk should use XIM (X Input Methods)
for filtering events.  The resulting state is returned.  XIM is used in
some locales (i.e., Japanese, Korean), to handle special input devices. This
feature is only significant on X.  If XIM support is not available, this
will always return 0.  If the \fIwindow\fR argument is omitted, it defaults
to the main window.  If the \fIboolean\fR argument is omitted, the current
state is returned.  This is turned on by default for the main display.
.\" METHOD: windowingsystem
.TP
\fBtk windowingsystem\fR
.
Returns the current Tk windowing system, one of
\fBx11\fR (X11-based), \fBwin32\fR (MS Windows),
or \fBaqua\fR (macOS Aqua).
.SH "SEE ALSO"
busy(n), fontchooser(n), send(n), winfo(n)
.SH KEYWORDS
application name, send
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/tk4.0.ps.
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% FrameMaker.
% NOTE
% This file fixes the problem with NeWS printers dithering color output.
% Any questions should be sent to mickey@magickingdom.eng.sun.com
%
% Known Problems:
%	Due to bugs in Transcript, the 'PS-Adobe-' is omitted from line 1
/FMversion (3.0) def
% Set up Color vs. Black-and-White

/FMPrintInColor { % once-thru loop gimmick
    % See if we're a NeWSprint printer
     /currentcanvas where {
        pop systemdict /separationdict known
	exit







|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% FrameMaker.
% NOTE
% This file fixes the problem with NeWS printers dithering color output.
% Any questions should be sent to mickey@magickingdom.eng.sun.com
%
% Known Problems:
%	Due to bugs in Transcript, the 'PS-Adobe-' is omitted from line 1
/FMversion (3.0) def 
% Set up Color vs. Black-and-White

/FMPrintInColor { % once-thru loop gimmick
    % See if we're a NeWSprint printer
     /currentcanvas where {
        pop systemdict /separationdict known
	exit
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
%    } if
    systemdict /colorimage known
    systemdict /currentcolortransfer known and
exit } loop def

% Uncomment the following line to force b&w on color printer
%   /FMPrintInColor false def
/FrameDict 195 dict def
systemdict /errordict known not {/errordict 10 dict def
		errordict /rangecheck {stop} put} if
% The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk
FrameDict /tmprangecheck errordict /rangecheck get put
errordict /rangecheck {FrameDict /bug true put} put
FrameDict /bug false put
mark
% Some PS machines read past the CR, so keep the following 3 lines together!
currentfile 5 string readline
00
0000000000
cleartomark
errordict /rangecheck FrameDict /tmprangecheck get put
FrameDict /bug get {
	/readline {
		/gstring exch def
		/gfile exch def
		/gindex 0 def
		{
			gfile read pop
			dup 10 eq {exit} if
			dup 13 eq {exit} if
			gstring exch gindex exch put
			/gindex gindex 1 add def
		} loop
		pop
		gstring 0 gindex getinterval true
		} def
	} if
/FMVERSION {
	FMversion ne {
		/Times-Roman findfont 18 scalefont setfont
		100 100 moveto
		(FrameMaker version does not match postscript_prolog!)
		dup =
		show showpage
		} if
	} def
/FMLOCAL {
	FrameDict begin
	0 def
	end
	} def
	/gstring FMLOCAL
	/gfile FMLOCAL
	/gindex FMLOCAL
	/orgxfer FMLOCAL
	/orgproc FMLOCAL
	/organgle FMLOCAL
	/orgfreq FMLOCAL
	/yscale FMLOCAL
	/xscale FMLOCAL
	/manualfeed FMLOCAL
	/paperheight FMLOCAL
	/paperwidth FMLOCAL
/FMDOCUMENT {
	array /FMfonts exch def
	/#copies exch def
	FrameDict begin
	0 ne dup {setmanualfeed} if
	/manualfeed exch def
	/paperheight exch def
	/paperwidth exch def
	/yscale exch def
	/xscale exch def
	currenttransfer cvlit /orgxfer exch def
	currentscreen cvlit /orgproc exch def
	/organgle exch def /orgfreq exch def
	setpapername
	manualfeed {true} {papersize} ifelse
	{manualpapersize} {false} ifelse
	{desperatepapersize} if
	end
	} def
	/pagesave FMLOCAL
	/orgmatrix FMLOCAL
	/landscape FMLOCAL
/FMBEGINPAGE {
	FrameDict begin
	/pagesave save def
	3.86 setmiterlimit
	/landscape exch 0 ne def
	landscape {
		90 rotate 0 exch neg translate pop
		}
		{pop pop}
		ifelse
	xscale yscale scale
	/orgmatrix matrix def
	gsave
	} def
/FMENDPAGE {
	grestore
	pagesave restore
	end
	showpage
	} def
/FMFONTDEFINE {
	FrameDict begin
	findfont
	ReEncode
	1 index exch
	definefont
	FMfonts 3 1 roll
	put
	end
	} def
/FMFILLS {
	FrameDict begin
	array /fillvals exch def
	end
	} def
/FMFILL {
	FrameDict begin
	 fillvals 3 1 roll put
	end
	} def
/FMNORMALIZEGRAPHICS {
	newpath
	0.0 0.0 moveto
	1 setlinewidth
	0 setlinecap
	0 0 0 sethsbcolor
	0 setgray
	} bind def
	/fx FMLOCAL
	/fy FMLOCAL
	/fh FMLOCAL
	/fw FMLOCAL
	/llx FMLOCAL
	/lly FMLOCAL
	/urx FMLOCAL
	/ury FMLOCAL
/FMBEGINEPSF {
	end
	/FMEPSF save def
	/showpage {} def
	FMNORMALIZEGRAPHICS
	[/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall
	fx fy translate
	rotate
	fw urx llx sub div fh ury lly sub div scale
	llx neg lly neg translate
	} bind def
/FMENDEPSF {
	FMEPSF restore
	FrameDict begin
	} bind def
FrameDict begin
/setmanualfeed {
%%BeginFeature *ManualFeed True
	 statusdict /manualfeed true put
%%EndFeature
	} def
/max {2 copy lt {exch} if pop} bind def
/min {2 copy gt {exch} if pop} bind def
/inch {72 mul} def
/pagedimen {
	paperheight sub abs 16 lt exch
	paperwidth sub abs 16 lt and
	{/papername exch def} {pop} ifelse
	} def
	/papersizedict FMLOCAL
/setpapername {
	/papersizedict 14 dict def
	papersizedict begin
	/papername /unknown def
		/Letter 8.5 inch 11.0 inch pagedimen
		/LetterSmall 7.68 inch 10.16 inch pagedimen
		/Tabloid 11.0 inch 17.0 inch pagedimen
		/Ledger 17.0 inch 11.0 inch pagedimen
		/Legal 8.5 inch 14.0 inch pagedimen
		/Statement 5.5 inch 8.5 inch pagedimen
		/Executive 7.5 inch 10.0 inch pagedimen







|



|
|
|
|




|
|
|





|
|
|
|
|

|
|










|


|
|
|












|
|











|
|
|

|
|



|
|



|
|





|
|

|

|

|
|

|
|
|
|
|

|
|



|
|



|
|
|





|









|
|
|
|
|
|
|

|
|



|

|








|
|




|
|

|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
%    } if
    systemdict /colorimage known
    systemdict /currentcolortransfer known and
exit } loop def

% Uncomment the following line to force b&w on color printer
%   /FMPrintInColor false def
/FrameDict 195 dict def 
systemdict /errordict known not {/errordict 10 dict def
		errordict /rangecheck {stop} put} if
% The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk
FrameDict /tmprangecheck errordict /rangecheck get put 
errordict /rangecheck {FrameDict /bug true put} put 
FrameDict /bug false put 
mark 
% Some PS machines read past the CR, so keep the following 3 lines together!
currentfile 5 string readline
00
0000000000
cleartomark 
errordict /rangecheck FrameDict /tmprangecheck get put 
FrameDict /bug get { 
	/readline {
		/gstring exch def
		/gfile exch def
		/gindex 0 def
		{
			gfile read pop 
			dup 10 eq {exit} if 
			dup 13 eq {exit} if 
			gstring exch gindex exch put 
			/gindex gindex 1 add def 
		} loop
		pop 
		gstring 0 gindex getinterval true 
		} def
	} if
/FMVERSION {
	FMversion ne {
		/Times-Roman findfont 18 scalefont setfont
		100 100 moveto
		(FrameMaker version does not match postscript_prolog!)
		dup =
		show showpage
		} if
	} def 
/FMLOCAL {
	FrameDict begin
	0 def 
	end 
	} def 
	/gstring FMLOCAL
	/gfile FMLOCAL
	/gindex FMLOCAL
	/orgxfer FMLOCAL
	/orgproc FMLOCAL
	/organgle FMLOCAL
	/orgfreq FMLOCAL
	/yscale FMLOCAL
	/xscale FMLOCAL
	/manualfeed FMLOCAL
	/paperheight FMLOCAL
	/paperwidth FMLOCAL
/FMDOCUMENT { 
	array /FMfonts exch def 
	/#copies exch def
	FrameDict begin
	0 ne dup {setmanualfeed} if
	/manualfeed exch def
	/paperheight exch def
	/paperwidth exch def
	/yscale exch def
	/xscale exch def
	currenttransfer cvlit /orgxfer exch def
	currentscreen cvlit /orgproc exch def
	/organgle exch def /orgfreq exch def
	setpapername 
	manualfeed {true} {papersize} ifelse 
	{manualpapersize} {false} ifelse 
	{desperatepapersize} if
	end 
	} def 
	/pagesave FMLOCAL
	/orgmatrix FMLOCAL
	/landscape FMLOCAL
/FMBEGINPAGE { 
	FrameDict begin 
	/pagesave save def
	3.86 setmiterlimit
	/landscape exch 0 ne def
	landscape { 
		90 rotate 0 exch neg translate pop 
		}
		{pop pop}
		ifelse
	xscale yscale scale
	/orgmatrix matrix def
	gsave 
	} def 
/FMENDPAGE {
	grestore 
	pagesave restore
	end 
	showpage
	} def 
/FMFONTDEFINE { 
	FrameDict begin
	findfont 
	ReEncode 
	1 index exch 
	definefont 
	FMfonts 3 1 roll 
	put
	end 
	} def 
/FMFILLS {
	FrameDict begin
	array /fillvals exch def
	end 
	} def 
/FMFILL {
	FrameDict begin
	 fillvals 3 1 roll put
	end 
	} def 
/FMNORMALIZEGRAPHICS { 
	newpath
	0.0 0.0 moveto
	1 setlinewidth
	0 setlinecap
	0 0 0 sethsbcolor
	0 setgray 
	} bind def
	/fx FMLOCAL
	/fy FMLOCAL
	/fh FMLOCAL
	/fw FMLOCAL
	/llx FMLOCAL
	/lly FMLOCAL
	/urx FMLOCAL
	/ury FMLOCAL
/FMBEGINEPSF { 
	end 
	/FMEPSF save def 
	/showpage {} def 
	FMNORMALIZEGRAPHICS 
	[/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall 
	fx fy translate 
	rotate
	fw urx llx sub div fh ury lly sub div scale 
	llx neg lly neg translate 
	} bind def
/FMENDEPSF {
	FMEPSF restore
	FrameDict begin 
	} bind def
FrameDict begin 
/setmanualfeed {
%%BeginFeature *ManualFeed True
	 statusdict /manualfeed true put
%%EndFeature
	} def
/max {2 copy lt {exch} if pop} bind def
/min {2 copy gt {exch} if pop} bind def
/inch {72 mul} def
/pagedimen { 
	paperheight sub abs 16 lt exch 
	paperwidth sub abs 16 lt and
	{/papername exch def} {pop} ifelse
	} def
	/papersizedict FMLOCAL
/setpapername { 
	/papersizedict 14 dict def 
	papersizedict begin
	/papername /unknown def 
		/Letter 8.5 inch 11.0 inch pagedimen
		/LetterSmall 7.68 inch 10.16 inch pagedimen
		/Tabloid 11.0 inch 17.0 inch pagedimen
		/Ledger 17.0 inch 11.0 inch pagedimen
		/Legal 8.5 inch 14.0 inch pagedimen
		/Statement 5.5 inch 8.5 inch pagedimen
		/Executive 7.5 inch 10.0 inch pagedimen
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
		/A4 {a4tray a4} def
		/A4Small {a4tray a4small} def
		/B4 {b4tray b4} def
		/B5 {b5tray b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	/FMdicttop countdictstack 1 add def
	statusdict begin stopped end
	countdictstack -1 FMdicttop {pop end} for
	} def
/manualpapersize {
	papersizedict begin
		/Letter {letter} def
		/LetterSmall {lettersmall} def
		/Tabloid {11x17} def
		/Ledger {ledger} def
		/Legal {legal} def
		/Statement {statement} def
		/Executive {executive} def
		/A3 {a3} def
		/A4 {a4} def
		/A4Small {a4small} def
		/B4 {b4} def
		/B5 {b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	stopped
	} def
/desperatepapersize {
	statusdict /setpageparams known
		{
		paperwidth paperheight 0 1
		statusdict begin
		{setpageparams} stopped pop
		end
		} if
	} def
/savematrix {
	orgmatrix currentmatrix pop
	} bind def
/restorematrix {







|
|
|


















|




|

|







233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
		/A4 {a4tray a4} def
		/A4Small {a4tray a4small} def
		/B4 {b4tray b4} def
		/B5 {b5tray b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	/FMdicttop countdictstack 1 add def 
	statusdict begin stopped end 
	countdictstack -1 FMdicttop {pop end} for 
	} def
/manualpapersize {
	papersizedict begin
		/Letter {letter} def
		/LetterSmall {lettersmall} def
		/Tabloid {11x17} def
		/Ledger {ledger} def
		/Legal {legal} def
		/Statement {statement} def
		/Executive {executive} def
		/A3 {a3} def
		/A4 {a4} def
		/A4Small {a4small} def
		/B4 {b4} def
		/B5 {b5} def
		/unknown {unknown} def
	papersizedict dup papername known {papername} {/unknown} ifelse get
	end
	stopped 
	} def
/desperatepapersize {
	statusdict /setpageparams known
		{
		paperwidth paperheight 0 1 
		statusdict begin
		{setpageparams} stopped pop 
		end
		} if
	} def
/savematrix {
	orgmatrix currentmatrix pop
	} bind def
/restorematrix {
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl
/periodcentered /quotesinglbase /quotedblbase /perthousand
/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute
/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve
/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron
/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron
] def
/ReEncode {
	dup
	length
	dict begin
	{
	1 index /FID ne
		{def}
		{pop pop} ifelse
	} forall
	0 eq {/Encoding DiacriticEncoding def} if
	currentdict
	end
	} bind def
/graymode true def
	/bwidth FMLOCAL
	/bpside FMLOCAL
	/bstring FMLOCAL
	/onbits FMLOCAL
	/offbits FMLOCAL
	/xindex FMLOCAL
	/yindex FMLOCAL
	/x FMLOCAL
	/y FMLOCAL
/setpattern {
	 /bwidth  exch def
	 /bpside  exch def
	 /bstring exch def
	 /onbits 0 def  /offbits 0 def
	 freq sangle landscape {90 add} if
		{/y exch def
		 /x exch def
		 /xindex x 1 add 2 div bpside mul cvi def
		 /yindex y 1 add 2 div bpside mul cvi def
		 bstring yindex bwidth mul xindex 8 idiv add get
		 1 7 xindex 8 mod sub bitshift and 0 ne
		 {/onbits  onbits  1 add def 1}







|
|
|
|

|
|
|
|
|
|
|
















|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/fraction /currency /guilsinglleft /guilsinglright /fi /fl /daggerdbl
/periodcentered /quotesinglbase /quotedblbase /perthousand
/Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute
/Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve
/Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron
/breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron
] def
/ReEncode { 
	dup 
	length 
	dict begin 
	{
	1 index /FID ne 
		{def} 
		{pop pop} ifelse 
	} forall 
	0 eq {/Encoding DiacriticEncoding def} if 
	currentdict 
	end 
	} bind def
/graymode true def
	/bwidth FMLOCAL
	/bpside FMLOCAL
	/bstring FMLOCAL
	/onbits FMLOCAL
	/offbits FMLOCAL
	/xindex FMLOCAL
	/yindex FMLOCAL
	/x FMLOCAL
	/y FMLOCAL
/setpattern {
	 /bwidth  exch def
	 /bpside  exch def
	 /bstring exch def
	 /onbits 0 def  /offbits 0 def
	 freq sangle landscape {90 add} if 
		{/y exch def
		 /x exch def
		 /xindex x 1 add 2 div bpside mul cvi def
		 /yindex y 1 add 2 div bpside mul cvi def
		 bstring yindex bwidth mul xindex 8 idiv add get
		 1 7 xindex 8 mod sub bitshift and 0 ne
		 {/onbits  onbits  1 add def 1}
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
		orgfreq organgle orgproc cvx setscreen
		} if
	} bind def
	/HUE FMLOCAL
	/SAT FMLOCAL
	/BRIGHT FMLOCAL
	/Colors FMLOCAL
FMPrintInColor

	{
	/HUE 0 def
	/SAT 0 def
	/BRIGHT 0 def
	% array of arrays Hue and Sat values for the separations [HUE BRIGHT]
	/Colors
	[[0    0  ]    % black
	 [0    0  ]    % white
	 [0.00 1.0]    % red
	 [0.37 1.0]    % green
	 [0.60 1.0]    % blue
	 [0.50 1.0]    % cyan
	 [0.83 1.0]    % magenta
	 [0.16 1.0]    % comment / yellow
	 ] def

	/BEGINBITMAPCOLOR {
		BITMAPCOLOR} def
	/BEGINBITMAPCOLORc {
		BITMAPCOLORc} def
	/BEGINBITMAPTRUECOLOR {
		BITMAPTRUECOLOR } def
	/BEGINBITMAPTRUECOLORc {
		BITMAPTRUECOLORc } def
	/K {
		Colors exch get dup
		0 get /HUE exch store
		1 get /BRIGHT exch store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor}
		  ifelse
		} def
	/FMsetgray {
		/SAT exch 1.0 exch sub store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor}
		  ifelse
		} bind def
	}

	{
	/BEGINBITMAPCOLOR {
		BITMAPGRAY} def
	/BEGINBITMAPCOLORc {
		BITMAPGRAYc} def
	/BEGINBITMAPTRUECOLOR {
		BITMAPTRUEGRAY } def
	/BEGINBITMAPTRUECOLORc {
		BITMAPTRUEGRAYc } def
	/FMsetgray {setgray} bind def
	/K {
		pop
		} def
	}
ifelse
/normalize {
	transform round exch round exch itransform
	} bind def
/dnormalize {
	dtransform round exch round exch idtransform
	} bind def
/lnormalize {
	0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
	} bind def
/H {
	lnormalize setlinewidth
	} bind def
/Z {
	setlinecap
	} bind def
	/fillvals FMLOCAL
/X {
	fillvals exch get
	dup type /stringtype eq
	{8 1 setpattern}
	{grayness}
	ifelse
	} bind def
/V {
	gsave eofill grestore
	} bind def
/N {
	stroke
	} bind def
/M {newpath moveto} bind def
/E {lineto} bind def
/D {curveto} bind def
/O {closepath} bind def
	/n FMLOCAL
/L {
 	/n exch def
	newpath
	normalize
	moveto
	2 1 n {pop normalize lineto} for
	} bind def
/Y {
	L
	closepath
	} bind def
	/x1 FMLOCAL
	/x2 FMLOCAL
	/y1 FMLOCAL
	/y2 FMLOCAL
	/rad FMLOCAL
/R {
	/y2 exch def
	/x2 exch def
	/y1 exch def
	/x1 exch def
	x1 y1
	x2 y1
	x2 y2
	x1 y2
	4 Y
	} bind def
/RR {
	/rad exch def
	normalize
	/y2 exch def
	/x2 exch def
	normalize
	/y1 exch def
	/x1 exch def
	newpath
	x1 y1 rad add moveto
	x1 y2 x2 y2 rad arcto
	x2 y2 x2 y1 rad arcto
	x2 y1 x1 y1 rad arcto
	x1 y1 x1 y2 rad arcto
	closepath
	16 {pop} repeat
	} bind def
/C {
	grestore
	gsave
	R
	clip
	} bind def
	/FMpointsize FMLOCAL
/F {
	FMfonts exch get
	FMpointsize scalefont
	setfont
	} bind def
/Q {
	/FMpointsize exch def
	F
	} bind def
/T {
	moveto show
	} bind def
/RF {
	rotate
	0 ne {-1 1 scale} if
	} bind def
/TF {
	gsave
	moveto
	RF
	show
	grestore
	} bind def
/P {
	moveto
	0 32 3 2 roll widthshow
	} bind def
/PF {
	gsave
	moveto
	RF
	0 32 3 2 roll widthshow
	grestore
	} bind def
/S {
	moveto
	0 exch ashow
	} bind def
/SF {
	gsave
	moveto
	RF
	0 exch ashow
	grestore
	} bind def
/B {
	moveto
	0 32 4 2 roll 0 exch awidthshow
	} bind def
/BF {
	gsave
	moveto
	RF
	0 32 4 2 roll 0 exch awidthshow
	grestore
	} bind def
/G {
	gsave
	newpath
	normalize translate 0.0 0.0 moveto
	dnormalize scale
	0.0 0.0 1.0 5 3 roll arc
	closepath fill
	grestore
	} bind def
/A {
	gsave
	savematrix
	newpath
	2 index 2 div add exch 3 index 2 div sub exch
	normalize 2 index 2 div sub exch 3 index 2 div add exch
	translate
	scale
	0.0 0.0 1.0 5 3 roll arc
	restorematrix
	stroke
	grestore
	} bind def
	/x FMLOCAL
	/y FMLOCAL
	/w FMLOCAL
	/h FMLOCAL
	/xx FMLOCAL
	/yy FMLOCAL
	/ww FMLOCAL
	/hh FMLOCAL
	/FMsaveobject FMLOCAL
	/FMoptop FMLOCAL
	/FMdicttop FMLOCAL
/BEGINPRINTCODE {
	/FMdicttop countdictstack 1 add def
	/FMoptop count 4 sub def
	/FMsaveobject save def
	userdict begin
	/showpage {} def
	FMNORMALIZEGRAPHICS
	3 index neg 3 index neg translate
	} bind def
/ENDPRINTCODE {
	count -1 FMoptop {pop pop} for
	countdictstack -1 FMdicttop {pop end} for
	FMsaveobject restore
	} bind def
/gn {
	0
	{	46 mul
		cf read pop
		32 sub
		dup 46 lt {exit} if
		46 sub add
		} loop
	add
	} bind def
	/str FMLOCAL
/cfs {
	/str sl string def
	0 1 sl 1 sub {str exch val put} for
	str def
	} bind def
/ic [
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0
	{0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx}
	{10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx}
	{19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}
	{13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh}







|
|





|









|
|

|

|

|

|

|



|


|
|


|



|

|

|

|

|


|










|


|






|


|



|


|







|



|


|
|







|








|

|
















|


|



|




|

|

|


|



|

|




|



|

|




|



|






|



|






|


|
|
|



|



|
|
|
|
|















|
|
|

|
|
|



|
|
|

|
|
|
|
|
|
|

|


|
|
|
|

|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
		orgfreq organgle orgproc cvx setscreen
		} if
	} bind def
	/HUE FMLOCAL
	/SAT FMLOCAL
	/BRIGHT FMLOCAL
	/Colors FMLOCAL
FMPrintInColor 
	
	{
	/HUE 0 def
	/SAT 0 def
	/BRIGHT 0 def
	% array of arrays Hue and Sat values for the separations [HUE BRIGHT]
	/Colors   
	[[0    0  ]    % black
	 [0    0  ]    % white
	 [0.00 1.0]    % red
	 [0.37 1.0]    % green
	 [0.60 1.0]    % blue
	 [0.50 1.0]    % cyan
	 [0.83 1.0]    % magenta
	 [0.16 1.0]    % comment / yellow
	 ] def
      
	/BEGINBITMAPCOLOR { 
		BITMAPCOLOR} def
	/BEGINBITMAPCOLORc { 
		BITMAPCOLORc} def
	/BEGINBITMAPTRUECOLOR { 
		BITMAPTRUECOLOR } def
	/BEGINBITMAPTRUECOLORc { 
		BITMAPTRUECOLORc } def
	/K { 
		Colors exch get dup
		0 get /HUE exch store 
		1 get /BRIGHT exch store
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor} 
		  ifelse
		} def
	/FMsetgray { 
		/SAT exch 1.0 exch sub store 
		  HUE 0 eq BRIGHT 0 eq and
			{1.0 SAT sub setgray}
			{HUE SAT BRIGHT sethsbcolor} 
		  ifelse
		} bind def
	}
	
	{
	/BEGINBITMAPCOLOR { 
		BITMAPGRAY} def
	/BEGINBITMAPCOLORc { 
		BITMAPGRAYc} def
	/BEGINBITMAPTRUECOLOR { 
		BITMAPTRUEGRAY } def
	/BEGINBITMAPTRUECOLORc { 
		BITMAPTRUEGRAYc } def
	/FMsetgray {setgray} bind def
	/K { 
		pop
		} def
	}
ifelse
/normalize {
	transform round exch round exch itransform
	} bind def
/dnormalize {
	dtransform round exch round exch idtransform
	} bind def
/lnormalize { 
	0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop
	} bind def
/H { 
	lnormalize setlinewidth
	} bind def
/Z {
	setlinecap
	} bind def
	/fillvals FMLOCAL
/X { 
	fillvals exch get
	dup type /stringtype eq
	{8 1 setpattern} 
	{grayness}
	ifelse
	} bind def
/V { 
	gsave eofill grestore
	} bind def
/N { 
	stroke
	} bind def
/M {newpath moveto} bind def
/E {lineto} bind def
/D {curveto} bind def
/O {closepath} bind def
	/n FMLOCAL
/L { 
 	/n exch def
	newpath
	normalize
	moveto 
	2 1 n {pop normalize lineto} for
	} bind def
/Y { 
	L 
	closepath
	} bind def
	/x1 FMLOCAL
	/x2 FMLOCAL
	/y1 FMLOCAL
	/y2 FMLOCAL
	/rad FMLOCAL
/R { 
	/y2 exch def
	/x2 exch def
	/y1 exch def
	/x1 exch def
	x1 y1
	x2 y1
	x2 y2
	x1 y2
	4 Y 
	} bind def
/RR { 
	/rad exch def
	normalize
	/y2 exch def
	/x2 exch def
	normalize
	/y1 exch def
	/x1 exch def
	newpath
	x1 y1 rad add moveto
	x1 y2 x2 y2 rad arcto
	x2 y2 x2 y1 rad arcto
	x2 y1 x1 y1 rad arcto
	x1 y1 x1 y2 rad arcto
	closepath
	16 {pop} repeat
	} bind def
/C { 
	grestore
	gsave
	R 
	clip
	} bind def
	/FMpointsize FMLOCAL
/F { 
	FMfonts exch get
	FMpointsize scalefont
	setfont
	} bind def
/Q { 
	/FMpointsize exch def
	F 
	} bind def
/T { 
	moveto show
	} bind def
/RF { 
	rotate
	0 ne {-1 1 scale} if
	} bind def
/TF { 
	gsave
	moveto 
	RF
	show
	grestore
	} bind def
/P { 
	moveto
	0 32 3 2 roll widthshow
	} bind def
/PF { 
	gsave
	moveto 
	RF
	0 32 3 2 roll widthshow
	grestore
	} bind def
/S { 
	moveto
	0 exch ashow
	} bind def
/SF { 
	gsave
	moveto
	RF
	0 exch ashow
	grestore
	} bind def
/B { 
	moveto
	0 32 4 2 roll 0 exch awidthshow
	} bind def
/BF { 
	gsave
	moveto
	RF
	0 32 4 2 roll 0 exch awidthshow
	grestore
	} bind def
/G { 
	gsave
	newpath
	normalize translate 0.0 0.0 moveto 
	dnormalize scale 
	0.0 0.0 1.0 5 3 roll arc 
	closepath fill
	grestore
	} bind def
/A { 
	gsave
	savematrix
	newpath
	2 index 2 div add exch 3 index 2 div sub exch 
	normalize 2 index 2 div sub exch 3 index 2 div add exch 
	translate 
	scale 
	0.0 0.0 1.0 5 3 roll arc 
	restorematrix
	stroke
	grestore
	} bind def
	/x FMLOCAL
	/y FMLOCAL
	/w FMLOCAL
	/h FMLOCAL
	/xx FMLOCAL
	/yy FMLOCAL
	/ww FMLOCAL
	/hh FMLOCAL
	/FMsaveobject FMLOCAL
	/FMoptop FMLOCAL
	/FMdicttop FMLOCAL
/BEGINPRINTCODE { 
	/FMdicttop countdictstack 1 add def 
	/FMoptop count 4 sub def 
	/FMsaveobject save def
	userdict begin 
	/showpage {} def 
	FMNORMALIZEGRAPHICS 
	3 index neg 3 index neg translate
	} bind def
/ENDPRINTCODE {
	count -1 FMoptop {pop pop} for 
	countdictstack -1 FMdicttop {pop end} for 
	FMsaveobject restore 
	} bind def
/gn { 
	0 
	{	46 mul 
		cf read pop 
		32 sub 
		dup 46 lt {exit} if 
		46 sub add 
		} loop
	add 
	} bind def
	/str FMLOCAL
/cfs { 
	/str sl string def 
	0 1 sl 1 sub {str exch val put} for 
	str def 
	} bind def
/ic [ 
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223
	0
	{0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx}
	{10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx}
	{19 hx} {gn hx} {0} {1} {2} {3} {4} {5} {6} {7} {8} {9} {10} {11} {12}
	{13} {14} {15} {16} {17} {18} {19} {gn} {0 wh} {1 wh} {2 wh} {3 wh}
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
	/val FMLOCAL
	/ws FMLOCAL
	/im FMLOCAL
	/bs FMLOCAL
	/cs FMLOCAL
	/len FMLOCAL
	/pos FMLOCAL
/ms {
	/sl exch def
	/val 255 def
	/ws cfs
	/im cfs
	/val 0 def
	/bs cfs
	/cs cfs
	} bind def
400 ms
/ip {
	is
	0
	cf cs readline pop
	{	ic exch get exec
		add
		} forall
	pop

	} bind def
/wh {
	/len exch def
	/pos exch def
	ws 0 len getinterval im pos len getinterval copy pop
	pos len
	} bind def
/bl {
	/len exch def
	/pos exch def
	bs 0 len getinterval im pos len getinterval copy pop
	pos len
	} bind def
/s1 1 string def
/fl {
	/len exch def
	/pos exch def
	/val cf s1 readhexstring pop 0 get def
	pos 1 pos len add 1 sub {im exch val put} for
	pos len
	} bind def
/hx {
	3 copy getinterval
	cf exch readhexstring pop pop
	} bind def
	/h FMLOCAL
	/w FMLOCAL
	/d FMLOCAL
	/lb FMLOCAL
	/bitmapsave FMLOCAL
	/is FMLOCAL
	/cf FMLOCAL
/wbytes {
	dup
	8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
	} bind def
/BEGINBITMAPBWc {
	1 {} COMMONBITMAPc
	} bind def
/BEGINBITMAPGRAYc {
	8 {} COMMONBITMAPc
	} bind def
/BEGINBITMAP2BITc {
	2 {} COMMONBITMAPc
	} bind def
/COMMONBITMAPc {
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def
	sl lb lt {lb ms} if
	/bitmapsave save def
	r
	/is im 0 lb getinterval def
	ws 0 lb getinterval is copy pop
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{ip} image
	bitmapsave restore
	grestore
	} bind def
/BEGINBITMAPBW {
	1 {} COMMONBITMAP
	} bind def
/BEGINBITMAPGRAY {
	8 {} COMMONBITMAP
	} bind def
/BEGINBITMAP2BIT {
	2 {} COMMONBITMAP
	} bind def
/COMMONBITMAP {
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def
	r
	/is w d wbytes string def
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{cf is readhexstring pop} image
	bitmapsave restore
	grestore
	} bind def
	/proc1 FMLOCAL
	/proc2 FMLOCAL
	/newproc FMLOCAL
/Fmcc {
    /proc2 exch cvlit def







|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|

|
|
|

|

|
|
|

|


|
|
|


|

|
|
|








|
|


|


|


|


|




|
|
|
|
|
|
|
|
|
|


|


|


|


|




|
|

|
|

|







651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
	/val FMLOCAL
	/ws FMLOCAL
	/im FMLOCAL
	/bs FMLOCAL
	/cs FMLOCAL
	/len FMLOCAL
	/pos FMLOCAL
/ms { 
	/sl exch def 
	/val 255 def 
	/ws cfs 
	/im cfs 
	/val 0 def 
	/bs cfs 
	/cs cfs 
	} bind def
400 ms 
/ip { 
	is 
	0 
	cf cs readline pop 
	{	ic exch get exec 
		add 
		} forall 
	pop 
	
	} bind def
/wh { 
	/len exch def 
	/pos exch def 
	ws 0 len getinterval im pos len getinterval copy pop
	pos len 
	} bind def
/bl { 
	/len exch def 
	/pos exch def 
	bs 0 len getinterval im pos len getinterval copy pop
	pos len 
	} bind def
/s1 1 string def
/fl { 
	/len exch def 
	/pos exch def 
	/val cf s1 readhexstring pop 0 get def
	pos 1 pos len add 1 sub {im exch val put} for
	pos len 
	} bind def
/hx { 
	3 copy getinterval 
	cf exch readhexstring pop pop 
	} bind def
	/h FMLOCAL
	/w FMLOCAL
	/d FMLOCAL
	/lb FMLOCAL
	/bitmapsave FMLOCAL
	/is FMLOCAL
	/cf FMLOCAL
/wbytes { 
	dup 
	8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse
	} bind def
/BEGINBITMAPBWc { 
	1 {} COMMONBITMAPc
	} bind def
/BEGINBITMAPGRAYc { 
	8 {} COMMONBITMAPc
	} bind def
/BEGINBITMAP2BITc { 
	2 {} COMMONBITMAPc
	} bind def
/COMMONBITMAPc { 
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def 
	sl lb lt {lb ms} if 
	/bitmapsave save def 
	r                    
	/is im 0 lb getinterval def 
	ws 0 lb getinterval is copy pop 
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{ip} image 
	bitmapsave restore 
	grestore
	} bind def
/BEGINBITMAPBW { 
	1 {} COMMONBITMAP
	} bind def
/BEGINBITMAPGRAY { 
	8 {} COMMONBITMAP
	} bind def
/BEGINBITMAP2BIT { 
	2 {} COMMONBITMAP
	} bind def
/COMMONBITMAP { 
	/r exch def
	/d exch def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def 
	r                    
	/is w d wbytes string def
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{cf is readhexstring pop} image
	bitmapsave restore 
	grestore
	} bind def
	/proc1 FMLOCAL
	/proc2 FMLOCAL
	/newproc FMLOCAL
/Fmcc {
    /proc2 exch cvlit def
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
	setcolortransfer
	{pop 0} setundercolorremoval
	{} setblackgeneration
	} bind def
	/tran FMLOCAL
/fakecolorsetup {
	/tran 256 string def
	0 1 255 {/indx exch def
		tran indx
		red indx get 77 mul
		green indx get 151 mul
		blue indx get 28 mul
		add add 256 idiv put} for
	currenttransfer
	{255 mul cvi tran exch get 255.0 div}
	exch Fmcc settransfer
} bind def
/BITMAPCOLOR {
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def
	colorsetup
	/is w d wbytes string def
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{cf is readhexstring pop} {is} {is} true 3 colorimage
	bitmapsave restore
	grestore
	} bind def
/BITMAPCOLORc {
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def
	sl lb lt {lb ms} if
	/bitmapsave save def
	colorsetup
	/is im 0 lb getinterval def
	ws 0 lb getinterval is copy pop
	/cf currentfile def
	w h d [w 0 0 h neg 0 h]
	{ip} {is} {is} true 3 colorimage
	bitmapsave restore
	grestore
	} bind def
/BITMAPTRUECOLORc {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def

        /is w string def

        ws 0 w getinterval is copy pop
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        {ip} {gip} {bip} true 3 colorimage
        bitmapsave restore
        grestore
        } bind def
/BITMAPTRUECOLOR {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        { cf is readhexstring pop }
        { cf gis readhexstring pop }
        { cf bis readhexstring pop }
        true 3 colorimage
        bitmapsave restore
        grestore
        } bind def
/BITMAPTRUEGRAYc {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def

        /is w string def

        ws 0 w getinterval is copy pop
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        {ip gip bip w gray} image
        bitmapsave restore
        grestore
        } bind def
/ww FMLOCAL
/r FMLOCAL
/g FMLOCAL
/b FMLOCAL
/i FMLOCAL
/gray {
        /ww exch def
        /b exch def
        /g exch def
        /r exch def
        0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul
			b i get .114 mul add add r i 3 -1 roll floor cvi put } for
        r
        } bind def
/BITMAPTRUEGRAY {
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def
        w h 8 [w 0 0 h neg 0 h]
        { cf is readhexstring pop
          cf gis readhexstring pop
          cf bis readhexstring pop w gray}  image
        bitmapsave restore
        grestore
        } bind def
/BITMAPGRAY {
	8 {fakecolorsetup} COMMONBITMAP
	} bind def
/BITMAPGRAYc {
	8 {fakecolorsetup} COMMONBITMAPc
	} bind def
/ENDBITMAP {
	} bind def
end
	/ALDsave FMLOCAL
	/ALDmatrix matrix def ALDmatrix currentmatrix pop
/StartALD {
	/ALDsave save def
	 savematrix
	 ALDmatrix setmatrix
	} bind def







|









|



|


|
|
|
|


|



|
|
|

|
|
|
|

|


|


|
|

|
|
|
|

|


|


|



|
|
|
|
|
|
|


|


|
|

|
|
|
|

|







|








|


|



|
|
|
|

|


|


|




|







809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
	setcolortransfer
	{pop 0} setundercolorremoval
	{} setblackgeneration
	} bind def
	/tran FMLOCAL
/fakecolorsetup {
	/tran 256 string def
	0 1 255 {/indx exch def 
		tran indx
		red indx get 77 mul
		green indx get 151 mul
		blue indx get 28 mul
		add add 256 idiv put} for
	currenttransfer
	{255 mul cvi tran exch get 255.0 div}
	exch Fmcc settransfer
} bind def
/BITMAPCOLOR { 
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/bitmapsave save def 
	colorsetup
	/is w d wbytes string def
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{cf is readhexstring pop} {is} {is} true 3 colorimage 
	bitmapsave restore 
	grestore
	} bind def
/BITMAPCOLORc { 
	/d 8 def
	gsave
	translate rotate scale /h exch def /w exch def
	/lb w d wbytes def 
	sl lb lt {lb ms} if 
	/bitmapsave save def 
	colorsetup
	/is im 0 lb getinterval def 
	ws 0 lb getinterval is copy pop 
	/cf currentfile def 
	w h d [w 0 0 h neg 0 h] 
	{ip} {is} {is} true 3 colorimage
	bitmapsave restore 
	grestore
	} bind def
/BITMAPTRUECOLORc { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        
        /is w string def
        
        ws 0 w getinterval is copy pop 
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        {ip} {gip} {bip} true 3 colorimage
        bitmapsave restore 
        grestore
        } bind def
/BITMAPTRUECOLOR { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        { cf is readhexstring pop } 
        { cf gis readhexstring pop } 
        { cf bis readhexstring pop } 
        true 3 colorimage 
        bitmapsave restore 
        grestore
        } bind def
/BITMAPTRUEGRAYc { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        
        /is w string def
        
        ws 0 w getinterval is copy pop 
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        {ip gip bip w gray} image
        bitmapsave restore 
        grestore
        } bind def
/ww FMLOCAL
/r FMLOCAL
/g FMLOCAL
/b FMLOCAL
/i FMLOCAL
/gray { 
        /ww exch def
        /b exch def
        /g exch def
        /r exch def
        0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul
			b i get .114 mul add add r i 3 -1 roll floor cvi put } for
        r
        } bind def
/BITMAPTRUEGRAY { 
        gsave
        translate rotate scale /h exch def /w exch def
        /bitmapsave save def 
        /is w string def
        /gis w string def
        /bis w string def
        /cf currentfile def 
        w h 8 [w 0 0 h neg 0 h] 
        { cf is readhexstring pop 
          cf gis readhexstring pop 
          cf bis readhexstring pop w gray}  image
        bitmapsave restore 
        grestore
        } bind def
/BITMAPGRAY { 
	8 {fakecolorsetup} COMMONBITMAP
	} bind def
/BITMAPGRAYc { 
	8 {fakecolorsetup} COMMONBITMAPc
	} bind def
/ENDBITMAP {
	} bind def
end 
	/ALDsave FMLOCAL
	/ALDmatrix matrix def ALDmatrix currentmatrix pop
/StartALD {
	/ALDsave save def
	 savematrix
	 ALDmatrix setmatrix
	} bind def
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
-0.27 ( binding, and) 457.95 580 P
(a binding on) 152.1 567.89 T
5 F
(<Control-a>) 204.57 567.89 T
3 F
( takes precedence over a binding on) 270.54 567.89 T
5 F
(<Key>.) 416.24 567.89 T
3 F
-0.26 (The mechanism for con\337ict resolution is similar in Tk 4.0 except that one binding can) 170.1 555.89 P
-0.35 (trigger for) 152.1 543.78 P
2 F
-0.35 (each) 194.7 543.78 P
3 F
-0.35 ( binding tag on the window where the event occurs. The bindings trigger in) 213.57 543.78 P







|







1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
-0.27 ( binding, and) 457.95 580 P
(a binding on) 152.1 567.89 T
5 F
(<Control-a>) 204.57 567.89 T
3 F
( takes precedence over a binding on) 270.54 567.89 T
5 F
(<KeyPress>.) 416.24 567.89 T
3 F
-0.26 (The mechanism for con\337ict resolution is similar in Tk 4.0 except that one binding can) 170.1 555.89 P
-0.35 (trigger for) 152.1 543.78 P
2 F
-0.35 (each) 194.7 543.78 P
3 F
-0.35 ( binding tag on the window where the event occurs. The bindings trigger in) 213.57 543.78 P
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
5 F
(Control) 391.17 608.33 T
3 F
(, or any combina-) 433.15 608.33 T
(tion of them. If you wish for a binding not to trigger when a modi\336er is present, you can) 152.1 596.33 T
(just de\336ne an empty binding for that modi\336er combination. For example,) 152.1 584.33 T
5 9 Q
(bind .b <Control-Button-1> {# this script is a no-op}) 179.1 570 T
3 10 Q
(creates a binding that will trigger on mouse button presses when the) 152.1 556.33 T
5 F
(Control) 426.36 556.33 T
3 F
( key is) 468.34 556.33 T
-0.22 (down. If there is also a) 152.1 544.33 P
5 F
-0.52 (<Button-1>) 244.35 544.33 P
3 F
-0.22 ( binding for) 334.3 544.33 P
5 F
-0.52 (.b) 383.35 544.33 P
3 F
-0.22 (, it will no longer be invoked) 395.34 544.33 P
-0.02 (if the) 152.1 532.33 P







|








|







1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
5 F
(Control) 391.17 608.33 T
3 F
(, or any combina-) 433.15 608.33 T
(tion of them. If you wish for a binding not to trigger when a modi\336er is present, you can) 152.1 596.33 T
(just de\336ne an empty binding for that modi\336er combination. For example,) 152.1 584.33 T
5 9 Q
(bind .b <Control-ButtonPress-1> {# this script is a no-op}) 179.1 570 T
3 10 Q
(creates a binding that will trigger on mouse button presses when the) 152.1 556.33 T
5 F
(Control) 426.36 556.33 T
3 F
( key is) 468.34 556.33 T
-0.22 (down. If there is also a) 152.1 544.33 P
5 F
-0.52 (<ButtonPress-1>) 244.35 544.33 P
3 F
-0.22 ( binding for) 334.3 544.33 P
5 F
-0.52 (.b) 383.35 544.33 P
3 F
-0.22 (, it will no longer be invoked) 395.34 544.33 P
-0.02 (if the) 152.1 532.33 P
Changes to doc/tk_mac.n.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2011 Kevin Walzer.
'\" Copyright (c) 2011 Donal K. Fellows.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tk::mac n 8.6 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk::mac \- Access Mac-Specific Functionality on OS X from Tk
.SH SYNOPSIS
.nf
\fB::tk::mac::DoScriptFile\fR
\fB::tk::mac::DoScriptText\fR
\fB::tk::mac::ShowPreferences\fR
\fB::tk::mac::OpenApplication\fR
\fB::tk::mac::ReopenApplication\fR












|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
'\"
'\" Copyright (c) 2011 Kevin Walzer.
'\" Copyright (c) 2011 Donal K. Fellows.
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH tk::mac n 8.6 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
tk::mac \- Access Mac-Specific Functionality on macOS from Tk
.SH SYNOPSIS
.nf
\fB::tk::mac::DoScriptFile\fR
\fB::tk::mac::DoScriptText\fR
\fB::tk::mac::ShowPreferences\fR
\fB::tk::mac::OpenApplication\fR
\fB::tk::mac::ReopenApplication\fR
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

48
49
50
51
52
53
54

55
56
57
58
59
60
61

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

80
81
82
83
84
85
86

87
88
89
90
91
92
93
\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/macOS application environment defines a number of additional
events that applications should respond to. These events are mapped by Tk to
calls to commands in the \fB::tk::mac\fR namespace; unless otherwise noted, if
the command is absent, no action will be taken.
.\" COMMAND: DoScriptFile
.TP
\fB::tk::mac::DoScriptFile\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes a Tcl file when an AppleScript sends a
.QW "do script"
command to Wish with a file path as a parameter.
.\" COMMAND: DoScriptText
.TP
\fB::tk::mac::DoScriptText\fR
.
The default Apple Event handler for AEDoScriptHandler. This command
executes Tcl code when an AppleScript sends a
.QW "do script"
command to Wish with Tcl code or a Tcl procedure as a parameter.
.\" COMMAND: ShowPreferences
.TP
\fB::tk::mac::ShowPreferences\fR
.
The default Apple Event handler for kAEShowPreferences,
.QW pref .
The application menu
.QW "Preferences"
menu item is only enabled when this proc is defined. Typically this command is
used to wrap a specific own preferences command, which pops up a preferences
window. Something like:
.RS
.PP
.CS
proc ::tk::mac::ShowPreferences {} {
    setPref
}
.CE
.RE
.\" COMMAND: OpenApplication
.TP
\fB::tk::mac::OpenApplication\fR
.
If a proc of this name is defined, this proc fill fire when your application
is initially opened. It is the default Apple Event handler for
kAEOpenApplication,
.QW oapp .
.\" COMMAND: ReopenApplication
.TP
\fB::tk::mac::ReopenApplication\fR
.
If a proc of this name is defined it is the default Apple Event handler for
kAEReopenApplication,
.QW rapp ,
the Apple Event sent when your application is opened when it is already
102
103
104
105
106
107
108

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

127
128
129
130
131
132
133
134

135
136
137
138
139
140
141
142
143
144

145
146
147
148
149

150
151
152
153
154
155

156
157
158
159
160
161
162
163
164

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


.SH "ADDITIONAL DIALOGS"
.PP
Aqua/macOS defines additional dialogs that applications should
support.
.\" COMMAND: standardAboutPanel
.TP
\fB::tk::mac::standardAboutPanel\fR
.
Brings the standard Cocoa about panel to the front with 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/tkvars.n.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
This variable holds the file name for a directory containing a library
of Tcl scripts related to Tk.  These scripts include an initialization
file that is normally processed whenever a Tk application starts up,
plus other files containing procedures that implement default behaviors
for widgets.
.RS
.PP
The initial value of \fBtcl_library\fR is set when Tk is added to
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,







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
This variable holds the file name for a directory containing a library
of Tcl scripts related to Tk.  These scripts include an initialization
file that is normally processed whenever a Tk application starts up,
plus other files containing procedures that implement default behaviors
for widgets.
.RS
.PP
The initial value of \fBtk_library\fR is set when Tk is added to
an interpreter;  this is done by searching several different directories
until one is found that contains an appropriate Tk startup script.
If the \fBTK_LIBRARY\fR environment variable exists, then
the directory it names is checked first.
If \fBTK_LIBRARY\fR is not set or does not refer to an appropriate
directory, then Tk checks several other directories based on a
compiled-in default location, the location of the Tcl library directory,
Changes to doc/toplevel.n.
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43


44
45
46
47
48
49
50
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fB\-background\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.
.VS "8.7, TIP262"
An empty background will disable drawing the background image.
.OP \-backgroundimage backgroundImage BackgroundImage
This specifies an image to display on the toplevel's background within
the border of the toplevel (i.e., the image will be clipped by the
toplevel's highlight ring and border, if either are present) on top of
the background;
subwidgets of the toplevel will be drawn on top. The image must have
been created with the \fBimage create\fR command. If specified as the
empty string, no image will be displayed.
.VE "8.7, TIP262"
.OP \-class class Class
Specifies a class for the window.
This class will be used when querying the option database for
the window's other options, and it will also be used later for
other purposes such as bindings.


The \fB\-class\fR option may not be changed with the \fBconfigure\fR
widget command.
.OP \-colormap colormap Colormap
Specifies a colormap to use for the window.
The value may be either \fBnew\fR, in which case a new colormap is
created for the window and its children, or the name of another
window (which must be on the same screen and have the same visual







<
<
<
<
<
<
<
<
<
<
<




|
>
>







21
22
23
24
25
26
27











28
29
30
31
32
33
34
35
36
37
38
39
40
41
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-background background Background
This option is the same as the standard \fB\-background\fR option
except that its value may also be specified as an empty string.
In this case, the widget will display no background or border, and
no colors will be consumed from its colormap for its background
and border.











.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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
Specifies the screen on which to place the new window.
Any valid screen name may be used, even one associated with a
different display.
Defaults to the same screen as its parent.
This option is special in that it may not be specified via the option
database, and it may not be modified with the \fBconfigure\fR
widget command.
.OP \-tile tile Tile
.VS "8.7, TIP262"
This specifies how to draw the background image (see
\fB\-backgroundimage\fR) on the toplevel.
If true (according to \fBTcl_GetBoolean\fR), the image will be tiled
to fill the whole toplevel, with the origin of the first copy of the
image being the top left of the interior of the toplevel.
If false (the default), the image will be centered within the toplevel.
.VE "8.7, TIP262"
.OP \-use use Use
This option is used for embedding. If the value is not an empty string,
it must be the window identifier of a container window, specified as
a hexadecimal string like the ones returned by the \fBwinfo id\fR
command. The toplevel widget will be created as a child of the given
container instead of the root window for the screen.  If the container
window is in a Tk application, it must be a frame or toplevel widget for







<
<
<
<
<
<
<
<
<







69
70
71
72
73
74
75









76
77
78
79
80
81
82
Specifies the screen on which to place the new window.
Any valid screen name may be used, even one associated with a
different display.
Defaults to the same screen as its parent.
This option is special in that it may not be specified via the option
database, and it may not be modified with the \fBconfigure\fR
widget command.









.OP \-use use Use
This option is used for embedding. If the value is not an empty string,
it must be the window identifier of a container window, specified as
a hexadecimal string like the ones returned by the \fBwinfo id\fR
command. The toplevel widget will be created as a child of the given
container instead of the root window for the screen.  If the container
window is in a Tk application, it must be a frame or toplevel widget for
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
path name of the new window.
.PP
A toplevel is similar to a \fBframe\fR except that it is created as a
top-level window:  its X parent is the root window of a screen
rather than the logical parent from its Tk path name.  The primary
purpose of a toplevel is to serve as a container for dialog boxes
and other collections of widgets.  The only visible features
of a toplevel are its background and an optional 3-D border
to make the toplevel appear raised or sunken.
.SH "WIDGET COMMAND"
.PP
The \fBtoplevel\fR command creates a new Tcl command whose
name is the same as the path name of the toplevel's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.PP
.CS
\fIpathName option \fR?\fIarg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the toplevel widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for toplevel widgets:
.TP







|









|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
path name of the new window.
.PP
A toplevel is similar to a \fBframe\fR except that it is created as a
top-level window:  its X parent is the root window of a screen
rather than the logical parent from its Tk path name.  The primary
purpose of a toplevel is to serve as a container for dialog boxes
and other collections of widgets.  The only visible features
of a toplevel are its background color and an optional 3-D border
to make the toplevel appear raised or sunken.
.SH "WIDGET COMMAND"
.PP
The \fBtoplevel\fR command creates a new Tcl command whose
name is the same as the path name of the toplevel's window.  This
command may be used to invoke various
operations on the widget.  It has the following general form:
.PP
.CS
\fIpathName option \fR?\fIarg arg ...\fR?
.CE
.PP
\fIPathName\fR is the name of the command, which is the same as
the toplevel widget's path name.  \fIOption\fR and the \fIarg\fRs
determine the exact behavior of the command.  The following
commands are possible for toplevel widgets:
.TP
Changes to doc/ttk_button.n.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
\fBttk::button\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::button\fR widget displays a textual label and/or image,
and evaluates a command when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-justify	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A script to evaluate when the widget is invoked.
.OP \-default default Default







|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
\fBttk::button\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
A \fBttk::button\fR widget displays a textual label and/or image,
and evaluates a command when pressed.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-state	\-style
\-takefocus	\-text	\-textvariable
\-underline	\-width
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
A script to evaluate when the widget is invoked.
.OP \-default default Default
Changes to doc/ttk_combobox.n.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.SH DESCRIPTION
.PP
A \fBttk::combobox\fR combines a text field with a pop-down list of values;
the user may select the value of the text field from among the
values in the list.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style	\-placeholder	\-placeholderforeground
.SE
.\" ALSO: Other entry widget options
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
Boolean value.
If set, the widget selection is linked to the X selection.
.OP \-justify justify Justify







|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.SH DESCRIPTION
.PP
A \fBttk::combobox\fR combines a text field with a pop-down list of values;
the user may select the value of the text field from among the
values in the list.
.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style
.SE
.\" ALSO: Other entry widget options
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
Boolean value.
If set, the widget selection is linked to the X selection.
.OP \-justify justify Justify
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-postoffset\fP \fIpadding\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.RS
Text entry select background.
.RE
\fB\-selectforeground\fP \fIcolor\fP







<
<







146
147
148
149
150
151
152


153
154
155
156
157
158
159
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br


\fB\-postoffset\fP \fIpadding\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.RS
Text entry select background.
.RE
\fB\-selectforeground\fP \fIcolor\fP
Changes to doc/ttk_entry.n.
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
with the \fB\-textvariable\fR option.
Entry widgets support horizontal scrolling with the
standard \fB\-xscrollcommand\fR option and \fBxview\fR widget command.
.SO ttk_widget
\-class	\-cursor
\-font	\-foreground
\-style
\-takefocus	\-xscrollcommand	\-placeholder	\-placeholderforeground
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
A boolean value specifying whether or not
a selection in the widget should be linked to the X selection.
If the selection is exported, then selecting in the widget deselects
the current X selection, selecting outside the widget deselects any







|







22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
with the \fB\-textvariable\fR option.
Entry widgets support horizontal scrolling with the
standard \fB\-xscrollcommand\fR option and \fBxview\fR widget command.
.SO ttk_widget
\-class	\-cursor
\-font	\-foreground
\-style
\-takefocus	\-xscrollcommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-exportselection exportSelection ExportSelection
A boolean value specifying whether or not
a selection in the widget should be linked to the X selection.
If the selection is exported, then selecting in the widget deselects
the current X selection, selecting outside the widget deselects any
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectborderwidth\fP \fIamount\fP
.br
\fB\-selectforeground\fP \fIcolor\fP







<
<







452
453
454
455
456
457
458


459
460
461
462
463
464
465
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br


\fB\-relief\fP \fIrelief\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectborderwidth\fP \fIamount\fP
.br
\fB\-selectforeground\fP \fIcolor\fP
Changes to doc/ttk_frame.n.
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
\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:







|
|







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
\fBttk::frame\fR \fIpathName \fR?\fIoptions\fR?
.BE
.SH DESCRIPTION
.PP
A \fBttk::frame\fR widget is a container, used to group other widgets
together.
.SO ttk_widget
\-class	\-cursor	\-padding
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-borderwidth borderWidth BorderWidth
The desired width of the widget border.  Defaults to 0.
May be ignored depending on the theme used.
.OP \-relief relief Relief
One of the standard Tk border styles:
Changes to doc/ttk_image.n.
75
76
77
78
79
80
81



82
83
84
85
86
87
88
89
90
91
92
93
94
95
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







>
>
>






|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
or vertically (\fB\-sticky ns\fR),
subregions of the image are replicated to fill the parcel
based on the \fB\-border\fR option.
The \fB\-border\fR divides the image into 9 regions:
four fixed corners, top and left edges (which may be tiled horizontally),
left and right edges (which may be tiled vertically),
and the central area (which may be tiled in both directions).
.PP
An image element that is not meant to claim any space (for example when used
as a background image) should use \fB\-width 0\fR and \fB\-height 0\fR.
.SH "EXAMPLE"
.PP
.CS
set img1 [image create photo \-file button.png]
set img2 [image create photo \-file button-pressed.png]
set img3 [image create photo \-file button-active.png]
ttk::style element create Button.button image \e
    [list $img1  pressed $img2  active $img3] \e
    \-border {2 4} \-sticky we
.CE
.SH "SEE ALSO"
ttk::intro(n), ttk::style(n), ttk_vsapi(n), image(n), photo(n)
.SH KEYWORDS
style, theme, appearance, pixmap theme, image
Changes to doc/ttk_intro.n.
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
.PP
For example, the class bindings for the \fBttk::button\fR
widget are:
.PP
.CS
bind TButton <Enter>		{ %W state active }
bind TButton <Leave>		{ %W state !active }
bind TButton <Button-1>		{ %W state pressed }
bind TButton <Button1-Leave>	{ %W state !pressed }
bind TButton <Button1-Enter>	{ %W state pressed }
bind TButton <ButtonRelease-1>	\e
    { %W instate {pressed} { %W state !pressed ; %W invoke } }
.CE
.PP
This specifies that the widget becomes \fBactive\fR when







|







117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
.PP
For example, the class bindings for the \fBttk::button\fR
widget are:
.PP
.CS
bind TButton <Enter>		{ %W state active }
bind TButton <Leave>		{ %W state !active }
bind TButton <ButtonPress-1>	{ %W state pressed }
bind TButton <Button1-Leave>	{ %W state !pressed }
bind TButton <Button1-Enter>	{ %W state pressed }
bind TButton <ButtonRelease-1>	\e
    { %W instate {pressed} { %W state !pressed ; %W invoke } }
.CE
.PP
This specifies that the widget becomes \fBactive\fR when
Changes to doc/ttk_label.n.
14
15
16
17
18
19
20
21
22
23
24
25
26
27






28
29
30










31
32
33
34
35
36
37
.BE
.SH DESCRIPTION
.PP
A \fBttk::label\fR widget displays a textual label and/or image.
The label may be linked to a Tcl variable
to automatically change the displayed text.
.SO ttk_widget
\-anchor	\-class	\-compound	\-cursor
\-font	\-foreground
\-image	\-justify	\-padding	\-state	\-style	\-takefocus
\-text	\-textvariable	\-underline
\-width	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"






.OP \-background frameColor FrameColor
The widget's background color.
If unspecified, the theme default is used.










.OP \-relief relief Relief
.\" Rewrite this:
Specifies the 3-D effect desired for the widget border.
Valid values are
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR,
and \fBsunken\fR.
.OP \-wraplength wrapLength WrapLength







|
|
|
|
<


>
>
>
>
>
>



>
>
>
>
>
>
>
>
>
>







14
15
16
17
18
19
20
21
22
23
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
.BE
.SH DESCRIPTION
.PP
A \fBttk::label\fR widget displays a textual label and/or image.
The label may be linked to a Tcl variable
to automatically change the displayed text.
.SO ttk_widget
\-class	\-compound	\-cursor
\-image	\-padding	\-state
\-style	\-takefocus	\-text
\-textvariable	\-underline	\-width

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-anchor anchor Anchor
Specifies how the information in the widget is positioned
relative to the inner margins.  Legal values are
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, and \fBcenter\fR.
See also \fB\-justify\fR.
.OP \-background frameColor FrameColor
The widget's background color.
If unspecified, the theme default is used.
.OP \-font font Font
Font to use for label text.
.OP \-foreground textColor TextColor
The widget's foreground color.
If unspecified, the theme default is used.
.OP \-justify justify Justify
If there are multiple lines of text, specifies how
the lines are laid out relative to one another.
One of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
See also \fB\-anchor\fR.
.OP \-relief relief Relief
.\" Rewrite this:
Specifies the 3-D effect desired for the widget border.
Valid values are
\fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR,
and \fBsunken\fR.
.OP \-wraplength wrapLength WrapLength
Changes to doc/ttk_labelframe.n.
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.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:







|
|







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
.BE
.SH DESCRIPTION
.PP
A \fBttk::labelframe\fR widget is a container used to group other widgets
together.  It has an optional label, which may be a plain text string or
another widget.
.SO ttk_widget
\-class	\-cursor	\-padding
\-style	\-takefocus
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.\" XXX: Currently included, but may go away:
.\" XXX: .OP -borderwidth borderWidth BorderWidth
.\" XXX: The desired width of the widget border.  Default is theme-dependent.
.\" XXX: .OP -relief relief Relief
.\" XXX: One of the standard Tk border styles:
Changes to doc/ttk_notebook.n.
228
229
230
231
232
233
234
235








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




















252
253
254
255
256
257














258
259
260
261
262
263
264
265
266
267
268
269
.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:







|
>
>
>
>
>
>
>
>
















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>






>
>
>
>
>
>
>
>
>
>
>
>
>
>












228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-tabmargins\fP \fIpadding\fP
.br
\fB\-tabposition\fP \fIposition\fP
.RS
Specifies the position of the tab row or column as a string of length
1 or 2.  The first character indicates the side as \fBn\fP, \fBs\fP,
\fBw\fP, or \fBe\fP, while the second character (if present) is the
sticky bit (specified as \fBw\fP, \fBe\fP, \fBn\fP, or \fBs\fP) within
the tab position.  The default position is \fBn\fP for the \fBaqua\fP
theme and \fBnw\fP for all the other built-in themes.
.RE
.br
.PP
\fBTNotebook.Tab\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-compound\fP \fIcompound\fP
.br
\fB\-expand\fP \fIpadding\fP
.RS
Defines how much the tab grows in size.  Usually used with the
\fBselected\fP dynamic state.  \fB\-tabmargins\fP should be
set appropriately so that there is room for the tab growth.
For example, the Ttk library file \fBvistaTheme.tcl\fP contains
the lines
.CS
ttk::style configure TNotebook -tabmargins {2 2 2 0}
ttk::style map TNotebook.Tab -expand {selected {2 2 2 2}}
.CE
which are valid for the default value \fBnw\fP of the \fB\-tabposition\fP
style option.  For a \fBttk::notebook\fP style \fBnbStyle\fP defined by
.CS
set nbStyle SW.TNotebook
ttk::style configure $nbStyle -tabposition sw
.CE
you will have to adapt the above settings as follows:
.CS
ttk::style configure $nbStyle -tabmargins {2 0 2 2}
ttk::style map $nbStyle.Tab -expand {selected {2 2 2 2}}
.CE
The easiest way to do this is to invoke the library procedure
\fBttk::configureNotebookStyle\fP with \fB$nbStyle\fP as argument, after
setting the style's \fB\-tabposition\fP option.
.RE
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.RS
Some themes use a different \fIpadding\fP for the selected tab.  For example,
the Ttk library file \fBclamTheme.tcl\fP contains the lines
.CS
ttk::style configure TNotebook.Tab -padding {6 2 6 2}
ttk::style map TNotebook.Tab -padding {selected {6 4 6 2}}
.CE
which are valid for the default value \fBnw\fP of the \fB\-tabposition\fP
style option.  For a \fBttk::notebook\fP style having a different tab position
you will have to adapt the above settings accordingly.  Again, the easiest way
to do this is to invoke the library procedure \fBttk::configureNotebookStyle\fP
with the style name as argument, after setting the style's \fB\-tabposition\fP
option.
.RE
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), grid(n)
.SH "KEYWORDS"
pane, tab
'\" Local Variables:
'\" mode: nroff
'\" End:
Changes to doc/ttk_panedwindow.n.
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
.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:







|
<
<







113
114
115
116
117
118
119
120


121
122
123
124
125
126
127
.ta 5.5c 11c
\fBcget\fR	\fBconfigure\fR
\fBinstate\fR	\fBstate\fR
.DE
.SH "VIRTUAL EVENTS"
.PP
The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
LeaveNotify/NotifyInferior events.


.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::panedwindow\fP is \fBTPanedwindow\fP.  The
sash has a class name of \fBSash\fP.
.PP
\fBTPanedwindow\fP styling options configurable with \fBttk::style\fP
are:
Changes to doc/ttk_progressbar.n.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
.SH DESCRIPTION
.PP
A \fBttk::progressbar\fR widget shows the status of a long-running
operation.  They can operate in two modes: \fIdeterminate\fR mode shows the
amount completed relative to the total amount of work to be done, and
\fIindeterminate\fR mode provides an animated display to let the user know
that something is happening.
.PP
If the value of \fB-orient\fR is \fBhorizontal\fR a text string can be
displayed inside the progressbar. This string can be configured using
the \fB-anchor\fR, \fB-font\fR, \fB-foreground\fR, \fB-justify\fR,
\fB-text\fR and \fB-wraplength\fR options. If the value of \fB-orient\fR
is \fBvertical\fR then these options are ignored.
.SO ttk_widget
\-anchor	\-class	\-cursor
\-font	\-foreground	\-justify	\-style
\-takefocus	\-text	\-wraplength
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-length length Length
Specifies the length of the long axis of the progress bar
(width if horizontal, height if vertical). The value may have any of the forms
acceptable to \fBTk_GetPixels\fR.
.OP \-maximum maximum Maximum
A floating point number specifying the maximum \fB\-value\fR.
Defaults to 100.
.OP \-mode mode Mode
One of \fBdeterminate\fR or \fBindeterminate\fR.
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.







<
<
<
<
<
<

|
|
<




|
<







15
16
17
18
19
20
21






22
23
24

25
26
27
28
29

30
31
32
33
34
35
36
.SH DESCRIPTION
.PP
A \fBttk::progressbar\fR widget shows the status of a long-running
operation.  They can operate in two modes: \fIdeterminate\fR mode shows the
amount completed relative to the total amount of work to be done, and
\fIindeterminate\fR mode provides an animated display to let the user know
that something is happening.






.SO ttk_widget
\-class	\-cursor	\-takefocus
\-style

.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-length length Length
Specifies the length of the long axis of the progress bar
(width if horizontal, height if vertical).

.OP \-maximum maximum Maximum
A floating point number specifying the maximum \fB\-value\fR.
Defaults to 100.
.OP \-mode mode Mode
One of \fBdeterminate\fR or \fBindeterminate\fR.
.OP \-orient orient Orient
One of \fBhorizontal\fR or \fBvertical\fR.
Changes to doc/ttk_scale.n.
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
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







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
is omitted.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scale\fP is \fBTScale\fP.
.PP
Dynamic states: \fBactive\fP.
.PP
\fBTScale\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
Changes to doc/ttk_scrollbar.n.
114
115
116
117
118
119
120








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







>
>
>
>
>
>
>
>








<
<
<
<
<
<
<
<







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








137
138
139
140
141
142
143
The widget should adjust its view so that the point given
by \fIfraction\fR appears at the beginning of the widget.
If \fIfraction\fR is 0 it refers to the beginning of the
document.  1.0 refers to the end of the document, 0.333
refers to a point one-third of the way through the document,
and so on.
.TP
\fIprefix \fBscroll \fInumber \fBunits\fR
The widget should adjust its view by \fInumber\fR units.
The units are defined in whatever way makes sense for the widget,
such as characters or lines in a text widget.
\fINumber\fR is either 1, which means one unit should scroll off
the top or left of the window, or \-1, which means that one unit
should scroll off the bottom or right of the window.
.TP
\fIprefix \fBscroll \fInumber \fBpages\fR
The widget should adjust its view by \fInumber\fR pages.
It is up to the widget to define the meaning of a page;  typically
it is slightly less than what fits in the window, so that there
is a slight overlap between the old and new views.
\fINumber\fR is either 1, which means the next page should
become visible, or \-1, which means that the previous page should
become visible.








.SH "WIDGET STATES"
.PP
The scrollbar automatically sets the \fBdisabled\fR state bit.
when the entire range is visible (range is 0.0 to 1.0),
and clears it otherwise.
It also sets the \fBactive\fR and \fBpressed\fR state flags
of individual elements, based on the position and state of the mouse pointer.
Changes to doc/ttk_sizegrip.n.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.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







|







24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
.SH "WIDGET COMMAND"
.PP
Sizegrip widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
.SH "PLATFORM-SPECIFIC NOTES"
.PP
On macOS, toplevel windows automatically include a built-in
size grip by default.
Adding a \fBttk::sizegrip\fR there is harmless, since
the built-in grip will just mask the widget.
.SH EXAMPLES
.PP
Using pack:
.CS
Changes to doc/ttk_spinbox.n.
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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.







|
|







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
A \fBttk::spinbox\fR widget is a \fBttk::entry\fR widget with built-in
up and down buttons that are used to either modify a numeric value or
to select among a set of values. The widget implements all the features
of the \fBttk::entry\fR widget including support of the
\fB\-textvariable\fR option to link the value displayed by the widget
to a Tcl variable.
.SO ttk_widget
\-class	\-cursor	\-state
\-style	\-takefocus	\-xscrollcommand
.SE
.SO ttk_entry
\-validate	\-validatecommand
.SE
.SH "WIDGET-SPECIFIC OPTIONS"
.OP \-command command Command
Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-placeholderforeground\fP \fIcolor\fP
.br
\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectforeground\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure







<
<







111
112
113
114
115
116
117


118
119
120
121
122
123
124
.br
\fB\-insertwidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br


\fB\-selectbackground\fP \fIcolor\fP
.br
\fB\-selectforeground\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
Changes to doc/ttk_treeview.n.
97
98
99
100
101
102
103


104
105
106
107
108
109
110
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.







>
>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
Returns the bounding box (relative to the treeview widget's window)
of the specified \fIitem\fR
in the form \fIx y width height\fR.
If \fIcolumn\fR is specified, returns the bounding box of that cell.
If the \fIitem\fR is not visible
(i.e., if it is a descendant of a closed item or is scrolled offscreen),
returns the empty list.
If the element is partially visible, the result gives the full area of the
element, including any parts that are not visible.
.TP
\fIpathname \fBcget \fIoption\fR
Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
.TP
\fIpathname \fBchildren \fIitem\fR ?\fInewchildren\fR?
If \fInewchildren\fR is not specified,
returns the list of children belonging to \fIitem\fR.
207
208
209
210
211
212
213


214
215
216
217
218
219
220
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
.RS
Returns one of:
.IP heading







>
>







209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
Use \fIpathname heading #0\fR to configure the tree column heading.
.RE
.TP
\fIpathname \fBidentify \fIcomponent x y\fR
Returns a description of the specified \fIcomponent\fR
under the point given by \fIx\fR and \fIy\fR,
or the empty string if no such \fIcomponent\fR is present at that position.
The values \fIx\fR and \fIy\fR may have any of the forms acceptable to
\fBTk_GetPixels\fR.
The following subcommands are supported:
.RS
.TP
\fIpathname \fBidentify region \fIx y\fR
.RS
Returns one of:
.IP heading
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394





395
396
397
398
399
400
401
.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







<
<
<
<
<







|

|


















<
<
<
<
<
<









>
>
>
>
>







344
345
346
347
348
349
350





351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378






379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
.TP
\fIpathname \fBstate\fR ?\fIstateSpec\fR?
Modify or query the widget state; see \fIttk::widget(n)\fR.
.TP
\fIpathName \fBtag \fIargs...\fR
.RS
.TP





\fIpathName \fBtag bind \fItagName \fR?\fIsequence\fR? ?\fIscript\fR?
Add a Tk binding script for the event sequence \fIsequence\fR
to the tag \fItagName\fR.  When an X event is delivered to an item,
binding scripts for each of the item's \fB\-tags\fR are evaluated
in order as per \fIbindtags(n)\fR.
.RS
.PP
\fB<KeyPress>\fR, \fB<KeyRelease>\fR, and virtual events
are sent to the focus item.
\fB<ButtonPress>\fR, \fB<ButtonRelease>\fR, and \fB<Motion>\fR events
are sent to the item under the mouse pointer.
No other event types are supported.
.PP
The binding \fIscript\fR undergoes \fB%\fR-substitutions before
evaluation; see \fBbind(n)\fR for details.
.RE
.TP
\fIpathName \fBtag configure \fItagName\fR ?\fIoption\fR? ?\fIvalue option value...\fR?
Query or modify the options for the specified \fItagName\fR.
If one or more \fIoption/value\fR pairs are specified,
sets the value of those options for the specified tag.
If a single \fIoption\fR is specified,
returns the value of that option
(or the empty string if the option has not been specified for \fItagName\fR).
With no additional arguments,
returns a dictionary of the option settings for \fItagName\fR.
See \fBTAG OPTIONS\fR for the list of available options.
.TP






\fIpathName \fBtag has \fItagName\fR ?\fIitem\fR?
If \fIitem\fR is specified, returns 1 or 0
depending on whether the specified item has the named tag.
Otherwise, returns a list of all items which have
the specified tag.
.TP
\fIpathName \fBtag names\fR
Returns a list of all tags used by the widget.
.TP
\fIpathName \fBtag add \fItag items\fR
Adds the specified \fItag\fR to each of the listed \fIitems\fR.
If \fItag\fR is already present for a particular item,
then the \fB\-tags\fR for that item are unchanged.
.TP
\fIpathName \fBtag remove \fItag\fR ?\fIitems\fR?
Removes the specified \fItag\fR from each of the listed \fIitems\fR.
If \fIitems\fR is omitted, removes \fItag\fR from each item in the tree.
If \fItag\fR is not present for a particular item,
then the \fB\-tags\fR for that item are unchanged.
.RE
.PP
474
475
476
477
478
479
480



481
482
483
484
485
486
487
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.







>
>
>







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
then data column \fIn\fR is displayed in display column \fB#\fIn+1\fR.
Again, \fBcolumn #0 always refers to the tree column\fR.
.SH "VIRTUAL EVENTS"
.PP
The treeview widget generates the following virtual events.
.IP <<TreeviewSelect>>
Generated whenever the selection changes.
It might also be generated when selection is affected but not actually changed.
Further, multiple selection changes could happen before events can be processed
leading to multiple events with the same visible selection.
.IP <<TreeviewOpen>>
Generated just before setting the focus item to \fB\-open true\fR.
.IP <<TreeviewClose>>
Generated just after setting the focus item to \fB\-open false\fR.
.PP
The \fBfocus\fR and \fBselection\fR widget commands can be used
to determine the affected item or items.
503
504
505
506
507
508
509






510
511
512


513

514


515
516
517
518
519
520
521
522
\fB\-background\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP






.br
\fB\-rowheight\fP \fIamount\fP
.RS


The \fB\-rowheight\fP value is not corrected by the \fBtk scaling\fP

value or by the configured font size and must always be set.  Also make


sure that the \fB\-rowheight\fP is large enough to contain any images.
.PP
To adjust the \fB\-rowheight\fP for the Treeview style, use the following code
after \fBtk scaling\fP has been applied.
Note that even if you do not support or change \fBtk scaling\fP
in your program, your users may have it set in their .wishrc.
.RE
.PP







>
>
>
>
>
>



>
>
|
>
|
>
>
|







504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
\fB\-background\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indent\fP \fIamount\fP
.RS
Specifies how far items are indented from their parents. Defaults to 20 pixels.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
.RE
.br
\fB\-rowheight\fP \fIamount\fP
.RS
This is the standard height for an item. Defaults to 20 pixels.
The value may have any of the forms acceptable to \fBTk_GetPixels\fR.
If \fB\-rowheight\fP is not set by the style, it is set by measuring an
item and a cell layout with the style's settings.
This thus picks up the font and
any focus ring or padding from the theme's layout.
The \fB\-rowheight\fP may need to be set to make sure that a row
is large enough to contain any images.
.PP
To adjust the \fB\-rowheight\fP for the Treeview style, use the following code
after \fBtk scaling\fP has been applied.
Note that even if you do not support or change \fBtk scaling\fP
in your program, your users may have it set in their .wishrc.
.RE
.PP
Changes to doc/ttk_widget.n.
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
.RE
.OP \-yscrollcommand yScrollCommand ScrollCommand
A command prefix, used to communicate with vertical scrollbars.
See the description of \fB\-xscrollcommand\fR above for details.
.SH "LABEL OPTIONS"
The following options are supported by labels, buttons,
and other button-like widgets:
.OP \-anchor anchor Anchor
Specifies how the information in the widget is positioned
relative to the inner margins.  Legal values are
\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR,
\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, and \fBcenter\fR.
See also \fB\-justify\fR (for widgets supporting this option).
.OP \-compound compound Compound
Specifies how to display the image relative to the text,
in the case both \fB\-text\fR and \fB\-image\fR are present.
If set to the empty string (the default), the rules described in the
"Elements" section of \fIttk::intro(n)\fR explain which value is actually
used.
Valid values are:
.RS
.IP text
Display text only.
.IP image
Display image only.
.IP center
Display text centered on top of image.







<
<
<
<
<
<






|







67
68
69
70
71
72
73






74
75
76
77
78
79
80
81
82
83
84
85
86
87
.RE
.OP \-yscrollcommand yScrollCommand ScrollCommand
A command prefix, used to communicate with vertical scrollbars.
See the description of \fB\-xscrollcommand\fR above for details.
.SH "LABEL OPTIONS"
The following options are supported by labels, buttons,
and other button-like widgets:






.OP \-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.
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

175
176
177
178
179

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

196
197
198
199
200
201
202
203


204
205
206
207
208
209
210
211
212
213

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

231
232

233
234
235
236
237
238

239
240
241
242
243
244
245
246
247
248

249
250
251
252

253
254
255
256
257

258
259
260
261
262
263
264

265
266
267
268
269
270
271

272
273

274
275
276
277
278
279

280
281
282
283
284
285
286
287
288
289

290
291
292
293

294
295
296
297
298

299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384


385
386
387
388
389
390
391
Specifies an image to display.
This is a list of 1 or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR pairs
as per \fBstyle map\fR, specifying different images to use when
the widget is in a particular state or combination of states.
All images in the list should have the same size.
.OP \-justify justify Justify
If there are multiple lines of text, specifies how
the lines are laid out relative to one another.
One of \fBleft\fR, \fBcenter\fR, or \fBright\fR.
See also \fB\-anchor\fR (for widgets supporting this option).
.OP \-padding padding Padding
Specifies the internal padding for the widget.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right padding;
a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-text text Text
Specifies a text string to be displayed inside the widget
(unless overridden by \fB\-textvariable\fR for the widgets supporting this option).
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value will be used
in place of the \fB\-text\fR resource.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to underline
in the text string.
The underlined character is used for mnemonic activation.
.OP \-width width Width
If greater than zero, specifies how much space, in character widths,
to allocate for the text label.
If less than zero, specifies a minimum width.
If zero or unspecified, the natural width of the text label is used.
Note that some themes may specify a non-zero \fB\-width\fR
in the style.
.OP \-wraplength wrapLength WrapLength
Specifies the maximum line length. The value may have any of the forms
acceptable to \fBTk_GetPixels\fR. If this option is less than or equal
to zero, then automatic wrapping is not performed; otherwise
the text is split into lines such that no line is longer
than the specified value.
.SH "ENTRY OPTIONS"
The following options are supported by entry, spinbox and combobox:
.OP \-placeholder placeHolder PlaceHolder
Specifies a help text string to display if no text is otherwise displayed,
that is when the widget is empty. The placeholder text is displayed using
the values of the \fB\-font\fR, \fB\-justify\fR and
\fB\-placeholderforeground\fR options.
.OP \-placeholderforeground placeHolderForeground PlaceHolderForeground
Specifies the foreground color of the placeholder text.
.SH "COMPATIBILITY OPTIONS"
This option is only available for themed widgets that have
.QW corresponding
traditional Tk widgets.
.OP \-state state State
May be set to \fBnormal\fR or \fBdisabled\fR
to control the \fBdisabled\fR state bit.
This is a write-only option:
setting it changes the widget state,
but the \fBstate\fR widget command
does not affect the \fB\-state\fR option.
.SH COMMANDS

.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.

.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If one or more \fIoption\-value\fR pairs are specified,
then the command modifies the given widget option(s)
to have the given value(s);
in this case the command returns an empty string.
If \fIoption\fR is specified with no \fIvalue\fR,
then the command returns a list describing the named option:
the elements of the list are the
option name, database name, database class, default value,
and current value.
.\" Note: Ttk widgets don't use TK_OPTION_SYNONYM.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR.

.TP
\fIpathName \fBidentify element \fIx y\fR
.
Returns the name of the element under the point given
by \fIx\fR and \fIy\fR, or an empty string if the point does
not lie within any element.
\fIx\fR and \fIy\fR are pixel coordinates relative to the widget.
Some widgets accept other \fBidentify\fR subcommands.


.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget's state.
If \fIscript\fR is not specified, returns 1 if
the widget state matches \fIstatespec\fR and 0 otherwise.
If \fIscript\fR is specified, equivalent to
.CS
if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR
.CE

.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
.
Modify or inquire widget state.
If \fIstateSpec\fR is present, sets the widget state:
for each flag in \fIstateSpec\fR, sets the corresponding flag
or clears it if prefixed by an exclamation point.
.RS
Returns a new state spec indicating which flags were changed:
.CS
set changes [\fIpathName \fRstate \fIspec\fR]
\fIpathName \fRstate $changes
.CE
will restore \fIpathName\fR to the original state.
If \fIstateSpec\fR is not specified,
returns a list of the currently-enabled state flags.
.RE

.TP
\fIpathName \fBxview \fIargs\fR

This command is used to query and change the horizontal position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the left, the middle 40% is visible
in the window, and 40% of the content is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\fR \fIindex\fR

Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the left edge of the window.
.TP
\fIpathName \fBxview moveto\fI fraction\fR

Adjusts the view in the window so that the character \fIfraction\fR of the
way through the content appears at the left edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fBxview scroll \fInumber what\fR

This command shifts the view in the window left or right according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer or a float, but if it is a float then
it is converted to an integer, rounded away from 0.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is

\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display.
.RE

.TP
\fIpathName \fByview \fIargs\fR

This command is used to query and change the vertical position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fByview\fR

Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the vertical span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the top, the middle 40% is visible
in the window, and 40% of the content is off-screen to the bottom.
These are the same values passed to scrollbars via the \fB\-yscrollcommand\fR
option.
.TP
\fIpathName \fByview\fR \fIindex\fR

Adjusts the view in the window so that the content given by \fIindex\fR
is displayed at the top edge of the window.
.TP
\fIpathName \fByview moveto\fI fraction\fR

Adjusts the view in the window so that the item \fIfraction\fR of the
way through the content appears at the top edge of the window.
\fIFraction\fR must be a fraction between 0 and 1.
.TP
\fIpathName \fByview scroll \fInumber what\fR

This command shifts the view in the window up or down according to
\fInumber\fR and \fIwhat\fR.
\fINumber\fR must be an integer.
\fIWhat\fR must be either \fBpages\fR or \fBunits\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is

\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then items farther to the top
become visible;  if it is positive then items farther to the bottom
become visible.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR average-width characters on the display.
.RE
.SH "WIDGET STATES"
The widget state is a bitmap of independent state flags.
Widget state flags include:
.TP
\fBactive\fR
.
The mouse cursor is over the widget
and pressing a mouse button will cause some action to occur. (aka
.QW prelight
(Gnome),
.QW hot
(Windows),
.QW hover ).
.TP
\fBdisabled\fR
.
Widget is disabled under program control (aka
.QW unavailable ,
.QW inactive ).
.TP
\fBfocus\fR
.
Widget has keyboard focus.
.TP
\fBpressed\fR
.
Widget is being pressed (aka
.QW armed
in Motif).
.TP
\fBselected\fR
.
.QW On ,
.QW true ,
or
.QW current
for things like checkbuttons and radiobuttons.
.TP
\fBbackground\fR
.
Windows and the Mac have a notion of an
.QW active
or foreground window.
The \fBbackground\fR state is set for widgets in a background window,
and cleared for those in the foreground window.
.TP
\fBreadonly\fR
.
Widget should not allow user modification.
.TP
\fBalternate\fR
.
A widget-specific alternate display format.
For example, used for checkbuttons and radiobuttons in the
.QW tristate
or
.QW mixed
state, and for buttons with \fB\-default active\fR.
.TP
\fBinvalid\fR
.
The widget's value is invalid.
(Potential uses: scale widget value out of bounds,
entry widget value failed validation.)
.TP
\fBhover\fR
.
The mouse cursor is within the widget.
This is similar to the \fBactive\fP state;
it is used in some themes for widgets that
provide distinct visual feedback for
the active widget in addition to the active element
within the widget.


.PP
A \fIstate specification\fR or \fIstateSpec\fR is a list
of state names, optionally prefixed with an exclamation point (!)
indicating that the bit is off.
.SH EXAMPLES
.CS
set b [ttk::button .b]







<
<
<
<
<








|
|


|
|












<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<












>





>
















>







|
>
>










>

















>


>






>









|
>




>





>


|
<
|

|
>




<
<

>


>






>









|
>




>





>



|

|
>




<
<




<
|
<







<
|
<



<
|
<

<
|
<



<
|
<





<
|
<





<
|
<

<
|
<






<
|
<



<
|
<






>
>







102
103
104
105
106
107
108





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

















135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244

245
246
247
248
249
250
251
252


253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297


298
299
300
301

302

303
304
305
306
307
308
309

310

311
312
313

314

315

316

317
318
319

320

321
322
323
324
325

326

327
328
329
330
331

332

333

334

335
336
337
338
339
340

341

342
343
344

345

346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
Specifies an image to display.
This is a list of 1 or more elements.
The first element is the default image name.
The rest of the list is a sequence of \fIstatespec / value\fR pairs
as per \fBstyle map\fR, specifying different images to use when
the widget is in a particular state or combination of states.
All images in the list should have the same size.





.OP \-padding padding Padding
Specifies the internal padding for the widget.
The padding is a list of up to four length specifications
\fIleft top right bottom\fR.
If fewer than four elements are specified,
\fIbottom\fR defaults to \fItop\fR,
\fIright\fR defaults to \fIleft\fR, and
\fItop\fR defaults to \fIleft\fR.
In other words, a list of three numbers specify the left, vertical, and right
padding; a list of two numbers specify the horizontal and the vertical padding;
a single number specifies the same padding all the way around the widget.
.OP \-text text Text
Specifies a text string to be displayed inside the widget (unless overridden
by \fB\-textvariable\fR for the widgets supporting this option).
.OP \-textvariable textVariable Variable
Specifies the name of a global variable whose value will be used
in place of the \fB\-text\fR resource.
.OP \-underline underline Underline
If set, specifies the integer index (0-based) of a character to underline
in the text string.
The underlined character is used for mnemonic activation.
.OP \-width width Width
If greater than zero, specifies how much space, in character widths,
to allocate for the text label.
If less than zero, specifies a minimum width.
If zero or unspecified, the natural width of the text label is used.

















.SH "COMPATIBILITY OPTIONS"
This option is only available for themed widgets that have
.QW corresponding
traditional Tk widgets.
.OP \-state state State
May be set to \fBnormal\fR or \fBdisabled\fR
to control the \fBdisabled\fR state bit.
This is a write-only option:
setting it changes the widget state,
but the \fBstate\fR widget command
does not affect the \fB\-state\fR option.
.SH COMMANDS
.\" METHOD: cget
.TP
\fIpathName \fBcget \fIoption\fR
.
Returns the current value of the configuration option given
by \fIoption\fR.
.\" METHOD: configure
.TP
\fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?
.
Query or modify the configuration options of the widget.
If one or more \fIoption\-value\fR pairs are specified,
then the command modifies the given widget option(s)
to have the given value(s);
in this case the command returns an empty string.
If \fIoption\fR is specified with no \fIvalue\fR,
then the command returns a list describing the named option:
the elements of the list are the
option name, database name, database class, default value,
and current value.
.\" Note: Ttk widgets don't use TK_OPTION_SYNONYM.
If no \fIoption\fR is specified, returns a list describing all of
the available options for \fIpathName\fR.
.\" METHOD: identify
.TP
\fIpathName \fBidentify element \fIx y\fR
.
Returns the name of the element under the point given
by \fIx\fR and \fIy\fR, or an empty string if the point does
not lie within any element.
\fIx\fR and \fIy\fR are pixel coordinates relative to the widget.
Some widgets accept other \fBidentify\fR subcommands described
in these widgets documentation.
.\" METHOD: instate
.TP
\fIpathName \fBinstate \fIstatespec\fR ?\fIscript\fR?
.
Test the widget's state.
If \fIscript\fR is not specified, returns 1 if
the widget state matches \fIstatespec\fR and 0 otherwise.
If \fIscript\fR is specified, equivalent to
.CS
if {[\fIpathName\fR instate \fIstateSpec\fR]} \fIscript\fR
.CE
.\" METHOD: state
.TP
\fIpathName \fBstate\fR ?\fIstateSpec\fR?
.
Modify or inquire widget state.
If \fIstateSpec\fR is present, sets the widget state:
for each flag in \fIstateSpec\fR, sets the corresponding flag
or clears it if prefixed by an exclamation point.
.RS
Returns a new state spec indicating which flags were changed:
.CS
set changes [\fIpathName \fRstate \fIspec\fR]
\fIpathName \fRstate $changes
.CE
will restore \fIpathName\fR to the original state.
If \fIstateSpec\fR is not specified,
returns a list of the currently-enabled state flags.
.RE
.\" METHOD: xview
.TP
\fIpathName \fBxview \fIargs\fR
.
This command is used to query and change the horizontal position of the
content in the widget's window.  It can take any of the following
forms:
.RS
.TP
\fIpathName \fBxview\fR
.
Returns a list containing two elements.
Each element is a real fraction between 0 and 1; together they describe
the horizontal span that is visible in the window.
For example, if the first element is .2 and the second element is .6,
20% of the widget's content is off-screen to the left, the middle 40% is visible
in the window, and 40% of the content is off-screen to the right.
These are the same values passed to scrollbars via the \fB\-xscrollcommand\fR
option.
.TP
\fIpathName \fBxview\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.

\fIWhat\fR must be either \fBunits\fR or \fBpages\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is \fBunits\fR, the view adjusts left or right by
\fInumber\fR average-width characters on the display;  if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then characters farther to the left
become visible;  if it is positive then characters farther to the right
become visible.


.RE
.\" 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.
\fIWhat\fR must be either \fBunits\fR or \fBpages\fR.
'\" or an abbreviation of one of these, but we don't document that.
If \fIwhat\fR is \fBunits\fR, the view adjusts up or down by
\fInumber\fR average-width characters on the display;  if it is
\fBpages\fR then the view adjusts by \fInumber\fR screenfuls.
If \fInumber\fR is negative then items farther to the top
become visible;  if it is positive then items farther to the bottom
become visible.


.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.
.IP \fBuser1\fR-\fBuser3\fR
Freely usable for other purposes
.PP
A \fIstate specification\fR or \fIstateSpec\fR is a list
of state names, optionally prefixed with an exclamation point (!)
indicating that the bit is off.
.SH EXAMPLES
.CS
set b [ttk::button .b]
Changes to doc/winfo.n.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.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







|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
.TH winfo n 4.3 Tk "Tk Built-In Commands"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
winfo \- Return window-related information
.SH SYNOPSIS
\fBwinfo\fR \fIoption \fR?\fIarg arg ...\fR?
.BE
.SH DESCRIPTION
.PP
The \fBwinfo\fR command is used to retrieve information about windows
managed by Tk.  It can take any of a number of different forms,
depending on the \fIoption\fR argument.  The legal forms are:
.TP
Changes to doc/wish.1.
8
9
10
11
12
13
14
15
16

17
18
19

20
21
22

23
24

25
26
27
28

29
30
31

32
33
34
35

36
37
38
39
40
41
42
43
44
45
46

47
48
49
50

51
52
53
54
55
56
57
.TH wish 1 8.0 Tk "Tk Applications"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wish \- Simple windowing shell
.SH SYNOPSIS
\fBwish\fR ?\fB\-encoding \fIname\fR? ?\fIfileName arg ...\fR?
.SH OPTIONS

.IP "\fB\-encoding \fIname\fR" 20
Specifies the encoding of the text stored in \fIfileName\fR.
This option is only recognized prior to the \fIfileName\fR argument.

.IP "\fB\-colormap \fInew\fR" 20
Specifies that the window should have a new private colormap instead of
using the default colormap for the screen.

.IP "\fB\-display \fIdisplay\fR" 20
Display (and screen) on which to display window.

.IP "\fB\-geometry \fIgeometry\fR" 20
Initial geometry to use for window.  If this option is specified, its
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







|

>



>



>


>




>



>




>











>




>







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
.TH wish 1 8.0 Tk "Tk Applications"
.so man.macros
.BS
'\" Note:  do not modify the .SH NAME line immediately below!
.SH NAME
wish \- Simple windowing shell
.SH SYNOPSIS
\fBwish\fR ?\fBoptions\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
.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 macOS, general window decorations on X11).
.\" OPTION: -topmost
.TP
\fB\-topmost\fR
.
Specifies whether this is a topmost window (displays above all other windows).
.PP
On Windows, the following attributes may be set.
.\" OPTION: -disabled
.TP
\fB\-disabled\fR
.
Specifies whether the window is in a disabled state.
.\" OPTION: -toolwindow
.TP
\fB\-toolwindow\fR
.
Specifies a toolwindow style window (as defined in the MSDN).
.\" OPTION: -transparentcolor
.TP
\fB\-transparentcolor\fR
.
Specifies the transparent color index of the toplevel.  It takes any color
value accepted by \fBTk_GetColor\fR.  If the empty string is specified
(default), no transparent color is used.  This is supported on Windows
2000/XP+.  Where not supported, the \fB\-transparentcolor\fR value remains
at \fB{}\fR.
.PP
On macOS, the following attributes may be set.
.\" OPTION: -modified
.TP
\fB\-modified\fR
.
Specifies the modification state of the window (determines whether the
window close widget contains the modification indicator and whether the
proxy icon is draggable).
.\" OPTION: -notify
.TP
\fB\-notify\fR
.
Specifies process notification state (bouncing of the application dock icon).
.\" OPTION: -titlepath
.TP
\fB\-titlepath\fR
.
Specifies the path of the file referenced as the window proxy icon
(which can be dragged and dropped in lieu of the file's finder icon).
.\" 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 macOS.
.PP
On X11, changes to window attributes are performed asynchronously. Querying
the value of an attribute returns the current state, which will not be the
same as the value most recently set if the window manager has not yet
processed the request or if it does not support the attribute.
.RE
.\" METHOD: client
.TP
\fBwm client \fIwindow\fR ?\fIname\fR?
.
If \fIname\fR is specified, this command stores \fIname\fR (which
should be the name of
the host on which the application is executing) in \fIwindow\fR's
\fBWM_CLIENT_MACHINE\fR property for use by the window manager or
session manager.
The command returns an empty string in this case.
If \fIname\fR is not specified, the command returns the last name
set in a \fBwm client\fR command for \fIwindow\fR.
If \fIname\fR is specified as an empty string, the command deletes the
\fBWM_CLIENT_MACHINE\fR property from \fIwindow\fR.
.\" METHOD: colormapwindows
.TP
\fBwm colormapwindows \fIwindow\fR ?\fIwindowList\fR?
.
This command is used to manipulate the \fBWM_COLORMAP_WINDOWS\fR
property, which provides information to the window managers about
windows that have private colormaps.
.RS
252
253
254
255
256
257
258

259
260
261
262
263
264
265
266
267
268
269
270

271
272
273
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

301
302
303
304
305
306
307
308

309
310
311
312
313
314
315
316
317

318
319
320
321
322
323
324
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







>












>










>




















>








>









>







240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
If \fBwm colormapwindows\fR is not invoked, Tk will automatically set
the property for each top-level window to all the internal windows
whose colormaps differ from their parents, followed by the top-level
itself;  the order of the internal windows is undefined.
See the ICCCM documentation for more information on the
\fBWM_COLORMAP_WINDOWS\fR property.
.RE
.\" METHOD: command
.TP
\fBwm command \fIwindow\fR ?\fIvalue\fR?
.
If \fIvalue\fR is specified, this command stores \fIvalue\fR in \fIwindow\fR's
\fBWM_COMMAND\fR property for use by the window manager or
session manager and returns an empty string.
\fIValue\fR must have proper list structure;  the elements should
contain the words of the command used to invoke the application.
If \fIvalue\fR is not specified then the command returns the last value
set in a \fBwm command\fR command for \fIwindow\fR.
If \fIvalue\fR is specified as an empty string, the command
deletes the \fBWM_COMMAND\fR property from \fIwindow\fR.
.\" METHOD: deiconify
.TP
\fBwm deiconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be displayed in normal (non-iconified) form.
This is done by mapping the window.  If the window has never been
mapped then this command will not map the window, but it will ensure
that when the window is first mapped it will be displayed
in de-iconified form.  On Windows, a deiconified window will also be
raised and be given the focus (made the active window).
Returns an empty string.
.\" METHOD: focusmodel
.TP
\fBwm focusmodel \fIwindow\fR ?\fBactive\fR|\fBpassive\fR?
.
If \fBactive\fR or \fBpassive\fR is supplied as an optional argument
to the command, then it specifies the focus model for \fIwindow\fR.
In this case the command returns an empty string.  If no additional
argument is supplied, then the command returns the current focus
model for \fIwindow\fR.
.RS
.PP
An \fBactive\fR focus model means that \fIwindow\fR will claim the
input focus for itself or its descendants, even at times when
the focus is currently in some other application.  \fBPassive\fR means that
\fIwindow\fR will never claim the focus for itself:  the window manager
should give the focus to \fIwindow\fR at appropriate times.  However,
once the focus has been given to \fIwindow\fR or one of its descendants,
the application may re-assign the focus among \fIwindow\fR's descendants.
The focus model defaults to \fBpassive\fR, and Tk's \fBfocus\fR command
assumes a passive model of focusing.
.RE
.\" METHOD: forget
.TP
\fBwm forget \fIwindow\fR
.
The \fIwindow\fR will be unmapped from the screen and will no longer
be managed by \fBwm\fR.  Windows created with the \fBtoplevel\fR
command will be treated like \fBframe\fR windows once they are no
longer managed by \fBwm\fR, however, the \fB\-menu\fR configuration will be
remembered and the menus will return once the widget is managed again.
.\" METHOD: frame
.TP
\fBwm frame \fIwindow\fR
.
If \fIwindow\fR has been reparented by the window manager into a
decorative frame, the command returns the platform specific window
identifier for the outermost frame that contains \fIwindow\fR (the
window whose parent is the root or virtual root).  If \fIwindow\fR
has not been reparented by the window manager then the command returns
the platform specific window identifier for \fIwindow\fR.
.\" METHOD: geometry
.TP
\fBwm geometry \fIwindow\fR ?\fInewGeometry\fR?
.
If \fInewGeometry\fR is specified, then the geometry of \fIwindow\fR
is changed and an empty string is returned.  Otherwise the current
geometry for \fIwindow\fR is returned (this is the most recent
geometry specified either by manual resizing or
355
356
357
358
359
360
361

362
363
364
365
366
367
368
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







>







349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
actual size and location of \fIwindow\fR, whereas \fBwm geometry\fR allows
both setting and querying of the \fIwindow manager\fR's understanding of the
size and location of the window. This can vary significantly, for example to
reflect the addition of decorative elements to \fIwindow\fR such as title
bars, and window managers are not required to precisely follow the requests
made through this command.
.RE
.\" METHOD: grid
.TP
\fBwm grid \fIwindow\fR ?\fIbaseWidth baseHeight widthInc heightInc\fR?
.
This command indicates that \fIwindow\fR is to be managed as a
gridded window.
It also specifies the relationship between grid units and pixel units.
\fIBaseWidth\fR and \fIbaseHeight\fR specify the number of grid
387
388
389
390
391
392
393
394
395
396
397

398
399
400
401
402
403
404
405
406
407
408

409
410
411
412
413
414
415
.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







|



>











>







382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
.PP
Otherwise the return value is a Tcl list containing
four elements corresponding to the current \fIbaseWidth\fR,
\fIbaseHeight\fR, \fIwidthInc\fR, and \fIheightInc\fR;  if
\fIwindow\fR is not currently gridded, then an empty string
is returned.
.PP
Note that this command should not be needed very often, since the
\fBTk_SetGrid\fR library procedure and the \fBsetGrid\fR option
provide easier access to the same functionality.
.RE
.\" METHOD: group
.TP
\fBwm group \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it gives the path name for the leader of
a group of related windows.  The window manager may use this information,
for example, to unmap all of the windows in a group when the group's
leader is iconified.  \fIPathName\fR may be specified as an empty string to
remove \fIwindow\fR from any group association.  If \fIpathName\fR is
specified then the command returns an empty string;  otherwise it
returns the path name of \fIwindow\fR's current group leader, or an empty
string if \fIwindow\fR is not part of any group.
.\" METHOD: iconbitmap
.TP
\fBwm iconbitmap \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be displayed in
\fIwindow\fR's icon, and the command returns an empty string.  If
431
432
433
434
435
436
437

438
439
440
441
442
443

444
445
446
447
448
449
450
451
452
453
454
455
456
457
458

459
460
461
462
463
464
465
466
467
468
469

470
471
472
473
474
475
476
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







>






>















>











>







428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
any file which contains a valid
Windows icon is also accepted (usually .ico or .icr files), or any
file for which the shell has assigned an icon.  Tcl will
first test if the file contains an icon, then if it has an assigned
icon, and finally, if that fails, test for
a bitmap.
.RE
.\" METHOD: iconify
.TP
\fBwm iconify \fIwindow\fR
.
Arrange for \fIwindow\fR to be iconified.  It \fIwindow\fR has not
yet been mapped for the first time, this command will arrange for
it to appear in the iconified state when it is eventually mapped.
.\" METHOD: iconmask
.TP
\fBwm iconmask \fIwindow\fR ?\fIbitmap\fR?
.
If \fIbitmap\fR is specified, then it names a bitmap in the standard
forms accepted by Tk (see the \fBTk_GetBitmap\fR manual entry for details).
This bitmap is passed to the window manager to be used as a mask
in conjunction with the \fBiconbitmap\fR option:  where the mask
has zeroes no icon will be displayed;  where it has ones, the bits
from the icon bitmap will be displayed.  If
an empty string is specified for \fIbitmap\fR then any current icon
mask is cancelled for \fIwindow\fR (this is equivalent to specifying
a bitmap of all ones).  If \fIbitmap\fR is specified
then the command returns an empty string.  Otherwise it
returns the name of the current icon mask associated with
\fIwindow\fR, or an empty string if no mask is in effect.
.\" METHOD: iconname
.TP
\fBwm iconname \fIwindow\fR ?\fInewName\fR?
.
If \fInewName\fR is specified, then it is passed to the window
manager;  the window manager should display \fInewName\fR inside
the icon associated with \fIwindow\fR.  In this case an empty
string is returned as result.  If \fInewName\fR is not specified
then the command returns the current icon name for \fIwindow\fR,
or an empty string if no icon name has been specified (in this
case the window manager will normally display the window's title,
as specified with the \fBwm title\fR command).
.\" METHOD: iconphoto
.TP
\fBwm iconphoto \fIwindow\fR ?\fB\-default\fR? \fIimage1\fR ?\fIimage2 ...\fR?
.
Sets the titlebar icon for \fIwindow\fR based on the named photo images.
If \fB\-default\fR is specified, this is applied to all future created
toplevels as well.  The data in the images is taken as a snapshot at the
time of invocation.  If the images are later changed, this is not
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498

499
500
501
502
503
504
505
506
507
508

509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526


527
528
529
530
531
532
533
534
535

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

551
552
553
554
555
556
557
558
559
560
561
562
563
564
565

566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585

586
587
588
589
590
591
592
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







|







>










>

















|
>
>









>















>















>




















>







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
vice versa.
.PP
On X, the images are arranged into the _NET_WM_ICON X property, which
most modern window managers support.  A \fBwm iconbitmap\fR may exist
simultaneously.  It is recommended to use not more than 2 icons, placing
the larger icon first.
.PP
On Macintosh, the first image called is loaded into an OS-native icon
format, and becomes the application icon in dialogs, the Dock, and
other contexts. At the
script level the command will accept only the first image passed in the
parameters as support for multiple sizes/resolutions on macOS is outside Tk's
scope. Developers should use the largest icon they can support
(preferably 512 pixels) to ensure smooth rendering on the Mac.
.RE
.\" METHOD: iconposition
.TP
\fBwm iconposition \fIwindow\fR ?\fIx y\fR?
.
If \fIx\fR and \fIy\fR are specified, they are passed to the window
manager as a hint about where to position the icon for \fIwindow\fR.
In this case an empty string is returned.  If \fIx\fR and \fIy\fR are
specified as empty strings then any existing icon position hint is cancelled.
If neither \fIx\fR nor \fIy\fR is specified, then the command returns
a Tcl list containing two values, which are the current icon position
hints (if no hints are in effect then an empty string is returned).
.\" METHOD: iconwindow
.TP
\fBwm iconwindow \fIwindow\fR ?\fIpathName\fR?
.
If \fIpathName\fR is specified, it is the path name for a window to
use as icon for \fIwindow\fR: when \fIwindow\fR is iconified then
\fIpathName\fR will be mapped to serve as icon, and when \fIwindow\fR
is de-iconified then \fIpathName\fR will be unmapped again.  If
\fIpathName\fR is specified as an empty string then any existing
icon window association for \fIwindow\fR will be cancelled.  If
the \fIpathName\fR argument is specified then an empty string is
returned.  Otherwise the command returns the path name of the
current icon window for \fIwindow\fR, or an empty string if there
is no icon window currently specified for \fIwindow\fR.
Button press events are disabled for \fIwindow\fR as long as it is
an icon window;  this is needed in order to allow window managers to
.QW own
those events.
Note 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







>



|
<
|
|
|
|
|
|
|
|
>
|
|
|
<
|
|
|
|
|
|
<
>
|
>
>
|
>


>
|
>
>
>
>
|
>
>
|
>
>
|
>
|
>

>
















>


















>














>





|
|





>









>


















>










|







609
610
611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
629
630
631
632

633
634
635
636
637
638

639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
source of the window's current position, or an empty string if
no source has been specified yet.  Most window managers interpret
.QW "no source"
as equivalent to \fBprogram\fR.
Tk will automatically set the position source to \fBuser\fR
when a \fBwm geometry\fR command is invoked, unless the source has
been set explicitly to \fBprogram\fR.
.\" METHOD: protocol
.TP
\fBwm protocol \fIwindow\fR ?\fIname\fR? ?\fIcommand\fR?
.
This command is used to manage window manager protocols. 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 macOS
only) \fBzoomed\fR.
The difference between \fBiconic\fR and \fBicon\fR is that
\fBiconic\fR refers to a window that has been iconified (e.g., with the
\fBwm iconify\fR command) while \fBicon\fR refers to a window whose only
purpose is to serve as the icon for some other window (via the \fBwm
iconwindow\fR command).  The \fBicon\fR state cannot be set.
.\" METHOD: title
.TP
\fBwm title \fIwindow\fR ?\fIstring\fR?
.
If \fIstring\fR is specified, then it will be passed to the window
manager for use as the title for \fIwindow\fR (the window manager
should display this string in \fIwindow\fR's title bar).  In this
case the command returns an empty string.  If \fIstring\fR is not
specified then the command returns the current title for the
\fIwindow\fR.  The title for a window defaults to its name.
.\" METHOD: transient
.TP
\fBwm transient \fIwindow\fR ?\fIcontainer\fR?
.
If \fIcontainer\fR is specified, then the window manager is informed that
\fIwindow\fR is a transient window (e.g. pull-down menu) working on
behalf of \fIcontainer\fR (where \fIcontainer\fR is the path name for a
top-level window).  If \fIcontainer\fR is specified as an empty string
then \fIwindow\fR is marked as not being a transient window any more.
Otherwise the command returns the path name of \fIwindow\fR's current
container, or an empty string if \fIwindow\fR is not currently a
transient window.  A transient window will mirror state changes in the
container and inherit the state of the container when initially mapped. The
directed graph with an edge from each transient to its container must be
acyclic.  In particular, it is an error to attempt to make a window a
transient of itself.  The window manager may also decorate a transient
window differently, removing some features normally present (e.g.,
minimize and maximize buttons) though this is entirely at the
discretion of the window manager.
.\" METHOD: widthdraw
.TP
\fBwm withdraw \fIwindow\fR
.
Arranges for \fIwindow\fR to be withdrawn from the screen.  This
causes the window to be unmapped and forgotten about by the window
manager.  If the window
has never been mapped, then this command
causes the window to be mapped in the withdrawn state.  Not all
window managers appear to know how to handle windows that are
mapped in the withdrawn state.
Note that it sometimes seems to be necessary to withdraw a
window and then re-map it (e.g. with \fBwm deiconify\fR) to get some
window managers to pay attention to changes in window attributes
such as group.
.SH "GEOMETRY MANAGEMENT"
.PP
By default a top-level window appears on the screen in its
\fInatural size\fR, which is the one determined internally by its
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857

858
859
860
\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:







|
|
|
|








|
|








|
>



858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
\fBwm resizable\fR .fixed 0 0
.CE
.PP
A simple dialog-like window, centred on the screen:
.CS
# Create and arrange the dialog contents.
toplevel .msg
label  .msg.l  -text "This is a very simple dialog demo."
button .msg.ok -text OK -default active -command {destroy .msg}
pack .msg.ok -side bottom -fill x
pack .msg.l  -expand 1    -fill both

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







<

<
<
<
<

















>
>
>
>
>
>
|
>
>
>
>
>
|
|
>







16
17
18
19
20
21
22

23




24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{ "Linefeed", 0xFF0A },
{ "Clear", 0xFF0B },
{ "Return", 0xFF0D },
{ "Pause", 0xFF13 },
{ "Scroll_Lock", 0xFF14 },
{ "Sys_Req", 0xFF15 },
{ "Escape", 0xFF1B },

{ "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 },
69
70
71
72
73
74
75




76
77
78
79
80
81
82
{ "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 },







>
>
>
>







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{ "Menu", 0xFF67 },
{ "Find", 0xFF68 },
{ "Cancel", 0xFF69 },
{ "Help", 0xFF6A },
{ "Break", 0xFF6B },
{ "Mode_switch", 0xFF7E },
{ "script_switch", 0xFF7E },
{ "kana_switch", 0xFF7E },
{ "Arabic_switch", 0xFF7E },
{ "Greek_switch", 0xFF7E },
{ "Hebrew_switch", 0xFF7E },
{ "Num_Lock", 0xFF7F },
{ "KP_Space", 0xFF80 },
{ "KP_Tab", 0xFF89 },
{ "KP_Enter", 0xFF8D },
{ "KP_F1", 0xFF91 },
{ "KP_F2", 0xFF92 },
{ "KP_F3", 0xFF93 },
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113

114
115
116
117
118
119
120
{ "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 },







<
















>







101
102
103
104
105
106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
{ "KP_Page_Up", 0xFF9A },
{ "KP_Next", 0xFF9B },
{ "KP_Page_Down", 0xFF9B },
{ "KP_End", 0xFF9C },
{ "KP_Begin", 0xFF9D },
{ "KP_Insert", 0xFF9E },
{ "KP_Delete", 0xFF9F },

{ "KP_Multiply", 0xFFAA },
{ "KP_Add", 0xFFAB },
{ "KP_Separator", 0xFFAC },
{ "KP_Subtract", 0xFFAD },
{ "KP_Decimal", 0xFFAE },
{ "KP_Divide", 0xFFAF },
{ "KP_0", 0xFFB0 },
{ "KP_1", 0xFFB1 },
{ "KP_2", 0xFFB2 },
{ "KP_3", 0xFFB3 },
{ "KP_4", 0xFFB4 },
{ "KP_5", 0xFFB5 },
{ "KP_6", 0xFFB6 },
{ "KP_7", 0xFFB7 },
{ "KP_8", 0xFFB8 },
{ "KP_9", 0xFFB9 },
{ "KP_Equal", 0xFFBD },
{ "F1", 0xFFBE },
{ "F2", 0xFFBF },
{ "F3", 0xFFC0 },
{ "F4", 0xFFC1 },
{ "F5", 0xFFC2 },
{ "F6", 0xFFC3 },
{ "F7", 0xFFC4 },
181
182
183
184
185
186
187











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



207
208
209
210
211
212
213
{ "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 },







>
>
>
>
>
>
>
>
>
>
>





<
<
<











>
>
>







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



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
{ "Meta_R", 0xFFE8 },
{ "Alt_L", 0xFFE9 },
{ "Alt_R", 0xFFEA },
{ "Super_L", 0xFFEB },
{ "Super_R", 0xFFEC },
{ "Hyper_L", 0xFFED },
{ "Hyper_R", 0xFFEE },
{ "braille_dot_1", 0xFFF1 },
{ "braille_dot_2", 0xFFF2 },
{ "braille_dot_3", 0xFFF3 },
{ "braille_dot_4", 0xFFF4 },
{ "braille_dot_5", 0xFFF5 },
{ "braille_dot_6", 0xFFF6 },
{ "braille_dot_7", 0xFFF7 },
{ "braille_dot_8", 0xFFF8 },
{ "braille_dot_9", 0xFFF9 },
{ "braille_dot_10", 0xFFFA },
{ "Delete", 0xFFFF },
{ "ISO_Lock", 0xFE01 },
{ "ISO_Level2_Latch", 0xFE02 },
{ "ISO_Level3_Shift", 0xFE03 },
{ "ISO_Level3_Latch", 0xFE04 },
{ "ISO_Level3_Lock", 0xFE05 },



{ "ISO_Group_Shift", 0xFF7E },
{ "ISO_Group_Latch", 0xFE06 },
{ "ISO_Group_Lock", 0xFE07 },
{ "ISO_Next_Group", 0xFE08 },
{ "ISO_Next_Group_Lock", 0xFE09 },
{ "ISO_Prev_Group", 0xFE0A },
{ "ISO_Prev_Group_Lock", 0xFE0B },
{ "ISO_First_Group", 0xFE0C },
{ "ISO_First_Group_Lock", 0xFE0D },
{ "ISO_Last_Group", 0xFE0E },
{ "ISO_Last_Group_Lock", 0xFE0F },
{ "ISO_Level5_Shift", 0xFE11 },
{ "ISO_Level5_Latch", 0xFE12 },
{ "ISO_Level5_Lock", 0xFE13 },
{ "ISO_Left_Tab", 0xFE20 },
{ "ISO_Move_Line_Up", 0xFE21 },
{ "ISO_Move_Line_Down", 0xFE22 },
{ "ISO_Partial_Line_Up", 0xFE23 },
{ "ISO_Partial_Line_Down", 0xFE24 },
{ "ISO_Partial_Space_Left", 0xFE25 },
{ "ISO_Partial_Space_Right", 0xFE26 },
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295































296
297
298
299
300
301
302
{ "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 },







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







278
279
280
281
282
283
284






















285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
{ "dead_belowcircumflex", 0xFE69 },
{ "dead_belowtilde", 0xFE6A },
{ "dead_belowbreve", 0xFE6B },
{ "dead_belowdiaeresis", 0xFE6C },
{ "dead_invertedbreve", 0xFE6D },
{ "dead_belowcomma", 0xFE6E },
{ "dead_currency", 0xFE6F },






















{ "AccessX_Enable", 0xFE70 },
{ "AccessX_Feedback_Enable", 0xFE71 },
{ "RepeatKeys_Enable", 0xFE72 },
{ "SlowKeys_Enable", 0xFE73 },
{ "BounceKeys_Enable", 0xFE74 },
{ "StickyKeys_Enable", 0xFE75 },
{ "MouseKeys_Enable", 0xFE76 },
{ "MouseKeys_Accel_Enable", 0xFE77 },
{ "Overlay1_Enable", 0xFE78 },
{ "Overlay2_Enable", 0xFE79 },
{ "AudibleBell_Enable", 0xFE7A },
{ "dead_a", 0xFE80 },
{ "dead_A", 0xFE81 },
{ "dead_e", 0xFE82 },
{ "dead_E", 0xFE83 },
{ "dead_i", 0xFE84 },
{ "dead_I", 0xFE85 },
{ "dead_o", 0xFE86 },
{ "dead_O", 0xFE87 },
{ "dead_u", 0xFE88 },
{ "dead_U", 0xFE89 },
{ "dead_schwa", 0xFE8A },
{ "dead_small_schwa", 0xFE8A },
{ "dead_SCHWA", 0xFE8B },
{ "dead_capital_schwa", 0xFE8B },
{ "dead_greek", 0xFE8C },
{ "dead_hamza", 0xFE8D },
{ "dead_lowline", 0xFE90 },
{ "dead_aboveverticalline", 0xFE91 },
{ "dead_belowverticalline", 0xFE92 },
{ "dead_longsolidusoverlay", 0xFE93 },
{ "ch", 0xFEA0 },
{ "Ch", 0xFEA1 },
{ "CH", 0xFEA2 },
{ "c_h", 0xFEA3 },
{ "C_h", 0xFEA4 },
{ "C_H", 0xFEA5 },
{ "First_Virtual_Screen", 0xFED0 },
{ "Prev_Virtual_Screen", 0xFED1 },
{ "Next_Virtual_Screen", 0xFED2 },
{ "Last_Virtual_Screen", 0xFED4 },
{ "Terminate_Server", 0xFED5 },
{ "Pointer_Left", 0xFEE0 },
{ "Pointer_Right", 0xFEE1 },
{ "Pointer_Up", 0xFEE2 },
{ "Pointer_Down", 0xFEE3 },
{ "Pointer_UpLeft", 0xFEE4 },
{ "Pointer_UpRight", 0xFEE5 },
{ "Pointer_DownLeft", 0xFEE6 },
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
{ "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 },







<




|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







345
346
347
348
349
350
351

352
353
354
355
356



































357
358
359
360
361
362
363
{ "Pointer_DblClick4", 0xFEF2 },
{ "Pointer_DblClick5", 0xFEF3 },
{ "Pointer_Drag_Dflt", 0xFEF4 },
{ "Pointer_Drag1", 0xFEF5 },
{ "Pointer_Drag2", 0xFEF6 },
{ "Pointer_Drag3", 0xFEF7 },
{ "Pointer_Drag4", 0xFEF8 },

{ "Pointer_EnableKeys", 0xFEF9 },
{ "Pointer_Accelerate", 0xFEFA },
{ "Pointer_DfltBtnNext", 0xFEFB },
{ "Pointer_DfltBtnPrev", 0xFEFC },
{ "Pointer_Drag5", 0xFEFD },



































{ "space", 0x20 },
{ "exclam", 0x21 },
{ "quotedbl", 0x22 },
{ "numbersign", 0x23 },
{ "dollar", 0x24 },
{ "percent", 0x25 },
{ "ampersand", 0x26 },
463
464
465
466
467
468
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484

485

486
487
488
489
490
491
492
{ "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 },







>















>

>







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
{ "currency", 0xA4 },
{ "yen", 0xA5 },
{ "brokenbar", 0xA6 },
{ "section", 0xA7 },
{ "diaeresis", 0xA8 },
{ "copyright", 0xA9 },
{ "ordfeminine", 0xAA },
{ "guillemetleft", 0xAB },
{ "guillemotleft", 0xAB },
{ "notsign", 0xAC },
{ "hyphen", 0xAD },
{ "registered", 0xAE },
{ "macron", 0xAF },
{ "degree", 0xB0 },
{ "plusminus", 0xB1 },
{ "twosuperior", 0xB2 },
{ "threesuperior", 0xB3 },
{ "acute", 0xB4 },
{ "mu", 0xB5 },
{ "paragraph", 0xB6 },
{ "periodcentered", 0xB7 },
{ "cedilla", 0xB8 },
{ "onesuperior", 0xB9 },
{ "ordmasculine", 0xBA },
{ "masculine", 0xBA },
{ "guillemetright", 0xBB },
{ "guillemotright", 0xBB },
{ "onequarter", 0xBC },
{ "onehalf", 0xBD },
{ "threequarters", 0xBE },
{ "questiondown", 0xBF },
{ "Agrave", 0xC0 },
{ "Aacute", 0xC1 },
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
{ "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 },







<

<







508
509
510
511
512
513
514

515

516
517
518
519
520
521
522
{ "Ograve", 0xD2 },
{ "Oacute", 0xD3 },
{ "Ocircumflex", 0xD4 },
{ "Otilde", 0xD5 },
{ "Odiaeresis", 0xD6 },
{ "multiply", 0xD7 },
{ "Oslash", 0xD8 },

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







<

<







542
543
544
545
546
547
548

549

550
551
552
553
554
555
556
{ "ograve", 0xF2 },
{ "oacute", 0xF3 },
{ "ocircumflex", 0xF4 },
{ "otilde", 0xF5 },
{ "odiaeresis", 0xF6 },
{ "division", 0xF7 },
{ "oslash", 0xF8 },

{ "ooblique", 0xF8 },

{ "ugrave", 0xF9 },
{ "uacute", 0xFA },
{ "ucircumflex", 0xFB },
{ "udiaeresis", 0xFC },
{ "yacute", 0xFD },
{ "thorn", 0xFE },
{ "ydiaeresis", 0xFF },
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
{ "cabovedot", 0x2E5 },
{ "ccircumflex", 0x2E6 },
{ "gabovedot", 0x2F5 },
{ "gcircumflex", 0x2F8 },
{ "ubreve", 0x2FD },
{ "scircumflex", 0x2FE },
{ "kra", 0x3A2 },
#ifndef TK_NO_DEPRECATED
{ "kappa", 0x3A2 },
#endif
{ "Rcedilla", 0x3A3 },
{ "Itilde", 0x3A5 },
{ "Lcedilla", 0x3A6 },
{ "Emacron", 0x3AA },
{ "Gcedilla", 0x3AB },
{ "Tslash", 0x3AC },
{ "rcedilla", 0x3B3 },
{ "itilde", 0x3B5 },
{ "lcedilla", 0x3B6 },
{ "emacron", 0x3BA },
{ "gcedilla", 0x3BB },
#ifndef TK_NO_DEPRECATED
{ "gacute", 0x3BB },
#endif
{ "tslash", 0x3BC },
{ "ENG", 0x3BD },
{ "eng", 0x3BF },
{ "Amacron", 0x3C0 },
{ "Iogonek", 0x3C7 },
{ "Eabovedot", 0x3CC },
{ "Imacron", 0x3CF },







<

<











<

<







630
631
632
633
634
635
636

637

638
639
640
641
642
643
644
645
646
647
648

649

650
651
652
653
654
655
656
{ "cabovedot", 0x2E5 },
{ "ccircumflex", 0x2E6 },
{ "gabovedot", 0x2F5 },
{ "gcircumflex", 0x2F8 },
{ "ubreve", 0x2FD },
{ "scircumflex", 0x2FE },
{ "kra", 0x3A2 },

{ "kappa", 0x3A2 },

{ "Rcedilla", 0x3A3 },
{ "Itilde", 0x3A5 },
{ "Lcedilla", 0x3A6 },
{ "Emacron", 0x3AA },
{ "Gcedilla", 0x3AB },
{ "Tslash", 0x3AC },
{ "rcedilla", 0x3B3 },
{ "itilde", 0x3B5 },
{ "lcedilla", 0x3B6 },
{ "emacron", 0x3BA },
{ "gcedilla", 0x3BB },

{ "gacute", 0x3BB },

{ "tslash", 0x3BC },
{ "ENG", 0x3BD },
{ "eng", 0x3BF },
{ "Amacron", 0x3C0 },
{ "Iogonek", 0x3C7 },
{ "Eabovedot", 0x3CC },
{ "Imacron", 0x3CF },
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
{ "imacron", 0x3EF },
{ "ncedilla", 0x3F1 },
{ "omacron", 0x3F2 },
{ "kcedilla", 0x3F3 },
{ "uogonek", 0x3F9 },
{ "utilde", 0x3FD },
{ "umacron", 0x3FE },
{ "Wcircumflex", 0x1000174 },
{ "wcircumflex", 0x1000175 },
{ "Ycircumflex", 0x1000176 },
{ "ycircumflex", 0x1000177 },
{ "Babovedot", 0x1001E02 },
{ "babovedot", 0x1001E03 },
{ "Dabovedot", 0x1001E0A },
{ "dabovedot", 0x1001E0B },
{ "Fabovedot", 0x1001E1E },
{ "fabovedot", 0x1001E1F },
{ "Mabovedot", 0x1001E40 },
{ "mabovedot", 0x1001E41 },
{ "Pabovedot", 0x1001E56 },
{ "pabovedot", 0x1001E57 },
{ "Sabovedot", 0x1001E60 },
{ "sabovedot", 0x1001E61 },
{ "Tabovedot", 0x1001E6A },
{ "tabovedot", 0x1001E6B },
{ "Wgrave", 0x1001E80 },
{ "wgrave", 0x1001E81 },
{ "Wacute", 0x1001E82 },
{ "wacute", 0x1001E83 },
{ "Wdiaeresis", 0x1001E84 },
{ "wdiaeresis", 0x1001E85 },
{ "Ygrave", 0x1001EF2 },
{ "ygrave", 0x1001EF3 },
{ "OE", 0x13BC },
{ "oe", 0x13BD },
{ "Ydiaeresis", 0x13BE },
{ "overline", 0x47E },
{ "kana_fullstop", 0x4A1 },
{ "kana_openingbracket", 0x4A2 },
{ "kana_closingbracket", 0x4A3 },
{ "kana_comma", 0x4A4 },
{ "kana_conjunctive", 0x4A5 },
#ifndef TK_NO_DEPRECATED
{ "kana_middledot", 0x4A5 },
#endif
{ "kana_WO", 0x4A6 },
{ "kana_a", 0x4A7 },
{ "kana_i", 0x4A8 },
{ "kana_u", 0x4A9 },
{ "kana_e", 0x4AA },
{ "kana_o", 0x4AB },
{ "kana_ya", 0x4AC },
{ "kana_yu", 0x4AD },
{ "kana_yo", 0x4AE },
{ "kana_tsu", 0x4AF },
#ifndef TK_NO_DEPRECATED
{ "kana_tu", 0x4AF },
#endif
{ "prolongedsound", 0x4B0 },
{ "kana_A", 0x4B1 },
{ "kana_I", 0x4B2 },
{ "kana_U", 0x4B3 },
{ "kana_E", 0x4B4 },
{ "kana_O", 0x4B5 },
{ "kana_KA", 0x4B6 },
{ "kana_KI", 0x4B7 },
{ "kana_KU", 0x4B8 },
{ "kana_KE", 0x4B9 },
{ "kana_KO", 0x4BA },
{ "kana_SA", 0x4BB },
{ "kana_SHI", 0x4BC },
{ "kana_SU", 0x4BD },
{ "kana_SE", 0x4BE },
{ "kana_SO", 0x4BF },
{ "kana_TA", 0x4C0 },
{ "kana_CHI", 0x4C1 },
#ifndef TK_NO_DEPRECATED
{ "kana_TI", 0x4C1 },
#endif
{ "kana_TSU", 0x4C2 },
#ifndef TK_NO_DEPRECATED
{ "kana_TU", 0x4C2 },
#endif
{ "kana_TE", 0x4C3 },
{ "kana_TO", 0x4C4 },
{ "kana_NA", 0x4C5 },
{ "kana_NI", 0x4C6 },
{ "kana_NU", 0x4C7 },
{ "kana_NE", 0x4C8 },
{ "kana_NO", 0x4C9 },
{ "kana_HA", 0x4CA },
{ "kana_HI", 0x4CB },
{ "kana_FU", 0x4CC },
#ifndef TK_NO_DEPRECATED
{ "kana_HU", 0x4CC },
#endif
{ "kana_HE", 0x4CD },
{ "kana_HO", 0x4CE },
{ "kana_MA", 0x4CF },
{ "kana_MI", 0x4D0 },
{ "kana_MU", 0x4D1 },
{ "kana_ME", 0x4D2 },
{ "kana_MO", 0x4D3 },
{ "kana_YA", 0x4D4 },
{ "kana_YU", 0x4D5 },
{ "kana_YO", 0x4D6 },
{ "kana_RA", 0x4D7 },
{ "kana_RI", 0x4D8 },
{ "kana_RU", 0x4D9 },
{ "kana_RE", 0x4DA },
{ "kana_RO", 0x4DB },
{ "kana_WA", 0x4DC },
{ "kana_N", 0x4DD },
{ "voicedsound", 0x4DE },
{ "semivoicedsound", 0x4DF },
{ "kana_switch", 0xFF7E },
{ "Farsi_0", 0x10006F0 },
{ "Farsi_1", 0x10006F1 },
{ "Farsi_2", 0x10006F2 },
{ "Farsi_3", 0x10006F3 },
{ "Farsi_4", 0x10006F4 },
{ "Farsi_5", 0x10006F5 },
{ "Farsi_6", 0x10006F6 },
{ "Farsi_7", 0x10006F7 },
{ "Farsi_8", 0x10006F8 },
{ "Farsi_9", 0x10006F9 },
{ "Arabic_percent", 0x100066A },
{ "Arabic_superscript_alef", 0x1000670 },
{ "Arabic_tteh", 0x1000679 },
{ "Arabic_peh", 0x100067E },
{ "Arabic_tcheh", 0x1000686 },
{ "Arabic_ddal", 0x1000688 },
{ "Arabic_rreh", 0x1000691 },
{ "Arabic_comma", 0x5AC },
{ "Arabic_fullstop", 0x10006D4 },
{ "Arabic_0", 0x1000660 },
{ "Arabic_1", 0x1000661 },
{ "Arabic_2", 0x1000662 },
{ "Arabic_3", 0x1000663 },
{ "Arabic_4", 0x1000664 },
{ "Arabic_5", 0x1000665 },
{ "Arabic_6", 0x1000666 },
{ "Arabic_7", 0x1000667 },
{ "Arabic_8", 0x1000668 },
{ "Arabic_9", 0x1000669 },
{ "Arabic_semicolon", 0x5BB },
{ "Arabic_question_mark", 0x5BF },
{ "Arabic_hamza", 0x5C1 },
{ "Arabic_maddaonalef", 0x5C2 },
{ "Arabic_hamzaonalef", 0x5C3 },
{ "Arabic_hamzaonwaw", 0x5C4 },
{ "Arabic_hamzaunderalef", 0x5C5 },







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<









<

<










<

<


















<

<

<

<










<

<



















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
<
<
<
<
<
<
<
<
<







666
667
668
669
670
671
672


























673
674
675
676
677
678
679
680
681

682

683
684
685
686
687
688
689
690
691
692

693

694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711

712

713

714

715
716
717
718
719
720
721
722
723
724

725

726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744


















745











746
747
748
749
750
751
752
{ "imacron", 0x3EF },
{ "ncedilla", 0x3F1 },
{ "omacron", 0x3F2 },
{ "kcedilla", 0x3F3 },
{ "uogonek", 0x3F9 },
{ "utilde", 0x3FD },
{ "umacron", 0x3FE },


























{ "OE", 0x13BC },
{ "oe", 0x13BD },
{ "Ydiaeresis", 0x13BE },
{ "overline", 0x47E },
{ "kana_fullstop", 0x4A1 },
{ "kana_openingbracket", 0x4A2 },
{ "kana_closingbracket", 0x4A3 },
{ "kana_comma", 0x4A4 },
{ "kana_conjunctive", 0x4A5 },

{ "kana_middledot", 0x4A5 },

{ "kana_WO", 0x4A6 },
{ "kana_a", 0x4A7 },
{ "kana_i", 0x4A8 },
{ "kana_u", 0x4A9 },
{ "kana_e", 0x4AA },
{ "kana_o", 0x4AB },
{ "kana_ya", 0x4AC },
{ "kana_yu", 0x4AD },
{ "kana_yo", 0x4AE },
{ "kana_tsu", 0x4AF },

{ "kana_tu", 0x4AF },

{ "prolongedsound", 0x4B0 },
{ "kana_A", 0x4B1 },
{ "kana_I", 0x4B2 },
{ "kana_U", 0x4B3 },
{ "kana_E", 0x4B4 },
{ "kana_O", 0x4B5 },
{ "kana_KA", 0x4B6 },
{ "kana_KI", 0x4B7 },
{ "kana_KU", 0x4B8 },
{ "kana_KE", 0x4B9 },
{ "kana_KO", 0x4BA },
{ "kana_SA", 0x4BB },
{ "kana_SHI", 0x4BC },
{ "kana_SU", 0x4BD },
{ "kana_SE", 0x4BE },
{ "kana_SO", 0x4BF },
{ "kana_TA", 0x4C0 },
{ "kana_CHI", 0x4C1 },

{ "kana_TI", 0x4C1 },

{ "kana_TSU", 0x4C2 },

{ "kana_TU", 0x4C2 },

{ "kana_TE", 0x4C3 },
{ "kana_TO", 0x4C4 },
{ "kana_NA", 0x4C5 },
{ "kana_NI", 0x4C6 },
{ "kana_NU", 0x4C7 },
{ "kana_NE", 0x4C8 },
{ "kana_NO", 0x4C9 },
{ "kana_HA", 0x4CA },
{ "kana_HI", 0x4CB },
{ "kana_FU", 0x4CC },

{ "kana_HU", 0x4CC },

{ "kana_HE", 0x4CD },
{ "kana_HO", 0x4CE },
{ "kana_MA", 0x4CF },
{ "kana_MI", 0x4D0 },
{ "kana_MU", 0x4D1 },
{ "kana_ME", 0x4D2 },
{ "kana_MO", 0x4D3 },
{ "kana_YA", 0x4D4 },
{ "kana_YU", 0x4D5 },
{ "kana_YO", 0x4D6 },
{ "kana_RA", 0x4D7 },
{ "kana_RI", 0x4D8 },
{ "kana_RU", 0x4D9 },
{ "kana_RE", 0x4DA },
{ "kana_RO", 0x4DB },
{ "kana_WA", 0x4DC },
{ "kana_N", 0x4DD },
{ "voicedsound", 0x4DE },
{ "semivoicedsound", 0x4DF },


















{ "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 },
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
{ "Arabic_feh", 0x5E1 },
{ "Arabic_qaf", 0x5E2 },
{ "Arabic_kaf", 0x5E3 },
{ "Arabic_lam", 0x5E4 },
{ "Arabic_meem", 0x5E5 },
{ "Arabic_noon", 0x5E6 },
{ "Arabic_ha", 0x5E7 },
#ifndef TK_NO_DEPRECATED
{ "Arabic_heh", 0x5E7 },
#endif
{ "Arabic_waw", 0x5E8 },
{ "Arabic_alefmaksura", 0x5E9 },
{ "Arabic_yeh", 0x5EA },
{ "Arabic_fathatan", 0x5EB },
{ "Arabic_dammatan", 0x5EC },
{ "Arabic_kasratan", 0x5ED },
{ "Arabic_fatha", 0x5EE },
{ "Arabic_damma", 0x5EF },
{ "Arabic_kasra", 0x5F0 },
{ "Arabic_shadda", 0x5F1 },
{ "Arabic_sukun", 0x5F2 },
{ "Arabic_madda_above", 0x1000653 },
{ "Arabic_hamza_above", 0x1000654 },
{ "Arabic_hamza_below", 0x1000655 },
{ "Arabic_jeh", 0x1000698 },
{ "Arabic_veh", 0x10006A4 },
{ "Arabic_keheh", 0x10006A9 },
{ "Arabic_gaf", 0x10006AF },
{ "Arabic_noon_ghunna", 0x10006BA },
{ "Arabic_heh_doachashmee", 0x10006BE },
{ "Farsi_yeh", 0x10006CC },
{ "Arabic_farsi_yeh", 0x10006CC },
{ "Arabic_yeh_baree", 0x10006D2 },
{ "Arabic_heh_goal", 0x10006C1 },
{ "Arabic_switch", 0xFF7E },
{ "Cyrillic_GHE_bar", 0x1000492 },
{ "Cyrillic_ghe_bar", 0x1000493 },
{ "Cyrillic_ZHE_descender", 0x1000496 },
{ "Cyrillic_zhe_descender", 0x1000497 },
{ "Cyrillic_KA_descender", 0x100049A },
{ "Cyrillic_ka_descender", 0x100049B },
{ "Cyrillic_KA_vertstroke", 0x100049C },
{ "Cyrillic_ka_vertstroke", 0x100049D },
{ "Cyrillic_EN_descender", 0x10004A2 },
{ "Cyrillic_en_descender", 0x10004A3 },
{ "Cyrillic_U_straight", 0x10004AE },
{ "Cyrillic_u_straight", 0x10004AF },
{ "Cyrillic_U_straight_bar", 0x10004B0 },
{ "Cyrillic_u_straight_bar", 0x10004B1 },
{ "Cyrillic_HA_descender", 0x10004B2 },
{ "Cyrillic_ha_descender", 0x10004B3 },
{ "Cyrillic_CHE_descender", 0x10004B6 },
{ "Cyrillic_che_descender", 0x10004B7 },
{ "Cyrillic_CHE_vertstroke", 0x10004B8 },
{ "Cyrillic_che_vertstroke", 0x10004B9 },
{ "Cyrillic_SHHA", 0x10004BA },
{ "Cyrillic_shha", 0x10004BB },
{ "Cyrillic_SCHWA", 0x10004D8 },
{ "Cyrillic_schwa", 0x10004D9 },
{ "Cyrillic_I_macron", 0x10004E2 },
{ "Cyrillic_i_macron", 0x10004E3 },
{ "Cyrillic_O_bar", 0x10004E8 },
{ "Cyrillic_o_bar", 0x10004E9 },
{ "Cyrillic_U_macron", 0x10004EE },
{ "Cyrillic_u_macron", 0x10004EF },
{ "Serbian_dje", 0x6A1 },
{ "Macedonia_gje", 0x6A2 },
{ "Cyrillic_io", 0x6A3 },
{ "Ukrainian_ie", 0x6A4 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_je", 0x6A4 },
#endif
{ "Macedonia_dse", 0x6A5 },
{ "Ukrainian_i", 0x6A6 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_i", 0x6A6 },
#endif
{ "Ukrainian_yi", 0x6A7 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_yi", 0x6A7 },
#endif
{ "Cyrillic_je", 0x6A8 },
#ifndef TK_NO_DEPRECATED
{ "Serbian_je", 0x6A8 },
#endif
{ "Cyrillic_lje", 0x6A9 },
#ifndef TK_NO_DEPRECATED
{ "Serbian_lje", 0x6A9 },
#endif
{ "Cyrillic_nje", 0x6AA },
#ifndef TK_NO_DEPRECATED
{ "Serbian_nje", 0x6AA },
#endif
{ "Serbian_tshe", 0x6AB },
{ "Macedonia_kje", 0x6AC },
{ "Ukrainian_ghe_with_upturn", 0x6AD },
{ "Byelorussian_shortu", 0x6AE },
{ "Cyrillic_dzhe", 0x6AF },
#ifndef TK_NO_DEPRECATED
{ "Serbian_dze", 0x6AF },
#endif
{ "numerosign", 0x6B0 },
{ "Serbian_DJE", 0x6B1 },
{ "Macedonia_GJE", 0x6B2 },
{ "Cyrillic_IO", 0x6B3 },
{ "Ukrainian_IE", 0x6B4 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_JE", 0x6B4 },
#endif
{ "Macedonia_DSE", 0x6B5 },
{ "Ukrainian_I", 0x6B6 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_I", 0x6B6 },
#endif
{ "Ukrainian_YI", 0x6B7 },
#ifndef TK_NO_DEPRECATED
{ "Ukranian_YI", 0x6B7 },
#endif
{ "Cyrillic_JE", 0x6B8 },
#ifndef TK_NO_DEPRECATED
{ "Serbian_JE", 0x6B8 },
#endif
{ "Cyrillic_LJE", 0x6B9 },
#ifndef TK_NO_DEPRECATED
{ "Serbian_LJE", 0x6B9 },
#endif
{ "Cyrillic_NJE", 0x6BA },
#ifndef TK_NO_DEPRECATED
{ "Serbian_NJE", 0x6BA },
#endif
{ "Serbian_TSHE", 0x6BB },
{ "Macedonia_KJE", 0x6BC },
{ "Ukrainian_GHE_WITH_UPTURN", 0x6BD },
{ "Byelorussian_SHORTU", 0x6BE },
{ "Cyrillic_DZHE", 0x6BF },
#ifndef TK_NO_DEPRECATED
{ "Serbian_DZE", 0x6BF },
#endif
{ "Cyrillic_yu", 0x6C0 },
{ "Cyrillic_a", 0x6C1 },
{ "Cyrillic_be", 0x6C2 },
{ "Cyrillic_tse", 0x6C3 },
{ "Cyrillic_de", 0x6C4 },
{ "Cyrillic_ie", 0x6C5 },
{ "Cyrillic_ef", 0x6C6 },







<

<











<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




<

<


<

<

<

<

<

<

<

<

<

<





<

<





<

<


<

<

<

<

<

<

<

<

<

<





<

<







775
776
777
778
779
780
781

782

783
784
785
786
787
788
789
790
791
792
793












































794
795
796
797

798

799
800

801

802

803

804

805

806

807

808

809

810
811
812
813
814

815

816
817
818
819
820

821

822
823

824

825

826

827

828

829

830

831

832

833
834
835
836
837

838

839
840
841
842
843
844
845
{ "Arabic_feh", 0x5E1 },
{ "Arabic_qaf", 0x5E2 },
{ "Arabic_kaf", 0x5E3 },
{ "Arabic_lam", 0x5E4 },
{ "Arabic_meem", 0x5E5 },
{ "Arabic_noon", 0x5E6 },
{ "Arabic_ha", 0x5E7 },

{ "Arabic_heh", 0x5E7 },

{ "Arabic_waw", 0x5E8 },
{ "Arabic_alefmaksura", 0x5E9 },
{ "Arabic_yeh", 0x5EA },
{ "Arabic_fathatan", 0x5EB },
{ "Arabic_dammatan", 0x5EC },
{ "Arabic_kasratan", 0x5ED },
{ "Arabic_fatha", 0x5EE },
{ "Arabic_damma", 0x5EF },
{ "Arabic_kasra", 0x5F0 },
{ "Arabic_shadda", 0x5F1 },
{ "Arabic_sukun", 0x5F2 },












































{ "Serbian_dje", 0x6A1 },
{ "Macedonia_gje", 0x6A2 },
{ "Cyrillic_io", 0x6A3 },
{ "Ukrainian_ie", 0x6A4 },

{ "Ukranian_je", 0x6A4 },

{ "Macedonia_dse", 0x6A5 },
{ "Ukrainian_i", 0x6A6 },

{ "Ukranian_i", 0x6A6 },

{ "Ukrainian_yi", 0x6A7 },

{ "Ukranian_yi", 0x6A7 },

{ "Cyrillic_je", 0x6A8 },

{ "Serbian_je", 0x6A8 },

{ "Cyrillic_lje", 0x6A9 },

{ "Serbian_lje", 0x6A9 },

{ "Cyrillic_nje", 0x6AA },

{ "Serbian_nje", 0x6AA },

{ "Serbian_tshe", 0x6AB },
{ "Macedonia_kje", 0x6AC },
{ "Ukrainian_ghe_with_upturn", 0x6AD },
{ "Byelorussian_shortu", 0x6AE },
{ "Cyrillic_dzhe", 0x6AF },

{ "Serbian_dze", 0x6AF },

{ "numerosign", 0x6B0 },
{ "Serbian_DJE", 0x6B1 },
{ "Macedonia_GJE", 0x6B2 },
{ "Cyrillic_IO", 0x6B3 },
{ "Ukrainian_IE", 0x6B4 },

{ "Ukranian_JE", 0x6B4 },

{ "Macedonia_DSE", 0x6B5 },
{ "Ukrainian_I", 0x6B6 },

{ "Ukranian_I", 0x6B6 },

{ "Ukrainian_YI", 0x6B7 },

{ "Ukranian_YI", 0x6B7 },

{ "Cyrillic_JE", 0x6B8 },

{ "Serbian_JE", 0x6B8 },

{ "Cyrillic_LJE", 0x6B9 },

{ "Serbian_LJE", 0x6B9 },

{ "Cyrillic_NJE", 0x6BA },

{ "Serbian_NJE", 0x6BA },

{ "Serbian_TSHE", 0x6BB },
{ "Macedonia_KJE", 0x6BC },
{ "Ukrainian_GHE_WITH_UPTURN", 0x6BD },
{ "Byelorussian_SHORTU", 0x6BE },
{ "Cyrillic_DZHE", 0x6BF },

{ "Serbian_DZE", 0x6BF },

{ "Cyrillic_yu", 0x6C0 },
{ "Cyrillic_a", 0x6C1 },
{ "Cyrillic_be", 0x6C2 },
{ "Cyrillic_tse", 0x6C3 },
{ "Cyrillic_de", 0x6C4 },
{ "Cyrillic_ie", 0x6C5 },
{ "Cyrillic_ef", 0x6C6 },
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
{ "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 },







<







972
973
974
975
976
977
978

979
980
981
982
983
984
985
{ "Greek_finalsmallsigma", 0x7F3 },
{ "Greek_tau", 0x7F4 },
{ "Greek_upsilon", 0x7F5 },
{ "Greek_phi", 0x7F6 },
{ "Greek_chi", 0x7F7 },
{ "Greek_psi", 0x7F8 },
{ "Greek_omega", 0x7F9 },

{ "leftradical", 0x8A1 },
{ "topleftradical", 0x8A2 },
{ "horizconnector", 0x8A3 },
{ "topintegral", 0x8A4 },
{ "botintegral", 0x8A5 },
{ "vertconnector", 0x8A6 },
{ "topleftsqbracket", 0x8A7 },
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
{ "rightshoe", 0xBD8 },
{ "leftshoe", 0xBDA },
{ "lefttack", 0xBDC },
{ "righttack", 0xBFC },
{ "hebrew_doublelowline", 0xCDF },
{ "hebrew_aleph", 0xCE0 },
{ "hebrew_bet", 0xCE1 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_beth", 0xCE1 },
#endif
{ "hebrew_gimel", 0xCE2 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_gimmel", 0xCE2 },
#endif
{ "hebrew_dalet", 0xCE3 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_daleth", 0xCE3 },
#endif
{ "hebrew_he", 0xCE4 },
{ "hebrew_waw", 0xCE5 },
{ "hebrew_zain", 0xCE6 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_zayin", 0xCE6 },
#endif
{ "hebrew_chet", 0xCE7 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_het", 0xCE7 },
#endif
{ "hebrew_tet", 0xCE8 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_teth", 0xCE8 },
#endif
{ "hebrew_yod", 0xCE9 },
{ "hebrew_finalkaph", 0xCEA },
{ "hebrew_kaph", 0xCEB },
{ "hebrew_lamed", 0xCEC },
{ "hebrew_finalmem", 0xCED },
{ "hebrew_mem", 0xCEE },
{ "hebrew_finalnun", 0xCEF },
{ "hebrew_nun", 0xCF0 },
{ "hebrew_samech", 0xCF1 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_samekh", 0xCF1 },
#endif
{ "hebrew_ayin", 0xCF2 },
{ "hebrew_finalpe", 0xCF3 },
{ "hebrew_pe", 0xCF4 },
{ "hebrew_finalzade", 0xCF5 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_finalzadi", 0xCF5 },
#endif
{ "hebrew_zade", 0xCF6 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_zadi", 0xCF6 },
#endif
{ "hebrew_qoph", 0xCF7 },
#ifndef TK_NO_DEPRECATED
{ "hebrew_kuf", 0xCF7 },
#endif
{ "hebrew_resh", 0xCF8 },
{ "hebrew_shin", 0xCF9 },
{ "hebrew_taw", 0xCFA },
#ifndef TK_NO_DEPRECATED
{ "hebrew_taf", 0xCFA },
#endif
{ "Hebrew_switch", 0xFF7E },
{ "Thai_kokai", 0xDA1 },
{ "Thai_khokhai", 0xDA2 },
{ "Thai_khokhuat", 0xDA3 },
{ "Thai_khokhwai", 0xDA4 },
{ "Thai_khokhon", 0xDA5 },
{ "Thai_khorakhang", 0xDA6 },
{ "Thai_ngongu", 0xDA7 },







<

<

<

<

<

<



<

<

<

<

<

<









<

<




<

<

<

<

<

<



<

<
<







1151
1152
1153
1154
1155
1156
1157

1158

1159

1160

1161

1162

1163
1164
1165

1166

1167

1168

1169

1170

1171
1172
1173
1174
1175
1176
1177
1178
1179

1180

1181
1182
1183
1184

1185

1186

1187

1188

1189

1190
1191
1192

1193


1194
1195
1196
1197
1198
1199
1200
{ "rightshoe", 0xBD8 },
{ "leftshoe", 0xBDA },
{ "lefttack", 0xBDC },
{ "righttack", 0xBFC },
{ "hebrew_doublelowline", 0xCDF },
{ "hebrew_aleph", 0xCE0 },
{ "hebrew_bet", 0xCE1 },

{ "hebrew_beth", 0xCE1 },

{ "hebrew_gimel", 0xCE2 },

{ "hebrew_gimmel", 0xCE2 },

{ "hebrew_dalet", 0xCE3 },

{ "hebrew_daleth", 0xCE3 },

{ "hebrew_he", 0xCE4 },
{ "hebrew_waw", 0xCE5 },
{ "hebrew_zain", 0xCE6 },

{ "hebrew_zayin", 0xCE6 },

{ "hebrew_chet", 0xCE7 },

{ "hebrew_het", 0xCE7 },

{ "hebrew_tet", 0xCE8 },

{ "hebrew_teth", 0xCE8 },

{ "hebrew_yod", 0xCE9 },
{ "hebrew_finalkaph", 0xCEA },
{ "hebrew_kaph", 0xCEB },
{ "hebrew_lamed", 0xCEC },
{ "hebrew_finalmem", 0xCED },
{ "hebrew_mem", 0xCEE },
{ "hebrew_finalnun", 0xCEF },
{ "hebrew_nun", 0xCF0 },
{ "hebrew_samech", 0xCF1 },

{ "hebrew_samekh", 0xCF1 },

{ "hebrew_ayin", 0xCF2 },
{ "hebrew_finalpe", 0xCF3 },
{ "hebrew_pe", 0xCF4 },
{ "hebrew_finalzade", 0xCF5 },

{ "hebrew_finalzadi", 0xCF5 },

{ "hebrew_zade", 0xCF6 },

{ "hebrew_zadi", 0xCF6 },

{ "hebrew_qoph", 0xCF7 },

{ "hebrew_kuf", 0xCF7 },

{ "hebrew_resh", 0xCF8 },
{ "hebrew_shin", 0xCF9 },
{ "hebrew_taw", 0xCFA },

{ "hebrew_taf", 0xCFA },


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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1271
1272
1273
1274
1275
1276
1277
















1278
1279
1280
1281
1282
1283
1284
{ "Thai_leksam", 0xDF3 },
{ "Thai_leksi", 0xDF4 },
{ "Thai_lekha", 0xDF5 },
{ "Thai_lekhok", 0xDF6 },
{ "Thai_lekchet", 0xDF7 },
{ "Thai_lekpaet", 0xDF8 },
{ "Thai_lekkao", 0xDF9 },
















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







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1362
1363
1364
1365
1366
1367
1368






















































































































































































































































































































































































































































































































































































































































1369
1370
1371
1372
1373
1374
1375
{ "Hangul_YeorinHieuh", 0xEF5 },
{ "Hangul_AraeA", 0xEF6 },
{ "Hangul_AraeAE", 0xEF7 },
{ "Hangul_J_PanSios", 0xEF8 },
{ "Hangul_J_KkogjiDalrinIeung", 0xEF9 },
{ "Hangul_J_YeorinHieuh", 0xEFA },
{ "Korean_Won", 0xEFF },






















































































































































































































































































































































































































































































































































































































































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







>


















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
{ "XF86TouchpadOff", 0x1008FFB1 },
{ "XF86AudioMicMute", 0x1008FFB2 },
{ "XF86Keyboard", 0x1008FFB3 },
{ "XF86WWAN", 0x1008FFB4 },
{ "XF86RFKill", 0x1008FFB5 },
{ "XF86AudioPreset", 0x1008FFB6 },
{ "XF86RotationLockToggle", 0x1008FFB7 },
{ "XF86FullScreen", 0x1008FFB8 },
{ "XF86Switch_VT_1", 0x1008FE01 },
{ "XF86Switch_VT_2", 0x1008FE02 },
{ "XF86Switch_VT_3", 0x1008FE03 },
{ "XF86Switch_VT_4", 0x1008FE04 },
{ "XF86Switch_VT_5", 0x1008FE05 },
{ "XF86Switch_VT_6", 0x1008FE06 },
{ "XF86Switch_VT_7", 0x1008FE07 },
{ "XF86Switch_VT_8", 0x1008FE08 },
{ "XF86Switch_VT_9", 0x1008FE09 },
{ "XF86Switch_VT_10", 0x1008FE0A },
{ "XF86Switch_VT_11", 0x1008FE0B },
{ "XF86Switch_VT_12", 0x1008FE0C },
{ "XF86Ungrab", 0x1008FE20 },
{ "XF86ClearGrab", 0x1008FE21 },
{ "XF86Next_VMode", 0x1008FE22 },
{ "XF86Prev_VMode", 0x1008FE23 },
{ "XF86LogWindowTree", 0x1008FE24 },
{ "XF86LogGrabInfo", 0x1008FE25 },
{ "XF86BrightnessAuto", 0x100810F4 },
{ "XF86DisplayOff", 0x100810F5 },
{ "XF86Info", 0x10081166 },
{ "XF86AspectRatio", 0x10081177 },
{ "XF86DVD", 0x10081185 },
{ "XF86Audio", 0x10081188 },
{ "XF86ChannelUp", 0x10081192 },
{ "XF86ChannelDown", 0x10081193 },
{ "XF86Break", 0x1008119B },
{ "XF86VideoPhone", 0x100811A0 },
{ "XF86ZoomReset", 0x100811A4 },
{ "XF86Editor", 0x100811A6 },
{ "XF86GraphicsEditor", 0x100811A8 },
{ "XF86Presentation", 0x100811A9 },
{ "XF86Database", 0x100811AA },
{ "XF86Voicemail", 0x100811AC },
{ "XF86Addressbook", 0x100811AD },
{ "XF86DisplayToggle", 0x100811AF },
{ "XF86SpellCheck", 0x100811B0 },
{ "XF86ContextMenu", 0x100811B6 },
{ "XF86MediaRepeat", 0x100811B7 },
{ "XF8610ChannelsUp", 0x100811B8 },
{ "XF8610ChannelsDown", 0x100811B9 },
{ "XF86Images", 0x100811BA },
{ "XF86NotificationCenter", 0x100811BC },
{ "XF86PickupPhone", 0x100811BD },
{ "XF86HangupPhone", 0x100811BE },
{ "XF86Fn", 0x100811D0 },
{ "XF86Fn_Esc", 0x100811D1 },
{ "XF86FnRightShift", 0x100811E5 },
{ "XF86Numeric0", 0x10081200 },
{ "XF86Numeric1", 0x10081201 },
{ "XF86Numeric2", 0x10081202 },
{ "XF86Numeric3", 0x10081203 },
{ "XF86Numeric4", 0x10081204 },
{ "XF86Numeric5", 0x10081205 },
{ "XF86Numeric6", 0x10081206 },
{ "XF86Numeric7", 0x10081207 },
{ "XF86Numeric8", 0x10081208 },
{ "XF86Numeric9", 0x10081209 },
{ "XF86NumericStar", 0x1008120A },
{ "XF86NumericPound", 0x1008120B },
{ "XF86NumericA", 0x1008120C },
{ "XF86NumericB", 0x1008120D },
{ "XF86NumericC", 0x1008120E },
{ "XF86NumericD", 0x1008120F },
{ "XF86CameraFocus", 0x10081210 },
{ "XF86WPSButton", 0x10081211 },
{ "XF86CameraZoomIn", 0x10081215 },
{ "XF86CameraZoomOut", 0x10081216 },
{ "XF86CameraUp", 0x10081217 },
{ "XF86CameraDown", 0x10081218 },
{ "XF86CameraLeft", 0x10081219 },
{ "XF86CameraRight", 0x1008121A },
{ "XF86AttendantOn", 0x1008121B },
{ "XF86AttendantOff", 0x1008121C },
{ "XF86AttendantToggle", 0x1008121D },
{ "XF86LightsToggle", 0x1008121E },
{ "XF86ALSToggle", 0x10081230 },
{ "XF86Buttonconfig", 0x10081240 },
{ "XF86Taskmanager", 0x10081241 },
{ "XF86Journal", 0x10081242 },
{ "XF86ControlPanel", 0x10081243 },
{ "XF86AppSelect", 0x10081244 },
{ "XF86Screensaver", 0x10081245 },
{ "XF86VoiceCommand", 0x10081246 },
{ "XF86Assistant", 0x10081247 },
{ "XF86EmojiPicker", 0x10081249 },
{ "XF86Dictate", 0x1008124A },
{ "XF86BrightnessMin", 0x10081250 },
{ "XF86BrightnessMax", 0x10081251 },
{ "XF86KbdInputAssistPrev", 0x10081260 },
{ "XF86KbdInputAssistNext", 0x10081261 },
{ "XF86KbdInputAssistPrevgroup", 0x10081262 },
{ "XF86KbdInputAssistNextgroup", 0x10081263 },
{ "XF86KbdInputAssistAccept", 0x10081264 },
{ "XF86KbdInputAssistCancel", 0x10081265 },
{ "XF86RightUp", 0x10081266 },
{ "XF86RightDown", 0x10081267 },
{ "XF86LeftUp", 0x10081268 },
{ "XF86LeftDown", 0x10081269 },
{ "XF86RootMenu", 0x1008126A },
{ "XF86MediaTopMenu", 0x1008126B },
{ "XF86Numeric11", 0x1008126C },
{ "XF86Numeric12", 0x1008126D },
{ "XF86AudioDesc", 0x1008126E },
{ "XF863DMode", 0x1008126F },
{ "XF86NextFavorite", 0x10081270 },
{ "XF86StopRecord", 0x10081271 },
{ "XF86PauseRecord", 0x10081272 },
{ "XF86VOD", 0x10081273 },
{ "XF86Unmute", 0x10081274 },
{ "XF86FastReverse", 0x10081275 },
{ "XF86SlowReverse", 0x10081276 },
{ "XF86Data", 0x10081277 },
{ "XF86OnScreenKeyboard", 0x10081278 },
{ "XF86PrivacyScreenToggle", 0x10081279 },
{ "XF86SelectiveScreenshot", 0x1008127A },
{ "XF86Macro1", 0x10081290 },
{ "XF86Macro2", 0x10081291 },
{ "XF86Macro3", 0x10081292 },
{ "XF86Macro4", 0x10081293 },
{ "XF86Macro5", 0x10081294 },
{ "XF86Macro6", 0x10081295 },
{ "XF86Macro7", 0x10081296 },
{ "XF86Macro8", 0x10081297 },
{ "XF86Macro9", 0x10081298 },
{ "XF86Macro10", 0x10081299 },
{ "XF86Macro11", 0x1008129A },
{ "XF86Macro12", 0x1008129B },
{ "XF86Macro13", 0x1008129C },
{ "XF86Macro14", 0x1008129D },
{ "XF86Macro15", 0x1008129E },
{ "XF86Macro16", 0x1008129F },
{ "XF86Macro17", 0x100812A0 },
{ "XF86Macro18", 0x100812A1 },
{ "XF86Macro19", 0x100812A2 },
{ "XF86Macro20", 0x100812A3 },
{ "XF86Macro21", 0x100812A4 },
{ "XF86Macro22", 0x100812A5 },
{ "XF86Macro23", 0x100812A6 },
{ "XF86Macro24", 0x100812A7 },
{ "XF86Macro25", 0x100812A8 },
{ "XF86Macro26", 0x100812A9 },
{ "XF86Macro27", 0x100812AA },
{ "XF86Macro28", 0x100812AB },
{ "XF86Macro29", 0x100812AC },
{ "XF86Macro30", 0x100812AD },
{ "XF86MacroRecordStart", 0x100812B0 },
{ "XF86MacroRecordStop", 0x100812B1 },
{ "XF86MacroPresetCycle", 0x100812B2 },
{ "XF86MacroPreset1", 0x100812B3 },
{ "XF86MacroPreset2", 0x100812B4 },
{ "XF86MacroPreset3", 0x100812B5 },
{ "XF86KbdLcdMenu1", 0x100812B8 },
{ "XF86KbdLcdMenu2", 0x100812B9 },
{ "XF86KbdLcdMenu3", 0x100812BA },
{ "XF86KbdLcdMenu4", 0x100812BB },
{ "XF86KbdLcdMenu5", 0x100812BC },
{ "SunFA_Grave", 0x1005FF00 },
{ "SunFA_Circum", 0x1005FF01 },
{ "SunFA_Tilde", 0x1005FF02 },
{ "SunFA_Acute", 0x1005FF03 },
{ "SunFA_Diaeresis", 0x1005FF04 },
{ "SunFA_Cedilla", 0x1005FF05 },
{ "SunF36", 0x1005FF10 },
Deleted generic/nanosvg.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
/*
 * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 * The SVG parser is based on Anti-Grain Geometry 2.4 SVG example
 * Copyright (C) 2002-2004 Maxim Shemanarev (McSeem) (http://www.antigrain.com/)
 *
 * Arc calculation code based on canvg (https://code.google.com/p/canvg/)
 *
 * Bounding box calculation based on http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html
 *
 */

#ifndef NANOSVG_H
#define NANOSVG_H

#ifdef __cplusplus
extern "C" {
#endif

// NanoSVG is a simple stupid single-header-file SVG parse. The output of the parser is a list of cubic bezier shapes.
//
// The library suits well for anything from rendering scalable icons in your editor application to prototyping a game.
//
// NanoSVG supports a wide range of SVG features, but something may be missing, feel free to create a pull request!
//
// The shapes in the SVG images are transformed by the viewBox and converted to specified units.
// That is, you should get the same looking data as your designed in your favorite app.
//
// NanoSVG can return the paths in few different units. For example if you want to render an image, you may choose
// to get the paths in pixels, or if you are feeding the data into a CNC-cutter, you may want to use millimeters.
//
// The units passed to NanoSVG should be one of: 'px', 'pt', 'pc' 'mm', 'cm', or 'in'.
// DPI (dots-per-inch) controls how the unit conversion is done.
//
// If you don't know or care about the units stuff, "px" and 96 should get you going.


/* Example Usage:
	// Load SVG
	NSVGimage* image;
	image = nsvgParseFromFile("test.svg", "px", 96);
	printf("size: %f x %f\n", image->width, image->height);
	// Use...
	for (NSVGshape *shape = image->shapes; shape != NULL; shape = shape->next) {
		for (NSVGpath *path = shape->paths; path != NULL; path = path->next) {
			for (int i = 0; i < path->npts-1; i += 3) {
				float* p = &path->pts[i*2];
				drawCubicBez(p[0],p[1], p[2],p[3], p[4],p[5], p[6],p[7]);
			}
		}
	}
	// Delete
	nsvgDelete(image);
*/

#ifndef NANOSVG_SCOPE
#define NANOSVG_SCOPE
#endif

#ifndef NANOSVG_malloc
#define NANOSVG_malloc malloc
#endif

#ifndef NANOSVG_realloc
#define NANOSVG_realloc realloc
#endif

#ifndef NANOSVG_free
#define NANOSVG_free free
#endif

// float emulation for MS VC6++ compiler
#if defined(_MSC_VER) && (_MSC_VER == 1200)
#define tanf(a) (float)tan(a)
#define cosf(a) (float)cos(a)
#define sinf(a) (float)sin(a)
#define sqrtf(a) (float)sqrt(a)
#define fabsf(a) (float)fabs(a)
#define acosf(a) (float)acos(a)
#define atan2f(a,b) (float)atan2(a,b)
#define ceilf(a) (float)ceil(a)
#define fmodf(a,b) (float)fmod(a,b)
#define floorf(a) (float)floor(a)
#endif
// float emulation for MS VC8++ compiler
#if defined(_MSC_VER) && (_MSC_VER == 1400)
#define fabsf(a) (float)fabs(a)
#endif

enum NSVGpaintType {
	NSVG_PAINT_NONE = 0,
	NSVG_PAINT_COLOR = 1,
	NSVG_PAINT_LINEAR_GRADIENT = 2,
	NSVG_PAINT_RADIAL_GRADIENT = 3
};

enum NSVGspreadType {
	NSVG_SPREAD_PAD = 0,
	NSVG_SPREAD_REFLECT = 1,
	NSVG_SPREAD_REPEAT = 2
};

enum NSVGlineJoin {
	NSVG_JOIN_MITER = 0,
	NSVG_JOIN_ROUND = 1,
	NSVG_JOIN_BEVEL = 2
};

enum NSVGlineCap {
	NSVG_CAP_BUTT = 0,
	NSVG_CAP_ROUND = 1,
	NSVG_CAP_SQUARE = 2
};

enum NSVGfillRule {
	NSVG_FILLRULE_NONZERO = 0,
	NSVG_FILLRULE_EVENODD = 1
};

enum NSVGflags {
	NSVG_FLAGS_VISIBLE = 0x01
};

typedef struct NSVGgradientStop {
	unsigned int color;
	float offset;
} NSVGgradientStop;

typedef struct NSVGgradient {
	float xform[6];
	char spread;
	float fx, fy;
	int nstops;
	NSVGgradientStop stops[1];
} NSVGgradient;

typedef struct NSVGpaint {
	char type;
	union {
		unsigned int color;
		NSVGgradient* gradient;
	};
} NSVGpaint;

typedef struct NSVGpath
{
	float* pts;					// Cubic bezier points: x0,y0, [cpx1,cpx1,cpx2,cpy2,x1,y1], ...
	int npts;					// Total number of bezier points.
	char closed;				// Flag indicating if shapes should be treated as closed.
	float bounds[4];			// Tight bounding box of the shape [minx,miny,maxx,maxy].
	struct NSVGpath* next;		// Pointer to next path, or NULL if last element.
} NSVGpath;

typedef struct NSVGshape
{
	char id[64];				// Optional 'id' attr of the shape or its group
	NSVGpaint fill;				// Fill paint
	NSVGpaint stroke;			// Stroke paint
	float opacity;				// Opacity of the shape.
	float strokeWidth;			// Stroke width (scaled).
	float strokeDashOffset;		// Stroke dash offset (scaled).
	float strokeDashArray[8];			// Stroke dash array (scaled).
	char strokeDashCount;				// Number of dash values in dash array.
	char strokeLineJoin;		// Stroke join type.
	char strokeLineCap;			// Stroke cap type.
	float miterLimit;			// Miter limit
	char fillRule;				// Fill rule, see NSVGfillRule.
	unsigned char flags;		// Logical or of NSVG_FLAGS_* flags
	float bounds[4];			// Tight bounding box of the shape [minx,miny,maxx,maxy].
	NSVGpath* paths;			// Linked list of paths in the image.
	struct NSVGshape* next;		// Pointer to next shape, or NULL if last element.
} NSVGshape;

typedef struct NSVGimage
{
	float width;				// Width of the image.
	float height;				// Height of the image.
	NSVGshape* shapes;			// Linked list of shapes in the image.
} NSVGimage;

// Parses SVG file from a file, returns SVG image as paths.
NANOSVG_SCOPE NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi);

// Parses SVG file from a null terminated string, returns SVG image as paths.
// Important note: changes the string.
NANOSVG_SCOPE NSVGimage* nsvgParse(char* input, const char* units, float dpi);

// Deletes list of paths.
NANOSVG_SCOPE void nsvgDelete(NSVGimage* image);

#ifdef __cplusplus
}
#endif

#endif // NANOSVG_H

#ifdef NANOSVG_IMPLEMENTATION

#include <string.h>
#include <stdlib.h>
#include <math.h>

#define NSVG_PI (3.14159265358979323846264338327f)
#define NSVG_KAPPA90 (0.5522847493f)	// Length proportional to radius of a cubic bezier handle for 90deg arcs.

#define NSVG_ALIGN_MIN 0
#define NSVG_ALIGN_MID 1
#define NSVG_ALIGN_MAX 2
#define NSVG_ALIGN_NONE 0
#define NSVG_ALIGN_MEET 1
#define NSVG_ALIGN_SLICE 2

#define NSVG_NOTUSED(v) do { (void)(1 ? (void)0 : ( (void)(v) ) ); } while(0)
#define NSVG_RGB(r, g, b) (((unsigned int)r) | ((unsigned int)g << 8) | ((unsigned int)b << 16))

#ifdef _MSC_VER
	#pragma warning (disable: 4996) // Switch off security warnings
	#pragma warning (disable: 4100) // Switch off unreferenced formal parameter warnings
	#ifdef __cplusplus
	#define NSVG_INLINE inline
	#else
	#define NSVG_INLINE
	#endif
	#if !defined(strtoll)           // old MSVC versions do not have strtoll()
		#define strtoll _strtoi64
	#endif
#else
	#define NSVG_INLINE inline
#endif


static int nsvg__isspace(char c)
{
	return strchr(" \t\n\v\f\r", c) != 0;
}

static int nsvg__isdigit(char c)
{
	return c >= '0' && c <= '9';
}

static NSVG_INLINE float nsvg__minf(float a, float b) { return a < b ? a : b; }
static NSVG_INLINE float nsvg__maxf(float a, float b) { return a > b ? a : b; }


// Simple XML parser

#define NSVG_XML_TAG 1
#define NSVG_XML_CONTENT 2
#define NSVG_XML_MAX_ATTRIBS 256

static void nsvg__parseContent(char* s,
							   void (*contentCb)(void* ud, const char* s),
							   void* ud)
{
	// Trim start white spaces
	while (*s && nsvg__isspace(*s)) s++;
	if (!*s) return;

	if (contentCb)
		(*contentCb)(ud, s);
}

static void nsvg__parseElement(char* s,
							   void (*startelCb)(void* ud, const char* el, const char** attr),
							   void (*endelCb)(void* ud, const char* el),
							   void* ud)
{
	const char* attr[NSVG_XML_MAX_ATTRIBS];
	int nattr = 0;
	char* cbname;
	int start = 0;
	int end = 0;
	char quote;

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

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

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

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

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

		// Skip white space before the attrib name
		while (*s && nsvg__isspace(*s)) s++;
		if (!*s) break;
		if (*s == '/') {
			end = 1;
			break;
		}
		name = s;
		// Find end of the attrib name.
		while (*s && !nsvg__isspace(*s) && *s != '=') s++;
		if (*s) { *s++ = '\0'; }
		// Skip until the beginning of the value.
		while (*s && *s != '\"' && *s != '\'') s++;
		if (!*s) break;
		quote = *s;
		s++;
		// Store value and find the end of it.
		value = s;
		while (*s && *s != quote) s++;
		if (*s) { *s++ = '\0'; }

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

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

	// Call callbacks.
	if (start && startelCb)
		(*startelCb)(ud, cbname, attr);
	if (end && endelCb)
		(*endelCb)(ud, cbname);
}

NANOSVG_SCOPE
int nsvg__parseXML(char* input,
				   void (*startelCb)(void* ud, const char* el, const char** attr),
				   void (*endelCb)(void* ud, const char* el),
				   void (*contentCb)(void* ud, const char* s),
				   void* ud)
{
	char* s = input;
	char* mark = s;
	int state = NSVG_XML_CONTENT;
	while (*s) {
		if (*s == '<' && state == NSVG_XML_CONTENT) {
			// Start of a tag
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			mark = s;
			state = NSVG_XML_TAG;
		} else if (*s == '>' && state == NSVG_XML_TAG) {
			// Start of a content or new tag.
			*s++ = '\0';
			nsvg__parseContent(mark, contentCb, ud);
			nsvg__parseElement(mark, startelCb, endelCb, ud);
			mark = s;
			state = NSVG_XML_CONTENT;
		} else {
			s++;
		}
	}

	return 1;
}


/* Simple SVG parser. */

#define NSVG_MAX_ATTR 128

enum NSVGgradientUnits {
	NSVG_USER_SPACE = 0,
	NSVG_OBJECT_SPACE = 1
};

#define NSVG_MAX_DASHES 8

enum NSVGunits {
	NSVG_UNITS_USER,
	NSVG_UNITS_PX,
	NSVG_UNITS_PT,
	NSVG_UNITS_PC,
	NSVG_UNITS_MM,
	NSVG_UNITS_CM,
	NSVG_UNITS_IN,
	NSVG_UNITS_PERCENT,
	NSVG_UNITS_EM,
	NSVG_UNITS_EX
};

enum NSVGvisible {
	NSVG_VIS_DISPLAY = 1,
	NSVG_VIS_VISIBLE = 2
};

typedef struct NSVGcoordinate {
	float value;
	int units;
} NSVGcoordinate;

typedef struct NSVGlinearData {
	NSVGcoordinate x1, y1, x2, y2;
} NSVGlinearData;

typedef struct NSVGradialData {
	NSVGcoordinate cx, cy, r, fx, fy;
} NSVGradialData;

typedef struct NSVGgradientData
{
	char id[64];
	char ref[64];
	char type;
	union {
		NSVGlinearData linear;
		NSVGradialData radial;
	};
	char spread;
	char units;
	float xform[6];
	int nstops;
	NSVGgradientStop* stops;
	struct NSVGgradientData* next;
} NSVGgradientData;

typedef struct NSVGattrib
{
	char id[64];
	float xform[6];
	unsigned int fillColor;
	unsigned int strokeColor;
	float opacity;
	float fillOpacity;
	float strokeOpacity;
	char fillGradient[64];
	char strokeGradient[64];
	float strokeWidth;
	float strokeDashOffset;
	float strokeDashArray[NSVG_MAX_DASHES];
	int strokeDashCount;
	char strokeLineJoin;
	char strokeLineCap;
	float miterLimit;
	char fillRule;
	float fontSize;
	unsigned int stopColor;
	float stopOpacity;
	float stopOffset;
	char hasFill;
	char hasStroke;
	char visible;
} NSVGattrib;

typedef struct NSVGstyles
{
	char*	name;
	char* description;
	struct NSVGstyles* next;
} NSVGstyles;

typedef struct NSVGparser
{
	NSVGattrib attr[NSVG_MAX_ATTR];
	int attrHead;
	float* pts;
	int npts;
	int cpts;
	NSVGpath* plist;
	NSVGimage* image;
	NSVGstyles* styles;
	NSVGgradientData* gradients;
	NSVGshape* shapesTail;
	float viewMinx, viewMiny, viewWidth, viewHeight;
	int alignX, alignY, alignType;
	float dpi;
	char pathFlag;
	char defsFlag;
	char styleFlag;
} NSVGparser;

static void nsvg__xformIdentity(float* t)
{
	t[0] = 1.0f; t[1] = 0.0f;
	t[2] = 0.0f; t[3] = 1.0f;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetTranslation(float* t, float tx, float ty)
{
	t[0] = 1.0f; t[1] = 0.0f;
	t[2] = 0.0f; t[3] = 1.0f;
	t[4] = tx; t[5] = ty;
}

static void nsvg__xformSetScale(float* t, float sx, float sy)
{
	t[0] = sx; t[1] = 0.0f;
	t[2] = 0.0f; t[3] = sy;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetSkewX(float* t, float a)
{
	t[0] = 1.0f; t[1] = 0.0f;
	t[2] = tanf(a); t[3] = 1.0f;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetSkewY(float* t, float a)
{
	t[0] = 1.0f; t[1] = tanf(a);
	t[2] = 0.0f; t[3] = 1.0f;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformSetRotation(float* t, float a)
{
	float cs = cosf(a), sn = sinf(a);
	t[0] = cs; t[1] = sn;
	t[2] = -sn; t[3] = cs;
	t[4] = 0.0f; t[5] = 0.0f;
}

static void nsvg__xformMultiply(float* t, float* s)
{
	float t0 = t[0] * s[0] + t[1] * s[2];
	float t2 = t[2] * s[0] + t[3] * s[2];
	float t4 = t[4] * s[0] + t[5] * s[2] + s[4];
	t[1] = t[0] * s[1] + t[1] * s[3];
	t[3] = t[2] * s[1] + t[3] * s[3];
	t[5] = t[4] * s[1] + t[5] * s[3] + s[5];
	t[0] = t0;
	t[2] = t2;
	t[4] = t4;
}

static void nsvg__xformInverse(float* inv, float* t)
{
	double invdet, det = (double)t[0] * t[3] - (double)t[2] * t[1];
	if (det > -1e-6 && det < 1e-6) {
		nsvg__xformIdentity(t);
		return;
	}
	invdet = 1.0 / det;
	inv[0] = (float)(t[3] * invdet);
	inv[2] = (float)(-t[2] * invdet);
	inv[4] = (float)(((double)t[2] * t[5] - (double)t[3] * t[4]) * invdet);
	inv[1] = (float)(-t[1] * invdet);
	inv[3] = (float)(t[0] * invdet);
	inv[5] = (float)(((double)t[1] * t[4] - (double)t[0] * t[5]) * invdet);
}

static void nsvg__xformPremultiply(float* t, float* s)
{
	float s2[6];
	memcpy(s2, s, sizeof(float)*6);
	nsvg__xformMultiply(s2, t);
	memcpy(t, s2, sizeof(float)*6);
}

static void nsvg__xformPoint(float* dx, float* dy, float x, float y, float* t)
{
	*dx = x*t[0] + y*t[2] + t[4];
	*dy = x*t[1] + y*t[3] + t[5];
}

static void nsvg__xformVec(float* dx, float* dy, float x, float y, float* t)
{
	*dx = x*t[0] + y*t[2];
	*dy = x*t[1] + y*t[3];
}

#define NSVG_EPSILON (1e-12)

static int nsvg__ptInBounds(float* pt, float* bounds)
{
	return pt[0] >= bounds[0] && pt[0] <= bounds[2] && pt[1] >= bounds[1] && pt[1] <= bounds[3];
}


static double nsvg__evalBezier(double t, double p0, double p1, double p2, double p3)
{
	double it = 1.0-t;
	return it*it*it*p0 + 3.0*it*it*t*p1 + 3.0*it*t*t*p2 + t*t*t*p3;
}

static void nsvg__curveBounds(float* bounds, float* curve)
{
	int i, j, count;
	double roots[2], a, b, c, b2ac, t, v;
	float* v0 = &curve[0];
	float* v1 = &curve[2];
	float* v2 = &curve[4];
	float* v3 = &curve[6];

	// Start the bounding box by end points
	bounds[0] = nsvg__minf(v0[0], v3[0]);
	bounds[1] = nsvg__minf(v0[1], v3[1]);
	bounds[2] = nsvg__maxf(v0[0], v3[0]);
	bounds[3] = nsvg__maxf(v0[1], v3[1]);

	// Bezier curve fits inside the convex hull of it's control points.
	// If control points are inside the bounds, we're done.
	if (nsvg__ptInBounds(v1, bounds) && nsvg__ptInBounds(v2, bounds))
		return;

	// Add bezier curve inflection points in X and Y.
	for (i = 0; i < 2; i++) {
		a = -3.0 * v0[i] + 9.0 * v1[i] - 9.0 * v2[i] + 3.0 * v3[i];
		b = 6.0 * v0[i] - 12.0 * v1[i] + 6.0 * v2[i];
		c = 3.0 * v1[i] - 3.0 * v0[i];
		count = 0;
		if (fabs(a) < NSVG_EPSILON) {
			if (fabs(b) > NSVG_EPSILON) {
				t = -c / b;
				if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
					roots[count++] = t;
			}
		} else {
			b2ac = b*b - 4.0*c*a;
			if (b2ac > NSVG_EPSILON) {
				t = (-b + sqrt(b2ac)) / (2.0 * a);
				if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
					roots[count++] = t;
				t = (-b - sqrt(b2ac)) / (2.0 * a);
				if (t > NSVG_EPSILON && t < 1.0-NSVG_EPSILON)
					roots[count++] = t;
			}
		}
		for (j = 0; j < count; j++) {
			v = nsvg__evalBezier(roots[j], v0[i], v1[i], v2[i], v3[i]);
			bounds[0+i] = nsvg__minf(bounds[0+i], (float)v);
			bounds[2+i] = nsvg__maxf(bounds[2+i], (float)v);
		}
	}
}

static NSVGparser* nsvg__createParser(void)
{
	NSVGparser* p;
	p = (NSVGparser*)NANOSVG_malloc(sizeof(NSVGparser));
	if (p == NULL) goto error;
	memset(p, 0, sizeof(NSVGparser));

	p->image = (NSVGimage*)NANOSVG_malloc(sizeof(NSVGimage));
	if (p->image == NULL) goto error;
	memset(p->image, 0, sizeof(NSVGimage));

	// Init style
	nsvg__xformIdentity(p->attr[0].xform);
	memset(p->attr[0].id, 0, sizeof p->attr[0].id);
	p->attr[0].fillColor = NSVG_RGB(0,0,0);
	p->attr[0].strokeColor = NSVG_RGB(0,0,0);
	p->attr[0].opacity = 1;
	p->attr[0].fillOpacity = 1;
	p->attr[0].strokeOpacity = 1;
	p->attr[0].stopOpacity = 1;
	p->attr[0].strokeWidth = 1;
	p->attr[0].strokeLineJoin = NSVG_JOIN_MITER;
	p->attr[0].strokeLineCap = NSVG_CAP_BUTT;
	p->attr[0].miterLimit = 4;
	p->attr[0].fillRule = NSVG_FILLRULE_NONZERO;
	p->attr[0].hasFill = 1;
	p->attr[0].visible = NSVG_VIS_DISPLAY | NSVG_VIS_VISIBLE;

	return p;

error:
	if (p) {
		if (p->image) NANOSVG_free(p->image);
		NANOSVG_free(p);
	}
	return NULL;
}

static void nsvg__deleteStyles(NSVGstyles* style) {
	while (style) {
		NSVGstyles *next = style->next;
		if (style->name!= NULL)
			NANOSVG_free(style->name);
		if (style->description != NULL)
			NANOSVG_free(style->description);
		NANOSVG_free(style);
		style = next;
	}
}

static void nsvg__deletePaths(NSVGpath* path)
{
	while (path) {
		NSVGpath *next = path->next;
		if (path->pts != NULL)
			NANOSVG_free(path->pts);
		NANOSVG_free(path);
		path = next;
	}
}

static void nsvg__deletePaint(NSVGpaint* paint)
{
	if (paint->type == NSVG_PAINT_LINEAR_GRADIENT || paint->type == NSVG_PAINT_RADIAL_GRADIENT)
		NANOSVG_free(paint->gradient);
}

static void nsvg__deleteGradientData(NSVGgradientData* grad)
{
	NSVGgradientData* next;
	while (grad != NULL) {
		next = grad->next;
		NANOSVG_free(grad->stops);
		NANOSVG_free(grad);
		grad = next;
	}
}

static void nsvg__deleteParser(NSVGparser* p)
{
	if (p != NULL) {
		nsvg__deleteStyles(p->styles);
		nsvg__deletePaths(p->plist);
		nsvg__deleteGradientData(p->gradients);
		nsvgDelete(p->image);
		NANOSVG_free(p->pts);
		NANOSVG_free(p);
	}
}

static void nsvg__resetPath(NSVGparser* p)
{
	p->npts = 0;
}

static void nsvg__addPoint(NSVGparser* p, float x, float y)
{
	if (p->npts+1 > p->cpts) {
		p->cpts = p->cpts ? p->cpts*2 : 8;
		p->pts = (float*)NANOSVG_realloc(p->pts, p->cpts*2*sizeof(float));
		if (!p->pts) return;
	}
	p->pts[p->npts*2+0] = x;
	p->pts[p->npts*2+1] = y;
	p->npts++;
}

static void nsvg__moveTo(NSVGparser* p, float x, float y)
{
	if (p->npts > 0) {
		p->pts[(p->npts-1)*2+0] = x;
		p->pts[(p->npts-1)*2+1] = y;
	} else {
		nsvg__addPoint(p, x, y);
	}
}

static void nsvg__lineTo(NSVGparser* p, float x, float y)
{
	float px,py, dx,dy;
	if (p->npts > 0) {
		px = p->pts[(p->npts-1)*2+0];
		py = p->pts[(p->npts-1)*2+1];
		dx = x - px;
		dy = y - py;
		nsvg__addPoint(p, px + dx/3.0f, py + dy/3.0f);
		nsvg__addPoint(p, x - dx/3.0f, y - dy/3.0f);
		nsvg__addPoint(p, x, y);
	}
}

static void nsvg__cubicBezTo(NSVGparser* p, float cpx1, float cpy1, float cpx2, float cpy2, float x, float y)
{
	if (p->npts > 0) {
		nsvg__addPoint(p, cpx1, cpy1);
		nsvg__addPoint(p, cpx2, cpy2);
		nsvg__addPoint(p, x, y);
	}
}

static NSVGattrib* nsvg__getAttr(NSVGparser* p)
{
	return &p->attr[p->attrHead];
}

static void nsvg__pushAttr(NSVGparser* p)
{
	if (p->attrHead < NSVG_MAX_ATTR-1) {
		p->attrHead++;
		memcpy(&p->attr[p->attrHead], &p->attr[p->attrHead-1], sizeof(NSVGattrib));
	}
}

static void nsvg__popAttr(NSVGparser* p)
{
	if (p->attrHead > 0)
		p->attrHead--;
}

static float nsvg__actualOrigX(NSVGparser* p)
{
	return p->viewMinx;
}

static float nsvg__actualOrigY(NSVGparser* p)
{
	return p->viewMiny;
}

static float nsvg__actualWidth(NSVGparser* p)
{
	return p->viewWidth;
}

static float nsvg__actualHeight(NSVGparser* p)
{
	return p->viewHeight;
}

static float nsvg__actualLength(NSVGparser* p)
{
	float w = nsvg__actualWidth(p), h = nsvg__actualHeight(p);
	return sqrtf(w*w + h*h) / sqrtf(2.0f);
}

static float nsvg__convertToPixels(NSVGparser* p, NSVGcoordinate c, float orig, float length)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	switch (c.units) {
		case NSVG_UNITS_USER:		return c.value;
		case NSVG_UNITS_PX:			return c.value;
		case NSVG_UNITS_PT:			return c.value / 72.0f * p->dpi;
		case NSVG_UNITS_PC:			return c.value / 6.0f * p->dpi;
		case NSVG_UNITS_MM:			return c.value / 25.4f * p->dpi;
		case NSVG_UNITS_CM:			return c.value / 2.54f * p->dpi;
		case NSVG_UNITS_IN:			return c.value * p->dpi;
		case NSVG_UNITS_EM:			return c.value * attr->fontSize;
		case NSVG_UNITS_EX:			return c.value * attr->fontSize * 0.52f; // x-height of Helvetica.
		case NSVG_UNITS_PERCENT:	return orig + c.value / 100.0f * length;
		default:					return c.value;
	}
	return c.value;
}

static NSVGgradientData* nsvg__findGradientData(NSVGparser* p, const char* id)
{
	NSVGgradientData* grad = p->gradients;
	if (id == NULL || *id == '\0')
		return NULL;
	while (grad != NULL) {
		if (strcmp(grad->id, id) == 0)
			return grad;
		grad = grad->next;
	}
	return NULL;
}

static NSVGgradient* nsvg__createGradient(NSVGparser* p, const char* id, const float* localBounds, char* paintType)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	NSVGgradientData* data = NULL;
	NSVGgradientData* ref = NULL;
	NSVGgradientStop* stops = NULL;
	NSVGgradient* grad;
	float ox, oy, sw, sh, sl;
	int nstops = 0;
	int refIter;

	data = nsvg__findGradientData(p, id);
	if (data == NULL) return NULL;

	// TODO: use ref to fill in all unset values too.
	ref = data;
	refIter = 0;
	while (ref != NULL) {
		NSVGgradientData* nextRef = NULL;
		if (stops == NULL && ref->stops != NULL) {
			stops = ref->stops;
			nstops = ref->nstops;
			break;
		}
		nextRef = nsvg__findGradientData(p, ref->ref);
		if (nextRef == ref) break; // prevent infite loops on malformed data
		ref = nextRef;
		refIter++;
		if (refIter > 32) break; // prevent infite loops on malformed data
	}
	if (stops == NULL) return NULL;

	grad = (NSVGgradient*)NANOSVG_malloc(sizeof(NSVGgradient) + sizeof(NSVGgradientStop)*(nstops-1));
	if (grad == NULL) return NULL;

	// The shape width and height.
	if (data->units == NSVG_OBJECT_SPACE) {
		ox = localBounds[0];
		oy = localBounds[1];
		sw = localBounds[2] - localBounds[0];
		sh = localBounds[3] - localBounds[1];
	} else {
		ox = nsvg__actualOrigX(p);
		oy = nsvg__actualOrigY(p);
		sw = nsvg__actualWidth(p);
		sh = nsvg__actualHeight(p);
	}
	sl = sqrtf(sw*sw + sh*sh) / sqrtf(2.0f);

	if (data->type == NSVG_PAINT_LINEAR_GRADIENT) {
		float x1, y1, x2, y2, dx, dy;
		x1 = nsvg__convertToPixels(p, data->linear.x1, ox, sw);
		y1 = nsvg__convertToPixels(p, data->linear.y1, oy, sh);
		x2 = nsvg__convertToPixels(p, data->linear.x2, ox, sw);
		y2 = nsvg__convertToPixels(p, data->linear.y2, oy, sh);
		// Calculate transform aligned to the line
		dx = x2 - x1;
		dy = y2 - y1;
		grad->xform[0] = dy; grad->xform[1] = -dx;
		grad->xform[2] = dx; grad->xform[3] = dy;
		grad->xform[4] = x1; grad->xform[5] = y1;
	} else {
		float cx, cy, fx, fy, r;
		cx = nsvg__convertToPixels(p, data->radial.cx, ox, sw);
		cy = nsvg__convertToPixels(p, data->radial.cy, oy, sh);
		fx = nsvg__convertToPixels(p, data->radial.fx, ox, sw);
		fy = nsvg__convertToPixels(p, data->radial.fy, oy, sh);
		r = nsvg__convertToPixels(p, data->radial.r, 0, sl);
		// Calculate transform aligned to the circle
		grad->xform[0] = r; grad->xform[1] = 0;
		grad->xform[2] = 0; grad->xform[3] = r;
		grad->xform[4] = cx; grad->xform[5] = cy;
		grad->fx = fx / r;
		grad->fy = fy / r;
	}

	nsvg__xformMultiply(grad->xform, data->xform);
	nsvg__xformMultiply(grad->xform, attr->xform);

	grad->spread = data->spread;
	memcpy(grad->stops, stops, nstops*sizeof(NSVGgradientStop));
	grad->nstops = nstops;

	*paintType = data->type;

	return grad;
}

static float nsvg__getAverageScale(float* t)
{
	float sx = sqrtf(t[0]*t[0] + t[2]*t[2]);
	float sy = sqrtf(t[1]*t[1] + t[3]*t[3]);
	return (sx + sy) * 0.5f;
}

static void nsvg__getLocalBounds(float* bounds, NSVGshape *shape, float* xform)
{
	NSVGpath* path;
	float curve[4*2], curveBounds[4];
	int i, first = 1;
	for (path = shape->paths; path != NULL; path = path->next) {
		nsvg__xformPoint(&curve[0], &curve[1], path->pts[0], path->pts[1], xform);
		for (i = 0; i < path->npts-1; i += 3) {
			nsvg__xformPoint(&curve[2], &curve[3], path->pts[(i+1)*2], path->pts[(i+1)*2+1], xform);
			nsvg__xformPoint(&curve[4], &curve[5], path->pts[(i+2)*2], path->pts[(i+2)*2+1], xform);
			nsvg__xformPoint(&curve[6], &curve[7], path->pts[(i+3)*2], path->pts[(i+3)*2+1], xform);
			nsvg__curveBounds(curveBounds, curve);
			if (first) {
				bounds[0] = curveBounds[0];
				bounds[1] = curveBounds[1];
				bounds[2] = curveBounds[2];
				bounds[3] = curveBounds[3];
				first = 0;
			} else {
				bounds[0] = nsvg__minf(bounds[0], curveBounds[0]);
				bounds[1] = nsvg__minf(bounds[1], curveBounds[1]);
				bounds[2] = nsvg__maxf(bounds[2], curveBounds[2]);
				bounds[3] = nsvg__maxf(bounds[3], curveBounds[3]);
			}
			curve[0] = curve[6];
			curve[1] = curve[7];
		}
	}
}

static void nsvg__addShape(NSVGparser* p)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	float scale = 1.0f;
	NSVGshape* shape;
	NSVGpath* path;
	int i;

	if (p->plist == NULL)
		return;

	shape = (NSVGshape*)NANOSVG_malloc(sizeof(NSVGshape));
	if (shape == NULL) goto error;
	memset(shape, 0, sizeof(NSVGshape));

	memcpy(shape->id, attr->id, sizeof shape->id);
	scale = nsvg__getAverageScale(attr->xform);
	shape->strokeWidth = attr->strokeWidth * scale;
	shape->strokeDashOffset = attr->strokeDashOffset * scale;
	shape->strokeDashCount = (char)attr->strokeDashCount;
	for (i = 0; i < attr->strokeDashCount; i++)
		shape->strokeDashArray[i] = attr->strokeDashArray[i] * scale;
	shape->strokeLineJoin = attr->strokeLineJoin;
	shape->strokeLineCap = attr->strokeLineCap;
	shape->miterLimit = attr->miterLimit;
	shape->fillRule = attr->fillRule;
	shape->opacity = attr->opacity;

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

	// Calculate shape bounds
	shape->bounds[0] = shape->paths->bounds[0];
	shape->bounds[1] = shape->paths->bounds[1];
	shape->bounds[2] = shape->paths->bounds[2];
	shape->bounds[3] = shape->paths->bounds[3];
	for (path = shape->paths->next; path != NULL; path = path->next) {
		shape->bounds[0] = nsvg__minf(shape->bounds[0], path->bounds[0]);
		shape->bounds[1] = nsvg__minf(shape->bounds[1], path->bounds[1]);
		shape->bounds[2] = nsvg__maxf(shape->bounds[2], path->bounds[2]);
		shape->bounds[3] = nsvg__maxf(shape->bounds[3], path->bounds[3]);
	}

	// Set fill
	if (attr->hasFill == 0) {
		shape->fill.type = NSVG_PAINT_NONE;
	} else if (attr->hasFill == 1) {
		shape->fill.type = NSVG_PAINT_COLOR;
		shape->fill.color = attr->fillColor;
		shape->fill.color |= (unsigned int)(attr->fillOpacity*255) << 24;
	} else if (attr->hasFill == 2) {
		float inv[6], localBounds[4];
		nsvg__xformInverse(inv, attr->xform);
		nsvg__getLocalBounds(localBounds, shape, inv);
		shape->fill.gradient = nsvg__createGradient(p, attr->fillGradient, localBounds, &shape->fill.type);
		if (shape->fill.gradient == NULL) {
			shape->fill.type = NSVG_PAINT_NONE;
		}
	}

	// Set stroke
	if (attr->hasStroke == 0) {
		shape->stroke.type = NSVG_PAINT_NONE;
	} else if (attr->hasStroke == 1) {
		shape->stroke.type = NSVG_PAINT_COLOR;
		shape->stroke.color = attr->strokeColor;
		shape->stroke.color |= (unsigned int)(attr->strokeOpacity*255) << 24;
	} else if (attr->hasStroke == 2) {
		float inv[6], localBounds[4];
		nsvg__xformInverse(inv, attr->xform);
		nsvg__getLocalBounds(localBounds, shape, inv);
		shape->stroke.gradient = nsvg__createGradient(p, attr->strokeGradient, localBounds, &shape->stroke.type);
		if (shape->stroke.gradient == NULL)
			shape->stroke.type = NSVG_PAINT_NONE;
	}

	// Set flags
	shape->flags = ((attr->visible & NSVG_VIS_DISPLAY) && (attr->visible & NSVG_VIS_VISIBLE) ? NSVG_FLAGS_VISIBLE : 0x00);

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

	return;

error:
	if (shape) NANOSVG_free(shape);
}

static void nsvg__addPath(NSVGparser* p, char closed)
{
	NSVGattrib* attr = nsvg__getAttr(p);
	NSVGpath* path = NULL;
	float bounds[4];
	float* curve;
	int i;

	if (p->npts < 4)
		return;

	if (closed)
		nsvg__lineTo(p, p->pts[0], p->pts[1]);

	// Expect 1 + N*3 points (N = number of cubic bezier segments).
	if ((p->npts % 3) != 1)
		return;

	path = (NSVGpath*)NANOSVG_malloc(sizeof(NSVGpath));
	if (path == NULL) goto error;
	memset(path, 0, sizeof(NSVGpath));

	path->pts = (float*)NANOSVG_malloc(p->npts*2*sizeof(float));
	if (path->pts == NULL) goto error;
	path->closed = closed;
	path->npts = p->npts;

	// Transform path.
	for (i = 0; i < p->npts; ++i)
		nsvg__xformPoint(&path->pts[i*2], &path->pts[i*2+1], p->pts[i*2], p->pts[i*2+1], attr->xform);

	// Find bounds
	for (i = 0; i < path->npts-1; i += 3) {
		curve = &path->pts[i*2];
		nsvg__curveBounds(bounds, curve);
		if (i == 0) {
			path->bounds[0] = bounds[0];
			path->bounds[1] = bounds[1];
			path->bounds[2] = bounds[2];
			path->bounds[3] = bounds[3];
		} else {
			path->bounds[0] = nsvg__minf(path->bounds[0], bounds[0]);
			path->bounds[1] = nsvg__minf(path->bounds[1], bounds[1]);
			path->bounds[2] = nsvg__maxf(path->bounds[2], bounds[2]);
			path->bounds[3] = nsvg__maxf(path->bounds[3], bounds[3]);
		}
	}

	path->next = p->plist;
	p->plist = path;

	return;

error:
	if (path != NULL) {
		if (path->pts != NULL) NANOSVG_free(path->pts);
		NANOSVG_free(path);
	}
}

// We roll our own string to float because the std library one uses locale and messes things up.
static double nsvg__atof(const char* s)
{
	char* cur = (char*)s;
	char* end = NULL;
	double res = 0.0, sign = 1.0;
#if defined(_MSC_VER) && (_MSC_VER == 1200)
	__int64 intPart = 0, fracPart = 0;
#else
	long long intPart = 0, fracPart = 0;
#endif
	char hasIntPart = 0, hasFracPart = 0;

	// Parse optional sign
	if (*cur == '+') {
		cur++;
	} else if (*cur == '-') {
		sign = -1;
		cur++;
	}

	// Parse integer part
	if (nsvg__isdigit(*cur)) {
		// Parse digit sequence
#if defined(_MSC_VER) && (_MSC_VER == 1200)
		intPart = strtol(cur, &end, 10);
#else
		intPart = strtoll(cur, &end, 10);
#endif
		if (cur != end) {
			res = (double)intPart;
			hasIntPart = 1;
			cur = end;
		}
	}

	// Parse fractional part.
	if (*cur == '.') {
		cur++; // Skip '.'
		if (nsvg__isdigit(*cur)) {
			// Parse digit sequence
#if defined(_MSC_VER) && (_MSC_VER == 1200)
			fracPart = strtol(cur, &end, 10);
#else
			fracPart = strtoll(cur, &end, 10);
#endif
			if (cur != end) {
				res += (double)fracPart / pow(10.0, (double)(end - cur));
				hasFracPart = 1;
				cur = end;
			}
		}
	}

	// A valid number should have integer or fractional part.
	if (!hasIntPart && !hasFracPart)
		return 0.0;

	// Parse optional exponent
	if (*cur == 'e' || *cur == 'E') {
		int expPart = 0;
		cur++; // skip 'E'
		expPart = strtol(cur, &end, 10); // Parse digit sequence with sign
		if (cur != end) {
			res *= pow(10.0, (double)expPart);
		}
	}

	return res * sign;
}


static const char* nsvg__parseNumber(const char* s, char* it, const int size)
{
	const int last = size-1;
	int i = 0;

	// sign
	if (*s == '-' || *s == '+') {
		if (i < last) it[i++] = *s;
		s++;
	}
	// integer part
	while (*s && nsvg__isdigit(*s)) {
		if (i < last) it[i++] = *s;
		s++;
	}
	if (*s == '.') {
		// decimal point
		if (i < last) it[i++] = *s;
		s++;
		// fraction part
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	// exponent
	if (*s == 'e' || *s == 'E') {
		if (i < last) it[i++] = *s;
		s++;
		if (*s == '-' || *s == '+') {
			if (i < last) it[i++] = *s;
			s++;
		}
		while (*s && nsvg__isdigit(*s)) {
			if (i < last) it[i++] = *s;
			s++;
		}
	}
	it[i] = '\0';

	return s;
}

static const char* nsvg__getNextPathItem(const char* s, char* it)
{
	it[0] = '\0';
	// Skip white spaces and commas
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	if (!*s) return s;
	if (*s == '-' || *s == '+' || *s == '.' || nsvg__isdigit(*s)) {
		s = nsvg__parseNumber(s, it, 64);
	} else {
		// Parse command
		it[0] = *s++;
		it[1] = '\0';
		return s;
	}

	return s;
}

static unsigned int nsvg__parseColorHex(const char* str)
{
	unsigned int c = 0, r = 0, g = 0, b = 0;
	int n = 0;
	str++; // skip #
	// Calculate number of characters.
	while(str[n] && !nsvg__isspace(str[n]))
		n++;
	if (n == 6) {
		sscanf(str, "%x", &c);
	} else if (n == 3) {
		sscanf(str, "%x", &c);
		c = (c&0xf) | ((c&0xf0) << 4) | ((c&0xf00) << 8);
		c |= c<<4;
	}
	r = (c >> 16) & 0xff;
	g = (c >> 8) & 0xff;
	b = c & 0xff;
	return NSVG_RGB(r,g,b);
}

static unsigned int nsvg__parseColorRGB(const char* str)
{
	int r = -1, g = -1, b = -1;
	char s1[32]="", s2[32]="";
	sscanf(str + 4, "%d%[%%, \t]%d%[%%, \t]%d", &r, s1, &g, s2, &b);
	if (strchr(s1, '%')) {
		return NSVG_RGB((r*255)/100,(g*255)/100,(b*255)/100);
	} else {
		return NSVG_RGB(r,g,b);
	}
}

typedef struct NSVGNamedColor {
	const char* name;
	unsigned int color;
} NSVGNamedColor;

NSVGNamedColor nsvg__colors[] = {

	{ "red", NSVG_RGB(255, 0, 0) },
	{ "green", NSVG_RGB( 0, 128, 0) },
	{ "blue", NSVG_RGB( 0, 0, 255) },
	{ "yellow", NSVG_RGB(255, 255, 0) },
	{ "cyan", NSVG_RGB( 0, 255, 255) },
	{ "magenta", NSVG_RGB(255, 0, 255) },
	{ "black", NSVG_RGB( 0, 0, 0) },
	{ "grey", NSVG_RGB(128, 128, 128) },
	{ "gray", NSVG_RGB(128, 128, 128) },
	{ "white", NSVG_RGB(255, 255, 255) },

#ifdef NANOSVG_ALL_COLOR_KEYWORDS
	{ "aliceblue", NSVG_RGB(240, 248, 255) },
	{ "antiquewhite", NSVG_RGB(250, 235, 215) },
	{ "aqua", NSVG_RGB( 0, 255, 255) },
	{ "aquamarine", NSVG_RGB(127, 255, 212) },
	{ "azure", NSVG_RGB(240, 255, 255) },
	{ "beige", NSVG_RGB(245, 245, 220) },
	{ "bisque", NSVG_RGB(255, 228, 196) },
	{ "blanchedalmond", NSVG_RGB(255, 235, 205) },
	{ "blueviolet", NSVG_RGB(138, 43, 226) },
	{ "brown", NSVG_RGB(165, 42, 42) },
	{ "burlywood", NSVG_RGB(222, 184, 135) },
	{ "cadetblue", NSVG_RGB( 95, 158, 160) },
	{ "chartreuse", NSVG_RGB(127, 255, 0) },
	{ "chocolate", NSVG_RGB(210, 105, 30) },
	{ "coral", NSVG_RGB(255, 127, 80) },
	{ "cornflowerblue", NSVG_RGB(100, 149, 237) },
	{ "cornsilk", NSVG_RGB(255, 248, 220) },
	{ "crimson", NSVG_RGB(220, 20, 60) },
	{ "darkblue", NSVG_RGB( 0, 0, 139) },
	{ "darkcyan", NSVG_RGB( 0, 139, 139) },
	{ "darkgoldenrod", NSVG_RGB(184, 134, 11) },
	{ "darkgray", NSVG_RGB(169, 169, 169) },
	{ "darkgreen", NSVG_RGB( 0, 100, 0) },
	{ "darkgrey", NSVG_RGB(169, 169, 169) },
	{ "darkkhaki", NSVG_RGB(189, 183, 107) },
	{ "darkmagenta", NSVG_RGB(139, 0, 139) },
	{ "darkolivegreen", NSVG_RGB( 85, 107, 47) },
	{ "darkorange", NSVG_RGB(255, 140, 0) },
	{ "darkorchid", NSVG_RGB(153, 50, 204) },
	{ "darkred", NSVG_RGB(139, 0, 0) },
	{ "darksalmon", NSVG_RGB(233, 150, 122) },
	{ "darkseagreen", NSVG_RGB(143, 188, 143) },
	{ "darkslateblue", NSVG_RGB( 72, 61, 139) },
	{ "darkslategray", NSVG_RGB( 47, 79, 79) },
	{ "darkslategrey", NSVG_RGB( 47, 79, 79) },
	{ "darkturquoise", NSVG_RGB( 0, 206, 209) },
	{ "darkviolet", NSVG_RGB(148, 0, 211) },
	{ "deeppink", NSVG_RGB(255, 20, 147) },
	{ "deepskyblue", NSVG_RGB( 0, 191, 255) },
	{ "dimgray", NSVG_RGB(105, 105, 105) },
	{ "dimgrey", NSVG_RGB(105, 105, 105) },
	{ "dodgerblue", NSVG_RGB( 30, 144, 255) },
	{ "firebrick", NSVG_RGB(178, 34, 34) },
	{ "floralwhite", NSVG_RGB(255, 250, 240) },
	{ "forestgreen", NSVG_RGB( 34, 139, 34) },
	{ "fuchsia", NSVG_RGB(255, 0, 255) },
	{ "gainsboro", NSVG_RGB(220, 220, 220) },
	{ "ghostwhite", NSVG_RGB(248, 248, 255) },
	{ "gold", NSVG_RGB(255, 215, 0) },
	{ "goldenrod", NSVG_RGB(218, 165, 32) },
	{ "greenyellow", NSVG_RGB(173, 255, 47) },
	{ "honeydew", NSVG_RGB(240, 255, 240) },
	{ "hotpink", NSVG_RGB(255, 105, 180) },
	{ "indianred", NSVG_RGB(205, 92, 92) },
	{ "indigo", NSVG_RGB( 75, 0, 130) },
	{ "ivory", NSVG_RGB(255, 255, 240) },
	{ "khaki", NSVG_RGB(240, 230, 140) },
	{ "lavender", NSVG_RGB(230, 230, 250) },
	{ "lavenderblush", NSVG_RGB(255, 240, 245) },
	{ "lawngreen", NSVG_RGB(124, 252, 0) },
	{ "lemonchiffon", NSVG_RGB(255, 250, 205) },
	{ "lightblue", NSVG_RGB(173, 216, 230) },
	{ "lightcoral", NSVG_RGB(240, 128, 128) },
	{ "lightcyan", NSVG_RGB(224, 255, 255) },
	{ "lightgoldenrodyellow", NSVG_RGB(250, 250, 210) },
	{ "lightgray", NSVG_RGB(211, 211, 211) },
	{ "lightgreen", NSVG_RGB(144, 238, 144) },
	{ "lightgrey", NSVG_RGB(211, 211, 211) },
	{ "lightpink", NSVG_RGB(255, 182, 193) },
	{ "lightsalmon", NSVG_RGB(255, 160, 122) },
	{ "lightseagreen", NSVG_RGB( 32, 178, 170) },
	{ "lightskyblue", NSVG_RGB(135, 206, 250) },
	{ "lightslategray", NSVG_RGB(119, 136, 153) },
	{ "lightslategrey", NSVG_RGB(119, 136, 153) },
	{ "lightsteelblue", NSVG_RGB(176, 196, 222) },
	{ "lightyellow", NSVG_RGB(255, 255, 224) },
	{ "lime", NSVG_RGB( 0, 255, 0) },
	{ "limegreen", NSVG_RGB( 50, 205, 50) },
	{ "linen", NSVG_RGB(250, 240, 230) },
	{ "maroon", NSVG_RGB(128, 0, 0) },
	{ "mediumaquamarine", NSVG_RGB(102, 205, 170) },
	{ "mediumblue", NSVG_RGB( 0, 0, 205) },
	{ "mediumorchid", NSVG_RGB(186, 85, 211) },
	{ "mediumpurple", NSVG_RGB(147, 112, 219) },
	{ "mediumseagreen", NSVG_RGB( 60, 179, 113) },
	{ "mediumslateblue", NSVG_RGB(123, 104, 238) },
	{ "mediumspringgreen", NSVG_RGB( 0, 250, 154) },
	{ "mediumturquoise", NSVG_RGB( 72, 209, 204) },
	{ "mediumvioletred", NSVG_RGB(199, 21, 133) },
	{ "midnightblue", NSVG_RGB( 25, 25, 112) },
	{ "mintcream", NSVG_RGB(245, 255, 250) },
	{ "mistyrose", NSVG_RGB(255, 228, 225) },
	{ "moccasin", NSVG_RGB(255, 228, 181) },
	{ "navajowhite", NSVG_RGB(255, 222, 173) },
	{ "navy", NSVG_RGB( 0, 0, 128) },
	{ "oldlace", NSVG_RGB(253, 245, 230) },
	{ "olive", NSVG_RGB(128, 128, 0) },
	{ "olivedrab", NSVG_RGB(107, 142, 35) },
	{ "orange", NSVG_RGB(255, 165, 0) },
	{ "orangered", NSVG_RGB(255, 69, 0) },
	{ "orchid", NSVG_RGB(218, 112, 214) },
	{ "palegoldenrod", NSVG_RGB(238, 232, 170) },
	{ "palegreen", NSVG_RGB(152, 251, 152) },
	{ "paleturquoise", NSVG_RGB(175, 238, 238) },
	{ "palevioletred", NSVG_RGB(219, 112, 147) },
	{ "papayawhip", NSVG_RGB(255, 239, 213) },
	{ "peachpuff", NSVG_RGB(255, 218, 185) },
	{ "peru", NSVG_RGB(205, 133, 63) },
	{ "pink", NSVG_RGB(255, 192, 203) },
	{ "plum", NSVG_RGB(221, 160, 221) },
	{ "powderblue", NSVG_RGB(176, 224, 230) },
	{ "purple", NSVG_RGB(128, 0, 128) },
	{ "rosybrown", NSVG_RGB(188, 143, 143) },
	{ "royalblue", NSVG_RGB( 65, 105, 225) },
	{ "saddlebrown", NSVG_RGB(139, 69, 19) },
	{ "salmon", NSVG_RGB(250, 128, 114) },
	{ "sandybrown", NSVG_RGB(244, 164, 96) },
	{ "seagreen", NSVG_RGB( 46, 139, 87) },
	{ "seashell", NSVG_RGB(255, 245, 238) },
	{ "sienna", NSVG_RGB(160, 82, 45) },
	{ "silver", NSVG_RGB(192, 192, 192) },
	{ "skyblue", NSVG_RGB(135, 206, 235) },
	{ "slateblue", NSVG_RGB(106, 90, 205) },
	{ "slategray", NSVG_RGB(112, 128, 144) },
	{ "slategrey", NSVG_RGB(112, 128, 144) },
	{ "snow", NSVG_RGB(255, 250, 250) },
	{ "springgreen", NSVG_RGB( 0, 255, 127) },
	{ "steelblue", NSVG_RGB( 70, 130, 180) },
	{ "tan", NSVG_RGB(210, 180, 140) },
	{ "teal", NSVG_RGB( 0, 128, 128) },
	{ "thistle", NSVG_RGB(216, 191, 216) },
	{ "tomato", NSVG_RGB(255, 99, 71) },
	{ "turquoise", NSVG_RGB( 64, 224, 208) },
	{ "violet", NSVG_RGB(238, 130, 238) },
	{ "wheat", NSVG_RGB(245, 222, 179) },
	{ "whitesmoke", NSVG_RGB(245, 245, 245) },
	{ "yellowgreen", NSVG_RGB(154, 205, 50) },
#endif
};

static unsigned int nsvg__parseColorName(const char* str)
{
	int i, ncolors = sizeof(nsvg__colors) / sizeof(NSVGNamedColor);

	for (i = 0; i < ncolors; i++) {
		if (strcmp(nsvg__colors[i].name, str) == 0) {
			return nsvg__colors[i].color;
		}
	}

	return NSVG_RGB(128, 128, 128);
}

static unsigned int nsvg__parseColor(const char* str)
{
	size_t len = 0;
	while(*str == ' ') ++str;
	len = strlen(str);
	if (len >= 1 && *str == '#')
		return nsvg__parseColorHex(str);
	else if (len >= 4 && str[0] == 'r' && str[1] == 'g' && str[2] == 'b' && str[3] == '(')
		return nsvg__parseColorRGB(str);
	return nsvg__parseColorName(str);
}

static float nsvg__parseOpacity(const char* str)
{
	float val = 0;
	sscanf(str, "%f", &val);
	if (val < 0.0f) val = 0.0f;
	if (val > 1.0f) val = 1.0f;
	return val;
}

static float nsvg__parseMiterLimit(const char* str)
{
	float val = 0;
	sscanf(str, "%f", &val);
	if (val < 0.0f) val = 0.0f;
	return val;
}

static int nsvg__parseUnits(const char* units)
{
	if (units[0] == 'p' && units[1] == 'x')
		return NSVG_UNITS_PX;
	else if (units[0] == 'p' && units[1] == 't')
		return NSVG_UNITS_PT;
	else if (units[0] == 'p' && units[1] == 'c')
		return NSVG_UNITS_PC;
	else if (units[0] == 'm' && units[1] == 'm')
		return NSVG_UNITS_MM;
	else if (units[0] == 'c' && units[1] == 'm')
		return NSVG_UNITS_CM;
	else if (units[0] == 'i' && units[1] == 'n')
		return NSVG_UNITS_IN;
	else if (units[0] == '%')
		return NSVG_UNITS_PERCENT;
	else if (units[0] == 'e' && units[1] == 'm')
		return NSVG_UNITS_EM;
	else if (units[0] == 'e' && units[1] == 'x')
		return NSVG_UNITS_EX;
	return NSVG_UNITS_USER;
}

static int nsvg__isCoordinate(const char* s)
{
	// optional sign
	if (*s == '-' || *s == '+')
		s++;
	// must have at least one digit
	return nsvg__isdigit(*s);
}

static NSVGcoordinate nsvg__parseCoordinateRaw(const char* str)
{
	NSVGcoordinate coord = {0, NSVG_UNITS_USER};
	char units[32]="";
	sscanf(str, "%f%s", &coord.value, units);
	coord.units = nsvg__parseUnits(units);
	return coord;
}

static NSVGcoordinate nsvg__coord(float v, int units)
{
	NSVGcoordinate coord = {v, units};
	return coord;
}

static float nsvg__parseCoordinate(NSVGparser* p, const char* str, float orig, float length)
{
	NSVGcoordinate coord = nsvg__parseCoordinateRaw(str);
	return nsvg__convertToPixels(p, coord, orig, length);
}

static int nsvg__parseTransformArgs(const char* str, float* args, int maxNa, int* na)
{
	const char* end;
	const char* ptr;
	char it[64];

	*na = 0;
	ptr = str;
	while (*ptr && *ptr != '(') ++ptr;
	if (*ptr == 0)
		return 1;
	end = ptr;
	while (*end && *end != ')') ++end;
	if (*end == 0)
		return 1;

	while (ptr < end) {
		if (*ptr == '-' || *ptr == '+' || *ptr == '.' || nsvg__isdigit(*ptr)) {
			if (*na >= maxNa) return 0;
			ptr = nsvg__parseNumber(ptr, it, 64);
			args[(*na)++] = (float)nsvg__atof(it);
		} else {
			++ptr;
		}
	}
	return (int)(end - str);
}


static int nsvg__parseMatrix(float* xform, const char* str)
{
	float t[6];
	int na = 0;
	int len = nsvg__parseTransformArgs(str, t, 6, &na);
	if (na != 6) return len;
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseTranslate(float* xform, const char* str)
{
	float args[2];
	float t[6];
	int na = 0;
	int len = nsvg__parseTransformArgs(str, args, 2, &na);
	if (na == 1) args[1] = 0.0;

	nsvg__xformSetTranslation(t, args[0], args[1]);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseScale(float* xform, const char* str)
{
	float args[2];
	int na = 0;
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 2, &na);
	if (na == 1) args[1] = args[0];
	nsvg__xformSetScale(t, args[0], args[1]);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseSkewX(float* xform, const char* str)
{
	float args[1];
	int na = 0;
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 1, &na);
	nsvg__xformSetSkewX(t, args[0]/180.0f*NSVG_PI);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseSkewY(float* xform, const char* str)
{
	float args[1];
	int na = 0;
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 1, &na);
	nsvg__xformSetSkewY(t, args[0]/180.0f*NSVG_PI);
	memcpy(xform, t, sizeof(float)*6);
	return len;
}

static int nsvg__parseRotate(float* xform, const char* str)
{
	float args[3];
	int na = 0;
	float m[6];
	float t[6];
	int len = nsvg__parseTransformArgs(str, args, 3, &na);
	if (na == 1)
		args[1] = args[2] = 0.0f;
	nsvg__xformIdentity(m);

	if (na > 1) {
		nsvg__xformSetTranslation(t, -args[1], -args[2]);
		nsvg__xformMultiply(m, t);
	}

	nsvg__xformSetRotation(t, args[0]/180.0f*NSVG_PI);
	nsvg__xformMultiply(m, t);

	if (na > 1) {
		nsvg__xformSetTranslation(t, args[1], args[2]);
		nsvg__xformMultiply(m, t);
	}

	memcpy(xform, m, sizeof(float)*6);

	return len;
}

static void nsvg__parseTransform(float* xform, const char* str)
{
	float t[6];
        int len;
	nsvg__xformIdentity(xform);
	while (*str)
	{
		if (strncmp(str, "matrix", 6) == 0)
			len = nsvg__parseMatrix(t, str);
		else if (strncmp(str, "translate", 9) == 0)
			len = nsvg__parseTranslate(t, str);
		else if (strncmp(str, "scale", 5) == 0)
			len = nsvg__parseScale(t, str);
		else if (strncmp(str, "rotate", 6) == 0)
			len = nsvg__parseRotate(t, str);
		else if (strncmp(str, "skewX", 5) == 0)
			len = nsvg__parseSkewX(t, str);
		else if (strncmp(str, "skewY", 5) == 0)
			len = nsvg__parseSkewY(t, str);
		else{
			++str;
			continue;
		}
                if (len != 0) {
			str += len;
                } else {
			++str;
			continue;
                }

		nsvg__xformPremultiply(xform, t);
	}
}

static void nsvg__parseUrl(char* id, const char* str)
{
	int i = 0;
	str += 4; // "url(";
	if (*str == '#')
		str++;
	while (i < 63 && *str != ')') {
		id[i] = *str++;
		i++;
	}
	id[i] = '\0';
}

static char nsvg__parseLineCap(const char* str)
{
	if (strcmp(str, "butt") == 0)
		return NSVG_CAP_BUTT;
	else if (strcmp(str, "round") == 0)
		return NSVG_CAP_ROUND;
	else if (strcmp(str, "square") == 0)
		return NSVG_CAP_SQUARE;
	// TODO: handle inherit.
	return NSVG_CAP_BUTT;
}

static char nsvg__parseLineJoin(const char* str)
{
	if (strcmp(str, "miter") == 0)
		return NSVG_JOIN_MITER;
	else if (strcmp(str, "round") == 0)
		return NSVG_JOIN_ROUND;
	else if (strcmp(str, "bevel") == 0)
		return NSVG_JOIN_BEVEL;
	// TODO: handle inherit.
	return NSVG_JOIN_MITER;
}

static char nsvg__parseFillRule(const char* str)
{
	if (strcmp(str, "nonzero") == 0)
		return NSVG_FILLRULE_NONZERO;
	else if (strcmp(str, "evenodd") == 0)
		return NSVG_FILLRULE_EVENODD;
	// TODO: handle inherit.
	return NSVG_FILLRULE_NONZERO;
}

static const char* nsvg__getNextDashItem(const char* s, char* it)
{
	int n = 0;
	it[0] = '\0';
	// Skip white spaces and commas
	while (*s && (nsvg__isspace(*s) || *s == ',')) s++;
	// Advance until whitespace, comma or end.
	while (*s && (!nsvg__isspace(*s) && *s != ',')) {
		if (n < 63)
			it[n++] = *s;
		s++;
	}
	it[n++] = '\0';
	return s;
}

static int nsvg__parseStrokeDashArray(NSVGparser* p, const char* str, float* strokeDashArray)
{
	char item[64];
	int count = 0, i;
	float sum = 0.0f;

	// Handle "none"
	if (str[0] == 'n')
		return 0;

	// Parse dashes
	while (*str) {
		str = nsvg__getNextDashItem(str, item);
		if (!*item) break;
		if (count < NSVG_MAX_DASHES)
			strokeDashArray[count++] = fabsf(nsvg__parseCoordinate(p, item, 0.0f, nsvg__actualLength(p)));
	}

	for (i = 0; i < count; i++)
		sum += strokeDashArray[i];
	if (sum <= 1e-6f)
		count = 0;

	return count;
}

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

static int nsvg__parseAttr(NSVGparser* p, const char* name, const char* value)
{
	float xform[6];
	NSVGattrib* attr = nsvg__getAttr(p);
	if (!attr) return 0;

	if (strcmp(name, "style") == 0) {
		nsvg__parseStyle(p, value);
	} else if (strcmp(name, "display") == 0) {
		if (strcmp(value, "none") == 0)
			attr->visible &= ~NSVG_VIS_DISPLAY;
		// Don't reset ->visible on display:inline, one display:none hides the whole subtree

	} else if (strcmp(name, "visibility") == 0) {
		if (strcmp(value, "hidden") == 0) {
			attr->visible &= ~NSVG_VIS_VISIBLE;
		} else if (strcmp(value, "visible") == 0) {
			attr->visible |= NSVG_VIS_VISIBLE;
		}
	} else if (strcmp(name, "fill") == 0) {
		if (strcmp(value, "none") == 0) {
			attr->hasFill = 0;
		} else if (strncmp(value, "url(", 4) == 0) {
			attr->hasFill = 2;
			nsvg__parseUrl(attr->fillGradient, value);
		} else {
			attr->hasFill = 1;
			attr->fillColor = nsvg__parseColor(value);
		}
	} else if (strcmp(name, "opacity") == 0) {
		attr->opacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "fill-opacity") == 0) {
		attr->fillOpacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "stroke") == 0) {
		if (strcmp(value, "none") == 0) {
			attr->hasStroke = 0;
		} else if (strncmp(value, "url(", 4) == 0) {
			attr->hasStroke = 2;
			nsvg__parseUrl(attr->strokeGradient, value);
		} else {
			attr->hasStroke = 1;
			attr->strokeColor = nsvg__parseColor(value);
		}
	} else if (strcmp(name, "stroke-width") == 0) {
		attr->strokeWidth = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
	} else if (strcmp(name, "stroke-dasharray") == 0) {
		attr->strokeDashCount = nsvg__parseStrokeDashArray(p, value, attr->strokeDashArray);
	} else if (strcmp(name, "stroke-dashoffset") == 0) {
		attr->strokeDashOffset = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
	} else if (strcmp(name, "stroke-opacity") == 0) {
		attr->strokeOpacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "stroke-linecap") == 0) {
		attr->strokeLineCap = nsvg__parseLineCap(value);
	} else if (strcmp(name, "stroke-linejoin") == 0) {
		attr->strokeLineJoin = nsvg__parseLineJoin(value);
	} else if (strcmp(name, "stroke-miterlimit") == 0) {
		attr->miterLimit = nsvg__parseMiterLimit(value);
	} else if (strcmp(name, "fill-rule") == 0) {
		attr->fillRule = nsvg__parseFillRule(value);
	} else if (strcmp(name, "font-size") == 0) {
		attr->fontSize = nsvg__parseCoordinate(p, value, 0.0f, nsvg__actualLength(p));
	} else if (strcmp(name, "transform") == 0) {
		nsvg__parseTransform(xform, value);
		nsvg__xformPremultiply(attr->xform, xform);
	} else if (strcmp(name, "stop-color") == 0) {
		attr->stopColor = nsvg__parseColor(value);
	} else if (strcmp(name, "stop-opacity") == 0) {
		attr->stopOpacity = nsvg__parseOpacity(value);
	} else if (strcmp(name, "offset") == 0) {
		attr->stopOffset = nsvg__parseCoordinate(p, value, 0.0f, 1.0f);
	} else if (strcmp(name, "id") == 0) {
		strncpy(attr->id, value, 63);
		attr->id[63] = '\0';
	} else if (strcmp(name, "class") == 0) {
		NSVGstyles* style = p->styles;
		while (style) {
			if (strcmp(style->name + 1, value) == 0) {
				break;
			}
			style = style->next;
		}
		if (style) {
			nsvg__parseStyle(p, style->description);
		}
	} else {
		return 0;
	}
	return 1;
}

static int nsvg__parseNameValue(NSVGparser* p, const char* start, const char* end)
{
	const char* str;
	const char* val;
	char name[512];
	char value[512];
	int n;

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

	val = str;

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

	n = (int)(str - start);
	if (n > 511) n = 511;
	if (n) memcpy(name, start, n);
	name[n] = 0;

	while (val < end && (*val == ':' || nsvg__isspace(*val))) ++val;

	n = (int)(end - val);
	if (n > 511) n = 511;
	if (n) memcpy(value, val, n);
	value[n] = 0;

	return nsvg__parseAttr(p, name, value);
}

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

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

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

		nsvg__parseNameValue(p, start, end);
		if (*str) ++str;
	}
}

static void nsvg__parseAttribs(NSVGparser* p, const char** attr)
{
	int i;
	for (i = 0; attr[i]; i += 2)
	{
		if (strcmp(attr[i], "style") == 0)
			nsvg__parseStyle(p, attr[i + 1]);
		else
			nsvg__parseAttr(p, attr[i], attr[i + 1]);
	}
}

static int nsvg__getArgsPerElement(char cmd)
{
	switch (cmd) {
		case 'v':
		case 'V':
		case 'h':
		case 'H':
			return 1;
		case 'm':
		case 'M':
		case 'l':
		case 'L':
		case 't':
		case 'T':
			return 2;
		case 'q':
		case 'Q':
		case 's':
		case 'S':
			return 4;
		case 'c':
		case 'C':
			return 6;
		case 'a':
		case 'A':
			return 7;
		case 'z':
		case 'Z':
			return 0;
	}
	return -1;
}

static void nsvg__pathMoveTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel) {
		*cpx += args[0];
		*cpy += args[1];
	} else {
		*cpx = args[0];
		*cpy = args[1];
	}
	nsvg__moveTo(p, *cpx, *cpy);
}

static void nsvg__pathLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel) {
		*cpx += args[0];
		*cpy += args[1];
	} else {
		*cpx = args[0];
		*cpy = args[1];
	}
	nsvg__lineTo(p, *cpx, *cpy);
}

static void nsvg__pathHLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel)
		*cpx += args[0];
	else
		*cpx = args[0];
	nsvg__lineTo(p, *cpx, *cpy);
}

static void nsvg__pathVLineTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	if (rel)
		*cpy += args[0];
	else
		*cpy = args[0];
	nsvg__lineTo(p, *cpx, *cpy);
}

static void nsvg__pathCubicBezTo(NSVGparser* p, float* cpx, float* cpy,
								 float* cpx2, float* cpy2, float* args, int rel)
{
	float x2, y2, cx1, cy1, cx2, cy2;

	if (rel) {
		cx1 = *cpx + args[0];
		cy1 = *cpy + args[1];
		cx2 = *cpx + args[2];
		cy2 = *cpy + args[3];
		x2 = *cpx + args[4];
		y2 = *cpy + args[5];
	} else {
		cx1 = args[0];
		cy1 = args[1];
		cx2 = args[2];
		cy2 = args[3];
		x2 = args[4];
		y2 = args[5];
	}

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx2;
	*cpy2 = cy2;
	*cpx = x2;
	*cpy = y2;
}

static void nsvg__pathCubicBezShortTo(NSVGparser* p, float* cpx, float* cpy,
									  float* cpx2, float* cpy2, float* args, int rel)
{
	float x1, y1, x2, y2, cx1, cy1, cx2, cy2;

	x1 = *cpx;
	y1 = *cpy;
	if (rel) {
		cx2 = *cpx + args[0];
		cy2 = *cpy + args[1];
		x2 = *cpx + args[2];
		y2 = *cpy + args[3];
	} else {
		cx2 = args[0];
		cy2 = args[1];
		x2 = args[2];
		y2 = args[3];
	}

	cx1 = 2*x1 - *cpx2;
	cy1 = 2*y1 - *cpy2;

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx2;
	*cpy2 = cy2;
	*cpx = x2;
	*cpy = y2;
}

static void nsvg__pathQuadBezTo(NSVGparser* p, float* cpx, float* cpy,
								float* cpx2, float* cpy2, float* args, int rel)
{
	float x1, y1, x2, y2, cx, cy;
	float cx1, cy1, cx2, cy2;

	x1 = *cpx;
	y1 = *cpy;
	if (rel) {
		cx = *cpx + args[0];
		cy = *cpy + args[1];
		x2 = *cpx + args[2];
		y2 = *cpy + args[3];
	} else {
		cx = args[0];
		cy = args[1];
		x2 = args[2];
		y2 = args[3];
	}

	// Convert to cubic bezier
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx;
	*cpy2 = cy;
	*cpx = x2;
	*cpy = y2;
}

static void nsvg__pathQuadBezShortTo(NSVGparser* p, float* cpx, float* cpy,
									 float* cpx2, float* cpy2, float* args, int rel)
{
	float x1, y1, x2, y2, cx, cy;
	float cx1, cy1, cx2, cy2;

	x1 = *cpx;
	y1 = *cpy;
	if (rel) {
		x2 = *cpx + args[0];
		y2 = *cpy + args[1];
	} else {
		x2 = args[0];
		y2 = args[1];
	}

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

	// Convert to cubix bezier
	cx1 = x1 + 2.0f/3.0f*(cx - x1);
	cy1 = y1 + 2.0f/3.0f*(cy - y1);
	cx2 = x2 + 2.0f/3.0f*(cx - x2);
	cy2 = y2 + 2.0f/3.0f*(cy - y2);

	nsvg__cubicBezTo(p, cx1,cy1, cx2,cy2, x2,y2);

	*cpx2 = cx;
	*cpy2 = cy;
	*cpx = x2;
	*cpy = y2;
}

static float nsvg__sqr(float x) { return x*x; }
static float nsvg__vmag(float x, float y) { return sqrtf(x*x + y*y); }

static float nsvg__vecrat(float ux, float uy, float vx, float vy)
{
	return (ux*vx + uy*vy) / (nsvg__vmag(ux,uy) * nsvg__vmag(vx,vy));
}

static float nsvg__vecang(float ux, float uy, float vx, float vy)
{
	float r = nsvg__vecrat(ux,uy, vx,vy);
	if (r < -1.0f) r = -1.0f;
	if (r > 1.0f) r = 1.0f;
	return ((ux*vy < uy*vx) ? -1.0f : 1.0f) * acosf(r);
}

static void nsvg__pathArcTo(NSVGparser* p, float* cpx, float* cpy, float* args, int rel)
{
	// Ported from canvg (https://code.google.com/p/canvg/)
	float rx, ry, rotx;
	float x1, y1, x2, y2, cx, cy, dx, dy, d;
	float x1p, y1p, cxp, cyp, s, sa, sb;
	float ux, uy, vx, vy, a1, da;
	float x, y, tanx, tany, a, px = 0, py = 0, ptanx = 0, ptany = 0, t[6];
	float sinrx, cosrx;
	int fa, fs;
	int i, ndivs;
	float hda, kappa;

	rx = fabsf(args[0]);				// y radius
	ry = fabsf(args[1]);				// x radius
	rotx = args[2] / 180.0f * NSVG_PI;		// x rotation angle
	fa = fabsf(args[3]) > 1e-6 ? 1 : 0;	// Large arc
	fs = fabsf(args[4]) > 1e-6 ? 1 : 0;	// Sweep direction
	x1 = *cpx;							// start point
	y1 = *cpy;
	if (rel) {							// end point
		x2 = *cpx + args[5];
		y2 = *cpy + args[6];
	} else {
		x2 = args[5];
		y2 = args[6];
	}

	dx = x1 - x2;
	dy = y1 - y2;
	d = sqrtf(dx*dx + dy*dy);
	if (d < 1e-6f || rx < 1e-6f || ry < 1e-6f) {
		// The arc degenerates to a line
		nsvg__lineTo(p, x2, y2);
		*cpx = x2;
		*cpy = y2;
		return;
	}

	sinrx = sinf(rotx);
	cosrx = cosf(rotx);

	// Convert to center point parameterization.
	// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes
	// 1) Compute x1', y1'
	x1p = cosrx * dx / 2.0f + sinrx * dy / 2.0f;
	y1p = -sinrx * dx / 2.0f + cosrx * dy / 2.0f;
	d = nsvg__sqr(x1p)/nsvg__sqr(rx) + nsvg__sqr(y1p)/nsvg__sqr(ry);
	if (d > 1) {
		d = sqrtf(d);
		rx *= d;
		ry *= d;
	}
	// 2) Compute cx', cy'
	s = 0.0f;
	sa = nsvg__sqr(rx)*nsvg__sqr(ry) - nsvg__sqr(rx)*nsvg__sqr(y1p) - nsvg__sqr(ry)*nsvg__sqr(x1p);
	sb = nsvg__sqr(rx)*nsvg__sqr(y1p) + nsvg__sqr(ry)*nsvg__sqr(x1p);
	if (sa < 0.0f) sa = 0.0f;
	if (sb > 0.0f)
		s = sqrtf(sa / sb);
	if (fa == fs)
		s = -s;
	cxp = s * rx * y1p / ry;
	cyp = s * -ry * x1p / rx;

	// 3) Compute cx,cy from cx',cy'
	cx = (x1 + x2)/2.0f + cosrx*cxp - sinrx*cyp;
	cy = (y1 + y2)/2.0f + sinrx*cxp + cosrx*cyp;

	// 4) Calculate theta1, and delta theta.
	ux = (x1p - cxp) / rx;
	uy = (y1p - cyp) / ry;
	vx = (-x1p - cxp) / rx;
	vy = (-y1p - cyp) / ry;
	a1 = nsvg__vecang(1.0f,0.0f, ux,uy);	// Initial angle
	da = nsvg__vecang(ux,uy, vx,vy);		// Delta angle

//	if (vecrat(ux,uy,vx,vy) <= -1.0f) da = NSVG_PI;
//	if (vecrat(ux,uy,vx,vy) >= 1.0f) da = 0;

	if (fs == 0 && da > 0)
		da -= 2 * NSVG_PI;
	else if (fs == 1 && da < 0)
		da += 2 * NSVG_PI;

	// Approximate the arc using cubic spline segments.
	t[0] = cosrx; t[1] = sinrx;
	t[2] = -sinrx; t[3] = cosrx;
	t[4] = cx; t[5] = cy;

	// Split arc into max 90 degree segments.
	// The loop assumes an iteration per end point (including start and end), this +1.
	ndivs = (int)(fabsf(da) / (NSVG_PI*0.5f) + 1.0f);
	hda = (da / (float)ndivs) / 2.0f;
	kappa = fabsf(4.0f / 3.0f * (1.0f - cosf(hda)) / sinf(hda));
	if (da < 0.0f)
		kappa = -kappa;

	for (i = 0; i <= ndivs; i++) {
		a = a1 + da * ((float)i/(float)ndivs);
		dx = cosf(a);
		dy = sinf(a);
		nsvg__xformPoint(&x, &y, dx*rx, dy*ry, t); // position
		nsvg__xformVec(&tanx, &tany, -dy*rx * kappa, dx*ry * kappa, t); // tangent
		if (i > 0)
			nsvg__cubicBezTo(p, px+ptanx,py+ptany, x-tanx, y-tany, x, y);
		px = x;
		py = y;
		ptanx = tanx;
		ptany = tany;
	}

	*cpx = x2;
	*cpy = y2;
}

static void nsvg__parsePath(NSVGparser* p, const char** attr)
{
	const char* s = NULL;
	char cmd = '\0';
	float args[10];
	int nargs;
	int rargs = 0;
	char initPoint;
	float cpx, cpy, cpx2, cpy2;
	const char* tmp[4];
	char closedFlag;
	int i;
	char item[64];

	for (i = 0; attr[i]; i += 2) {
		if (strcmp(attr[i], "d") == 0) {
			s = attr[i + 1];
		} else {
			tmp[0] = attr[i];
			tmp[1] = attr[i + 1];
			tmp[2] = 0;
			tmp[3] = 0;
			nsvg__parseAttribs(p, tmp);
		}
	}

	if (s) {
		nsvg__resetPath(p);
		cpx = 0; cpy = 0;
		cpx2 = 0; cpy2 = 0;
		initPoint = 0;
		closedFlag = 0;
		nargs = 0;

		while (*s) {
			s = nsvg__getNextPathItem(s, item);
			if (!*item) break;
			if (cmd != '\0' && nsvg__isCoordinate(item)) {
				if (nargs < 10)
					args[nargs++] = (float)nsvg__atof(item);
				if (nargs >= rargs) {
					switch (cmd) {
						case 'm':
						case 'M':
							nsvg__pathMoveTo(p, &cpx, &cpy, args, cmd == 'm' ? 1 : 0);
							// Moveto can be followed by multiple coordinate pairs,
							// which should be treated as linetos.
							cmd = (cmd == 'm') ? 'l' : 'L';
							rargs = nsvg__getArgsPerElement(cmd);
							cpx2 = cpx; cpy2 = cpy;
							initPoint = 1;
							break;
						case 'l':
						case 'L':
							nsvg__pathLineTo(p, &cpx, &cpy, args, cmd == 'l' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						case 'H':
						case 'h':
							nsvg__pathHLineTo(p, &cpx, &cpy, args, cmd == 'h' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						case 'V':
						case 'v':
							nsvg__pathVLineTo(p, &cpx, &cpy, args, cmd == 'v' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						case 'C':
						case 'c':
							nsvg__pathCubicBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'c' ? 1 : 0);
							break;
						case 'S':
						case 's':
							nsvg__pathCubicBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 's' ? 1 : 0);
							break;
						case 'Q':
						case 'q':
							nsvg__pathQuadBezTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 'q' ? 1 : 0);
							break;
						case 'T':
						case 't':
							nsvg__pathQuadBezShortTo(p, &cpx, &cpy, &cpx2, &cpy2, args, cmd == 't' ? 1 : 0);
							break;
						case 'A':
						case 'a':
							nsvg__pathArcTo(p, &cpx, &cpy, args, cmd == 'a' ? 1 : 0);
							cpx2 = cpx; cpy2 = cpy;
							break;
						default:
							if (nargs >= 2) {
								cpx = args[nargs-2];
								cpy = args[nargs-1];
								cpx2 = cpx; cpy2 = cpy;
							}
							break;
					}
					nargs = 0;
				}
			} else {
				cmd = item[0];
				if (cmd == 'M' || cmd == 'm') {
					// Commit path.
					if (p->npts > 0)
						nsvg__addPath(p, closedFlag);
					// Start new subpath.
					nsvg__resetPath(p);
					closedFlag = 0;
					nargs = 0;
				} else if (initPoint == 0) {
					// Do not allow other commands until initial point has been set (moveTo called once).
					cmd = '\0';
				}
				if (cmd == 'Z' || cmd == 'z') {
					closedFlag = 1;
					// Commit path.
					if (p->npts > 0) {
						// Move current point to first point
						cpx = p->pts[0];
						cpy = p->pts[1];
						cpx2 = cpx; cpy2 = cpy;
						nsvg__addPath(p, closedFlag);
					}
					// Start new subpath.
					nsvg__resetPath(p);
					nsvg__moveTo(p, cpx, cpy);
					closedFlag = 0;
					nargs = 0;
				}
				rargs = nsvg__getArgsPerElement(cmd);
				if (rargs == -1) {
					// Command not recognized
					cmd = '\0';
					rargs = 0;
				}
			}
		}
		// Commit path.
		if (p->npts)
			nsvg__addPath(p, closedFlag);
	}

	nsvg__addShape(p);
}

static void nsvg__parseRect(NSVGparser* p, const char** attr)
{
	float x = 0.0f;
	float y = 0.0f;
	float w = 0.0f;
	float h = 0.0f;
	float rx = -1.0f; // marks not set
	float ry = -1.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "x") == 0) x = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y") == 0) y = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "width") == 0) w = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p));
			if (strcmp(attr[i], "height") == 0) h = nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p));
			if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
			if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
		}
	}

	if (rx < 0.0f && ry > 0.0f) rx = ry;
	if (ry < 0.0f && rx > 0.0f) ry = rx;
	if (rx < 0.0f) rx = 0.0f;
	if (ry < 0.0f) ry = 0.0f;
	if (rx > w/2.0f) rx = w/2.0f;
	if (ry > h/2.0f) ry = h/2.0f;

	if (w != 0.0f && h != 0.0f) {
		nsvg__resetPath(p);

		if (rx < 0.00001f || ry < 0.0001f) {
			nsvg__moveTo(p, x, y);
			nsvg__lineTo(p, x+w, y);
			nsvg__lineTo(p, x+w, y+h);
			nsvg__lineTo(p, x, y+h);
		} else {
			// Rounded rectangle
			nsvg__moveTo(p, x+rx, y);
			nsvg__lineTo(p, x+w-rx, y);
			nsvg__cubicBezTo(p, x+w-rx*(1-NSVG_KAPPA90), y, x+w, y+ry*(1-NSVG_KAPPA90), x+w, y+ry);
			nsvg__lineTo(p, x+w, y+h-ry);
			nsvg__cubicBezTo(p, x+w, y+h-ry*(1-NSVG_KAPPA90), x+w-rx*(1-NSVG_KAPPA90), y+h, x+w-rx, y+h);
			nsvg__lineTo(p, x+rx, y+h);
			nsvg__cubicBezTo(p, x+rx*(1-NSVG_KAPPA90), y+h, x, y+h-ry*(1-NSVG_KAPPA90), x, y+h-ry);
			nsvg__lineTo(p, x, y+ry);
			nsvg__cubicBezTo(p, x, y+ry*(1-NSVG_KAPPA90), x+rx*(1-NSVG_KAPPA90), y, x+rx, y);
		}

		nsvg__addPath(p, 1);

		nsvg__addShape(p);
	}
}

static void nsvg__parseCircle(NSVGparser* p, const char** attr)
{
	float cx = 0.0f;
	float cy = 0.0f;
	float r = 0.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "r") == 0) r = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualLength(p)));
		}
	}

	if (r > 0.0f) {
		nsvg__resetPath(p);

		nsvg__moveTo(p, cx+r, cy);
		nsvg__cubicBezTo(p, cx+r, cy+r*NSVG_KAPPA90, cx+r*NSVG_KAPPA90, cy+r, cx, cy+r);
		nsvg__cubicBezTo(p, cx-r*NSVG_KAPPA90, cy+r, cx-r, cy+r*NSVG_KAPPA90, cx-r, cy);
		nsvg__cubicBezTo(p, cx-r, cy-r*NSVG_KAPPA90, cx-r*NSVG_KAPPA90, cy-r, cx, cy-r);
		nsvg__cubicBezTo(p, cx+r*NSVG_KAPPA90, cy-r, cx+r, cy-r*NSVG_KAPPA90, cx+r, cy);

		nsvg__addPath(p, 1);

		nsvg__addShape(p);
	}
}

static void nsvg__parseEllipse(NSVGparser* p, const char** attr)
{
	float cx = 0.0f;
	float cy = 0.0f;
	float rx = 0.0f;
	float ry = 0.0f;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "cx") == 0) cx = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "cy") == 0) cy = nsvg__parseCoordinate(p, attr[i+1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "rx") == 0) rx = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualWidth(p)));
			if (strcmp(attr[i], "ry") == 0) ry = fabsf(nsvg__parseCoordinate(p, attr[i+1], 0.0f, nsvg__actualHeight(p)));
		}
	}

	if (rx > 0.0f && ry > 0.0f) {

		nsvg__resetPath(p);

		nsvg__moveTo(p, cx+rx, cy);
		nsvg__cubicBezTo(p, cx+rx, cy+ry*NSVG_KAPPA90, cx+rx*NSVG_KAPPA90, cy+ry, cx, cy+ry);
		nsvg__cubicBezTo(p, cx-rx*NSVG_KAPPA90, cy+ry, cx-rx, cy+ry*NSVG_KAPPA90, cx-rx, cy);
		nsvg__cubicBezTo(p, cx-rx, cy-ry*NSVG_KAPPA90, cx-rx*NSVG_KAPPA90, cy-ry, cx, cy-ry);
		nsvg__cubicBezTo(p, cx+rx*NSVG_KAPPA90, cy-ry, cx+rx, cy-ry*NSVG_KAPPA90, cx+rx, cy);

		nsvg__addPath(p, 1);

		nsvg__addShape(p);
	}
}

static void nsvg__parseLine(NSVGparser* p, const char** attr)
{
	float x1 = 0.0;
	float y1 = 0.0;
	float x2 = 0.0;
	float y2 = 0.0;
	int i;

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "x1") == 0) x1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y1") == 0) y1 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
			if (strcmp(attr[i], "x2") == 0) x2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigX(p), nsvg__actualWidth(p));
			if (strcmp(attr[i], "y2") == 0) y2 = nsvg__parseCoordinate(p, attr[i + 1], nsvg__actualOrigY(p), nsvg__actualHeight(p));
		}
	}

	nsvg__resetPath(p);

	nsvg__moveTo(p, x1, y1);
	nsvg__lineTo(p, x2, y2);

	nsvg__addPath(p, 0);

	nsvg__addShape(p);
}

static void nsvg__parsePoly(NSVGparser* p, const char** attr, int closeFlag)
{
	int i;
	const char* s;
	float args[2];
	int nargs, npts = 0;
	char item[64];

	nsvg__resetPath(p);

	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "points") == 0) {
				s = attr[i + 1];
				nargs = 0;
				while (*s) {
					s = nsvg__getNextPathItem(s, item);
					args[nargs++] = (float)nsvg__atof(item);
					if (nargs >= 2) {
						if (npts == 0)
							nsvg__moveTo(p, args[0], args[1]);
						else
							nsvg__lineTo(p, args[0], args[1]);
						nargs = 0;
						npts++;
					}
				}
			}
		}
	}

	nsvg__addPath(p, (char)closeFlag);

	nsvg__addShape(p);
}

static void nsvg__parseSVG(NSVGparser* p, const char** attr)
{
	int i;
	for (i = 0; attr[i]; i += 2) {
		if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "width") == 0) {
				p->image->width = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "height") == 0) {
				p->image->height = nsvg__parseCoordinate(p, attr[i + 1], 0.0f, 0.0f);
			} else if (strcmp(attr[i], "viewBox") == 0) {
				sscanf(attr[i + 1], "%f%*[%%, \t]%f%*[%%, \t]%f%*[%%, \t]%f", &p->viewMinx, &p->viewMiny, &p->viewWidth, &p->viewHeight);
			} else if (strcmp(attr[i], "preserveAspectRatio") == 0) {
				if (strstr(attr[i + 1], "none") != 0) {
					// No uniform scaling
					p->alignType = NSVG_ALIGN_NONE;
				} else {
					// Parse X align
					if (strstr(attr[i + 1], "xMin") != 0)
						p->alignX = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "xMid") != 0)
						p->alignX = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "xMax") != 0)
						p->alignX = NSVG_ALIGN_MAX;
					// Parse X align
					if (strstr(attr[i + 1], "yMin") != 0)
						p->alignY = NSVG_ALIGN_MIN;
					else if (strstr(attr[i + 1], "yMid") != 0)
						p->alignY = NSVG_ALIGN_MID;
					else if (strstr(attr[i + 1], "yMax") != 0)
						p->alignY = NSVG_ALIGN_MAX;
					// Parse meet/slice
					p->alignType = NSVG_ALIGN_MEET;
					if (strstr(attr[i + 1], "slice") != 0)
						p->alignType = NSVG_ALIGN_SLICE;
				}
			}
		}
	}
}

static void nsvg__parseGradient(NSVGparser* p, const char** attr, char type)
{
	int i;
	NSVGgradientData* grad = (NSVGgradientData*)NANOSVG_malloc(sizeof(NSVGgradientData));
	if (grad == NULL) return;
	memset(grad, 0, sizeof(NSVGgradientData));
	grad->units = NSVG_OBJECT_SPACE;
	grad->type = type;
	if (grad->type == NSVG_PAINT_LINEAR_GRADIENT) {
		grad->linear.x1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
		grad->linear.y1 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
		grad->linear.x2 = nsvg__coord(100.0f, NSVG_UNITS_PERCENT);
		grad->linear.y2 = nsvg__coord(0.0f, NSVG_UNITS_PERCENT);
	} else if (grad->type == NSVG_PAINT_RADIAL_GRADIENT) {
		grad->radial.cx = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
		grad->radial.cy = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
		grad->radial.r = nsvg__coord(50.0f, NSVG_UNITS_PERCENT);
	}

	nsvg__xformIdentity(grad->xform);

	for (i = 0; attr[i]; i += 2) {
		if (strcmp(attr[i], "id") == 0) {
			strncpy(grad->id, attr[i+1], 63);
			grad->id[63] = '\0';
		} else if (!nsvg__parseAttr(p, attr[i], attr[i + 1])) {
			if (strcmp(attr[i], "gradientUnits") == 0) {
				if (strcmp(attr[i+1], "objectBoundingBox") == 0)
					grad->units = NSVG_OBJECT_SPACE;
				else
					grad->units = NSVG_USER_SPACE;
			} else if (strcmp(attr[i], "gradientTransform") == 0) {
				nsvg__parseTransform(grad->xform, attr[i + 1]);
			} else if (strcmp(attr[i], "cx") == 0) {
				grad->radial.cx = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "cy") == 0) {
				grad->radial.cy = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "r") == 0) {
				grad->radial.r = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "fx") == 0) {
				grad->radial.fx = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "fy") == 0) {
				grad->radial.fy = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "x1") == 0) {
				grad->linear.x1 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "y1") == 0) {
				grad->linear.y1 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "x2") == 0) {
				grad->linear.x2 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "y2") == 0) {
				grad->linear.y2 = nsvg__parseCoordinateRaw(attr[i + 1]);
			} else if (strcmp(attr[i], "spreadMethod") == 0) {
				if (strcmp(attr[i+1], "pad") == 0)
					grad->spread = NSVG_SPREAD_PAD;
				else if (strcmp(attr[i+1], "reflect") == 0)
					grad->spread = NSVG_SPREAD_REFLECT;
				else if (strcmp(attr[i+1], "repeat") == 0)
					grad->spread = NSVG_SPREAD_REPEAT;
			} else if (strcmp(attr[i], "xlink:href") == 0) {
				const char *href = attr[i+1];
				strncpy(grad->ref, href+1, 62);
				grad->ref[62] = '\0';
			}
		}
	}

	grad->next = p->gradients;
	p->gradients = grad;
}

static void nsvg__parseGradientStop(NSVGparser* p, const char** attr)
{
	NSVGattrib* curAttr = nsvg__getAttr(p);
	NSVGgradientData* grad;
	NSVGgradientStop* stop;
	int i, idx;

	curAttr->stopOffset = 0;
	curAttr->stopColor = 0;
	curAttr->stopOpacity = 1.0f;

	for (i = 0; attr[i]; i += 2) {
		nsvg__parseAttr(p, attr[i], attr[i + 1]);
	}

	// Add stop to the last gradient.
	grad = p->gradients;
	if (grad == NULL) return;

	grad->nstops++;
	grad->stops = (NSVGgradientStop*)NANOSVG_realloc(grad->stops, sizeof(NSVGgradientStop)*grad->nstops);
	if (grad->stops == NULL) return;

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

	stop = &grad->stops[idx];
	stop->color = curAttr->stopColor;
	stop->color |= (unsigned int)(curAttr->stopOpacity*255) << 24;
	stop->offset = curAttr->stopOffset;
}

static void nsvg__startElement(void* ud, const char* el, const char** attr)
{
	NSVGparser* p = (NSVGparser*)ud;

	if (p->defsFlag) {
		// Skip everything but gradients in defs
		if (strcmp(el, "linearGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
		} else if (strcmp(el, "radialGradient") == 0) {
			nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
		} else if (strcmp(el, "stop") == 0) {
			nsvg__parseGradientStop(p, attr);
		}
		return;
	}

	if (strcmp(el, "g") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseAttribs(p, attr);
	} else if (strcmp(el, "path") == 0) {
		if (p->pathFlag)	// Do not allow nested paths.
			return;
		nsvg__pushAttr(p);
		nsvg__parsePath(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "rect") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseRect(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "circle") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseCircle(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "ellipse") == 0) {
		nsvg__pushAttr(p);
		nsvg__parseEllipse(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "line") == 0)  {
		nsvg__pushAttr(p);
		nsvg__parseLine(p, attr);
		nsvg__popAttr(p);
	} else if (strcmp(el, "polyline") == 0)  {
		nsvg__pushAttr(p);
		nsvg__parsePoly(p, attr, 0);
		nsvg__popAttr(p);
	} else if (strcmp(el, "polygon") == 0)  {
		nsvg__pushAttr(p);
		nsvg__parsePoly(p, attr, 1);
		nsvg__popAttr(p);
	} else  if (strcmp(el, "linearGradient") == 0) {
		nsvg__parseGradient(p, attr, NSVG_PAINT_LINEAR_GRADIENT);
	} else if (strcmp(el, "radialGradient") == 0) {
		nsvg__parseGradient(p, attr, NSVG_PAINT_RADIAL_GRADIENT);
	} else if (strcmp(el, "stop") == 0) {
		nsvg__parseGradientStop(p, attr);
	} else if (strcmp(el, "defs") == 0) {
		p->defsFlag = 1;
	} else if (strcmp(el, "svg") == 0) {
		nsvg__parseSVG(p, attr);
	} else if (strcmp(el, "style") == 0) {
		p->styleFlag = 1;
	}
}

static void nsvg__endElement(void* ud, const char* el)
{
	NSVGparser* p = (NSVGparser*)ud;

	if (strcmp(el, "g") == 0) {
		nsvg__popAttr(p);
	} else if (strcmp(el, "path") == 0) {
		p->pathFlag = 0;
	} else if (strcmp(el, "defs") == 0) {
		p->defsFlag = 0;
	} else if (strcmp(el, "style") == 0) {
		p->styleFlag = 0;
	}
}

static char *nsvg__strndup(const char *s, size_t n)
{
	char *result;
	size_t len = strlen(s);

	if (n < len)
		len = n;

	result = (char*)NANOSVG_malloc(len+1);
	if (!result)
		return 0;

	result[len] = '\0';
	return (char *)memcpy(result, s, len);
}

static void nsvg__content(void* ud, const char* s)
{
	NSVGparser* p = (NSVGparser*)ud;
	if (p->styleFlag) {

		int state = 0;
		const char* start = NULL;
		while (*s) {
			char c = *s;
			if (nsvg__isspace(c) || c == '{') {
				if (state == 1) {
					NSVGstyles* next = p->styles;

					p->styles = (NSVGstyles*)NANOSVG_malloc(sizeof(NSVGstyles));
					p->styles->next = next;
					p->styles->name = nsvg__strndup(start, (size_t)(s - start));
					start = s + 1;
					state = 2;
				}
			} else if (state == 2 && c == '}') {
				p->styles->description = nsvg__strndup(start, (size_t)(s - start));
				state = 0;
			}
			else if (state == 0) {
				start = s;
				state = 1;
			}
			s++;
		/*
			if (*s == '{' && state == NSVG_XML_CONTENT) {
				// Start of a tag
				*s++ = '\0';
				nsvg__parseContent(mark, contentCb, ud);
				mark = s;
				state = NSVG_XML_TAG;
			}
			else if (*s == '>' && state == NSVG_XML_TAG) {
				// Start of a content or new tag.
				*s++ = '\0';
				nsvg__parseElement(mark, startelCb, endelCb, ud);
				mark = s;
				state = NSVG_XML_CONTENT;
			}
			else {
				s++;
			}
		*/
		}

	}
}

static void nsvg__imageBounds(NSVGparser* p, float* bounds)
{
	NSVGshape* shape;
	shape = p->image->shapes;
	if (shape == NULL) {
		bounds[0] = bounds[1] = bounds[2] = bounds[3] = 0.0;
		return;
	}
	bounds[0] = shape->bounds[0];
	bounds[1] = shape->bounds[1];
	bounds[2] = shape->bounds[2];
	bounds[3] = shape->bounds[3];
	for (shape = shape->next; shape != NULL; shape = shape->next) {
		bounds[0] = nsvg__minf(bounds[0], shape->bounds[0]);
		bounds[1] = nsvg__minf(bounds[1], shape->bounds[1]);
		bounds[2] = nsvg__maxf(bounds[2], shape->bounds[2]);
		bounds[3] = nsvg__maxf(bounds[3], shape->bounds[3]);
	}
}

static float nsvg__viewAlign(float content, float container, int type)
{
	if (type == NSVG_ALIGN_MIN)
		return 0;
	else if (type == NSVG_ALIGN_MAX)
		return container - content;
	// mid
	return (container - content) * 0.5f;
}

static void nsvg__scaleGradient(NSVGgradient* grad, float tx, float ty, float sx, float sy)
{
	float t[6];
	nsvg__xformSetTranslation(t, tx, ty);
	nsvg__xformMultiply (grad->xform, t);

	nsvg__xformSetScale(t, sx, sy);
	nsvg__xformMultiply (grad->xform, t);
}

static void nsvg__scaleToViewbox(NSVGparser* p, const char* units)
{
	NSVGshape* shape;
	NSVGpath* path;
	float tx, ty, sx, sy, us, bounds[4], t[6], avgs;
	int i;
	float* pt;

	// Guess image size if not set completely.
	nsvg__imageBounds(p, bounds);

	if (p->viewWidth == 0) {
		if (p->image->width > 0) {
			p->viewWidth = p->image->width;
		} else {
			p->viewMinx = bounds[0];
			p->viewWidth = bounds[2] - bounds[0];
		}
	}
	if (p->viewHeight == 0) {
		if (p->image->height > 0) {
			p->viewHeight = p->image->height;
		} else {
			p->viewMiny = bounds[1];
			p->viewHeight = bounds[3] - bounds[1];
		}
	}
	if (p->image->width == 0)
		p->image->width = p->viewWidth;
	if (p->image->height == 0)
		p->image->height = p->viewHeight;

	tx = -p->viewMinx;
	ty = -p->viewMiny;
	sx = p->viewWidth > 0 ? p->image->width / p->viewWidth : 0;
	sy = p->viewHeight > 0 ? p->image->height / p->viewHeight : 0;
	// Unit scaling
	us = 1.0f / nsvg__convertToPixels(p, nsvg__coord(1.0f, nsvg__parseUnits(units)), 0.0f, 1.0f);

	// Fix aspect ratio
	if (p->alignType == NSVG_ALIGN_MEET) {
		// fit whole image into viewbox
		sx = sy = nsvg__minf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	} else if (p->alignType == NSVG_ALIGN_SLICE) {
		// fill whole viewbox with image
		sx = sy = nsvg__maxf(sx, sy);
		tx += nsvg__viewAlign(p->viewWidth*sx, p->image->width, p->alignX) / sx;
		ty += nsvg__viewAlign(p->viewHeight*sy, p->image->height, p->alignY) / sy;
	}

	// Transform
	sx *= us;
	sy *= us;
	avgs = (sx+sy) / 2.0f;
	for (shape = p->image->shapes; shape != NULL; shape = shape->next) {
		shape->bounds[0] = (shape->bounds[0] + tx) * sx;
		shape->bounds[1] = (shape->bounds[1] + ty) * sy;
		shape->bounds[2] = (shape->bounds[2] + tx) * sx;
		shape->bounds[3] = (shape->bounds[3] + ty) * sy;
		for (path = shape->paths; path != NULL; path = path->next) {
			path->bounds[0] = (path->bounds[0] + tx) * sx;
			path->bounds[1] = (path->bounds[1] + ty) * sy;
			path->bounds[2] = (path->bounds[2] + tx) * sx;
			path->bounds[3] = (path->bounds[3] + ty) * sy;
			for (i =0; i < path->npts; i++) {
				pt = &path->pts[i*2];
				pt[0] = (pt[0] + tx) * sx;
				pt[1] = (pt[1] + ty) * sy;
			}
		}

		if (shape->fill.type == NSVG_PAINT_LINEAR_GRADIENT || shape->fill.type == NSVG_PAINT_RADIAL_GRADIENT) {
			nsvg__scaleGradient(shape->fill.gradient, tx,ty, sx,sy);
			memcpy(t, shape->fill.gradient->xform, sizeof(float)*6);
			nsvg__xformInverse(shape->fill.gradient->xform, t);
		}
		if (shape->stroke.type == NSVG_PAINT_LINEAR_GRADIENT || shape->stroke.type == NSVG_PAINT_RADIAL_GRADIENT) {
			nsvg__scaleGradient(shape->stroke.gradient, tx,ty, sx,sy);
			memcpy(t, shape->stroke.gradient->xform, sizeof(float)*6);
			nsvg__xformInverse(shape->stroke.gradient->xform, t);
		}

		shape->strokeWidth *= avgs;
		shape->strokeDashOffset *= avgs;
		for (i = 0; i < shape->strokeDashCount; i++)
			shape->strokeDashArray[i] *= avgs;
	}
}

NANOSVG_SCOPE
NSVGimage* nsvgParse(char* input, const char* units, float dpi)
{
	NSVGparser* p;
	NSVGimage* ret = 0;

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

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

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

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

	nsvg__deleteParser(p);

	return ret;
}

NANOSVG_SCOPE
NSVGimage* nsvgParseFromFile(const char* filename, const char* units, float dpi)
{
	FILE* fp = NULL;
	size_t size;
	char* data = NULL;
	NSVGimage* image = NULL;

	fp = fopen(filename, "rb");
	if (!fp) goto error;
	fseek(fp, 0, SEEK_END);
	size = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	data = (char*)NANOSVG_malloc(size+1);
	if (data == NULL) goto error;
	if (fread(data, 1, size, fp) != size) goto error;
	data[size] = '\0';	// Must be null terminated.
	fclose(fp);
	image = nsvgParse(data, units, dpi);
	NANOSVG_free(data);

	return image;

error:
	if (fp) fclose(fp);
	if (data) NANOSVG_free(data);
	if (image) nsvgDelete(image);
	return NULL;
}

NANOSVG_SCOPE
void nsvgDelete(NSVGimage* image)
{
	NSVGshape *snext, *shape;
	if (image == NULL) return;
	shape = image->shapes;
	while (shape != NULL) {
		snext = shape->next;
		nsvg__deletePaths(shape->paths);
		nsvg__deletePaint(&shape->fill);
		nsvg__deletePaint(&shape->stroke);
		NANOSVG_free(shape);
		shape = snext;
	}
	NANOSVG_free(image);
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Deleted generic/nanosvgrast.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
/*
 * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
 *
 * This software is provided 'as-is', without any express or implied
 * warranty.  In no event will the authors be held liable for any damages
 * arising from the use of this software.
 *
 * Permission is granted to anyone to use this software for any purpose,
 * including commercial applications, and to alter it and redistribute it
 * freely, subject to the following restrictions:
 *
 * 1. The origin of this software must not be misrepresented; you must not
 * claim that you wrote the original software. If you use this software
 * in a product, an acknowledgment in the product documentation would be
 * appreciated but is not required.
 * 2. Altered source versions must be plainly marked as such, and must not be
 * misrepresented as being the original software.
 * 3. This notice may not be removed or altered from any source distribution.
 *
 * The polygon rasterization is heavily based on stb_truetype rasterizer
 * by Sean Barrett - http://nothings.org/
 *
 */

#ifndef NANOSVGRAST_H
#define NANOSVGRAST_H

#ifdef __cplusplus
extern "C" {
#endif

#ifndef NANOSVG_SCOPE
#define NANOSVG_SCOPE
#endif

#ifndef NANOSVG_malloc
#define NANOSVG_malloc malloc
#endif

#ifndef NANOSVG_realloc
#define NANOSVG_realloc realloc
#endif

#ifndef NANOSVG_free
#define NANOSVG_free free
#endif

typedef struct NSVGrasterizer NSVGrasterizer;

/* Example Usage:
	// Load SVG
	struct SNVGImage* image = nsvgParseFromFile("test.svg.");

	// Create rasterizer (can be used to render multiple images).
	struct NSVGrasterizer* rast = nsvgCreateRasterizer();
	// Allocate memory for image
	unsigned char* img = malloc(w*h*4);
	// Rasterize
	nsvgRasterize(rast, image, 0,0,1, img, w, h, w*4);
*/

// Allocated rasterizer context.
NANOSVG_SCOPE NSVGrasterizer* nsvgCreateRasterizer(void);

// Rasterizes SVG image, returns RGBA image (non-premultiplied alpha)
//   r - pointer to rasterizer context
//   image - pointer to image to rasterize
//   tx,ty - image offset (applied after scaling)
//   scale - image scale
//   dst - pointer to destination image data, 4 bytes per pixel (RGBA)
//   w - width of the image to render
//   h - height of the image to render
//   stride - number of bytes per scaleline in the destination buffer
NANOSVG_SCOPE void nsvgRasterize(NSVGrasterizer* r,
				   NSVGimage* image, float tx, float ty, float scale,
				   unsigned char* dst, int w, int h, int stride);

// Deletes rasterizer context.
NANOSVG_SCOPE void nsvgDeleteRasterizer(NSVGrasterizer*);


#ifdef __cplusplus
}
#endif

#endif // NANOSVGRAST_H

#ifdef NANOSVGRAST_IMPLEMENTATION

#include <math.h>

#define NSVG__SUBSAMPLES	5
#define NSVG__FIXSHIFT		10
#define NSVG__FIX			(1 << NSVG__FIXSHIFT)
#define NSVG__FIXMASK		(NSVG__FIX-1)
#define NSVG__MEMPAGE_SIZE	1024

typedef struct NSVGedge {
	float x0,y0, x1,y1;
	int dir;
	struct NSVGedge* next;
} NSVGedge;

typedef struct NSVGpoint {
	float x, y;
	float dx, dy;
	float len;
	float dmx, dmy;
	unsigned char flags;
} NSVGpoint;

typedef struct NSVGactiveEdge {
	int x,dx;
	float ey;
	int dir;
	struct NSVGactiveEdge *next;
} NSVGactiveEdge;

typedef struct NSVGmemPage {
	unsigned char mem[NSVG__MEMPAGE_SIZE];
	int size;
	struct NSVGmemPage* next;
} NSVGmemPage;

typedef struct NSVGcachedPaint {
	char type;
	char spread;
	float xform[6];
	unsigned int colors[256];
} NSVGcachedPaint;

struct NSVGrasterizer
{
	float px, py;

	float tessTol;
	float distTol;

	NSVGedge* edges;
	int nedges;
	int cedges;

	NSVGpoint* points;
	int npoints;
	int cpoints;

	NSVGpoint* points2;
	int npoints2;
	int cpoints2;

	NSVGactiveEdge* freelist;
	NSVGmemPage* pages;
	NSVGmemPage* curpage;

	unsigned char* scanline;
	int cscanline;

	unsigned char* bitmap;
	int width, height, stride;
};

NANOSVG_SCOPE
NSVGrasterizer* nsvgCreateRasterizer(void)
{
	NSVGrasterizer* r = (NSVGrasterizer*)NANOSVG_malloc(sizeof(NSVGrasterizer));
	if (r == NULL) goto error;
	memset(r, 0, sizeof(NSVGrasterizer));

	r->tessTol = 0.25f;
	r->distTol = 0.01f;

	return r;

error:
	nsvgDeleteRasterizer(r);
	return NULL;
}

NANOSVG_SCOPE
void nsvgDeleteRasterizer(NSVGrasterizer* r)
{
	NSVGmemPage* p;

	if (r == NULL) return;

	p = r->pages;
	while (p != NULL) {
		NSVGmemPage* next = p->next;
		NANOSVG_free(p);
		p = next;
	}

	if (r->edges) NANOSVG_free(r->edges);
	if (r->points) NANOSVG_free(r->points);
	if (r->points2) NANOSVG_free(r->points2);
	if (r->scanline) NANOSVG_free(r->scanline);

	NANOSVG_free(r);
}

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

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

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

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

	return newp;
}

static void nsvg__resetPool(NSVGrasterizer* r)
{
	NSVGmemPage* p = r->pages;
	while (p != NULL) {
		p->size = 0;
		p = p->next;
	}
	r->curpage = r->pages;
}

static unsigned char* nsvg__alloc(NSVGrasterizer* r, int size)
{
	unsigned char* buf;
	if (size > NSVG__MEMPAGE_SIZE) return NULL;
	if (r->curpage == NULL || r->curpage->size+size > NSVG__MEMPAGE_SIZE) {
		r->curpage = nsvg__nextPage(r, r->curpage);
	}
	buf = &r->curpage->mem[r->curpage->size];
	r->curpage->size += size;
	return buf;
}

static int nsvg__ptEquals(float x1, float y1, float x2, float y2, float tol)
{
	float dx = x2 - x1;
	float dy = y2 - y1;
	return dx*dx + dy*dy < tol*tol;
}

static void nsvg__addPathPoint(NSVGrasterizer* r, float x, float y, int flags)
{
	NSVGpoint* pt;

	if (r->npoints > 0) {
		pt = &r->points[r->npoints-1];
		if (nsvg__ptEquals(pt->x,pt->y, x,y, r->distTol)) {
			pt->flags = (unsigned char)(pt->flags | flags);
			return;
		}
	}

	if (r->npoints+1 > r->cpoints) {
		r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64;
		r->points = (NSVGpoint*)NANOSVG_realloc(r->points, sizeof(NSVGpoint) * r->cpoints);
		if (r->points == NULL) return;
	}

	pt = &r->points[r->npoints];
	pt->x = x;
	pt->y = y;
	pt->flags = (unsigned char)flags;
	r->npoints++;
}

static void nsvg__appendPathPoint(NSVGrasterizer* r, NSVGpoint pt)
{
	if (r->npoints+1 > r->cpoints) {
		r->cpoints = r->cpoints > 0 ? r->cpoints * 2 : 64;
		r->points = (NSVGpoint*)NANOSVG_realloc(r->points, sizeof(NSVGpoint) * r->cpoints);
		if (r->points == NULL) return;
	}
	r->points[r->npoints] = pt;
	r->npoints++;
}

static void nsvg__duplicatePoints(NSVGrasterizer* r)
{
	if (r->npoints > r->cpoints2) {
		r->cpoints2 = r->npoints;
		r->points2 = (NSVGpoint*)NANOSVG_realloc(r->points2, sizeof(NSVGpoint) * r->cpoints2);
		if (r->points2 == NULL) return;
	}

	memcpy(r->points2, r->points, sizeof(NSVGpoint) * r->npoints);
	r->npoints2 = r->npoints;
}

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

	// Skip horizontal edges
	if (y0 == y1)
		return;

	if (r->nedges+1 > r->cedges) {
		r->cedges = r->cedges > 0 ? r->cedges * 2 : 64;
		r->edges = (NSVGedge*)NANOSVG_realloc(r->edges, sizeof(NSVGedge) * r->cedges);
		if (r->edges == NULL) return;
	}

	e = &r->edges[r->nedges];
	r->nedges++;

	if (y0 < y1) {
		e->x0 = x0;
		e->y0 = y0;
		e->x1 = x1;
		e->y1 = y1;
		e->dir = 1;
	} else {
		e->x0 = x1;
		e->y0 = y1;
		e->x1 = x0;
		e->y1 = y0;
		e->dir = -1;
	}
}

static float nsvg__normalize(float *x, float* y)
{
	float d = sqrtf((*x)*(*x) + (*y)*(*y));
	if (d > 1e-6f) {
		float id = 1.0f / d;
		*x *= id;
		*y *= id;
	}
	return d;
}

static float nsvg__absf(float x) { return x < 0 ? -x : x; }

static void nsvg__flattenCubicBez(NSVGrasterizer* r,
								  float x1, float y1, float x2, float y2,
								  float x3, float y3, float x4, float y4,
								  int level, int type)
{
	float x12,y12,x23,y23,x34,y34,x123,y123,x234,y234,x1234,y1234;
	float dx,dy,d2,d3;

	if (level > 10) return;

	x12 = (x1+x2)*0.5f;
	y12 = (y1+y2)*0.5f;
	x23 = (x2+x3)*0.5f;
	y23 = (y2+y3)*0.5f;
	x34 = (x3+x4)*0.5f;
	y34 = (y3+y4)*0.5f;
	x123 = (x12+x23)*0.5f;
	y123 = (y12+y23)*0.5f;

	dx = x4 - x1;
	dy = y4 - y1;
	d2 = nsvg__absf(((x2 - x4) * dy - (y2 - y4) * dx));
	d3 = nsvg__absf(((x3 - x4) * dy - (y3 - y4) * dx));

	if ((d2 + d3)*(d2 + d3) < r->tessTol * (dx*dx + dy*dy)) {
		nsvg__addPathPoint(r, x4, y4, type);
		return;
	}

	x234 = (x23+x34)*0.5f;
	y234 = (y23+y34)*0.5f;
	x1234 = (x123+x234)*0.5f;
	y1234 = (y123+y234)*0.5f;

	nsvg__flattenCubicBez(r, x1,y1, x12,y12, x123,y123, x1234,y1234, level+1, 0);
	nsvg__flattenCubicBez(r, x1234,y1234, x234,y234, x34,y34, x4,y4, level+1, type);
}

static void nsvg__flattenShape(NSVGrasterizer* r, NSVGshape* shape, float scale)
{
	int i, j;
	NSVGpath* path;

	for (path = shape->paths; path != NULL; path = path->next) {
		r->npoints = 0;
		// Flatten path
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, 0);
		}
		// Close path
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, 0);
		// Build edges
		for (i = 0, j = r->npoints-1; i < r->npoints; j = i++)
			nsvg__addEdge(r, r->points[j].x, r->points[j].y, r->points[i].x, r->points[i].y);
	}
}

enum NSVGpointFlags
{
	NSVG_PT_CORNER = 0x01,
	NSVG_PT_BEVEL = 0x02,
	NSVG_PT_LEFT = 0x04
};

static void nsvg__initClosed(NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float dx = p1->x - p0->x;
	float dy = p1->y - p0->y;
	float len = nsvg__normalize(&dx, &dy);
	float px = p0->x + dx*len*0.5f, py = p0->y + dy*len*0.5f;
	float dlx = dy, dly = -dx;
	float lx = px - dlx*w, ly = py - dly*w;
	float rx = px + dlx*w, ry = py + dly*w;
	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__buttCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect)
{
	float w = lineWidth * 0.5f;
	float px = p->x, py = p->y;
	float dlx = dy, dly = -dx;
	float lx = px - dlx*w, ly = py - dly*w;
	float rx = px + dlx*w, ry = py + dly*w;

	nsvg__addEdge(r, lx, ly, rx, ry);

	if (connect) {
		nsvg__addEdge(r, left->x, left->y, lx, ly);
		nsvg__addEdge(r, rx, ry, right->x, right->y);
	}
	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__squareCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int connect)
{
	float w = lineWidth * 0.5f;
	float px = p->x - dx*w, py = p->y - dy*w;
	float dlx = dy, dly = -dx;
	float lx = px - dlx*w, ly = py - dly*w;
	float rx = px + dlx*w, ry = py + dly*w;

	nsvg__addEdge(r, lx, ly, rx, ry);

	if (connect) {
		nsvg__addEdge(r, left->x, left->y, lx, ly);
		nsvg__addEdge(r, rx, ry, right->x, right->y);
	}
	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

#ifndef NSVG_PI
#define NSVG_PI (3.14159265358979323846264338327f)
#endif

static void nsvg__roundCap(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p, float dx, float dy, float lineWidth, int ncap, int connect)
{
	int i;
	float w = lineWidth * 0.5f;
	float px = p->x, py = p->y;
	float dlx = dy, dly = -dx;
	float lx = 0, ly = 0, rx = 0, ry = 0, prevx = 0, prevy = 0;

	for (i = 0; i < ncap; i++) {
		float a = (float)i/(float)(ncap-1)*NSVG_PI;
		float ax = cosf(a) * w, ay = sinf(a) * w;
		float x = px - dlx*ax - dx*ay;
		float y = py - dly*ax - dy*ay;

		if (i > 0)
			nsvg__addEdge(r, prevx, prevy, x, y);

		prevx = x;
		prevy = y;

		if (i == 0) {
			lx = x; ly = y;
		} else if (i == ncap-1) {
			rx = x; ry = y;
		}
	}

	if (connect) {
		nsvg__addEdge(r, left->x, left->y, lx, ly);
		nsvg__addEdge(r, rx, ry, right->x, right->y);
	}

	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__bevelJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float dlx0 = p0->dy, dly0 = -p0->dx;
	float dlx1 = p1->dy, dly1 = -p1->dx;
	float lx0 = p1->x - (dlx0 * w), ly0 = p1->y - (dly0 * w);
	float rx0 = p1->x + (dlx0 * w), ry0 = p1->y + (dly0 * w);
	float lx1 = p1->x - (dlx1 * w), ly1 = p1->y - (dly1 * w);
	float rx1 = p1->x + (dlx1 * w), ry1 = p1->y + (dly1 * w);

	nsvg__addEdge(r, lx0, ly0, left->x, left->y);
	nsvg__addEdge(r, lx1, ly1, lx0, ly0);

	nsvg__addEdge(r, right->x, right->y, rx0, ry0);
	nsvg__addEdge(r, rx0, ry0, rx1, ry1);

	left->x = lx1; left->y = ly1;
	right->x = rx1; right->y = ry1;
}

static void nsvg__miterJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float dlx0 = p0->dy, dly0 = -p0->dx;
	float dlx1 = p1->dy, dly1 = -p1->dx;
	float lx0, rx0, lx1, rx1;
	float ly0, ry0, ly1, ry1;

	if (p1->flags & NSVG_PT_LEFT) {
		lx0 = lx1 = p1->x - p1->dmx * w;
		ly0 = ly1 = p1->y - p1->dmy * w;
		nsvg__addEdge(r, lx1, ly1, left->x, left->y);

		rx0 = p1->x + (dlx0 * w);
		ry0 = p1->y + (dly0 * w);
		rx1 = p1->x + (dlx1 * w);
		ry1 = p1->y + (dly1 * w);
		nsvg__addEdge(r, right->x, right->y, rx0, ry0);
		nsvg__addEdge(r, rx0, ry0, rx1, ry1);
	} else {
		lx0 = p1->x - (dlx0 * w);
		ly0 = p1->y - (dly0 * w);
		lx1 = p1->x - (dlx1 * w);
		ly1 = p1->y - (dly1 * w);
		nsvg__addEdge(r, lx0, ly0, left->x, left->y);
		nsvg__addEdge(r, lx1, ly1, lx0, ly0);

		rx0 = rx1 = p1->x + p1->dmx * w;
		ry0 = ry1 = p1->y + p1->dmy * w;
		nsvg__addEdge(r, right->x, right->y, rx1, ry1);
	}

	left->x = lx1; left->y = ly1;
	right->x = rx1; right->y = ry1;
}

static void nsvg__roundJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p0, NSVGpoint* p1, float lineWidth, int ncap)
{
	int i, n;
	float w = lineWidth * 0.5f;
	float dlx0 = p0->dy, dly0 = -p0->dx;
	float dlx1 = p1->dy, dly1 = -p1->dx;
	float a0 = atan2f(dly0, dlx0);
	float a1 = atan2f(dly1, dlx1);
	float da = a1 - a0;
	float lx, ly, rx, ry;

	if (da < NSVG_PI) da += NSVG_PI*2;
	if (da > NSVG_PI) da -= NSVG_PI*2;

	n = (int)ceilf((nsvg__absf(da) / NSVG_PI) * (float)ncap);
	if (n < 2) n = 2;
	if (n > ncap) n = ncap;

	lx = left->x;
	ly = left->y;
	rx = right->x;
	ry = right->y;

	for (i = 0; i < n; i++) {
		float u = (float)i/(float)(n-1);
		float a = a0 + u*da;
		float ax = cosf(a) * w, ay = sinf(a) * w;
		float lx1 = p1->x - ax, ly1 = p1->y - ay;
		float rx1 = p1->x + ax, ry1 = p1->y + ay;

		nsvg__addEdge(r, lx1, ly1, lx, ly);
		nsvg__addEdge(r, rx, ry, rx1, ry1);

		lx = lx1; ly = ly1;
		rx = rx1; ry = ry1;
	}

	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static void nsvg__straightJoin(NSVGrasterizer* r, NSVGpoint* left, NSVGpoint* right, NSVGpoint* p1, float lineWidth)
{
	float w = lineWidth * 0.5f;
	float lx = p1->x - (p1->dmx * w), ly = p1->y - (p1->dmy * w);
	float rx = p1->x + (p1->dmx * w), ry = p1->y + (p1->dmy * w);

	nsvg__addEdge(r, lx, ly, left->x, left->y);
	nsvg__addEdge(r, right->x, right->y, rx, ry);

	left->x = lx; left->y = ly;
	right->x = rx; right->y = ry;
}

static int nsvg__curveDivs(float r, float arc, float tol)
{
	float da = acosf(r / (r + tol)) * 2.0f;
	int divs = (int)ceilf(arc / da);
	if (divs < 2) divs = 2;
	return divs;
}

static void nsvg__expandStroke(NSVGrasterizer* r, NSVGpoint* points, int npoints, int closed, int lineJoin, int lineCap, float lineWidth)
{
	int ncap = nsvg__curveDivs(lineWidth*0.5f, NSVG_PI, r->tessTol);	// Calculate divisions per half circle.
	NSVGpoint left = {0,0,0,0,0,0,0,0}, right = {0,0,0,0,0,0,0,0}, firstLeft = {0,0,0,0,0,0,0,0}, firstRight = {0,0,0,0,0,0,0,0};
	NSVGpoint* p0, *p1;
	int j, s, e;

	// Build stroke edges
	if (closed) {
		// Looping
		p0 = &points[npoints-1];
		p1 = &points[0];
		s = 0;
		e = npoints;
	} else {
		// Add cap
		p0 = &points[0];
		p1 = &points[1];
		s = 1;
		e = npoints-1;
	}

	if (closed) {
		nsvg__initClosed(&left, &right, p0, p1, lineWidth);
		firstLeft = left;
		firstRight = right;
	} else {
		// Add cap
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &left, &right, p0, dx, dy, lineWidth, 0);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &left, &right, p0, dx, dy, lineWidth, 0);
		else if (lineCap == NSVG_CAP_ROUND)
			nsvg__roundCap(r, &left, &right, p0, dx, dy, lineWidth, ncap, 0);
	}

	for (j = s; j < e; ++j) {
		if (p1->flags & NSVG_PT_CORNER) {
			if (lineJoin == NSVG_JOIN_ROUND)
				nsvg__roundJoin(r, &left, &right, p0, p1, lineWidth, ncap);
			else if (lineJoin == NSVG_JOIN_BEVEL || (p1->flags & NSVG_PT_BEVEL))
				nsvg__bevelJoin(r, &left, &right, p0, p1, lineWidth);
			else
				nsvg__miterJoin(r, &left, &right, p0, p1, lineWidth);
		} else {
			nsvg__straightJoin(r, &left, &right, p1, lineWidth);
		}
		p0 = p1++;
	}

	if (closed) {
		// Loop it
		nsvg__addEdge(r, firstLeft.x, firstLeft.y, left.x, left.y);
		nsvg__addEdge(r, right.x, right.y, firstRight.x, firstRight.y);
	} else {
		// Add cap
		float dx = p1->x - p0->x;
		float dy = p1->y - p0->y;
		nsvg__normalize(&dx, &dy);
		if (lineCap == NSVG_CAP_BUTT)
			nsvg__buttCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_SQUARE)
			nsvg__squareCap(r, &right, &left, p1, -dx, -dy, lineWidth, 1);
		else if (lineCap == NSVG_CAP_ROUND)
			nsvg__roundCap(r, &right, &left, p1, -dx, -dy, lineWidth, ncap, 1);
	}
}

static void nsvg__prepareStroke(NSVGrasterizer* r, float miterLimit, int lineJoin)
{
	int i, j;
	NSVGpoint* p0, *p1;

	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (i = 0; i < r->npoints; i++) {
		// Calculate segment direction and length
		p0->dx = p1->x - p0->x;
		p0->dy = p1->y - p0->y;
		p0->len = nsvg__normalize(&p0->dx, &p0->dy);
		// Advance
		p0 = p1++;
	}

	// calculate joins
	p0 = &r->points[r->npoints-1];
	p1 = &r->points[0];
	for (j = 0; j < r->npoints; j++) {
		float dlx0, dly0, dlx1, dly1, dmr2, cross;
		dlx0 = p0->dy;
		dly0 = -p0->dx;
		dlx1 = p1->dy;
		dly1 = -p1->dx;
		// Calculate extrusions
		p1->dmx = (dlx0 + dlx1) * 0.5f;
		p1->dmy = (dly0 + dly1) * 0.5f;
		dmr2 = p1->dmx*p1->dmx + p1->dmy*p1->dmy;
		if (dmr2 > 0.000001f) {
			float s2 = 1.0f / dmr2;
			if (s2 > 600.0f) {
				s2 = 600.0f;
			}
			p1->dmx *= s2;
			p1->dmy *= s2;
		}

		// Clear flags, but keep the corner.
		p1->flags = (p1->flags & NSVG_PT_CORNER) ? NSVG_PT_CORNER : 0;

		// Keep track of left turns.
		cross = p1->dx * p0->dy - p0->dx * p1->dy;
		if (cross > 0.0f)
			p1->flags |= NSVG_PT_LEFT;

		// Check to see if the corner needs to be beveled.
		if (p1->flags & NSVG_PT_CORNER) {
			if ((dmr2 * miterLimit*miterLimit) < 1.0f || lineJoin == NSVG_JOIN_BEVEL || lineJoin == NSVG_JOIN_ROUND) {
				p1->flags |= NSVG_PT_BEVEL;
			}
		}

		p0 = p1++;
	}
}

static void nsvg__flattenShapeStroke(NSVGrasterizer* r, NSVGshape* shape, float scale)
{
	int i, j, closed;
	NSVGpath* path;
	NSVGpoint* p0, *p1;
	float miterLimit = shape->miterLimit;
	int lineJoin = shape->strokeLineJoin;
	int lineCap = shape->strokeLineCap;
	float lineWidth = shape->strokeWidth * scale;

	for (path = shape->paths; path != NULL; path = path->next) {
		// Flatten path
		r->npoints = 0;
		nsvg__addPathPoint(r, path->pts[0]*scale, path->pts[1]*scale, NSVG_PT_CORNER);
		for (i = 0; i < path->npts-1; i += 3) {
			float* p = &path->pts[i*2];
			nsvg__flattenCubicBez(r, p[0]*scale,p[1]*scale, p[2]*scale,p[3]*scale, p[4]*scale,p[5]*scale, p[6]*scale,p[7]*scale, 0, NSVG_PT_CORNER);
		}
		if (r->npoints < 2)
			continue;

		closed = path->closed;

		// If the first and last points are the same, remove the last, mark as closed path.
		p0 = &r->points[r->npoints-1];
		p1 = &r->points[0];
		if (nsvg__ptEquals(p0->x,p0->y, p1->x,p1->y, r->distTol)) {
			r->npoints--;
			p0 = &r->points[r->npoints-1];
			closed = 1;
		}

		if (shape->strokeDashCount > 0) {
			int idash = 0, dashState = 1;
			float totalDist = 0, dashLen, allDashLen, dashOffset;
			NSVGpoint cur;

			if (closed)
				nsvg__appendPathPoint(r, r->points[0]);

			// Duplicate points -> points2.
			nsvg__duplicatePoints(r);

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

			// Figure out dash offset.
			allDashLen = 0;
			for (j = 0; j < shape->strokeDashCount; j++)
				allDashLen += shape->strokeDashArray[j];
			if (shape->strokeDashCount & 1)
				allDashLen *= 2.0f;
			// Find location inside pattern
			dashOffset = fmodf(shape->strokeDashOffset, allDashLen);
			if (dashOffset < 0.0f)
				dashOffset += allDashLen;

			while (dashOffset > shape->strokeDashArray[idash]) {
				dashOffset -= shape->strokeDashArray[idash];
				idash = (idash + 1) % shape->strokeDashCount;
			}
			dashLen = (shape->strokeDashArray[idash] - dashOffset) * scale;

			for (j = 1; j < r->npoints2; ) {
				float dx = r->points2[j].x - cur.x;
				float dy = r->points2[j].y - cur.y;
				float dist = sqrtf(dx*dx + dy*dy);

				if ((totalDist + dist) > dashLen) {
					// Calculate intermediate point
					float d = (dashLen - totalDist) / dist;
					float x = cur.x + dx * d;
					float y = cur.y + dy * d;
					nsvg__addPathPoint(r, x, y, NSVG_PT_CORNER);

					// Stroke
					if (r->npoints > 1 && dashState) {
						nsvg__prepareStroke(r, miterLimit, lineJoin);
						nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
					}
					// Advance dash pattern
					dashState = !dashState;
					idash = (idash+1) % shape->strokeDashCount;
					dashLen = shape->strokeDashArray[idash] * scale;
					// Restart
					cur.x = x;
					cur.y = y;
					cur.flags = NSVG_PT_CORNER;
					totalDist = 0.0f;
					r->npoints = 0;
					nsvg__appendPathPoint(r, cur);
				} else {
					totalDist += dist;
					cur = r->points2[j];
					nsvg__appendPathPoint(r, cur);
					j++;
				}
			}
			// Stroke any leftover path
			if (r->npoints > 1 && dashState)
				nsvg__expandStroke(r, r->points, r->npoints, 0, lineJoin, lineCap, lineWidth);
		} else {
			nsvg__prepareStroke(r, miterLimit, lineJoin);
			nsvg__expandStroke(r, r->points, r->npoints, closed, lineJoin, lineCap, lineWidth);
		}
	}
}

static int nsvg__cmpEdge(const void *p, const void *q)
{
	const NSVGedge* a = (const NSVGedge*)p;
	const NSVGedge* b = (const NSVGedge*)q;

	if (a->y0 < b->y0) return -1;
	if (a->y0 > b->y0) return  1;
	return 0;
}


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

	if (r->freelist != NULL) {
		// Restore from freelist.
		z = r->freelist;
		r->freelist = z->next;
	} else {
		// Alloc new edge.
		z = (NSVGactiveEdge*)nsvg__alloc(r, sizeof(NSVGactiveEdge));
		if (z == NULL) return NULL;
	}

	dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
//	STBTT_assert(e->y0 <= start_point);
	// round dx down to avoid going too far
	if (dxdy < 0)
		z->dx = (int)(-floorf(NSVG__FIX * -dxdy));
	else
		z->dx = (int)floorf(NSVG__FIX * dxdy);
	z->x = (int)floorf(NSVG__FIX * (e->x0 + dxdy * (startPoint - e->y0)));
//	z->x -= off_x * FIX;
	z->ey = e->y1;
	z->next = 0;
	z->dir = e->dir;

	return z;
}

static void nsvg__freeActive(NSVGrasterizer* r, NSVGactiveEdge* z)
{
	z->next = r->freelist;
	r->freelist = z;
}

static void nsvg__fillScanline(unsigned char* scanline, int len, int x0, int x1, int maxWeight, int* xmin, int* xmax)
{
	int i = x0 >> NSVG__FIXSHIFT;
	int j = x1 >> NSVG__FIXSHIFT;
	if (i < *xmin) *xmin = i;
	if (j > *xmax) *xmax = j;
	if (i < len && j >= 0) {
		if (i == j) {
			// x0,x1 are the same pixel, so compute combined coverage
			scanline[i] = (unsigned char)(scanline[i] + ((x1 - x0) * maxWeight >> NSVG__FIXSHIFT));
		} else {
			if (i >= 0) // add antialiasing for x0
				scanline[i] = (unsigned char)(scanline[i] + (((NSVG__FIX - (x0 & NSVG__FIXMASK)) * maxWeight) >> NSVG__FIXSHIFT));
			else
				i = -1; // clip

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

			for (++i; i < j; ++i) // fill pixels between x0 and x1
				scanline[i] = (unsigned char)(scanline[i] + maxWeight);
		}
	}
}

// note: this routine clips fills that extend off the edges... ideally this
// wouldn't happen, but it could happen if the truetype glyph bounding boxes
// are wrong, or if the user supplies a too-small bitmap
static void nsvg__fillActiveEdges(unsigned char* scanline, int len, NSVGactiveEdge* e, int maxWeight, int* xmin, int* xmax, char fillRule)
{
	// non-zero winding fill
	int x0 = 0, w = 0;

	if (fillRule == NSVG_FILLRULE_NONZERO) {
		// Non-zero
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				x0 = e->x; w += e->dir;
			} else {
				int x1 = e->x; w += e->dir;
				// if we went to zero, we need to draw
				if (w == 0)
					nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	} else if (fillRule == NSVG_FILLRULE_EVENODD) {
		// Even-odd
		while (e != NULL) {
			if (w == 0) {
				// if we're currently at zero, we need to record the edge start point
				x0 = e->x; w = 1;
			} else {
				int x1 = e->x; w = 0;
				nsvg__fillScanline(scanline, len, x0, x1, maxWeight, xmin, xmax);
			}
			e = e->next;
		}
	}
}

static float nsvg__clampf(float a, float mn, float mx) { return a < mn ? mn : (a > mx ? mx : a); }

static unsigned int nsvg__RGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
{
	return (r) | (g << 8) | (b << 16) | (a << 24);
}

static unsigned int nsvg__lerpRGBA(unsigned int c0, unsigned int c1, float u)
{
	int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f);
	int r = (((c0) & 0xff)*(256-iu) + (((c1) & 0xff)*iu)) >> 8;
	int g = (((c0>>8) & 0xff)*(256-iu) + (((c1>>8) & 0xff)*iu)) >> 8;
	int b = (((c0>>16) & 0xff)*(256-iu) + (((c1>>16) & 0xff)*iu)) >> 8;
	int a = (((c0>>24) & 0xff)*(256-iu) + (((c1>>24) & 0xff)*iu)) >> 8;
	return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a);
}

static unsigned int nsvg__applyOpacity(unsigned int c, float u)
{
	int iu = (int)(nsvg__clampf(u, 0.0f, 1.0f) * 256.0f);
	int r = (c) & 0xff;
	int g = (c>>8) & 0xff;
	int b = (c>>16) & 0xff;
	int a = (((c>>24) & 0xff)*iu) >> 8;
	return nsvg__RGBA((unsigned char)r, (unsigned char)g, (unsigned char)b, (unsigned char)a);
}

static inline int nsvg__div255(int x)
{
    return ((x+1) * 257) >> 16;
}

static void nsvg__scanlineSolid(unsigned char* dst, int count, unsigned char* cover, int x, int y,
								float tx, float ty, float scale, NSVGcachedPaint* cache)
{

	if (cache->type == NSVG_PAINT_COLOR) {
		int i, cr, cg, cb, ca;
		cr = cache->colors[0] & 0xff;
		cg = (cache->colors[0] >> 8) & 0xff;
		cb = (cache->colors[0] >> 16) & 0xff;
		ca = (cache->colors[0] >> 24) & 0xff;

		for (i = 0; i < count; i++) {
			int r,g,b;
			int a = nsvg__div255((int)cover[0] * ca);
			int ia = 255 - a;
			// Premultiply
			r = nsvg__div255(cr * a);
			g = nsvg__div255(cg * a);
			b = nsvg__div255(cb * a);

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
		}
	} else if (cache->type == NSVG_PAINT_LINEAR_GRADIENT) {
		// TODO: spread modes.
		// TODO: plenty of opportunities to optimize.
		float fx, fy, dx, gy;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;
		dx = 1.0f / scale;

		for (i = 0; i < count; i++) {
			int r,g,b,a,ia;
			gy = fx*t[1] + fy*t[3] + t[5];
			c = cache->colors[(int)nsvg__clampf(gy*255.0f, 0, 255.0f)];
			cr = (c) & 0xff;
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

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

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

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
			fx += dx;
		}
	} else if (cache->type == NSVG_PAINT_RADIAL_GRADIENT) {
		// TODO: spread modes.
		// TODO: plenty of opportunities to optimize.
		// TODO: focus (fx,fy)
		float fx, fy, dx, gx, gy, gd;
		float* t = cache->xform;
		int i, cr, cg, cb, ca;
		unsigned int c;

		fx = ((float)x - tx) / scale;
		fy = ((float)y - ty) / scale;
		dx = 1.0f / scale;

		for (i = 0; i < count; i++) {
			int r,g,b,a,ia;
			gx = fx*t[0] + fy*t[2] + t[4];
			gy = fx*t[1] + fy*t[3] + t[5];
			gd = sqrtf(gx*gx + gy*gy);
			c = cache->colors[(int)nsvg__clampf(gd*255.0f, 0, 255.0f)];
			cr = (c) & 0xff;
			cg = (c >> 8) & 0xff;
			cb = (c >> 16) & 0xff;
			ca = (c >> 24) & 0xff;

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

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

			// Blend over
			r += nsvg__div255(ia * (int)dst[0]);
			g += nsvg__div255(ia * (int)dst[1]);
			b += nsvg__div255(ia * (int)dst[2]);
			a += nsvg__div255(ia * (int)dst[3]);

			dst[0] = (unsigned char)r;
			dst[1] = (unsigned char)g;
			dst[2] = (unsigned char)b;
			dst[3] = (unsigned char)a;

			cover++;
			dst += 4;
			fx += dx;
		}
	}
}

static void nsvg__rasterizeSortedEdges(NSVGrasterizer *r, float tx, float ty, float scale, NSVGcachedPaint* cache, char fillRule)
{
	NSVGactiveEdge *active = NULL;
	int y, s;
	int e = 0;
	int maxWeight = (255 / NSVG__SUBSAMPLES);  // weight per vertical scanline
	int xmin, xmax;

	for (y = 0; y < r->height; y++) {
		memset(r->scanline, 0, r->width);
		xmin = r->width;
		xmax = 0;
		for (s = 0; s < NSVG__SUBSAMPLES; ++s) {
			// find center of pixel for this scanline
			float scany = (float)(y*NSVG__SUBSAMPLES + s) + 0.5f;
			NSVGactiveEdge **step = &active;

			// update all active edges;
			// remove all active edges that terminate before the center of this scanline
			while (*step) {
				NSVGactiveEdge *z = *step;
				if (z->ey <= scany) {
					*step = z->next; // delete from list
//					NSVG__assert(z->valid);
					nsvg__freeActive(r, z);
				} else {
					z->x += z->dx; // advance to position for current scanline
					step = &((*step)->next); // advance through list
				}
			}

			// resort the list if needed
			for (;;) {
				int changed = 0;
				step = &active;
				while (*step && (*step)->next) {
					if ((*step)->x > (*step)->next->x) {
						NSVGactiveEdge* t = *step;
						NSVGactiveEdge* q = t->next;
						t->next = q->next;
						q->next = t;
						*step = q;
						changed = 1;
					}
					step = &(*step)->next;
				}
				if (!changed) break;
			}

			// insert all edges that start before the center of this scanline -- omit ones that also end on this scanline
			while (e < r->nedges && r->edges[e].y0 <= scany) {
				if (r->edges[e].y1 > scany) {
					NSVGactiveEdge* z = nsvg__addActive(r, &r->edges[e], scany);
					if (z == NULL) break;
					// find insertion point
					if (active == NULL) {
						active = z;
					} else if (z->x < active->x) {
						// insert at front
						z->next = active;
						active = z;
					} else {
						// find thing to insert AFTER
						NSVGactiveEdge* p = active;
						while (p->next && p->next->x < z->x)
							p = p->next;
						// at this point, p->next->x is NOT < z->x
						z->next = p->next;
						p->next = z;
					}
				}
				e++;
			}

			// now process all active edges in non-zero fashion
			if (active != NULL)
				nsvg__fillActiveEdges(r->scanline, r->width, active, maxWeight, &xmin, &xmax, fillRule);
		}
		// Blit
		if (xmin < 0) xmin = 0;
		if (xmax > r->width-1) xmax = r->width-1;
		if (xmin <= xmax) {
			nsvg__scanlineSolid(&r->bitmap[y * r->stride] + xmin*4, xmax-xmin+1, &r->scanline[xmin], xmin, y, tx,ty, scale, cache);
		}
	}

}

static void nsvg__unpremultiplyAlpha(unsigned char* image, int w, int h, int stride)
{
	int x,y;

	// Unpremultiply
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = row[0], g = row[1], b = row[2], a = row[3];
			if (a != 0) {
				row[0] = (unsigned char)(r*255/a);
				row[1] = (unsigned char)(g*255/a);
				row[2] = (unsigned char)(b*255/a);
			}
			row += 4;
		}
	}

	// Defringe
	for (y = 0; y < h; y++) {
		unsigned char *row = &image[y*stride];
		for (x = 0; x < w; x++) {
			int r = 0, g = 0, b = 0, a = row[3], n = 0;
			if (a == 0) {
				if (x-1 > 0 && row[-1] != 0) {
					r += row[-4];
					g += row[-3];
					b += row[-2];
					n++;
				}
				if (x+1 < w && row[7] != 0) {
					r += row[4];
					g += row[5];
					b += row[6];
					n++;
				}
				if (y-1 > 0 && row[-stride+3] != 0) {
					r += row[-stride];
					g += row[-stride+1];
					b += row[-stride+2];
					n++;
				}
				if (y+1 < h && row[stride+3] != 0) {
					r += row[stride];
					g += row[stride+1];
					b += row[stride+2];
					n++;
				}
				if (n > 0) {
					row[0] = (unsigned char)(r/n);
					row[1] = (unsigned char)(g/n);
					row[2] = (unsigned char)(b/n);
				}
			}
			row += 4;
		}
	}
}


static void nsvg__initPaint(NSVGcachedPaint* cache, NSVGpaint* paint, float opacity)
{
	int i, j;
	NSVGgradient* grad;

	cache->type = paint->type;

	if (paint->type == NSVG_PAINT_COLOR) {
		cache->colors[0] = nsvg__applyOpacity(paint->color, opacity);
		return;
	}

	grad = paint->gradient;

	cache->spread = grad->spread;
	memcpy(cache->xform, grad->xform, sizeof(float)*6);

	if (grad->nstops == 0) {
		for (i = 0; i < 256; i++)
			cache->colors[i] = 0;
	} if (grad->nstops == 1) {
		for (i = 0; i < 256; i++)
			cache->colors[i] = nsvg__applyOpacity(grad->stops[i].color, opacity);
	} else {
		unsigned int ca, cb = 0;
		float ua, ub, du, u;
		int ia, ib, count;

		ca = nsvg__applyOpacity(grad->stops[0].color, opacity);
		ua = nsvg__clampf(grad->stops[0].offset, 0, 1);
		ub = nsvg__clampf(grad->stops[grad->nstops-1].offset, ua, 1);
		ia = (int)(ua * 255.0f);
		ib = (int)(ub * 255.0f);
		for (i = 0; i < ia; i++) {
			cache->colors[i] = ca;
		}

		for (i = 0; i < grad->nstops-1; i++) {
			ca = nsvg__applyOpacity(grad->stops[i].color, opacity);
			cb = nsvg__applyOpacity(grad->stops[i+1].color, opacity);
			ua = nsvg__clampf(grad->stops[i].offset, 0, 1);
			ub = nsvg__clampf(grad->stops[i+1].offset, 0, 1);
			ia = (int)(ua * 255.0f);
			ib = (int)(ub * 255.0f);
			count = ib - ia;
			if (count <= 0) continue;
			u = 0;
			du = 1.0f / (float)count;
			for (j = 0; j < count; j++) {
				cache->colors[ia+j] = nsvg__lerpRGBA(ca,cb,u);
				u += du;
			}
		}

		for (i = ib; i < 256; i++)
			cache->colors[i] = cb;
	}

}

/*
static void dumpEdges(NSVGrasterizer* r, const char* name)
{
	float xmin = 0, xmax = 0, ymin = 0, ymax = 0;
	NSVGedge *e = NULL;
	int i;
	if (r->nedges == 0) return;
	FILE* fp = fopen(name, "w");
	if (fp == NULL) return;

	xmin = xmax = r->edges[0].x0;
	ymin = ymax = r->edges[0].y0;
	for (i = 0; i < r->nedges; i++) {
		e = &r->edges[i];
		xmin = nsvg__minf(xmin, e->x0);
		xmin = nsvg__minf(xmin, e->x1);
		xmax = nsvg__maxf(xmax, e->x0);
		xmax = nsvg__maxf(xmax, e->x1);
		ymin = nsvg__minf(ymin, e->y0);
		ymin = nsvg__minf(ymin, e->y1);
		ymax = nsvg__maxf(ymax, e->y0);
		ymax = nsvg__maxf(ymax, e->y1);
	}

	fprintf(fp, "<svg viewBox=\"%f %f %f %f\" xmlns=\"http://www.w3.org/2000/svg\">", xmin, ymin, (xmax - xmin), (ymax - ymin));

	for (i = 0; i < r->nedges; i++) {
		e = &r->edges[i];
		fprintf(fp ,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:#000;\" />", e->x0,e->y0, e->x1,e->y1);
	}

	for (i = 0; i < r->npoints; i++) {
		if (i+1 < r->npoints)
			fprintf(fp ,"<line x1=\"%f\" y1=\"%f\" x2=\"%f\" y2=\"%f\" style=\"stroke:#f00;\" />", r->points[i].x, r->points[i].y, r->points[i+1].x, r->points[i+1].y);
		fprintf(fp ,"<circle cx=\"%f\" cy=\"%f\" r=\"1\" style=\"fill:%s;\" />", r->points[i].x, r->points[i].y, r->points[i].flags == 0 ? "#f00" : "#0f0");
	}

	fprintf(fp, "</svg>");
	fclose(fp);
}
*/

NANOSVG_SCOPE
void nsvgRasterize(NSVGrasterizer* r,
				   NSVGimage* image, float tx, float ty, float scale,
				   unsigned char* dst, int w, int h, int stride)
{
	NSVGshape *shape = NULL;
	NSVGedge *e = NULL;
	NSVGcachedPaint cache;
	int i;

	r->bitmap = dst;
	r->width = w;
	r->height = h;
	r->stride = stride;

	if (w > r->cscanline) {
		r->cscanline = w;
		r->scanline = (unsigned char*)NANOSVG_realloc(r->scanline, w);
		if (r->scanline == NULL) return;
	}

	for (i = 0; i < h; i++)
		memset(&dst[i*stride], 0, w*4);

	for (shape = image->shapes; shape != NULL; shape = shape->next) {
		if (!(shape->flags & NSVG_FLAGS_VISIBLE))
			continue;

		if (shape->fill.type != NSVG_PAINT_NONE) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShape(r, shape, scale);

			// Scale and translate edges
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			// Rasterize edges
			qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
			nsvg__initPaint(&cache, &shape->fill, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, shape->fillRule);
		}
		if (shape->stroke.type != NSVG_PAINT_NONE && (shape->strokeWidth * scale) > 0.01f) {
			nsvg__resetPool(r);
			r->freelist = NULL;
			r->nedges = 0;

			nsvg__flattenShapeStroke(r, shape, scale);

//			dumpEdges(r, "edge.svg");

			// Scale and translate edges
			for (i = 0; i < r->nedges; i++) {
				e = &r->edges[i];
				e->x0 = tx + e->x0;
				e->y0 = (ty + e->y0) * NSVG__SUBSAMPLES;
				e->x1 = tx + e->x1;
				e->y1 = (ty + e->y1) * NSVG__SUBSAMPLES;
			}

			// Rasterize edges
			qsort(r->edges, r->nedges, sizeof(NSVGedge), nsvg__cmpEdge);

			// now, traverse the scanlines and find the intersections on each scanline, use non-zero rule
			nsvg__initPaint(&cache, &shape->stroke, shape->opacity);

			nsvg__rasterizeSortedEdges(r, tx,ty,scale, &cache, NSVG_FILLRULE_NONZERO);
		}
	}

	nsvg__unpremultiplyAlpha(dst, w, h, stride);

	r->bitmap = NULL;
	r->width = 0;
	r->height = 0;
	r->stride = 0;
}

#endif
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tk.decls.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    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,







|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
    void Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc)
}
declare 18 {
    int Tk_CanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 19 {
    CONST86 char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 20 {
    Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas)
}
declare 21 {
    void Tk_CanvasWindowCoords(Tk_Canvas canvas, double x, double y,
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    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 {







|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    int Tk_ConfigureValue(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    char *widgRec, const char *argvName, int flags)
}
declare 29 {
    int Tk_ConfigureWidget(Tcl_Interp *interp,
	    Tk_Window tkwin, const Tk_ConfigSpec *specs,
	    int argc, CONST84 char **argv, char *widgRec,
	    int flags)
}
declare 30 {
    void Tk_ConfigureWindow(Tk_Window tkwin,
	    unsigned int valueMask, XWindowChanges *valuePtr)
}
declare 31 {
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
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,







|







241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
declare 53 {
    void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection, Atom target)
}
declare 54 {
    void Tk_DestroyWindow(Tk_Window tkwin)
}
declare 55 {
    CONST84_RETURN char *Tk_DisplayName(Tk_Window tkwin)
}
declare 56 {
    int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y)
}
declare 57 {
    void Tk_Draw3DPolygon(Tk_Window tkwin,
	    Drawable drawable, Tk_3DBorder border,
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
}
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)







|







322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
}
declare 75 {
    void Tk_FreePixmap(Display *display, Pixmap pixmap)
}
declare 76 {
    void Tk_FreeTextLayout(Tk_TextLayout textLayout)
}
declare 77 {
    void Tk_FreeXId(Display *display, XID xid)
}
declare 78 {
    GC Tk_GCForColor(XColor *colorPtr, Drawable drawable)
}
declare 79 {
    void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,  int reqHeight)
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
	    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 {







|


|







344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
	    Tk_BindingTable bindingTable, ClientData object)
}
declare 82 {
    int Tk_GetAnchor(Tcl_Interp *interp,
	    const char *str, Tk_Anchor *anchorPtr)
}
declare 83 {
    CONST84_RETURN char *Tk_GetAtomName(Tk_Window tkwin, Atom atom)
}
declare 84 {
    CONST84_RETURN char *Tk_GetBinding(Tcl_Interp *interp,
	    Tk_BindingTable bindingTable, ClientData object,
	    const char *eventStr)
}
declare 85 {
    Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *str)
}
declare 86 {
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr)
}
declare 97 {
    Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, const char *name,
	    Tk_ImageChangedProc *changeProc, ClientData clientData)
}
declare 98 {
    ClientData Tk_GetImageModelData(Tcl_Interp *interp,
	    const char *name, const Tk_ImageType **typePtrPtr)
}
declare 99 {
    Tk_ItemType *Tk_GetItemTypes(void)
}
declare 100 {
    int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr)
}







|
|







399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
    GC Tk_GetGC(Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr)
}
declare 97 {
    Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, const char *name,
	    Tk_ImageChangedProc *changeProc, ClientData clientData)
}
declare 98 {
    ClientData Tk_GetImageMasterData(Tcl_Interp *interp,
	    const char *name, CONST86 Tk_ImageType **typePtrPtr)
}
declare 99 {
    Tk_ItemType *Tk_GetItemTypes(void)
}
declare 100 {
    int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr)
}
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
    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,







|







435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
    int Tk_GetRelief(Tcl_Interp *interp, const char *name, int *reliefPtr)
}
declare 107 {
    void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr)
}
declare 108 {
    int Tk_GetScrollInfo(Tcl_Interp *interp,
	    int argc, CONST84 char **argv, double *dblPtr, int *intPtr)
}
declare 109 {
    int Tk_GetScreenMM(Tcl_Interp *interp,
	    Tk_Window tkwin, const char *str, double *doublePtr)
}
declare 110 {
    int Tk_GetSelection(Tcl_Interp *interp,
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
declare 115 {
    void Tk_HandleEvent(XEvent *eventPtr)
}
declare 116 {
    Tk_Window Tk_IdToWindow(Display *display, Window window)
}
declare 117 {
    void Tk_ImageChanged(Tk_ImageModel model, int x, int y,
	    int width, int height, int imageWidth, int imageHeight)
}
declare 118 {
    int Tk_Init(Tcl_Interp *interp)
}
declare 119 {
    Atom Tk_InternAtom(Tk_Window tkwin, const char *name)







|







468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
declare 115 {
    void Tk_HandleEvent(XEvent *eventPtr)
}
declare 116 {
    Tk_Window Tk_IdToWindow(Display *display, Window window)
}
declare 117 {
    void Tk_ImageChanged(Tk_ImageMaster model, int x, int y,
	    int width, int height, int imageWidth, int imageHeight)
}
declare 118 {
    int Tk_Init(Tcl_Interp *interp)
}
declare 119 {
    Atom Tk_InternAtom(Tk_Window tkwin, const char *name)
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
declare 128 {
    void Tk_MoveWindow(Tk_Window tkwin, int x, int y)
}
declare 129 {
    void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y)
}
declare 130 {
    const char *Tk_NameOf3DBorder(Tk_3DBorder border)
}
declare 131 {
    const char *Tk_NameOfAnchor(Tk_Anchor anchor)
}
declare 132 {
    const char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
}
declare 133 {
    const char *Tk_NameOfCapStyle(int cap)
}
declare 134 {
    const char *Tk_NameOfColor(XColor *colorPtr)
}
declare 135 {
    const char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
}
declare 136 {
    const char *Tk_NameOfFont(Tk_Font font)
}
declare 137 {
    const char *Tk_NameOfImage(Tk_ImageModel model)
}
declare 138 {
    const char *Tk_NameOfJoinStyle(int join)
}
declare 139 {
    const char *Tk_NameOfJustify(Tk_Justify justify)
}
declare 140 {
    const char *Tk_NameOfRelief(int relief)
}
declare 141 {
    Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
	    const char *pathName, Tk_Window tkwin)
}
declare 142 {
    void Tk_OwnSelection(Tk_Window tkwin,
	    Atom selection, Tk_LostSelProc *proc,
	    ClientData clientData)
}
declare 143 {
    int Tk_ParseArgv(Tcl_Interp *interp,
	    Tk_Window tkwin, int *argcPtr, const char **argv,
	    const Tk_ArgvInfo *argTable, int flags)
}
declare 144 {deprecated {function signature changed}} {
    void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height)
}
declare 145 {deprecated {function signature changed}} {
    void Tk_PhotoPutZoomedBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int zoomX, int zoomY,
	    int subsampleX, int subsampleY)
}
declare 146 {
    int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr)
}
declare 147 {
    void Tk_PhotoBlank(Tk_PhotoHandle handle)
}
declare 148 {deprecated {function signature changed}} {
    void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height )
}
declare 149 {
    void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr)
}
declare 150 {deprecated {function signature changed}} {
    void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height)
}
declare 151 {
    int Tk_PointToChar(Tk_TextLayout layout, int x, int y)
}
declare 152 {
    int Tk_PostscriptFontName(Tk_Font tkfont, Tcl_DString *dsPtr)







|


|


|


|


|


|


|


|


|


|


|












|


|




|











|





|







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
declare 128 {
    void Tk_MoveWindow(Tk_Window tkwin, int x, int y)
}
declare 129 {
    void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y)
}
declare 130 {
    CONST84_RETURN char *Tk_NameOf3DBorder(Tk_3DBorder border)
}
declare 131 {
    CONST84_RETURN char *Tk_NameOfAnchor(Tk_Anchor anchor)
}
declare 132 {
    CONST84_RETURN char *Tk_NameOfBitmap(Display *display, Pixmap bitmap)
}
declare 133 {
    CONST84_RETURN char *Tk_NameOfCapStyle(int cap)
}
declare 134 {
    CONST84_RETURN char *Tk_NameOfColor(XColor *colorPtr)
}
declare 135 {
    CONST84_RETURN char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor)
}
declare 136 {
    CONST84_RETURN char *Tk_NameOfFont(Tk_Font font)
}
declare 137 {
    CONST84_RETURN char *Tk_NameOfImage(Tk_ImageMaster model)
}
declare 138 {
    CONST84_RETURN char *Tk_NameOfJoinStyle(int join)
}
declare 139 {
    CONST84_RETURN char *Tk_NameOfJustify(Tk_Justify justify)
}
declare 140 {
    CONST84_RETURN char *Tk_NameOfRelief(int relief)
}
declare 141 {
    Tk_Window Tk_NameToWindow(Tcl_Interp *interp,
	    const char *pathName, Tk_Window tkwin)
}
declare 142 {
    void Tk_OwnSelection(Tk_Window tkwin,
	    Atom selection, Tk_LostSelProc *proc,
	    ClientData clientData)
}
declare 143 {
    int Tk_ParseArgv(Tcl_Interp *interp,
	    Tk_Window tkwin, int *argcPtr, CONST84 char **argv,
	    const Tk_ArgvInfo *argTable, int flags)
}
declare 144 {
    void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height)
}
declare 145 {
    void Tk_PhotoPutZoomedBlock_NoComposite(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int zoomX, int zoomY,
	    int subsampleX, int subsampleY)
}
declare 146 {
    int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr)
}
declare 147 {
    void Tk_PhotoBlank(Tk_PhotoHandle handle)
}
declare 148 {
    void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height )
}
declare 149 {
    void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr)
}
declare 150 {
    void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height)
}
declare 151 {
    int Tk_PointToChar(Tk_TextLayout layout, int x, int y)
}
declare 152 {
    int Tk_PostscriptFontName(Tk_Font tkfont, Tcl_DString *dsPtr)
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
declare 193 {
    void  Tk_FreeBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 194 {
    void  Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 195 {
    void  Tk_FreeConfigOptions(void *recordPtr, Tk_OptionTable optionToken,
	    Tk_Window tkwin)
}
declare 196 {
    void  Tk_FreeSavedOptions(Tk_SavedOptions *savePtr)
}
declare 197 {
    void  Tk_FreeCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)







|







740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
declare 193 {
    void  Tk_FreeBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 194 {
    void  Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 195 {
    void  Tk_FreeConfigOptions(char *recordPtr, Tk_OptionTable optionToken,
	    Tk_Window tkwin)
}
declare 196 {
    void  Tk_FreeSavedOptions(Tk_SavedOptions *savePtr)
}
declare 197 {
    void  Tk_FreeCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
    XColor *Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 203 {
    Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 204 {
    Tcl_Obj *Tk_GetOptionInfo(Tcl_Interp *interp,
	    void *recordPtr, Tk_OptionTable optionTable,
	    Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 205 {
    Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, void *recordPtr,
	    Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 206 {
    int	 Tk_GetJustifyFromObj(Tcl_Interp *interp,
	    Tcl_Obj *objPtr, Tk_Justify *justifyPtr)
}
declare 207 {







|



|







770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
    XColor *Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 203 {
    Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr)
}
declare 204 {
    Tcl_Obj *Tk_GetOptionInfo(Tcl_Interp *interp,
	    char *recordPtr, Tk_OptionTable optionTable,
	    Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 205 {
    Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, char *recordPtr,
	    Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin)
}
declare 206 {
    int	 Tk_GetJustifyFromObj(Tcl_Interp *interp,
	    Tcl_Obj *objPtr, Tk_Justify *justifyPtr)
}
declare 207 {
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
	    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)
}







|


|







|







798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
	    Tcl_Obj *objPtr, int *resultPtr)
}
declare 210 {
    int	 Tk_GetScrollInfoObj(Tcl_Interp *interp,
	    int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr)
}
declare 211 {
    int	 Tk_InitOptions(Tcl_Interp *interp, char *recordPtr,
	    Tk_OptionTable optionToken, Tk_Window tkwin)
}
declare 212 {
    void  Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc,
	    Tcl_Interp *interp)
}
declare 213 {
    void  Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr)
}
declare 214 {
    int	 Tk_SetOptions(Tcl_Interp *interp, char *recordPtr,
	    Tk_OptionTable optionTable, int objc,
	    Tcl_Obj *const objv[], Tk_Window tkwin,
	    Tk_SavedOptions *savePtr, int *maskPtr)
}
declare 215 {
    void Tk_InitConsoleChannels(Tcl_Interp *interp)
}
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
}

# New in 8.4a5
#
declare 245 {
    void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
declare 246 {deprecated {function signature changed}} {
    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)







|




|







939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
}

# New in 8.4a5
#
declare 245 {
    void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height)
}
declare 246 {
    void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int compRule)
}
declare 247 {
    void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
	    Tk_PhotoImageBlock *blockPtr, int x, int y,
	    int width, int height, int zoomX, int zoomY,
	    int subsampleX, int subsampleY, int compRule)
}
declare 248 {
    int Tk_CollapseMotionEvents(Display *display, int collapse)
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
}
declare 260 {
    Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId,
	Tk_OptionTable optionTable)
}
declare 261 {
    void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, int width, int height,
	    int inner, int *widthPtr, int *heightPtr)
}
declare 262 {
    void Tk_GetElementBox(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, int x, int y, int width,
	    int height, int inner, int *xPtr, int *yPtr, int *widthPtr,
	    int *heightPtr)
}
declare 263 {
    int Tk_GetElementBorderWidth(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin)
}
declare 264 {
    void Tk_DrawElement(Tk_Style style, Tk_StyledElement element,
	    void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y,
	    int width, int height, int state)
}

# TIP#116
declare 265 {
    int Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle,
	    int width, int height)







|




|





|



|







997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
}
declare 260 {
    Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId,
	Tk_OptionTable optionTable)
}
declare 261 {
    void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element,
	    char *recordPtr, Tk_Window tkwin, int width, int height,
	    int inner, int *widthPtr, int *heightPtr)
}
declare 262 {
    void Tk_GetElementBox(Tk_Style style, Tk_StyledElement element,
	    char *recordPtr, Tk_Window tkwin, int x, int y, int width,
	    int height, int inner, int *xPtr, int *yPtr, int *widthPtr,
	    int *heightPtr)
}
declare 263 {
    int Tk_GetElementBorderWidth(Tk_Style style, Tk_StyledElement element,
	    char *recordPtr, Tk_Window tkwin)
}
declare 264 {
    void Tk_DrawElement(Tk_Style style, Tk_StyledElement element,
	    char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y,
	    int width, int height, int state)
}

# TIP#116
declare 265 {
    int Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle,
	    int width, int height)
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
# build against legacy sources.
declare 272 {
    void Tk_CreateOldImageType(const Tk_ImageType *typePtr)
}
declare 273 {
    void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}

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

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

interface tkPlat








<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
|
<
<
<
<







1064
1065
1066
1067
1068
1069
1070


1071













1072




1073
1074
1075
1076
1077
1078
1079
# build against legacy sources.
declare 272 {
    void Tk_CreateOldImageType(const Tk_ImageType *typePtr)
}
declare 273 {
    void Tk_CreateOldPhotoImageFormat(const Tk_PhotoImageFormat *formatPtr)
}


declare 290 {













    void TkUnusedStubEntry(void)




}

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

interface tkPlat

1117
1118
1119
1120
1121
1122
1123
1124














1125
1126
1127

1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141

1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
declare 5 win {
    int Tk_TranslateWinEvent(HWND hwnd,
	    UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
}

################################
# Aqua specific functions
# Stub removed because the function no longer exists.














#declare 3 aqua {
#    void TkMacOSXInitMenus(Tcl_Interp *interp)
#}

declare 4 aqua {
    void TkMacOSXInitAppleEvents(Tcl_Interp *interp)
}
declare 5 aqua {
    void TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}
declare 6 aqua {
    void TkMacOSXInvalClipRgns(Tk_Window tkwin)
}
# Stub removed because it just returned NULL.
#declare 7 aqua {
#    void *TkMacOSXGetDrawablePort(Drawable drawable)
#}

declare 8 aqua {
    void *TkMacOSXGetRootControl(Drawable drawable)
}
declare 9 aqua {
    void Tk_MacOSXSetupTkNotifier(void)
}
declare 10 aqua {
    int Tk_MacOSXIsAppInFront(void)
}
declare 11 aqua {
    Tk_Window Tk_MacOSXGetTkWindow(void *w)
}
declare 12 aqua {
    void *Tk_MacOSXGetCGContextForDrawable(Drawable drawable)
}
# Replaces TkMacOSXDrawable
declare 13 aqua {
    void *Tk_MacOSXGetNSWindowForDrawable(Drawable drawable)
}
declare 16 aqua {
    void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}

##############################################################################

# Public functions that are not accessible via the stubs table.








|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
<
>




|





<
|
|
<
>




















|







1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121

1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132

1133
1134

1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
declare 5 win {
    int Tk_TranslateWinEvent(HWND hwnd,
	    UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result)
}

################################
# Aqua specific functions

declare 0 aqua {
    void Tk_MacOSXSetEmbedHandler(
	    Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
	    Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
	    Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
	    Tk_MacOSXEmbedGetClipProc *getClipProc,
	    Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc)
}
declare 1 aqua {
    void Tk_MacOSXTurnOffMenus(void)
}
declare 2 aqua {
    void Tk_MacOSXTkOwnsCursor(int tkOwnsIt)
}
declare 3 aqua {
    void TkMacOSXInitMenus(Tcl_Interp *interp)

}
declare 4 aqua {
    void TkMacOSXInitAppleEvents(Tcl_Interp *interp)
}
declare 5 aqua {
    void TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}
declare 6 aqua {
    void TkMacOSXInvalClipRgns(Tk_Window tkwin)
}

declare 7 aqua {
    void *TkMacOSXGetDrawablePort(Drawable drawable)

}
declare 8 aqua {
    void *TkMacOSXGetRootControl(Drawable drawable)
}
declare 9 aqua {
    void Tk_MacOSXSetupTkNotifier(void)
}
declare 10 aqua {
    int Tk_MacOSXIsAppInFront(void)
}
declare 11 aqua {
    Tk_Window Tk_MacOSXGetTkWindow(void *w)
}
declare 12 aqua {
    void *Tk_MacOSXGetCGContextForDrawable(Drawable drawable)
}
# Replaces TkMacOSXDrawable
declare 13 aqua {
    void *Tk_MacOSXGetNSWindowForDrawable(Drawable drawable)
}
declare 16 aqua {
    void TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y, int width,
	    int height, int flags)
}

##############################################################################

# Public functions that are not accessible via the stubs table.

Changes to generic/tk.h.
13
14
15
16
17
18
19
20
21
22
23







24
25
26
27
28
29
30
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK
#define _TK

#include <tcl.h>
#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6)
#	error Tk 8.7 must be compiled with tcl.h from Tcl 8.6 or better
#endif








#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif

/*
 * Utility macros: STRINGIFY takes an argument and wraps it in "" (double
 * quotation marks), JOIN joins two arguments.







|
|


>
>
>
>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK
#define _TK

#include <tcl.h>
#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 6)
#	error Tk 8.6 must be compiled with tcl.h from Tcl 8.6 or better
#endif

#ifndef CONST84
#   define CONST84 const
#   define CONST84_RETURN const
#endif
#ifndef CONST86
#   define CONST86 CONST84
#endif
#ifndef EXTERN
#   define EXTERN extern TCL_STORAGE_CLASS
#endif

/*
 * Utility macros: STRINGIFY takes an argument and wraps it in "" (double
 * quotation marks), JOIN joins two arguments.
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#endif

/*
 * When version numbers change here, you must also go into the following files
 * and update the version numbers:
 *
 * library/tk.tcl	(1 LOC patch)
 * unix/configure.ac	(2 LOC Major, 2 LOC minor, 1 LOC patch)
 * win/configure.ac	(as above)
 * README		(sections 0 and 1)
 * macosx/Tk-Common.xcconfig (not patchlevel) 1 LOC
 * win/README		(not patchlevel)
 * unix/README		(not patchlevel)
 * unix/tk.spec		(1 LOC patch)
 * win/tcl.m4		(not patchlevel)
 *
 * You may also need to update some of these files when the numbers change for
 * the version of Tcl that this release of Tk is compiled against.
 */

#define TK_MAJOR_VERSION	8
#define TK_MINOR_VERSION	7
#define TK_RELEASE_LEVEL	TCL_ALPHA_RELEASE
#define TK_RELEASE_SERIAL	4

#define TK_VERSION		"8.7"
#define TK_PATCH_LEVEL		"8.7a4"

/*
 * A special definition used to allow this header file to be included from
 * windows or mac resource files so that they can obtain version information.
 * RC_INVOKED is defined by default by the windows RC tool and manually set
 * for macintosh.
 *







|
|












|
|
|

|
|







55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#endif

/*
 * When version numbers change here, you must also go into the following files
 * and update the version numbers:
 *
 * library/tk.tcl	(1 LOC patch)
 * unix/configure.in	(2 LOC Major, 2 LOC minor, 1 LOC patch)
 * win/configure.in	(as above)
 * README		(sections 0 and 1)
 * macosx/Tk-Common.xcconfig (not patchlevel) 1 LOC
 * win/README		(not patchlevel)
 * unix/README		(not patchlevel)
 * unix/tk.spec		(1 LOC patch)
 * win/tcl.m4		(not patchlevel)
 *
 * You may also need to update some of these files when the numbers change for
 * the version of Tcl that this release of Tk is compiled against.
 */

#define TK_MAJOR_VERSION	8
#define TK_MINOR_VERSION	6
#define TK_RELEASE_LEVEL	TCL_FINAL_RELEASE
#define TK_RELEASE_SERIAL	17

#define TK_VERSION		"8.6"
#define TK_PATCH_LEVEL		"8.6.17"

/*
 * A special definition used to allow this header file to be included from
 * windows or mac resource files so that they can obtain version information.
 * RC_INVOKED is defined by default by the windows RC tool and manually set
 * for macintosh.
 *
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
     || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC)
#   include <stddef.h>
#endif

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS	DLLEXPORT
#else
# ifndef TCL_STORAGE_CLASS
#   define TCL_STORAGE_CLASS DLLIMPORT
# endif
#endif

/*
 *----------------------------------------------------------------------
 *
 * Decide whether or not to use input methods.
 */

#if defined(XNQueryInputStyle) && !defined(_WIN32) && !defined(MAC_OSX_TK)
#define TK_USE_INPUT_METHODS
#endif

/*
 * Dummy types that are used by clients:
 */

#define Tk_ImageMaster Tk_ImageModel
typedef struct Tk_BindingTable_ *Tk_BindingTable;
typedef struct Tk_Canvas_ *Tk_Canvas;
typedef struct Tk_Cursor_ *Tk_Cursor;
typedef struct Tk_ErrorHandler_ *Tk_ErrorHandler;
typedef struct Tk_Font_ *Tk_Font;
typedef struct Tk_Image__ *Tk_Image;
typedef struct Tk_ImageModel_ *Tk_ImageModel;
typedef struct Tk_OptionTable_ *Tk_OptionTable;
typedef struct Tk_PostscriptInfo_ *Tk_PostscriptInfo;
typedef struct Tk_TextLayout_ *Tk_TextLayout;
typedef struct Tk_Window_ *Tk_Window;
typedef struct Tk_3DBorder_ *Tk_3DBorder;
typedef struct Tk_Style_ *Tk_Style;
typedef struct Tk_StyleEngine_ *Tk_StyleEngine;







<
<
<
<
















|






|







105
106
107
108
109
110
111




112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
     || defined(__cplusplus) || defined(_MSC_VER) || defined(__ICC)
#   include <stddef.h>
#endif

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS	DLLEXPORT




#endif

/*
 *----------------------------------------------------------------------
 *
 * Decide whether or not to use input methods.
 */

#if defined(XNQueryInputStyle) && !defined(_WIN32) && !defined(MAC_OSX_TK)
#define TK_USE_INPUT_METHODS
#endif

/*
 * Dummy types that are used by clients:
 */

#define Tk_ImageModel Tk_ImageMaster
typedef struct Tk_BindingTable_ *Tk_BindingTable;
typedef struct Tk_Canvas_ *Tk_Canvas;
typedef struct Tk_Cursor_ *Tk_Cursor;
typedef struct Tk_ErrorHandler_ *Tk_ErrorHandler;
typedef struct Tk_Font_ *Tk_Font;
typedef struct Tk_Image__ *Tk_Image;
typedef struct Tk_ImageMaster_ *Tk_ImageMaster;
typedef struct Tk_OptionTable_ *Tk_OptionTable;
typedef struct Tk_PostscriptInfo_ *Tk_PostscriptInfo;
typedef struct Tk_TextLayout_ *Tk_TextLayout;
typedef struct Tk_Window_ *Tk_Window;
typedef struct Tk_3DBorder_ *Tk_3DBorder;
typedef struct Tk_Style_ *Tk_Style;
typedef struct Tk_StyleEngine_ *Tk_StyleEngine;
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
    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







<
|


|
|
|
|



|
|
|
|
<
<
<
<







191
192
193
194
195
196
197

198
199
200
201
202
203
204
205
206
207
208
209
210
211




212
213
214
215
216
217
218
    const char *optionName;	/* Name used to specify option in Tcl
				 * commands. */
    const char *dbName;		/* Name for option in option database. */
    const char *dbClass;	/* Class for option in database. */
    const char *defValue;	/* Default value for option if not specified
				 * in command line, the option database, or
				 * the system. */

    int objOffset;		/* Where in record to store a Tcl_Obj * that
				 * holds the value of this option, specified
				 * as an offset in bytes from the start of the
				 * record. Use the Tk_Offset macro to generate
				 * values for this. -1 means don't store the
				 * Tcl_Obj in the record. */
    int internalOffset;		/* Where in record to store the internal
				 * representation of the value of this option,
				 * such as an int or XColor *. This field is
				 * specified as an offset in bytes from the
				 * start of the record. Use the Tk_Offset
				 * macro to generate values for it. -1 means
				 * don't store the internal representation in
				 * the record. */




    int flags;			/* Any combination of the values defined
				 * below. */
    const void *clientData;	/* An alternate place to put option-specific
				 * data. Used for the monochrome default value
				 * for colors, etc. */
    int typeMask;		/* An arbitrary bit mask defined by the class
				 * manager; typically bits correspond to
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

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







<
<
<
<
<
<
<





<







233
234
235
236
237
238
239







240
241
242
243
244

245
246
247
248
249
250
251

/*
 * The following structure and function types are used by TK_OPTION_CUSTOM
 * options; the structure holds pointers to the functions needed by the Tk
 * option config code to handle a custom option.
 */








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

typedef void (Tk_CustomOptionRestoreProc) (ClientData clientData,
	Tk_Window tkwin, char *internalPtr, char *saveInternalPtr);
typedef void (Tk_CustomOptionFreeProc) (ClientData clientData, Tk_Window tkwin,
	char *internalPtr);

typedef struct Tk_ObjCustomOption {
    const char *name;		/* Name of the custom option. */
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
} 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







<
|
<







267
268
269
270
271
272
273

274

275
276
277
278
279
280
281
} Tk_ObjCustomOption;

/*
 * Macro to use to fill in "offset" fields of the Tk_OptionSpec structure.
 * Computes number of bytes from beginning of structure to a given field.
 */


#define Tk_Offset(type, field) ((int) offsetof(type, field))

/* Workaround for platforms missing offsetof(), e.g. VC++ 6.0 */
#ifndef offsetof
#   define offsetof(type, field) ((size_t) ((char *) &((type *) 0)->field))
#endif

/*
 * The following two structures are used for error handling. When config
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
				 * option. */
    Tcl_Obj *valuePtr;		/* The old value of the option, in the form of
				 * a Tcl object; may be NULL if the value was
				 * not saved as an object. */
    double internalForm;	/* The old value of the option, in some
				 * internal representation such as an int or
				 * (XColor *). Valid only if the field
				 * optionPtr->specPtr->objOffset is -1. The
				 * space must be large enough to accommodate a
				 * double, a long, or a pointer; right now it
				 * looks like a double (i.e., 8 bytes) is big
				 * enough. Also, using a double guarantees
				 * that the field is properly aligned for
				 * storing large values. */
} Tk_SavedOption;

#ifdef TCL_MEM_DEBUG
#   define TK_NUM_SAVED_OPTIONS 2
#else
#   define TK_NUM_SAVED_OPTIONS 20
#endif

typedef struct Tk_SavedOptions {
    void *recordPtr;		/* The data structure in which to restore
				 * configuration options. */
    Tk_Window tkwin;		/* Window associated with recordPtr; needed to
				 * restore certain options. */
#if TCL_MAJOR_VERSION > 8
    size_t numItems;		/* The number of valid items in items field. */
#else
    int numItems;
#endif
    Tk_SavedOption items[TK_NUM_SAVED_OPTIONS];
				/* Items used to hold old values. */
    struct Tk_SavedOptions *nextPtr;
				/* Points to next structure in list; needed if
				 * too many options changed to hold all the
				 * old values in a single structure. NULL
				 * means no more structures. */







|















|



<
|
<
<
<







291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317

318



319
320
321
322
323
324
325
				 * option. */
    Tcl_Obj *valuePtr;		/* The old value of the option, in the form of
				 * a Tcl object; may be NULL if the value was
				 * not saved as an object. */
    double internalForm;	/* The old value of the option, in some
				 * internal representation such as an int or
				 * (XColor *). Valid only if the field
				 * optionPtr->specPtr->objOffset is < 0. The
				 * space must be large enough to accommodate a
				 * double, a long, or a pointer; right now it
				 * looks like a double (i.e., 8 bytes) is big
				 * enough. Also, using a double guarantees
				 * that the field is properly aligned for
				 * storing large values. */
} Tk_SavedOption;

#ifdef TCL_MEM_DEBUG
#   define TK_NUM_SAVED_OPTIONS 2
#else
#   define TK_NUM_SAVED_OPTIONS 20
#endif

typedef struct Tk_SavedOptions {
    char *recordPtr;		/* The data structure in which to restore
				 * configuration options. */
    Tk_Window tkwin;		/* Window associated with recordPtr; needed to
				 * restore certain options. */

    int numItems;		/* The number of valid items in items field. */



    Tk_SavedOption items[TK_NUM_SAVED_OPTIONS];
				/* Items used to hold old values. */
    struct Tk_SavedOptions *nextPtr;
				/* Points to next structure in list; needed if
				 * too many options changed to hold all the
				 * old values in a single structure. NULL
				 * means no more structures. */
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
/*
 * This is a temporary flag used while tkObjConfig and new widgets are in
 * development.
 */

#ifndef __NO_OLD_CONFIG

#if TCL_MAJOR_VERSION > 8
typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,
	Tk_Window tkwin, const char *value, char *widgRec, size_t offset);
typedef const char *(Tk_OptionPrintProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, size_t offset, Tcl_FreeProc **freeProcPtr);
#else
typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,
	Tk_Window tkwin, const char *value, char *widgRec, int offset);
typedef const char *(Tk_OptionPrintProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);
#endif

typedef struct Tk_CustomOption {
    Tk_OptionParseProc *parseProc;
				/* Procedure to call to parse an option and
				 * store it in converted form. */
    Tk_OptionPrintProc *printProc;
				/* Procedure to return a printable string







<

<
<
<
<
<
|
|

<







335
336
337
338
339
340
341

342





343
344
345

346
347
348
349
350
351
352
/*
 * This is a temporary flag used while tkObjConfig and new widgets are in
 * development.
 */

#ifndef __NO_OLD_CONFIG


typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp,





	Tk_Window tkwin, CONST84 char *value, char *widgRec, int offset);
typedef CONST86 char *(Tk_OptionPrintProc) (ClientData clientData,
	Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);


typedef struct Tk_CustomOption {
    Tk_OptionParseProc *parseProc;
				/* Procedure to call to parse an option and
				 * store it in converted form. */
    Tk_OptionPrintProc *printProc;
				/* Procedure to return a printable string
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
 * database, etc.
 */

typedef struct Tk_ConfigSpec {
    int type;			/* Type of option, such as TK_CONFIG_COLOR;
				 * see definitions below. Last option in table
				 * must have type TK_CONFIG_END. */
    const char *argvName;	/* Switch used to specify option in argv. NULL
				 * means this spec is part of a group. */
    Tk_Uid dbName;		/* Name for option in option database. */
    Tk_Uid dbClass;		/* Class for option in database. */
    Tk_Uid defValue;		/* Default value for option if not specified
				 * in command line or database. */
#if TCL_MAJOR_VERSION > 8
    size_t offset;			/* Where in widget record to store value; use
				 * offsetof macro to generate values for
				 * this. */
#else
    int offset;
#endif
    int specFlags;		/* Any combination of the values defined
				 * below; other bits are used internally by
				 * tkConfig.c. */
    const Tk_CustomOption *customPtr;
				/* If type is TK_CONFIG_CUSTOM then this is a
				 * pointer to info about how to parse and
				 * print the option. Otherwise it is
				 * irrelevant. */
} Tk_ConfigSpec;

/*







|





<
|
|

<
<
<



|







363
364
365
366
367
368
369
370
371
372
373
374
375

376
377
378



379
380
381
382
383
384
385
386
387
388
389
 * database, etc.
 */

typedef struct Tk_ConfigSpec {
    int type;			/* Type of option, such as TK_CONFIG_COLOR;
				 * see definitions below. Last option in table
				 * must have type TK_CONFIG_END. */
    CONST86 char *argvName;	/* Switch used to specify option in argv. NULL
				 * means this spec is part of a group. */
    Tk_Uid dbName;		/* Name for option in option database. */
    Tk_Uid dbClass;		/* Class for option in database. */
    Tk_Uid defValue;		/* Default value for option if not specified
				 * in command line or database. */

    int offset;			/* Where in widget record to store value; use
				 * Tk_Offset macro to generate values for
				 * this. */



    int specFlags;		/* Any combination of the values defined
				 * below; other bits are used internally by
				 * tkConfig.c. */
    CONST86 Tk_CustomOption *customPtr;
				/* If type is TK_CONFIG_CUSTOM then this is a
				 * pointer to info about how to parse and
				 * print the option. Otherwise it is
				 * irrelevant. */
} Tk_ConfigSpec;

/*
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
 * (internal-use-only flags are defined there).
 */

#define TK_CONFIG_NULL_OK		(1 << 0)
#define TK_CONFIG_COLOR_ONLY		(1 << 1)
#define TK_CONFIG_MONO_ONLY		(1 << 2)
#define TK_CONFIG_DONT_SET_DEFAULT	(1 << 3)
#ifndef TK_NO_DEPRECATED
#  define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)
#endif /* !TK_NO_DEPRECATED */
#define TK_CONFIG_USER_BIT		0x100
#endif /* __NO_OLD_CONFIG */

/*
 * Structure used to specify how to handle argv options.
 */

typedef struct {
    const char *key;		/* The key string that flags the option in the
				 * argv array. */
    int type;			/* Indicates option type; see below. */
    void *src;			/* Value to be used in setting dst; usage
				 * depends on type. */
    void *dst;			/* Address of value to be modified; usage
				 * depends on type. */
    const char *help;		/* Documentation message describing this
				 * option. */
} Tk_ArgvInfo;

/*
 * Legal values for the type field of a Tk_ArgvInfo: see the user
 * documentation for details.
 */







<
|
<








|


|

|

|







415
416
417
418
419
420
421

422

423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
 * (internal-use-only flags are defined there).
 */

#define TK_CONFIG_NULL_OK		(1 << 0)
#define TK_CONFIG_COLOR_ONLY		(1 << 1)
#define TK_CONFIG_MONO_ONLY		(1 << 2)
#define TK_CONFIG_DONT_SET_DEFAULT	(1 << 3)

#define TK_CONFIG_OPTION_SPECIFIED      (1 << 4)

#define TK_CONFIG_USER_BIT		0x100
#endif /* __NO_OLD_CONFIG */

/*
 * Structure used to specify how to handle argv options.
 */

typedef struct {
    CONST86 char *key;		/* The key string that flags the option in the
				 * argv array. */
    int type;			/* Indicates option type; see below. */
    char *src;			/* Value to be used in setting dst; usage
				 * depends on type. */
    char *dst;			/* Address of value to be modified; usage
				 * depends on type. */
    CONST86 char *help;		/* Documentation message describing this
				 * option. */
} Tk_ArgvInfo;

/*
 * Legal values for the type field of a Tk_ArgvInfo: see the user
 * documentation for details.
 */
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623

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







<
<
<

<







576
577
578
579
580
581
582



583

584
585
586
587
588
589
590

typedef Window (Tk_ClassCreateProc) (Tk_Window tkwin, Window parent,
	ClientData instanceData);
typedef void (Tk_ClassWorldChangedProc) (ClientData instanceData);
typedef void (Tk_ClassModalProc) (Tk_Window tkwin, XEvent *eventPtr);

typedef struct Tk_ClassProcs {



    unsigned int size;

    Tk_ClassWorldChangedProc *worldChangedProc;
				/* Procedure to invoke when the widget needs
				 * to respond in some way to a change in the
				 * world (font changes, etc.) */
    Tk_ClassCreateProc *createProc;
				/* Procedure to invoke when the platform-
				 * dependent window needs to be created. */
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
 * (or NULL if the structure is NULL).
 *
 * A more general version of this function may be useful if other
 * size-versioned structure pop up in the future:
 *
 *	#define Tk_GetField(name, who, which) \
 *	    (((who) == NULL) ? NULL :
 *	    (((who)->size <= offsetof(name, which)) ? NULL :(name)->which))
 */

#define Tk_GetClassProc(procs, which) \
    (((procs) == NULL) ? NULL : \
    (((procs)->size <= offsetof(Tk_ClassProcs, which)) ? NULL:(procs)->which))

/*
 * Each geometry manager (the packer, the placer, etc.) is represented by a
 * structure of the following form, which indicates procedures to invoke in
 * the geometry manager to carry out certain functions.
 */

#define Tk_GeomLostSlaveProc Tk_GeomLostContentProc
typedef void (Tk_GeomRequestProc) (ClientData clientData, Tk_Window tkwin);
typedef void (Tk_GeomLostContentProc) (ClientData clientData, Tk_Window tkwin);

typedef struct Tk_GeomMgr {
    const char *name;		/* Name of the geometry manager (command used
				 * to invoke it, or name of widget class that
				 * allows embedded widgets). */
    Tk_GeomRequestProc *requestProc;
				/* Procedure to invoke when a content's
				 * requested geometry changes. */
    Tk_GeomLostContentProc *lostContentProc;
				/* Procedure to invoke when content is taken
				 * away from one geometry manager by another.
				 * NULL means geometry manager doesn't care
				 * when content lost. */
} Tk_GeomMgr;

/*







|




|







|










|







601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
 * (or NULL if the structure is NULL).
 *
 * A more general version of this function may be useful if other
 * size-versioned structure pop up in the future:
 *
 *	#define Tk_GetField(name, who, which) \
 *	    (((who) == NULL) ? NULL :
 *	    (((who)->size <= Tk_Offset(name, which)) ? NULL :(name)->which))
 */

#define Tk_GetClassProc(procs, which) \
    (((procs) == NULL) ? NULL : \
    (((procs)->size <= Tk_Offset(Tk_ClassProcs, which)) ? NULL:(procs)->which))

/*
 * Each geometry manager (the packer, the placer, etc.) is represented by a
 * structure of the following form, which indicates procedures to invoke in
 * the geometry manager to carry out certain functions.
 */

#define Tk_GeomLostContentProc Tk_GeomLostSlaveProc
typedef void (Tk_GeomRequestProc) (ClientData clientData, Tk_Window tkwin);
typedef void (Tk_GeomLostContentProc) (ClientData clientData, Tk_Window tkwin);

typedef struct Tk_GeomMgr {
    const char *name;		/* Name of the geometry manager (command used
				 * to invoke it, or name of widget class that
				 * allows embedded widgets). */
    Tk_GeomRequestProc *requestProc;
				/* Procedure to invoke when a content's
				 * requested geometry changes. */
    Tk_GeomLostContentProc *lostSlaveProc;
				/* Procedure to invoke when content is taken
				 * away from one geometry manager by another.
				 * NULL means geometry manager doesn't care
				 * when content lost. */
} Tk_GeomMgr;

/*
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
    (((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) \







|


<







748
749
750
751
752
753
754
755
756
757

758
759
760
761
762
763
764
    (((Tk_FakeWin *) (tkwin))->flags & TK_WIN_MANAGED)
#define Tk_TopWinHierarchy(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY)
#define Tk_IsManageable(tkwin) \
    (((Tk_FakeWin *) (tkwin))->flags & TK_WM_MANAGEABLE)
#define Tk_ReqWidth(tkwin)	(((Tk_FakeWin *) (tkwin))->reqWidth)
#define Tk_ReqHeight(tkwin)	(((Tk_FakeWin *) (tkwin))->reqHeight)
/* Tk_InternalBorderWidth is deprecated */
#define Tk_InternalBorderWidth(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)

#define Tk_InternalBorderLeft(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderLeft)
#define Tk_InternalBorderRight(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderRight)
#define Tk_InternalBorderTop(tkwin) \
    (((Tk_FakeWin *) (tkwin))->internalBorderTop)
#define Tk_InternalBorderBottom(tkwin) \
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
    Tk_Uid classUid;
    XWindowChanges changes;
    unsigned int dummy6;	/* dirtyChanges */
    XSetWindowAttributes atts;
    unsigned long dummy7;	/* dirtyAtts */
    unsigned int flags;
    char *dummy8;		/* handlerList */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIC dummy9;			/* inputContext */
#endif /* TK_USE_INPUT_METHODS */
    ClientData *dummy10;	/* tagPtr */
    int dummy11;		/* numTags */
    int dummy12;		/* optionLevel */
    char *dummy13;		/* selHandlerList */
    char *dummy14;		/* geomMgrPtr */
    ClientData dummy15;		/* geomData */
    int reqWidth, reqHeight;
    int internalBorderLeft;
    char *dummy16;		/* wmInfoPtr */
    char *dummy17;		/* classProcPtr */
    ClientData dummy18;		/* instanceData */
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    int dummy20;
#endif /* TK_USE_INPUT_METHODS */
    char *dummy21;		/* geomMgrName */
    Tk_Window dummy22;		/* maintainerPtr */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIC dummy9;			/* inputContext */
    int dummy20;
#endif /* TK_USE_INPUT_METHODS */
} Tk_FakeWin;

/*
 * Flag values for TkWindow (and Tk_FakeWin) structures are:
 *
 * TK_MAPPED:			1 means window is currently mapped,
 *				0 means unmapped.







|



















|




<
<
<
<







795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826




827
828
829
830
831
832
833
    Tk_Uid classUid;
    XWindowChanges changes;
    unsigned int dummy6;	/* dirtyChanges */
    XSetWindowAttributes atts;
    unsigned long dummy7;	/* dirtyAtts */
    unsigned int flags;
    char *dummy8;		/* handlerList */
#ifdef TK_USE_INPUT_METHODS
    XIC dummy9;			/* inputContext */
#endif /* TK_USE_INPUT_METHODS */
    ClientData *dummy10;	/* tagPtr */
    int dummy11;		/* numTags */
    int dummy12;		/* optionLevel */
    char *dummy13;		/* selHandlerList */
    char *dummy14;		/* geomMgrPtr */
    ClientData dummy15;		/* geomData */
    int reqWidth, reqHeight;
    int internalBorderLeft;
    char *dummy16;		/* wmInfoPtr */
    char *dummy17;		/* classProcPtr */
    ClientData dummy18;		/* instanceData */
    char *dummy19;		/* privatePtr */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;
    int minReqWidth;
    int minReqHeight;
#ifdef TK_USE_INPUT_METHODS
    int dummy20;
#endif /* TK_USE_INPUT_METHODS */
    char *dummy21;		/* geomMgrName */
    Tk_Window dummy22;		/* maintainerPtr */




} Tk_FakeWin;

/*
 * Flag values for TkWindow (and Tk_FakeWin) structures are:
 *
 * TK_MAPPED:			1 means window is currently mapped,
 *				0 means unmapped.
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016

typedef enum {
    TK_STATE_NULL = -1, TK_STATE_ACTIVE, TK_STATE_DISABLED,
    TK_STATE_NORMAL, TK_STATE_HIDDEN
} Tk_State;

typedef struct Tk_SmoothMethod {
    const char *name;
    int (*coordProc) (Tk_Canvas canvas, double *pointPtr, int numPoints,
	    int numSteps, XPoint xPoints[], double dblPoints[]);
    void (*postscriptProc) (Tcl_Interp *interp, Tk_Canvas canvas,
	    double *coordPtr, int numPoints, int numSteps);
} Tk_SmoothMethod;

/*
 * For each item in a canvas widget there exists one record with the following
 * structure. Each actual item is represented by a record with the following
 * stuff at its beginning, plus additional type-specific stuff after that.
 */

#define TK_TAG_SPACE 3

typedef struct Tk_Item {
#if TCL_MAJOR_VERSION > 8
    size_t id;		/* Unique identifier for this item (also
				 * serves as first tag for item). */
#else
    int id;
#endif
    struct Tk_Item *nextPtr;	/* Next in display list of all items in this
				 * canvas. Later items in list are drawn on
				 * top of earlier ones. */
    Tk_Uid staticTagSpace[TK_TAG_SPACE];
				/* Built-in space for limited # of tags. */
    Tk_Uid *tagPtr;		/* Pointer to array of tags. Usually points to
				 * staticTagSpace, but may point to malloc-ed
				 * space if there are lots of tags. */
#if TCL_MAJOR_VERSION > 8
    size_t tagSpace;		/* Total amount of tag space available at
				 * tagPtr. */
    size_t numTags;		/* Number of tag slots actually used at
				 * *tagPtr. */
#else
    int tagSpace, numTags;
#endif
    struct Tk_ItemType *typePtr;/* Table of procedures that implement this
				 * type of item. */
    int x1, y1, x2, y2;		/* Bounding box for item, in integer canvas
				 * units. Set by item-specific code and
				 * guaranteed to contain every pixel drawn in
				 * item. Item area includes x1 and y1 but not
				 * x2 and y2. */







|















<
|

<
<
<








<
|

|

<
<
<







927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949

950
951



952
953
954
955
956
957
958
959

960
961
962
963



964
965
966
967
968
969
970

typedef enum {
    TK_STATE_NULL = -1, TK_STATE_ACTIVE, TK_STATE_DISABLED,
    TK_STATE_NORMAL, TK_STATE_HIDDEN
} Tk_State;

typedef struct Tk_SmoothMethod {
    CONST86 char *name;
    int (*coordProc) (Tk_Canvas canvas, double *pointPtr, int numPoints,
	    int numSteps, XPoint xPoints[], double dblPoints[]);
    void (*postscriptProc) (Tcl_Interp *interp, Tk_Canvas canvas,
	    double *coordPtr, int numPoints, int numSteps);
} Tk_SmoothMethod;

/*
 * For each item in a canvas widget there exists one record with the following
 * structure. Each actual item is represented by a record with the following
 * stuff at its beginning, plus additional type-specific stuff after that.
 */

#define TK_TAG_SPACE 3

typedef struct Tk_Item {

    int id;			/* Unique identifier for this item (also
				 * serves as first tag for item). */



    struct Tk_Item *nextPtr;	/* Next in display list of all items in this
				 * canvas. Later items in list are drawn on
				 * top of earlier ones. */
    Tk_Uid staticTagSpace[TK_TAG_SPACE];
				/* Built-in space for limited # of tags. */
    Tk_Uid *tagPtr;		/* Pointer to array of tags. Usually points to
				 * staticTagSpace, but may point to malloc-ed
				 * space if there are lots of tags. */

    int tagSpace;		/* Total amount of tag space available at
				 * tagPtr. */
    int numTags;		/* Number of tag slots actually used at
				 * *tagPtr. */



    struct Tk_ItemType *typePtr;/* Table of procedures that implement this
				 * type of item. */
    int x1, y1, x2, y2;		/* Bounding box for item, in integer canvas
				 * units. Set by item-specific code and
				 * guaranteed to contain every pixel drawn in
				 * item. Item area includes x1 and y1 but not
				 * x2 and y2. */
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108



1109
1110
1111
1112







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
#define TK_ITEM_DONT_REDRAW		2

/*
 * Records of the following type are used to describe a type of item (e.g.
 * lines, circles, etc.) that can form part of a canvas widget.
 */

#if defined(USE_OLD_CANVAS) && TCL_MAJOR_VERSION < 9
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv, int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, char *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, char *indexString, int *indexPtr);
#else
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[]);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const objv[],
		    int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, Tcl_Obj *const argv[]);
#if TCL_MAJOR_VERSION > 8
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t beforeThis, Tcl_Obj *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, size_t *indexPtr);
#else
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, Tcl_Obj *string);
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, int *indexPtr);
#endif
#endif /* USE_OLD_CANVAS */
typedef void	(Tk_ItemDeleteProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display);
typedef void	(Tk_ItemDisplayProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    Display *display, Drawable dst, int x, int y, int width,
		    int height);
typedef double	(Tk_ItemPointProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *pointPtr);
typedef int	(Tk_ItemAreaProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double *rectPtr);
typedef int	(Tk_ItemPostscriptProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int prepass);
typedef void	(Tk_ItemRotateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double angleRadians);
typedef void	(Tk_ItemScaleProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double originX, double originY, double scaleX,
		    double scaleY);
typedef void	(Tk_ItemTranslateProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    double deltaX, double deltaY);
#if TCL_MAJOR_VERSION > 8
typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t index);
typedef size_t	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t offset, char *buffer, size_t maxBytes);
typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    size_t first, size_t last);
#else



typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int index);
typedef int	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int offset, char *buffer, int maxBytes);







typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int first, int last);
#endif

#ifndef __NO_OLD_CONFIG

typedef struct Tk_ItemType {
    const char *name;		/* The name of this type of item, such as
				 * "line". */
#if TCL_MAJOR_VERSION > 8
    size_t itemSize;		/* Total amount of space needed for item's
				 * record. */
#else
    int itemSize;
#endif
    Tk_ItemCreateProc *createProc;
				/* Procedure to create a new item of this
				 * type. */
    const Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for
				 * this type. Used for returning configuration
				 * info. */
    Tk_ItemConfigureProc *configProc;
				/* Procedure to call to change configuration
				 * options. */
    Tk_ItemCoordProc *coordProc;/* Procedure to call to get and set the item's
				 * coordinates. */







|






<
<
<
<


|

|


|
<
<
<
<
<
<
<
<
<
<
<












<
<





|
|
<
|
<
<
<

>
>
>




>
>
>
>
>
>
>


<




|

<
|

<
<
<



|







999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012




1013
1014
1015
1016
1017
1018
1019
1020











1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032


1033
1034
1035
1036
1037
1038
1039

1040



1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057

1058
1059
1060
1061
1062
1063

1064
1065



1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
#define TK_ITEM_DONT_REDRAW		2

/*
 * Records of the following type are used to describe a type of item (e.g.
 * lines, circles, etc.) that can form part of a canvas widget.
 */

#ifdef USE_OLD_CANVAS
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv, int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int argc, char **argv);




#else
typedef int	(Tk_ItemCreateProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]);
typedef int	(Tk_ItemConfigureProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[],
		    int flags);
typedef int	(Tk_ItemCoordProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, int objc, Tcl_Obj *const objv[]);











#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_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);
#ifdef USE_OLD_CANVAS
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,

		    Tk_Item *itemPtr, char *indexString, int *indexPtr);



#else
typedef int	(Tk_ItemIndexProc)(Tcl_Interp *interp, Tk_Canvas canvas,
		    Tk_Item *itemPtr, Tcl_Obj *indexString, int *indexPtr);
#endif /* USE_OLD_CANVAS */
typedef void	(Tk_ItemCursorProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int index);
typedef int	(Tk_ItemSelectionProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int offset, char *buffer, int maxBytes);
#ifdef USE_OLD_CANVAS
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, char *string);
#else
typedef void	(Tk_ItemInsertProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int beforeThis, Tcl_Obj *string);
#endif /* USE_OLD_CANVAS */
typedef void	(Tk_ItemDCharsProc)(Tk_Canvas canvas, Tk_Item *itemPtr,
		    int first, int last);


#ifndef __NO_OLD_CONFIG

typedef struct Tk_ItemType {
    CONST86 char *name;		/* The name of this type of item, such as
				 * "line". */

    int itemSize;		/* Total amount of space needed for item's
				 * record. */



    Tk_ItemCreateProc *createProc;
				/* Procedure to create a new item of this
				 * type. */
    CONST86 Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for
				 * this type. Used for returning configuration
				 * info. */
    Tk_ItemConfigureProc *configProc;
				/* Procedure to call to change configuration
				 * options. */
    Tk_ItemCoordProc *coordProc;/* Procedure to call to get and set the item's
				 * coordinates. */
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
    Tk_ItemInsertProc *insertProc;
				/* Procedure to insert something into an
				 * item. */
    Tk_ItemDCharsProc *dCharsProc;
				/* Procedure to delete characters from an
				 * item. */
    struct Tk_ItemType *nextPtr;/* Used to link types together into a list. */
    Tk_ItemRotateProc *rotateProc;
				/* Procedure to rotate an item's coordinates
				 * about a point. */
    int reserved2;		/* Carefully compatible with */
    char *reserved3;		/* Jan Nijtmans dash patch */
    char *reserved4;
} Tk_ItemType;

/*
 * Flag (used in the alwaysRedraw field) to say whether an item supports







<
<
|







1105
1106
1107
1108
1109
1110
1111


1112
1113
1114
1115
1116
1117
1118
1119
    Tk_ItemInsertProc *insertProc;
				/* Procedure to insert something into an
				 * item. */
    Tk_ItemDCharsProc *dCharsProc;
				/* Procedure to delete characters from an
				 * item. */
    struct Tk_ItemType *nextPtr;/* Used to link types together into a list. */


    char *reserved1;		/* Reserved for future extension. */
    int reserved2;		/* Carefully compatible with */
    char *reserved3;		/* Jan Nijtmans dash patch */
    char *reserved4;
} Tk_ItemType;

/*
 * Flag (used in the alwaysRedraw field) to say whether an item supports
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
    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







<
|

|

<
<
<



<
|



<
<
<







1138
1139
1140
1141
1142
1143
1144

1145
1146
1147
1148



1149
1150
1151

1152
1153
1154
1155



1156
1157
1158
1159
1160
1161
1162
    int selBorderWidth;		/* Width of border around selection. Read-only
				 * to items. */
    XColor *selFgColorPtr;	/* Foreground color for selected text.
				 * Read-only to items. */
    Tk_Item *selItemPtr;	/* Pointer to selected item. NULL means
				 * selection isn't in this canvas. Writable by
				 * items. */

    int selectFirst;		/* Character index of first selected
				 * character. Writable by items. */
    int selectLast;		/* Character index of last selected character.
				 * Writable by items. */



    Tk_Item *anchorItemPtr;	/* Item corresponding to "selectAnchor": not
				 * necessarily selItemPtr. Read-only to
				 * items. */

    int selectAnchor;		/* Character index of fixed end of selection
				 * (i.e. "select to" operation will use this
				 * as one end of the selection). Writable by
				 * items. */



    Tk_3DBorder insertBorder;	/* Used to draw vertical bar for insertion
				 * cursor. Read-only to items. */
    int insertWidth;		/* Total width of insertion cursor. Read-only
				 * to items. */
    int insertBorderWidth;	/* Width of 3-D border around insert cursor.
				 * Read-only to items. */
    Tk_Item *focusItemPtr;	/* Item that currently has the input focus, or
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
 *
 * 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);







|

|


|
|







1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
 *
 * Procedure prototypes and structures used for managing images:
 *
 *----------------------------------------------------------------------
 */

typedef struct Tk_ImageType Tk_ImageType;
#ifdef USE_OLD_IMAGE
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc,
	char **argv, Tk_ImageType *typePtr, Tk_ImageMaster model,
	ClientData *clientDataPtr);
#else
typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, CONST86 char *name, int objc,
	Tcl_Obj *const objv[], CONST86 Tk_ImageType *typePtr, Tk_ImageMaster model,
	ClientData *clientDataPtr);
#endif /* USE_OLD_IMAGE */
typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData clientData);
typedef void (Tk_ImageDisplayProc) (ClientData clientData, Display *display,
	Drawable drawable, int imageX, int imageY, int width, int height,
	int drawableX, int drawableY);
typedef void (Tk_ImageFreeProc) (ClientData clientData, Display *display);
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
 * image, etc.). It provides information common to all images of that type,
 * such as the type name and a collection of procedures in the image manager
 * that respond to various events. Each image manager is represented by one of
 * these structures.
 */

struct Tk_ImageType {
    const char *name;		/* Name of image type. */
    Tk_ImageCreateProc *createProc;
				/* Procedure to call to create a new image of
				 * this type. */
    Tk_ImageGetProc *getProc;	/* Procedure to call the first time
				 * Tk_GetImage is called in a new way (new
				 * visual or screen). */
    Tk_ImageDisplayProc *displayProc;







|







1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
 * image, etc.). It provides information common to all images of that type,
 * such as the type name and a collection of procedures in the image manager
 * that respond to various events. Each image manager is represented by one of
 * these structures.
 */

struct Tk_ImageType {
    CONST86 char *name;		/* Name of image type. */
    Tk_ImageCreateProc *createProc;
				/* Procedure to call to create a new image of
				 * this type. */
    Tk_ImageGetProc *getProc;	/* Procedure to call the first time
				 * Tk_GetImage is called in a new way (new
				 * visual or screen). */
    Tk_ImageDisplayProc *displayProc;
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
/*
 * The following structure represents a particular file format for storing
 * images (e.g., PPM, GIF, JPEG, etc.). It provides information to allow image
 * files of that format to be recognized and read into a photo image.
 */

struct Tk_PhotoImageFormat {
    const char *name;		/* Name of image file format */
    Tk_ImageFileMatchProc *fileMatchProc;
				/* Procedure to call to determine whether an
				 * image file matches this format. */
    Tk_ImageStringMatchProc *stringMatchProc;
				/* Procedure to call to determine whether the
				 * data in a string matches this format. */
    Tk_ImageFileReadProc *fileReadProc;







|







1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
/*
 * The following structure represents a particular file format for storing
 * images (e.g., PPM, GIF, JPEG, etc.). It provides information to allow image
 * files of that format to be recognized and read into a photo image.
 */

struct Tk_PhotoImageFormat {
    CONST86 char *name;		/* Name of image file format */
    Tk_ImageFileMatchProc *fileMatchProc;
				/* Procedure to call to determine whether an
				 * image file matches this format. */
    Tk_ImageStringMatchProc *stringMatchProc;
				/* Procedure to call to determine whether the
				 * data in a string matches this format. */
    Tk_ImageFileReadProc *fileReadProc;
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
 * 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







<







1473
1474
1475
1476
1477
1478
1479

1480
1481
1482
1483
1484
1485
1486
 * The definitions below provide backward compatibility for functions and
 * types related to event handling that used to be in Tk but have moved to
 * Tcl.
 *
 *----------------------------------------------------------------------
 */


#define TK_READABLE		TCL_READABLE
#define TK_WRITABLE		TCL_WRITABLE
#define TK_EXCEPTION		TCL_EXCEPTION

#define TK_DONT_WAIT		TCL_DONT_WAIT
#define TK_X_EVENTS		TCL_WINDOW_EVENTS
#define TK_WINDOW_EVENTS	TCL_WINDOW_EVENTS
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593

/* 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, \







<







1506
1507
1508
1509
1510
1511
1512

1513
1514
1515
1516
1517
1518
1519

/* Additional stuff that has moved to Tcl: */

#define Tk_EventuallyFree	Tcl_EventuallyFree
#define Tk_FreeProc		Tcl_FreeProc
#define Tk_Preserve		Tcl_Preserve
#define Tk_Release		Tcl_Release


/* Removed Tk_Main, use macro instead */
#if defined(_WIN32) || defined(__CYGWIN__)
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
	(Tcl_FindExecutable(0), (Tcl_CreateInterp)()))
#else
#define Tk_Main(argc, argv, proc) Tk_MainEx(argc, argv, proc, \
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
 */

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







|



<
<
<
<


<







1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550




1551
1552

1553
1554
1555
1556
1557
1558
1559
 */

typedef int (Tk_ErrorProc) (ClientData clientData, XErrorEvent *errEventPtr);
typedef void (Tk_EventProc) (ClientData clientData, XEvent *eventPtr);
typedef int (Tk_GenericProc) (ClientData clientData, XEvent *eventPtr);
typedef int (Tk_ClientMessageProc) (Tk_Window tkwin, XEvent *eventPtr);
typedef int (Tk_GetSelProc) (ClientData clientData, Tcl_Interp *interp,
	CONST86 char *portion);
typedef void (Tk_LostSelProc) (ClientData clientData);
typedef Tk_RestrictAction (Tk_RestrictProc) (ClientData clientData,
	XEvent *eventPtr);




typedef int (Tk_SelectionProc) (ClientData clientData, int offset,
	char *buffer, int maxBytes);


/*
 *----------------------------------------------------------------------
 *
 * Platform independent exported procedures and variables.
 *
 *----------------------------------------------------------------------
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
#define Tk_CreatePhotoImageFormat	Tk_CreateOldPhotoImageFormat
#endif /* USE_OLD_IMAGE */

/*
 *----------------------------------------------------------------------
 *
 * Allow users to say that they don't want to alter their source to add extra
 * arguments to Tk_PhotoPutBlock() et al.
 *
 * This goes after the inclusion of the stubbed-decls so that the declarations
 * of what is actually there can be correct.
 */

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
#ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK
#   ifdef Tk_PhotoPutBlock
#	undef Tk_PhotoPutBlock
#   endif
#   define Tk_PhotoPutBlock		Tk_PhotoPutBlock_NoComposite
#   ifdef Tk_PhotoPutZoomedBlock
#	undef Tk_PhotoPutZoomedBlock







|





<







1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580

1581
1582
1583
1584
1585
1586
1587
#define Tk_CreatePhotoImageFormat	Tk_CreateOldPhotoImageFormat
#endif /* USE_OLD_IMAGE */

/*
 *----------------------------------------------------------------------
 *
 * Allow users to say that they don't want to alter their source to add extra
 * arguments to Tk_PhotoPutBlock() et al; DO NOT DEFINE THIS WHEN BUILDING TK.
 *
 * This goes after the inclusion of the stubbed-decls so that the declarations
 * of what is actually there can be correct.
 */


#ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK
#   ifdef Tk_PhotoPutBlock
#	undef Tk_PhotoPutBlock
#   endif
#   define Tk_PhotoPutBlock		Tk_PhotoPutBlock_NoComposite
#   ifdef Tk_PhotoPutZoomedBlock
#	undef Tk_PhotoPutZoomedBlock
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
#   endif
#   define Tk_PhotoExpand		Tk_PhotoExpand_Panic
#   ifdef Tk_PhotoSetSize
#	undef Tk_PhotoSetSize
#   endif
#   define Tk_PhotoSetSize		Tk_PhotoSetSize_Panic
#endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */
#endif /* !TK_NO_DEPRECATED */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* RC_INVOKED */

/*







<







1606
1607
1608
1609
1610
1611
1612

1613
1614
1615
1616
1617
1618
1619
#   endif
#   define Tk_PhotoExpand		Tk_PhotoExpand_Panic
#   ifdef Tk_PhotoSetSize
#	undef Tk_PhotoSetSize
#   endif
#   define Tk_PhotoSetSize		Tk_PhotoSetSize_Panic
#endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */


#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* RC_INVOKED */

/*
Changes to generic/tk3d.c.
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656

657
658
659
660
661
662
663
664
665
666
667
668

669
670

671
672

673
674

675
676
677
678

679
680



681
682
683
684
685
686
687
 * 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 --







|
<















>




|
|
<
|


|
|
>
|
|
>
|
|
>
|

>
|
|
|
|
>


>
>
>







633
634
635
636
637
638
639
640

641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662

663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
 * Tk_GetRelief --
 *
 *	Parse a relief description and return the corresponding relief value,
 *	or an error.
 *
 * Results:
 *	A standard Tcl return value. If all goes well then *reliefPtr is
 *	filled in with one of the values TK_RELIEF_*

 *
 * 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 --
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:
 */







|

|













1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
	if (borderPtr == NULL) {
	    Tcl_Panic("TkDebugBorder found empty hash table entry");
	}
	for ( ; (borderPtr != NULL); borderPtr = borderPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(borderPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(borderPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tk3d.h.
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 (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK3D
#define _TK3D
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
    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. */
    int resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_Alloc3DBorderFromObj or Tk_Get3DBorder).
				 * If this count is 0, then this structure is
				 * no longer valid and it isn't present in
				 * borderTable: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when objRefCount and
				 * resourceRefCount are both 0. */
    int objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    XColor *bgColorPtr;		/* Background color (intensity between
				 * lightColorPtr and darkColorPtr). */
    XColor *darkColorPtr;	/* Color for darker areas (must free when
				 * deleting structure). NULL means shadows
				 * haven't been allocated yet.*/
    XColor *lightColorPtr;	/* Color used for lighter areas of border
Changes to generic/tkArgv.c.
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
	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;







|







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 through the argument descriptors searching for one with the
	 * matching key string. If found, leave a pointer to it in matchPtr.
	 */

	matchPtr = NULL;
	for (i = 0; i < 2; i++) {
	    if (i == 0) {
		infoPtr = argTable;
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_FUNC: {
	    typedef int (ArgvFunc)(char *, const char *, const char *);
	    ArgvFunc *handlerProc = (ArgvFunc *)infoPtr->src;

	    if (handlerProc((char *)infoPtr->dst, infoPtr->key, argv[srcIndex])) {
		srcIndex++;
		argc--;
	    }
	    break;
	}
	case TK_ARGV_GENFUNC: {
	    typedef int (ArgvGenFunc)(char *, Tcl_Interp *, const char *, int,
		    const char **);
	    ArgvGenFunc *handlerProc = (ArgvGenFunc *)infoPtr->src;

	    argc = handlerProc((char *)infoPtr->dst, interp, infoPtr->key, argc,
		    argv+srcIndex);
	    if (argc < 0) {
		return TCL_ERROR;
	    }
	    break;
	}
	case TK_ARGV_HELP:
	    PrintUsage(interp, argTable, flags);
	    Tcl_SetErrorCode(interp, "TK", "ARG", "HELP", NULL);
	    return TCL_ERROR;
	case TK_ARGV_CONST_OPTION:
	    Tk_AddOption(tkwin, (char *)infoPtr->dst, (char *)infoPtr->src,
		    TK_INTERACTIVE_PRIO);
	    break;
	case TK_ARGV_OPTION_VALUE:
	    if (argc < 1) {
		goto missingArg;
	    }
	    Tk_AddOption(tkwin, (char *)infoPtr->dst, argv[srcIndex],
		    TK_INTERACTIVE_PRIO);
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_OPTION_NAME_VALUE:
	    if (argc < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|

|








|

|











|






|







224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
		return TCL_ERROR;
	    }
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_FUNC: {
	    typedef int (ArgvFunc)(char *, const char *, const char *);
	    ArgvFunc *handlerProc = (ArgvFunc *) infoPtr->src;

	    if (handlerProc(infoPtr->dst, infoPtr->key, argv[srcIndex])) {
		srcIndex++;
		argc--;
	    }
	    break;
	}
	case TK_ARGV_GENFUNC: {
	    typedef int (ArgvGenFunc)(char *, Tcl_Interp *, const char *, int,
		    const char **);
	    ArgvGenFunc *handlerProc = (ArgvGenFunc *) infoPtr->src;

	    argc = handlerProc(infoPtr->dst, interp, infoPtr->key, argc,
		    argv+srcIndex);
	    if (argc < 0) {
		return TCL_ERROR;
	    }
	    break;
	}
	case TK_ARGV_HELP:
	    PrintUsage(interp, argTable, flags);
	    Tcl_SetErrorCode(interp, "TK", "ARG", "HELP", NULL);
	    return TCL_ERROR;
	case TK_ARGV_CONST_OPTION:
	    Tk_AddOption(tkwin, infoPtr->dst, infoPtr->src,
		    TK_INTERACTIVE_PRIO);
	    break;
	case TK_ARGV_OPTION_VALUE:
	    if (argc < 1) {
		goto missingArg;
	    }
	    Tk_AddOption(tkwin, infoPtr->dst, argv[srcIndex],
		    TK_INTERACTIVE_PRIO);
	    srcIndex++;
	    argc--;
	    break;
	case TK_ARGV_OPTION_NAME_VALUE:
	    if (argc < 2) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
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 (c) 2018-2019 Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Note that this file will not be included in header files, it is the purpose
Changes to generic/tkAtom.c.
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
	Tcl_SetHashValue(hPtr, INT2PTR(atom));
	if (mustFree) {
	    XFree(mustFree);
	}
	name = (const char *)Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
	hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr, (char *)name);
    }
    return (const char *)Tcl_GetHashValue(hPtr);
}

/*
 *--------------------------------------------------------------
 *







|







152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
	hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
	Tcl_SetHashValue(hPtr, INT2PTR(atom));
	if (mustFree) {
	    XFree(mustFree);
	}
	name = (const char *)Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
	hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr, name);
    }
    return (const char *)Tcl_GetHashValue(hPtr);
}

/*
 *--------------------------------------------------------------
 *
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
	}

	name = atomNameArray[atom - 1];
	hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
	Tcl_SetHashValue(hPtr, INT2PTR(atom));
	name = (const char *)Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
	hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr, (char *)name);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|










198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
	}

	name = atomNameArray[atom - 1];
	hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew);
	Tcl_SetHashValue(hPtr, INT2PTR(atom));
	name = (const char *)Tcl_GetHashKey(&dispPtr->nameTable, hPtr);
	hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew);
	Tcl_SetHashValue(hPtr, name);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkBind.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
 * 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 (c) 1989-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998 Scriptics Corporation.
 * Copyright (c) 2018-2019 Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkDList.h"
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

#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.
 *
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
 */

/*
 * In old implementation (the one that used an event ring), <Double-1> and <1><1> were
 * equivalent sequences. However it is logical to give <Double-1> higher precedence
 * since it is more specific. Indeed <Double-1> includes time and space requirements,
 * which is not the case for <1><1>.
 * This is achieved by setting PREFER_MOST_SPECIALIZED_EVENT to 1.
 */

#ifndef PREFER_MOST_SPECIALIZED_EVENT
# define PREFER_MOST_SPECIALIZED_EVENT 1
#endif

/*
 * Traditionally motion events can be combined with buttons in this way: <B1-B2-Motion>.
 * However it should be allowed to express this as <Motion-1-2> in addition. This is achieved
 * by setting SUPPORT_ADDITIONAL_MOTION_SYNTAX to 1.
 */

#ifndef SUPPORT_ADDITIONAL_MOTION_SYNTAX
# define SUPPORT_ADDITIONAL_MOTION_SYNTAX 1
#endif

/*
 * The output for motion events is of the type <B1-Motion>. This can be changed to become
 * <Motion-1> instead by setting PRINT_SHORT_MOTION_SYNTAX to 1, however this would be a
 * backwards incompatibility.
 */







|



|




|
|



|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
 */

/*
 * In old implementation (the one that used an event ring), <Double-1> and <1><1> were
 * equivalent sequences. However it is logical to give <Double-1> higher precedence
 * since it is more specific. Indeed <Double-1> includes time and space requirements,
 * which is not the case for <1><1>.
 * This can be achieved by setting PREFER_MOST_SPECIALIZED_EVENT to 1.
 */

#ifndef PREFER_MOST_SPECIALIZED_EVENT
# define PREFER_MOST_SPECIALIZED_EVENT 0
#endif

/*
 * Traditionally motion events can be combined with buttons in this way: <B1-B2-Motion>.
 * However it should be allowed to express this as <Motion-1-2> in addition. This can be
 * achieved by setting SUPPORT_ADDITIONAL_MOTION_SYNTAX to 1.
 */

#ifndef SUPPORT_ADDITIONAL_MOTION_SYNTAX
# define SUPPORT_ADDITIONAL_MOTION_SYNTAX 0 /* set to 1 if wanted */
#endif

/*
 * The output for motion events is of the type <B1-Motion>. This can be changed to become
 * <Motion-1> instead by setting PRINT_SHORT_MOTION_SYNTAX to 1, however this would be a
 * backwards incompatibility.
 */
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153

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

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








|







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

/*
 * Flags for ModInfo structures:
 *
 * DOUBLE -		Non-zero means duplicate this event, e.g. for double-clicks.
 * TRIPLE -		Non-zero means triplicate this event, e.g. for triple-clicks.
 * QUADRUPLE -		Non-zero means quadruple this event, e.g. for 4-fold-clicks.
 * MULT_CLICKS -	Combination of all the above.
 */

#define DOUBLE		(1<<0)
#define TRIPLE		(1<<1)
#define QUADRUPLE	(1<<2)
#define MULT_CLICKS	(DOUBLE|TRIPLE|QUADRUPLE)

441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
    {"Button2",		Button2Mask,	0},
    {"B3",		Button3Mask,	0},
    {"Button3",		Button3Mask,	0},
    {"B4",		Button4Mask,	0},
    {"Button4",		Button4Mask,	0},
    {"B5",		Button5Mask,	0},
    {"Button5",		Button5Mask,	0},
    {"B6",		Button6Mask,	0},
    {"Button6",		Button6Mask,	0},
    {"B7",		Button7Mask,	0},
    {"Button7",		Button7Mask,	0},
    {"B8",		Button8Mask,	0},
    {"Button8",		Button8Mask,	0},
    {"B9",		Button9Mask,	0},
    {"Button9",		Button9Mask,	0},
    {"Mod1",		Mod1Mask,	0},
    {"M1",		Mod1Mask,	0},
    {"Command",		Mod1Mask,	0},
    {"Mod2",		Mod2Mask,	0},
    {"M2",		Mod2Mask,	0},
    {"Option",		Mod2Mask,	0},
    {"Mod3",		Mod3Mask,	0},







<
<
<
<
<
<
<
<







433
434
435
436
437
438
439








440
441
442
443
444
445
446
    {"Button2",		Button2Mask,	0},
    {"B3",		Button3Mask,	0},
    {"Button3",		Button3Mask,	0},
    {"B4",		Button4Mask,	0},
    {"Button4",		Button4Mask,	0},
    {"B5",		Button5Mask,	0},
    {"Button5",		Button5Mask,	0},








    {"Mod1",		Mod1Mask,	0},
    {"M1",		Mod1Mask,	0},
    {"Command",		Mod1Mask,	0},
    {"Mod2",		Mod2Mask,	0},
    {"M2",		Mod2Mask,	0},
    {"Option",		Mod2Mask,	0},
    {"Mod3",		Mod3Mask,	0},
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
#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







|







544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
#define	MAPREQ			(1<<20)
#define	CONFIGREQ		(1<<21)
#define	RESIZEREQ		(1<<22)
#define CIRCREQ			(1<<23)

/*
 * These structs agree with xkey for the fields type, serial, send_event, display,
 * window, root, subwindow, time, x, y, x_root, and y_root. So when accessing
 * these fields we may pretend that we are using a struct xkey.
 */

#define HAS_XKEY_HEAD (KEY|BUTTON|MOTION|VIRTUAL|CROSSING|WHEEL)

/*
 * The xcrossing struct puts the state field in a different location, but the other
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
			    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)







|












|




>


|
|













|
|











|
|







693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
			    char *virtString, const char *eventString);
static int		DeleteVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    char *virtString, const char *eventString);
static void		DeleteVirtualEventTable(VirtualEventTable *vetPtr);
static void		ExpandPercents(TkWindow *winPtr, const char *before, Event *eventPtr,
			    unsigned scriptCount, Tcl_DString *dsPtr);
static PatSeq *		FindSequence(Tcl_Interp *interp, LookupTables *lookupTables,
			    void *object, const char *eventString, int create,
			    int allowVirtual, unsigned *maskPtr);
static void		GetAllVirtualEvents(Tcl_Interp *interp, VirtualEventTable *vetPtr);
static const char *	GetField(const char *p, char *copy, unsigned size);
static Tcl_Obj *	GetPatternObj(const PatSeq *psPtr);
static int		GetVirtualEvent(Tcl_Interp *interp, VirtualEventTable *vetPtr,
			    Tcl_Obj *virtName);
static Tk_Uid		GetVirtualEventUid(Tcl_Interp *interp, char *virtString);
static int		HandleEventGenerate(Tcl_Interp *interp, Tk_Window main,
			    int objc, Tcl_Obj *const objv[]);
static void		InitVirtualEventTable(VirtualEventTable *vetPtr);
static PatSeq *		MatchPatterns(TkDisplay *dispPtr, Tk_BindingTable bindPtr, PSList *psList,
			    PSList *psSuccList, unsigned patIndex, const Event *eventPtr,
			    void *object, PatSeq **physPtrPtr);
static int		NameToWindow(Tcl_Interp *interp, Tk_Window main,
			    Tcl_Obj *objPtr, Tk_Window *tkwinPtr);
static unsigned		ParseEventDescription(Tcl_Interp *interp, const char **eventStringPtr,
			    TkPattern *patPtr, unsigned *eventMaskPtr);
static void		DoWarp(void *clientData);
static PSList *		GetLookupForEvent(LookupTables* lookupPtr, const Event *eventPtr,
			    Tcl_Obj *object, int onlyConsiderDetailedEvents);
static void		ClearLookupTable(LookupTables *lookupTables, 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 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,	/* Is this a subset... */
    unsigned rhsMask)	/* ...of this bit field? */
{
    return (lhsMask & rhsMask) == lhsMask;
}

static const char*
SkipSpaces(
    const char* s)
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804

805
806
807
808
809
810
811
    return s;
}

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

static Time
CurrentTimeInMilliSecs(void)
{
    Tcl_Time now;

    Tcl_GetTime(&now);
    return ((Time) now.sec)*1000 + ((Time) now.usec)/1000;
}

static Info
GetInfo(
    const PatSeq *psPtr,







<

|
<






>







773
774
775
776
777
778
779

780
781

782
783
784
785
786
787
788
789
790
791
792
793
794
795
    return s;
}

static unsigned
GetButtonNumber(
    const char *field)
{

    assert(field);
    return (field[0] >= '1' && field[0] <= '5' && field[1] == '\0') ? field[0] - '0' : 0;

}

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







|

|




|








|
|















|
|







830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
    for (i = 0; i < sndMatchPtr->numPats; ++i) {
	if (GetInfo(sndMatchPtr, i)) { sndCount += GetCount(sndMatchPtr, i); }
    }

    return sndCount - fstCount;
}

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;







|







909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
    PSList_Append(pool, psEntry);
}

static void
ClearList(
    PSList *psList,
    PSList *pool,
    void *object)
{
    assert(psList);
    assert(pool);

    if (object) {
	PSEntry *psEntry;
	PSEntry *psNext;
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
    unsigned state)
{
    if (!(state & ALL_BUTTONS)) { return 0; }
    if (state & Button1Mask) { return 1; }
    if (state & Button2Mask) { return 2; }
    if (state & Button3Mask) { return 3; }
    if (state & Button4Mask) { return 4; }
    if (state & Button5Mask) { return 5; }
    if (state & Button6Mask) { return 6; }
    if (state & Button7Mask) { return 7; }
    if (state & Button8Mask) { return 8; }
    return 9;
}

static void
SetupPatternKey(
    PatternTableKey *key,
    const PatSeq *psPtr)
{







<
<
<
<
|







973
974
975
976
977
978
979




980
981
982
983
984
985
986
987
    unsigned state)
{
    if (!(state & ALL_BUTTONS)) { return 0; }
    if (state & Button1Mask) { return 1; }
    if (state & Button2Mask) { return 2; }
    if (state & Button3Mask) { return 3; }
    if (state & Button4Mask) { return 4; }




    return 5;
}

static void
SetupPatternKey(
    PatternTableKey *key,
    const PatSeq *psPtr)
{
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
{
    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;







|







1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
{
    PatternTableKey key;
    Tcl_HashEntry *hPtr;

    assert(lookupTables);
    assert(eventPtr);

    /* Otherwise on some systems the key contains uninitialized bytes. */
    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);







|







1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
 *	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)) {







|

|
<







1183
1184
1185
1186
1187
1188
1189
1190
1191
1192

1193
1194
1195
1196
1197
1198
1199
 *
 *--------------------------------------------------------------
 */

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
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
 * Side effects:
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

/*
 * Windoze compiler does not allow the definition of these static variables inside a function,
 * otherwise this should belong to function TkBindInit().
 */
TCL_DECLARE_MUTEX(bindMutex);
static int initialized = 0;

void
TkBindInit(
    TkMainInfo *mainPtr)	/* The newly created application. */
{
    BindInfo *bindInfoPtr;

    assert(mainPtr);

    /* otherwise virtual events can't be supported */
    assert(sizeof(XEvent) >= sizeof(XVirtualEvent));

    /* type of TkPattern.info is well defined? */
    assert(sizeof(Info) >= sizeof(KeySym));
    assert(sizeof(Info) >= sizeof(unsigned));

    /* ensure that our matching algorithm is working (when testing detail) */
    assert(sizeof(Detail) == sizeof(Tk_Uid));

    /* test expected indices of Button1..Button5, otherwise our button handling is not working */
    assert(Button1 == 1 && Button2 == 2 && Button3 == 3 && Button4 == 4 && Button5 == 5);
    assert(Button2Mask == (Button1Mask << 1));
    assert(Button3Mask == (Button1Mask << 2));
    assert(Button4Mask == (Button1Mask << 3));
    assert(Button5Mask == (Button1Mask << 4));

    /* test expected values of button motion masks, otherwise our button handling is not working */
    assert(Button1MotionMask == Button1Mask);
    assert(Button2MotionMask == Button2Mask);
    assert(Button3MotionMask == Button3Mask);
    assert(Button4MotionMask == Button4Mask);
    assert(Button5MotionMask == Button5Mask);

    /* because we expect zero if keySym is empty */
    assert(NoSymbol == 0L);

    /* this must be a union, not a struct, otherwise comparison with NULL will not work */
    assert(offsetof(Detail, name) == offsetof(Detail, info));

    /* we use some constraints about X*Event */
    assert(offsetof(XButtonEvent, time) == offsetof(XMotionEvent, time));
    assert(offsetof(XButtonEvent, x_root) == offsetof(XMotionEvent, x_root));
    assert(offsetof(XButtonEvent, y_root) == offsetof(XMotionEvent, y_root));
    assert(offsetof(XCreateWindowEvent, border_width) == offsetof(XConfigureEvent, border_width));
    assert(offsetof(XCreateWindowEvent, width) == offsetof(XConfigureEvent, width));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XCirculateRequestEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XConfigureEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XGravityEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XMapEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XReparentEvent, window));
    assert(offsetof(XCreateWindowEvent, window) == offsetof(XUnmapEvent, window));
    assert(offsetof(XCreateWindowEvent, x) == offsetof(XConfigureEvent, x));
    assert(offsetof(XCreateWindowEvent, x) == offsetof(XGravityEvent, x));
    assert(offsetof(XCreateWindowEvent, y) == offsetof(XConfigureEvent, y));
    assert(offsetof(XCreateWindowEvent, y) == offsetof(XGravityEvent, y));
    assert(offsetof(XCrossingEvent, time) == offsetof(XEnterWindowEvent, time));
    assert(offsetof(XCrossingEvent, time) == offsetof(XLeaveWindowEvent, time));
    assert(offsetof(XCrossingEvent, time) == offsetof(XKeyEvent, time));
    assert(offsetof(XKeyEvent, root) == offsetof(XButtonEvent, root));
    assert(offsetof(XKeyEvent, root) == offsetof(XCrossingEvent, root));
    assert(offsetof(XKeyEvent, root) == offsetof(XMotionEvent, root));
    assert(offsetof(XKeyEvent, state) == offsetof(XButtonEvent, state));
    assert(offsetof(XKeyEvent, state) == offsetof(XMotionEvent, state));
    assert(offsetof(XKeyEvent, subwindow) == offsetof(XButtonEvent, subwindow));
    assert(offsetof(XKeyEvent, subwindow) == offsetof(XCrossingEvent, subwindow));
    assert(offsetof(XKeyEvent, subwindow) == offsetof(XMotionEvent, subwindow));
    assert(offsetof(XKeyEvent, time) == offsetof(XButtonEvent, time));
    assert(offsetof(XKeyEvent, time) == offsetof(XMotionEvent, time));
    assert(offsetof(XKeyEvent, x) == offsetof(XButtonEvent, x));
    assert(offsetof(XKeyEvent, x) == offsetof(XCrossingEvent, x));
    assert(offsetof(XKeyEvent, x) == offsetof(XMotionEvent, x));
    assert(offsetof(XKeyEvent, x_root) == offsetof(XButtonEvent, x_root));
    assert(offsetof(XKeyEvent, x_root) == offsetof(XCrossingEvent, x_root));
    assert(offsetof(XKeyEvent, x_root) == offsetof(XMotionEvent, x_root));
    assert(offsetof(XKeyEvent, y) == offsetof(XButtonEvent, y));
    assert(offsetof(XKeyEvent, y) == offsetof(XCrossingEvent, y));
    assert(offsetof(XKeyEvent, y) == offsetof(XMotionEvent, y));
    assert(offsetof(XKeyEvent, y_root) == offsetof(XButtonEvent, y_root));
    assert(offsetof(XKeyEvent, y_root) == offsetof(XCrossingEvent, y_root));
    assert(offsetof(XKeyEvent, y_root) == offsetof(XMotionEvent, y_root));

    /*
     * Initialize the static data structures used by the binding package. They
     * are only initialized once, no matter how many interps are created.
     */

    if (!initialized) {







|













|


|



|


|






|






|


|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
 * Side effects:
 *	Memory allocated.
 *
 *---------------------------------------------------------------------------
 */

/*
 * 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(Tk_Offset(Detail, name) == Tk_Offset(Detail, info));

    /* We use some constraints about X*Event. */
    assert(Tk_Offset(XButtonEvent, time) == Tk_Offset(XMotionEvent, time));
    assert(Tk_Offset(XButtonEvent, x_root) == Tk_Offset(XMotionEvent, x_root));
    assert(Tk_Offset(XButtonEvent, y_root) == Tk_Offset(XMotionEvent, y_root));
    assert(Tk_Offset(XCreateWindowEvent, border_width) == Tk_Offset(XConfigureEvent, border_width));
    assert(Tk_Offset(XCreateWindowEvent, width) == Tk_Offset(XConfigureEvent, width));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XCirculateRequestEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XConfigureEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XGravityEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XMapEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XReparentEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, window) == Tk_Offset(XUnmapEvent, window));
    assert(Tk_Offset(XCreateWindowEvent, x) == Tk_Offset(XConfigureEvent, x));
    assert(Tk_Offset(XCreateWindowEvent, x) == Tk_Offset(XGravityEvent, x));
    assert(Tk_Offset(XCreateWindowEvent, y) == Tk_Offset(XConfigureEvent, y));
    assert(Tk_Offset(XCreateWindowEvent, y) == Tk_Offset(XGravityEvent, y));
    assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XEnterWindowEvent, time));
    assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XLeaveWindowEvent, time));
    assert(Tk_Offset(XCrossingEvent, time) == Tk_Offset(XKeyEvent, time));
    assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XButtonEvent, root));
    assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XCrossingEvent, root));
    assert(Tk_Offset(XKeyEvent, root) == Tk_Offset(XMotionEvent, root));
    assert(Tk_Offset(XKeyEvent, state) == Tk_Offset(XButtonEvent, state));
    assert(Tk_Offset(XKeyEvent, state) == Tk_Offset(XMotionEvent, state));
    assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XButtonEvent, subwindow));
    assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XCrossingEvent, subwindow));
    assert(Tk_Offset(XKeyEvent, subwindow) == Tk_Offset(XMotionEvent, subwindow));
    assert(Tk_Offset(XKeyEvent, time) == Tk_Offset(XButtonEvent, time));
    assert(Tk_Offset(XKeyEvent, time) == Tk_Offset(XMotionEvent, time));
    assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XButtonEvent, x));
    assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XCrossingEvent, x));
    assert(Tk_Offset(XKeyEvent, x) == Tk_Offset(XMotionEvent, x));
    assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XButtonEvent, x_root));
    assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XCrossingEvent, x_root));
    assert(Tk_Offset(XKeyEvent, x_root) == Tk_Offset(XMotionEvent, x_root));
    assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XButtonEvent, y));
    assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XCrossingEvent, y));
    assert(Tk_Offset(XKeyEvent, y) == Tk_Offset(XMotionEvent, y));
    assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XButtonEvent, y_root));
    assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XCrossingEvent, y_root));
    assert(Tk_Offset(XKeyEvent, y_root) == Tk_Offset(XMotionEvent, y_root));

    /*
     * Initialize the static data structures used by the binding package. They
     * are only initialized once, no matter how many interps are created.
     */

    if (!initialized) {
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
 *--------------------------------------------------------------
 */

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







|







1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
 *--------------------------------------------------------------
 */

unsigned long
Tk_CreateBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to create binding. */
    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);







|







1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
 *--------------------------------------------------------------
 */

int
Tk_DeleteBinding(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to delete binding. */
    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);







|







1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
 *--------------------------------------------------------------
 */

const char *
Tk_GetBinding(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_BindingTable bindPtr,	/* Table in which to look for binding. */
    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))) {







|







1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
 *--------------------------------------------------------------
 */

void
Tk_GetAllBindings(
    Tcl_Interp *interp,		/* Interpreter returning result or error. */
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    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;







|







1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
 */

static void
RemovePatSeqFromPromotionLists(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr)		/* Remove this pattern sequence. */
{
    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);







|







2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
 *
 *--------------------------------------------------------------
 */

void
Tk_DeleteAllBindings(
    Tk_BindingTable bindPtr,	/* Table in which to delete bindings. */
    void *object)		/* Token for object. */
{
    PatSeq *psPtr;
    PatSeq *nextPtr;
    Tcl_HashEntry *hPtr;

    assert(bindPtr);
    assert(object);
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
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;







|







2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
void
Tk_BindEvent(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    XEvent *eventPtr,		/* What actually happened. */
    Tk_Window tkwin,		/* Window on display where event occurred (needed in order to
    				 * locate display information). */
    int numObjects,		/* Number of objects at *objArr. */
    void **objArr)		/* Array of one or more objects to check for a matching binding. */
{
    Tcl_Interp *interp;
    ScreenInfo *screenPtr;
    TkDisplay *dispPtr;
    TkDisplay *oldDispPtr;
    Event *curEvent;
    TkWindow *winPtr = (TkWindow *)tkwin;
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229

2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
    }

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







<
<
<
<
<
<
<
|
>









<
<
<
<
<
<
<
<
<









|






|









|







2194
2195
2196
2197
2198
2199
2200







2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211









2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
    }

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    bindInfoPtr = winPtr->mainPtr->bindInfo;
    curEvent = bindPtr->eventInfo + eventPtr->type;

    /*







     * 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 < (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) {
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
    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);







|







2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
    bindPtr->curEvent = curEvent;
    physTables = &bindPtr->lookupTables;
    scriptCount = 0;
    arraySize = 0;
    Tcl_DStringInit(&scripts);

    if ((size_t) numObjects > SIZE_OF_ARRAY(matchPtrBuf)) {
	/* It's unrealistic that the buffer size is too small, but who knows? */
	matchPtrArr = (PatSeq **)ckalloc(numObjects*sizeof(matchPtrArr[0]));
    }
    memset(matchPtrArr, 0, numObjects*sizeof(matchPtrArr[0]));

    if (!PromArr_IsEmpty(bindPtr->promArr)) {
	for (k = 0; k < (unsigned) numObjects; ++k) {
	    psl[1] = PromArr_Last(bindPtr->promArr);
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
	     * 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);
		}
	    }
	}
    }

    /*







|



|







2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
	     * usually this list only contains one or two patterns.
	     */

	    for (i = PromArr_Size(bindPtr->promArr); i > 0; --i, --psl[0], --psl[1]) {
		psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psl[1], i, curEvent, objArr[k], NULL);

		if (IsBetterMatch(matchPtrArr[k], psPtr[0])) {
		    /* We will process it later, because we still may find a pattern with better match. */
		    matchPtrArr[k] = psPtr[0];
		}
		if (!PSList_IsEmpty(psl[1])) {
		    /* We have promoted sequences, adjust array size. */
		    arraySize = Max(i + 1, arraySize);
		}
	    }
	}
    }

    /*
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436

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







|







2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400

	assert(psl[0] == NULL || psl[0] != psl[1]);

	psPtr[0] = MatchPatterns(dispPtr, bindPtr, psl[0], psSuccList, 0, curEvent, objArr[k], NULL);
	psPtr[1] = MatchPatterns(dispPtr, bindPtr, psl[1], psSuccList, 0, curEvent, objArr[k], NULL);

	if (!PSList_IsEmpty(psSuccList)) {
	    /* We have promoted sequences, adjust array size. */
	    arraySize = Max(1u, arraySize);
	}

	bestPtr = psPtr[0] ? psPtr[0] : psPtr[1];

	if (matchPtrArr[k]) {
	    if (IsBetterMatch(matchPtrArr[k], bestPtr)) {
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
		    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);

    /*







|







2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
		    matchPtrArr[k] = matchPtr;
		}
	    }
	}

	if (matchPtrArr[k]) {
	    ExpandPercents(winPtr, matchPtrArr[k]->script, curEvent, scriptCount++, &scripts);
	    /* Null is added to the scripts string to separate the various scripts. */
	    Tcl_DStringAppend(&scripts, "", 1);
	}
    }

    PromArr_SetSize(bindPtr->promArr, arraySize);

    /*
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
		    }
		    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:







|











|







2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
		    }
		    break;
		}
	    }
	}

	if (!PSList_IsEmpty(psList)) {
	    /* We still have promoted sequences, adjust array size. */
	    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);








|







2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
     * something that destroys ".", bindInfoPtr would have been freed, but we
     * can tell that by first checking to see if winPtr->mainPtr == NULL.
     */

    Tcl_Preserve(bindInfoPtr);

    for (p = Tcl_DStringValue(&scripts), end = p + Tcl_DStringLength(&scripts); p < end; ) {
	size_t len = strlen(p);
	int code;

	if (!bindInfoPtr->deleted) {
	    ++screenPtr->bindingDepth;
	}
	Tcl_AllowExceptions(interp);

2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
 */

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







|


















|




|







2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
 */

/* helper function */
static int
VirtPatIsBound(
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PatSeq *psPtr,		/* Test this pattern. */
    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;







|







2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
    return 0;
}

/* helper function */
static int
Compare(
    const PatSeq *fstMatchPtr,
    const PatSeq *sndMatchPtr) /* Most recent match. */
{
    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
    /* 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;







>
>
>
>
>
>
>
>
>
>
>
>
>
>










|







2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
    /* Finally compare modifier masks of last pattern. */

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

    return fstCount - sndCount;
}

/* helper function */
static int
IsPSInPSList(
    const PatSeq *psPtr,   /* Is this pattern sequence... */
    const PSList *psList)  /* ...an element of this list of patterns sequence? */
{
    PSEntry *psEntry;

    TK_DLIST_FOREACH(psEntry, psList) {
        if (psEntry->psPtr == psPtr) { return 1; }
    }
    return 0;
}

static PatSeq *
MatchPatterns(
    TkDisplay *dispPtr,		/* Display from which the event came. */
    Tk_BindingTable bindPtr,	/* Table in which to look for bindings. */
    PSList *psList,		/* List of potentially matching patterns, can be NULL. */
    PSList *psSuccList,		/* Add all matching higher-level pattern sequences to this list.
    				 * Can be NULL. */
    unsigned patIndex,		/* Match only this tag in sequence. */
    const Event *curEvent,	/* Match this event. */
    void *object,		/* Check for this binding tag. */
    PatSeq **physPtrPtr)	/* Input: the best physical event; NULL if we test physical events.
    				 * Output: the associated physical event for the best matching virtual
				 * event; NULL when we match physical events. */
{
    Window window;
    PSEntry *psEntry;
    PatSeq *bestPtr;
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
	    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) {







|


















|
|















|







2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
	    assert(psPtr->numPats > patIndex);

	    if (psPtr->object
		    ? psPtr->object == object
		    : VirtPatIsBound(bindPtr, psPtr, object, physPtrPtr)) {
		TkPattern *patPtr = psPtr->pats + patIndex;

                /* Ignore modifier key events, and KeyRelease events if the current event
                 * 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 */








			    }
			}
		    }
		}
	    }
	}
    }







|



|
>


>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>







2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
				    bestModMaskArr = psEntry->lastModMaskArr;
				    if (physPtrPtr) {
					bestPhysPtr = *physPtrPtr;
				    }
				}
			    } else {
				DEBUG(psEntry->expired = 0;)
				psEntry->keepIt = 1; /* Don't remove it from promotion list. */
			    }
			} 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. */
			    }
			}
		    }
		}
	    }
	}
    }
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;








|











|
>
>
>
>
>
|
>
>
>
>
>









<
<
<
<
<
<
<
<
<
<







3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354










3355
3356
3357
3358
3359
3360
3361
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

int
Tk_EventObjCmd(
    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) {







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
	for (i = 3; i < objc; ++i) {
	    event = Tcl_GetString(objv[i]);
	    if (!CreateVirtualEvent(interp, vetPtr, name, event)) {
		return TCL_ERROR;
	    }
	}
	break;
#if SUPPORT_DEBUGGING
    case EVENT_DEBUG:
	if (objc > 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "debug number");
	    return TCL_ERROR;
	}
	if (objc < 3) {
	    Tcl_SetObjResult(interp,
		Tcl_NewIntObj(BindCount));
	    return TCL_OK;
	}
	if (Tcl_GetIntFromObj(interp, objv[2], &BindCount) != TCL_OK) {
	    return TCL_ERROR;
	}
	return TCL_OK;
#endif
    case EVENT_DELETE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "virtual ?sequence ...?");
	    return TCL_ERROR;
	}
	name = Tcl_GetString(objv[2]);
	if (objc == 3) {
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
    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));








|







3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
    assert(eventString);

    if (!(virtUid = GetVirtualEventUid(interp, virtString))) {
	return 0;
    }

    /*
     * Find/create physical event.
     */

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







|







3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667

	assert(TEST_PSENTRY(psPtr));

	if (!eventPSPtr || psPtr == eventPSPtr) {
	    VirtOwners *owners = psPtr->ptr.owners;
	    int iVirt = VirtOwners_Find(owners, vhPtr);

	    assert(iVirt != -1); /* Otherwise we couldn't find owner, and this should not happen. */

	    /*
	     * Remove association between this physical event and the given
	     * virtual event that it triggers.
	     */

	    if (VirtOwners_Size(owners) > 1) {
3971
3972
3973
3974
3975
3976
3977




3978

3979
3980
3981
3982
3983
3984
3985

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







>
>
>
>

>







3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994

    synch = 1;
    warp = 0;
    pos = TCL_QUEUE_TAIL;

    for (i = 2; i < (unsigned) objc; i += 2) {
	Tcl_Obj *optionPtr, *valuePtr;
#if defined(_MSC_VER)
        /* Work around MSVC compiler optimization bug, see [d93c8175fd]. */
	volatile int badOpt = 0;
#else
	int badOpt = 0;
#endif
	int index;

	optionPtr = objv[i];
	valuePtr = objv[i + 1];

	if (Tcl_GetIndexFromObjStruct(interp, optionPtr, fieldStrings,
		sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) {
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
	    }
	    break;
	case EVENT_BUTTON:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & BUTTON) {
		if (number >= Button4) {
		    number += (Button8 - Button4);
		}
		event.general.xbutton.button = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_COUNT:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {







<
<
<







4045
4046
4047
4048
4049
4050
4051



4052
4053
4054
4055
4056
4057
4058
	    }
	    break;
	case EVENT_BUTTON:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (flags & BUTTON) {



		event.general.xbutton.button = number;
	    } else {
		badOpt = 1;
	    }
	    break;
	case EVENT_COUNT:
	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
4414
4415
4416
4417
4418
4419
4420
4421
4422
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
		}
		dispPtr->warpWindow = warpWindow;
	    }
	    dispPtr->warpMainwin = mainWin;
	    dispPtr->warpX = event.general.xmotion.x;
	    dispPtr->warpY = event.general.xmotion.y;

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

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

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








<
<
<
<
<
<
<
<
|
<
|
|
|







4420
4421
4422
4423
4424
4425
4426








4427

4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
		}
		dispPtr->warpWindow = warpWindow;
	    }
	    dispPtr->warpMainwin = mainWin;
	    dispPtr->warpX = event.general.xmotion.x;
	    dispPtr->warpY = event.general.xmotion.y;









	    if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {

		Tcl_DoWhenIdle(DoWarp, dispPtr);
		dispPtr->flags |= TK_DISPLAY_IN_WARP;
	    }
	}

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

4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
4547
4548


4549
4550

4551
4552
4553
4554


4555
4556
4557

4558
4559
4560
4561
4562
4563
4564
    *tkwinPtr = tkwin;
    return 1;
}

/*
 *-------------------------------------------------------------------------
 *
 * TkDoWarpWrtWin --
 *
 *	Perform warping of mouse pointer with respect to a window.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Mouse pointer moves to a new location.
 *
 *-------------------------------------------------------------------------
 */

void
TkDoWarpWrtWin(
    TkDisplay *dispPtr)
{
    assert(dispPtr);

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

    if (dispPtr->warpWindow) {

        /*
         * Warping with respect to a window can only be done if the window is
         * mapped. This was checked in HandleEvent. The window needs to be
         * still mapped at the time the present code is executed. Also
         * one needs to guard against window destruction in the meantime,
         * which could have happened as a side effect of an event handler.


         */


        if (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None) {
            TkpWarpPointer(dispPtr);
            XForceScreenSaver(dispPtr->display, ScreenSaverReset);
        }


        Tcl_Release(dispPtr->warpWindow);
        dispPtr->warpWindow = NULL;
    }

}

/*
 *-------------------------------------------------------------------------
 *
 * GetVirtualEventUid --
 *







|

|










|
|
|

|

<
<
<
<
|
<

|
|
<
|
|
<
>
>
|

>
|
|
|
|
>
>
|
|

>







4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532




4533

4534
4535
4536

4537
4538

4539
4540
4541
4542
4543
4544
4545
4546
4547
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558
4559
4560
    *tkwinPtr = tkwin;
    return 1;
}

/*
 *-------------------------------------------------------------------------
 *
 * DoWarp --
 *
 *	Perform warping of mouse pointer. Executed as an idle handler only.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	Mouse pointer moves to a new location.
 *
 *-------------------------------------------------------------------------
 */

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





    assert(clientData);


    /*
     * DoWarp was scheduled only if the window was mapped. It needs to be

     * still mapped at the time the present idle callback is executed. Also
     * one needs to guard against window destruction in the meantime.

     * Finally, the case warpWindow == NULL is special in that it means
     * the whole screen.
     */

    if (!dispPtr->warpWindow ||
            (Tk_IsMapped(dispPtr->warpWindow) && Tk_WindowId(dispPtr->warpWindow) != None)) {
        TkpWarpPointer(dispPtr);
        XForceScreenSaver(dispPtr->display, ScreenSaverReset);
    }

    if (dispPtr->warpWindow) {
	Tcl_Release(dispPtr->warpWindow);
	dispPtr->warpWindow = NULL;
    }
    dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
}

/*
 *-------------------------------------------------------------------------
 *
 * GetVirtualEventUid --
 *
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
 *----------------------------------------------------------------------
 */

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







|







4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
 *----------------------------------------------------------------------
 */

static PatSeq *
FindSequence(
    Tcl_Interp *interp,		/* Interpreter to use for error reporting. */
    LookupTables *lookupTables,	/* Tables used for lookup. */
    void *object,		/* For binding table, token for object with which binding is
    				 * associated. For virtual event table, NULL. */
    const char *eventString,	/* String description of pattern to match on. See user
    				 * documentation for details. */
    int create,			/* 0 means don't create the entry if it doesn't already exist.
    				 * 1 means create. */
    int allowVirtual,		/* 0 means that virtual events are not allowed in the sequence.
    				 * 1 otherwise. */
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
    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];







|







4833
4834
4835
4836
4837
4838
4839
4840
4841
4842
4843
4844
4845
4846
4847
    unsigned count = 1;

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

    p = *eventStringPtr;
    memset(patPtr, 0, sizeof(TkPattern)); /* Otherwise memcmp doesn't work. */

    /*
     * Handle simple ASCII characters.
     */

    if (*p != '<') {
	char string[2];
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
	    }
	    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;







|







4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
	    }
	    if (*field) {
		unsigned button = GetButtonNumber(field);

		if ((eventFlags & BUTTON)
			|| (button && eventFlags == 0)
			|| (SUPPORT_ADDITIONAL_MOTION_SYNTAX && (eventFlags & MOTION) && button == 0)) {
		    /* This must be a button (or bad motion) event. */
		    if (button == 0) {
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
		    }
		    patPtr->info = button;
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("specified button \"%s\" for non-button event", field),
				"NON_BUTTON");
		    }
#if SUPPORT_ADDITIONAL_MOTION_SYNTAX
		    patPtr->modMask |= Tk_GetButtonMask(button);
		    p = SkipFieldDelims(p);
		    while (*p && *p != '>') {
			p = SkipFieldDelims(GetField(p, field, sizeof(field)));
			if ((button = GetButtonNumber(field)) == 0) {
			    return FinalizeParseEventDescription(
				    interp,
				    patPtr, 0,
				    Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
			}
			patPtr->modMask |= Tk_GetButtonMask(button);
		    }
		    patPtr->info = ButtonNumberFromState(patPtr->modMask);
#endif
		} else {
		    return FinalizeParseEventDescription(
			    interp,
			    patPtr, 0,







|









|







4998
4999
5000
5001
5002
5003
5004
5005
5006
5007
5008
5009
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020
5021
5022
			return FinalizeParseEventDescription(
				interp,
				patPtr, 0,
				Tcl_ObjPrintf("specified button \"%s\" for non-button event", field),
				"NON_BUTTON");
		    }
#if SUPPORT_ADDITIONAL_MOTION_SYNTAX
		    patPtr->modMask |= TkGetButtonMask(button);
		    p = SkipFieldDelims(p);
		    while (*p && *p != '>') {
			p = SkipFieldDelims(GetField(p, field, sizeof(field)));
			if ((button = GetButtonNumber(field)) == 0) {
			    return FinalizeParseEventDescription(
				    interp,
				    patPtr, 0,
				    Tcl_ObjPrintf("bad button number \"%s\"", field), "BUTTON");
			}
			patPtr->modMask |= TkGetButtonMask(button);
		    }
		    patPtr->info = ButtonNumberFromState(patPtr->modMask);
#endif
		} else {
		    return FinalizeParseEventDescription(
			    interp,
			    patPtr, 0,
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
			Tcl_AppendToObj(patternObj, "-", 1);
			Tcl_AppendToObj(patternObj, string, -1);
		    }
		    break;
		}
		case ButtonPress:
		case ButtonRelease:
		    assert(patPtr->info <= 13);
		    Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) ((patPtr->info > 7) ? (patPtr->info - 4) : patPtr->info));
		    break;
#if PRINT_SHORT_MOTION_SYNTAX
		case MotionNotify: {
		    unsigned mask = patPtr->modMask;
		    while (mask & ALL_BUTTONS) {
			unsigned button = ButtonNumberFromState(mask);
			Tcl_AppendPrintfToObj(patternObj, "-%u", (button > 7) ? (button - 4) : button);
			mask &= ~Tk_GetButtonMask(button);
		    }
		    break;
		}
#endif
		}
	    }








|
|






|
|







5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
			Tcl_AppendToObj(patternObj, "-", 1);
			Tcl_AppendToObj(patternObj, string, -1);
		    }
		    break;
		}
		case ButtonPress:
		case ButtonRelease:
		    assert(patPtr->info <= Button5);
		    Tcl_AppendPrintfToObj(patternObj, "-%u", (unsigned) patPtr->info);
		    break;
#if PRINT_SHORT_MOTION_SYNTAX
		case MotionNotify: {
		    unsigned mask = patPtr->modMask;
		    while (mask & ALL_BUTTONS) {
			unsigned button = ButtonNumberFromState(mask);
			Tcl_AppendPrintfToObj(patternObj, "-%u", button);
			mask &= ~TkGetButtonMask(button);
		    }
		    break;
		}
#endif
		}
	    }

5317
5318
5319
5320
5321
5322
5323





























5324
5325
5326
5327
5328
5329
5330
    Tcl_Interp *interp)		/* Interpreter. */
{
    TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
    BindingTable *bindPtr = winPtr->mainPtr->bindingTable;

    return &bindPtr->curEvent->xev;
}






























/*
 *----------------------------------------------------------------------
 *
 * TkpDumpPS --
 *
 *	Dump given pattern sequence to stdout.







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







5313
5314
5315
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
5349
5350
5351
5352
5353
5354
5355
    Tcl_Interp *interp)		/* Interpreter. */
{
    TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp);
    BindingTable *bindPtr = winPtr->mainPtr->bindingTable;

    return &bindPtr->curEvent->xev;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpCancelWarp --
 *
 *	This function cancels an outstanding pointer warp and
 *	is called during tear down of the display.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkpCancelWarp(
    TkDisplay *dispPtr)
{
    assert(dispPtr);

    if (dispPtr->flags & TK_DISPLAY_IN_WARP) {
	Tcl_CancelIdleCall(DoWarp, dispPtr);
	dispPtr->flags &= ~TK_DISPLAY_IN_WARP;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDumpPS --
 *
 *	Dump given pattern sequence to stdout.
Changes to generic/tkBitmap.c.
10
11
12
13
14
15
16




17
18
19
20
21
22
23
 *
 * 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
 * that warning message.







>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The includes below are for pre-defined bitmaps.
 *
 * Platform-specific issue: Windows complains when the bitmaps are included,
 * because an array of characters is being initialized with integers as
 * elements. For lint purposes, the following pragmas temporarily turn off
 * that warning message.
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (dispPtr == NULL || !dispPtr->bitmapInit) {
    unknown:
	Tcl_Panic("Tk_NameOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, bitmap);
    if (idHashPtr == NULL) {
	goto unknown;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    return bitmapPtr->nameHashPtr->key.string;
}








|







536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (dispPtr == NULL || !dispPtr->bitmapInit) {
    unknown:
	Tcl_Panic("Tk_NameOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	goto unknown;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    return bitmapPtr->nameHashPtr->key.string;
}

574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
    unknownBitmap:
	Tcl_Panic("Tk_SizeOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, bitmap);
    if (idHashPtr == NULL) {
	goto unknownBitmap;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    *widthPtr = bitmapPtr->width;
    *heightPtr = bitmapPtr->height;
}







|







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
    unknownBitmap:
	Tcl_Panic("Tk_SizeOfBitmap received unknown bitmap argument");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	goto unknownBitmap;
    }
    bitmapPtr = (TkBitmap *)Tcl_GetHashValue(idHashPtr);
    *widthPtr = bitmapPtr->width;
    *heightPtr = bitmapPtr->height;
}
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
	Tcl_Panic("Tk_FreeBitmap called before Tk_GetBitmap");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, bitmap);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument");
    }
    FreeBitmap((TkBitmap *)Tcl_GetHashValue(idHashPtr));
}

/*







|







666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->bitmapInit) {
	Tcl_Panic("Tk_FreeBitmap called before Tk_GetBitmap");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->bitmapIdTable, (char *) bitmap);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeBitmap received unknown bitmap argument");
    }
    FreeBitmap((TkBitmap *)Tcl_GetHashValue(idHashPtr));
}

/*
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
    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;
	}
    }







|







834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
    nameKey.height = height;
    dataHashPtr = Tcl_CreateHashEntry(&dispPtr->bitmapDataTable,
	    (char *) &nameKey, &isNew);
    if (!isNew) {
	name = (char *)Tcl_GetHashValue(dataHashPtr);
    } else {
	dispPtr->bitmapAutoNumber++;
	snprintf(string, sizeof(string), "_tk%d", dispPtr->bitmapAutoNumber);
	name = string;
	Tcl_SetHashValue(dataHashPtr, name);
	if (Tk_DefineBitmap(interp, name, source, width, height) != TCL_OK) {
	    Tcl_DeleteHashEntry(dataHashPtr);
	    return TCL_ERROR;
	}
    }
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
				 * 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);







|







1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
				 * or NULL if unavailable. */
{
    Tcl_Interp *dummy;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * First initialize the data in the ThreadSpecificData 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.
 *







|







1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092

/*
 *----------------------------------------------------------------------
 *
 * TkReadBitmapFile --
 *
 *	Loads a bitmap image in X bitmap format into the specified drawable.
 *	This is equivalent to the XReadBitmapFile in X.
 *
 * Results:
 *	Sets the size, hotspot, and bitmap on success.
 *
 * Side effects:
 *	Creates a new bitmap from the file data.
 *
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
	bitmapPtr = (TkBitmap *)Tcl_GetHashValue(hashPtr);
	if (bitmapPtr == NULL) {
	    Tcl_Panic("TkDebugBitmap found empty hash table entry");
	}
	for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(bitmapPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(bitmapPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * 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







|

|











|







1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
	bitmapPtr = (TkBitmap *)Tcl_GetHashValue(hashPtr);
	if (bitmapPtr == NULL) {
	    Tcl_Panic("TkDebugBitmap found empty hash table entry");
	}
	for ( ; (bitmapPtr != NULL); bitmapPtr = bitmapPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(bitmapPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(bitmapPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * 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
 * 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,







>
>
>
>







|

















|







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkBusy.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Things about the busy system that may be configured. Note that on some
 * platforms this may or may not have an effect.
 */

static const Tk_OptionSpec busyOptionSpecs[] = {
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUSY_CURSOR, -1, Tk_Offset(Busy, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations of functions defined in this file.
 */

static void		BusyEventProc(ClientData clientData,
			    XEvent *eventPtr);
static void		BusyGeometryProc(ClientData clientData,
			    Tk_Window tkwin);
static void		BusyCustodyProc(ClientData clientData,
			    Tk_Window tkwin);
static int		ConfigureBusy(Tcl_Interp *interp, Busy *busyPtr,
			    int objc, Tcl_Obj *const objv[]);
static Busy *		CreateBusy(Tcl_Interp *interp, Tk_Window tkRef);
static Tcl_FreeProc	DestroyBusy;
static void		DoConfigureNotify(Tk_FakeWin *winPtr);
static inline Tk_Window	FirstChild(Tk_Window parent);
static Busy *		GetBusy(Tcl_Interp *interp,
			    Tcl_HashTable *busyTablePtr,
			    Tcl_Obj *const windowObj);
static int		HoldBusy(Tcl_HashTable *busyTablePtr,
			    Tcl_Interp *interp, Tcl_Obj *const windowObj,
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
{
    Busy *busyPtr = (Busy *)clientData;

    Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);
    TkpHideBusyWindow(busyPtr);
    busyPtr->tkBusy = NULL;
    Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
}

/*
 *----------------------------------------------------------------------
 *
 * BusyGeometryProc --
 *







|







133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
{
    Busy *busyPtr = (Busy *)clientData;

    Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask, BusyEventProc,
	    busyPtr);
    TkpHideBusyWindow(busyPtr);
    busyPtr->tkBusy = NULL;
    Tcl_EventuallyFree(busyPtr, DestroyBusy);
}

/*
 *----------------------------------------------------------------------
 *
 * BusyGeometryProc --
 *
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
    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))) {







|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
    switch (eventPtr->type) {
    case ReparentNotify:
    case DestroyNotify:
	/*
	 * Arrange for the busy structure to be removed at a proper time.
	 */

	Tcl_EventuallyFree(busyPtr, DestroyBusy);
	break;

    case ConfigureNotify:
	if ((busyPtr->width != Tk_Width(busyPtr->tkRef)) ||
		(busyPtr->height != Tk_Height(busyPtr->tkRef)) ||
		(busyPtr->x != Tk_X(busyPtr->tkRef)) ||
		(busyPtr->y != Tk_Y(busyPtr->tkRef))) {
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
 *	Memory and resources are released and the Tk event handler is removed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyBusy(
    void *data)			/* Busy window structure record */
{
    Busy *busyPtr = (Busy *)data;

    if (busyPtr->hashPtr != NULL) {
	Tcl_DeleteHashEntry(busyPtr->hashPtr);
    }
    Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask,
	    RefWinEventProc, busyPtr);

    if (busyPtr->tkBusy != NULL) {
	Tk_FreeConfigOptions(data, busyPtr->optionTable, busyPtr->tkBusy);
	Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask,
		BusyEventProc, busyPtr);
	Tk_ManageGeometry(busyPtr->tkBusy, NULL, busyPtr);
	Tk_DestroyWindow(busyPtr->tkBusy);
    }
    ckfree(data);
}







|










|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
 *	Memory and resources are released and the Tk event handler is removed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyBusy(
    char *data)			/* Busy window structure record */
{
    Busy *busyPtr = (Busy *)data;

    if (busyPtr->hashPtr != NULL) {
	Tcl_DeleteHashEntry(busyPtr->hashPtr);
    }
    Tk_DeleteEventHandler(busyPtr->tkRef, StructureNotifyMask,
	    RefWinEventProc, busyPtr);

    if (busyPtr->tkBusy != NULL) {
	Tk_FreeConfigOptions((char *)data, busyPtr->optionTable, busyPtr->tkBusy);
	Tk_DeleteEventHandler(busyPtr->tkBusy, StructureNotifyMask,
		BusyEventProc, busyPtr);
	Tk_ManageGeometry(busyPtr->tkBusy, NULL, busyPtr);
	Tk_DestroyWindow(busyPtr->tkBusy);
    }
    ckfree(data);
}
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    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 --







|







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
    ClientData clientData,	/* Busy window record */
    XEvent *eventPtr)		/* Event which triggered call to routine */
{
    Busy *busyPtr = (Busy *)clientData;

    if (eventPtr->type == DestroyNotify) {
	busyPtr->tkBusy = NULL;
	Tcl_EventuallyFree(busyPtr, DestroyBusy);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MakeTransparentWindowExist --
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
	    y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
	}
    }
    for (tkChild = FirstChild(tkParent); tkChild != NULL;
	    tkChild = NextChild(tkChild)) {
	Tk_MakeWindowExist(tkChild);
    }
    sprintf(name, fmt, Tk_Name(tkRef));
    tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL);
    ckfree(name);

    if (tkBusy == NULL) {
	return NULL;
    }
    Tk_MakeWindowExist(tkRef);
    busyPtr->display = Tk_Display(tkRef);
    busyPtr->interp = interp;
    busyPtr->tkRef = tkRef;
    busyPtr->tkParent = tkParent;
    busyPtr->tkBusy = tkBusy;
    busyPtr->width = Tk_Width(tkRef);
    busyPtr->height = Tk_Height(tkRef);
    busyPtr->x = Tk_X(tkRef);
    busyPtr->y = Tk_Y(tkRef);
    busyPtr->cursor = NULL;
    Tk_SetClass(tkBusy, "Busy");
    busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs);
    if (Tk_InitOptions(interp, busyPtr, busyPtr->optionTable,
	    tkBusy) != TCL_OK) {
	Tk_DestroyWindow(tkBusy);
	return NULL;
    }
    SetWindowInstanceData(tkBusy, busyPtr);
    winPtr = (Tk_FakeWin *) tkRef;








|



















|







550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
	    y += Tk_Y(tkwin) + Tk_Changes(tkwin)->border_width;
	}
    }
    for (tkChild = FirstChild(tkParent); tkChild != NULL;
	    tkChild = NextChild(tkChild)) {
	Tk_MakeWindowExist(tkChild);
    }
    snprintf(name, length + 6, fmt, Tk_Name(tkRef));
    tkBusy = Tk_CreateWindow(interp, tkParent, name, NULL);
    ckfree(name);

    if (tkBusy == NULL) {
	return NULL;
    }
    Tk_MakeWindowExist(tkRef);
    busyPtr->display = Tk_Display(tkRef);
    busyPtr->interp = interp;
    busyPtr->tkRef = tkRef;
    busyPtr->tkParent = tkParent;
    busyPtr->tkBusy = tkBusy;
    busyPtr->width = Tk_Width(tkRef);
    busyPtr->height = Tk_Height(tkRef);
    busyPtr->x = Tk_X(tkRef);
    busyPtr->y = Tk_Y(tkRef);
    busyPtr->cursor = NULL;
    Tk_SetClass(tkBusy, "Busy");
    busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs);
    if (Tk_InitOptions(interp, (char *) busyPtr, busyPtr->optionTable,
	    tkBusy) != TCL_OK) {
	Tk_DestroyWindow(tkBusy);
	return NULL;
    }
    SetWindowInstanceData(tkBusy, busyPtr);
    winPtr = (Tk_FakeWin *) tkRef;

633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
    Tcl_Interp *interp,
    Busy *busyPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Cursor oldCursor = busyPtr->cursor;

    if (Tk_SetOptions(interp, busyPtr, busyPtr->optionTable, objc,
	    objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }
    if (busyPtr->cursor != oldCursor) {
	if (busyPtr->cursor == NULL) {
	    Tk_UndefineCursor(busyPtr->tkBusy);
	} else {







|







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
    Tcl_Interp *interp,
    Busy *busyPtr,
    int objc,
    Tcl_Obj *const objv[])
{
    Tk_Cursor oldCursor = busyPtr->cursor;

    if (Tk_SetOptions(interp, (char *) busyPtr, busyPtr->optionTable, objc,
	    objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }
    if (busyPtr->cursor != oldCursor) {
	if (busyPtr->cursor == NULL) {
	    Tk_UndefineCursor(busyPtr->tkBusy);
	} else {
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
    Tcl_Interp *interp,		/* Interpreter to look up main window of. */
    Tcl_HashTable *busyTablePtr,/* Busy hash table */
    Tcl_Obj *const windowObj)	/* Path name of parent window */
{
    Tcl_HashEntry *hPtr;
    Tk_Window tkwin;

    if (TkGetWindowFromObj(interp, Tk_MainWindow(interp), windowObj,
	    &tkwin) != TCL_OK) {
	return NULL;
    }
    hPtr = Tcl_FindHashEntry(busyTablePtr, tkwin);
    if (hPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't find busy window \"%s\"", Tcl_GetString(windowObj)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BUSY",
		Tcl_GetString(windowObj), NULL);
	return NULL;
    }







|
|


|







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
    Tcl_Interp *interp,		/* Interpreter to look up main window of. */
    Tcl_HashTable *busyTablePtr,/* Busy hash table */
    Tcl_Obj *const windowObj)	/* Path name of parent window */
{
    Tcl_HashEntry *hPtr;
    Tk_Window tkwin;

    tkwin = Tk_MainWindow(interp);
    if (!tkwin || (TkGetWindowFromObj(interp, tkwin, windowObj, &tkwin) != TCL_OK)) {
	return NULL;
    }
    hPtr = Tcl_FindHashEntry(busyTablePtr, (char *) tkwin);
    if (hPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"can't find busy window \"%s\"", Tcl_GetString(windowObj)));
	Tcl_SetErrorCode(interp, "TK", "LOOKUP", "BUSY",
		Tcl_GetString(windowObj), NULL);
	return NULL;
    }
735
736
737
738
739
740
741

742
743
744
745
746
747
748
	    &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);
    }







>







739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
	    &tkwin) != TCL_OK) {
	return TCL_ERROR;
    }
    hPtr = Tcl_CreateHashEntry(busyTablePtr, (char *) tkwin, &isNew);
    if (isNew) {
	busyPtr = CreateBusy(interp, tkwin);
	if (busyPtr == NULL) {
	    Tcl_DeleteHashEntry(hPtr);
	    return TCL_ERROR;
	}
	Tcl_SetHashValue(hPtr, busyPtr);
	busyPtr->hashPtr = hPtr;
    } else {
	busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
    }
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
     */

    if (Tk_IsMapped(busyPtr->tkRef)) {
	TkpShowBusyWindow(busyPtr);
    } else {
	TkpHideBusyWindow(busyPtr);
    }
    if (result == TCL_OK) {
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
    }
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BusyObjCmd --







<
<
<







761
762
763
764
765
766
767



768
769
770
771
772
773
774
     */

    if (Tk_IsMapped(busyPtr->tkRef)) {
	TkpShowBusyWindow(busyPtr);
    } else {
	TkpHideBusyWindow(busyPtr);
    }



    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_BusyObjCmd --
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable;
    Busy *busyPtr;
    Tcl_Obj *objPtr;
    int index, result = TCL_OK;
    static const char *const optionStrings[] = {
	"busywindow", "cget", "configure", "current", "forget", "hold",
        "status", NULL
    };
    enum options {
	BUSY_BUSYWINDOW, BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET,
	BUSY_HOLD, BUSY_STATUS
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "options ?arg ...?");
	return TCL_ERROR;
    }

    /*
     * [tk busy <window>] command shortcut.
     */

    if (Tcl_GetString(objv[1])[0] == '.') {
	if (objc%2 == 1) {
	    Tcl_WrongNumArgs(interp, 1, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}
	return HoldBusy(busyTablePtr, interp, objv[1], objc-2, objv+2);
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum options) index) {
    case BUSY_BUSYWINDOW:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    Tcl_ResetResult(interp);
            return TCL_OK;
	}
        Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1));
        return TCL_OK;

    case BUSY_CGET:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window option");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_Preserve(busyPtr);
	objPtr = Tk_GetOptionValue(interp, busyPtr,
		busyPtr->optionTable, objv[3], busyPtr->tkBusy);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, objPtr);
	}
	Tcl_Release(busyPtr);
	return result;

    case BUSY_CONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_Preserve(busyPtr);
	if (objc <= 4) {
	    objPtr = Tk_GetOptionInfo(interp, busyPtr,
		    busyPtr->optionTable, (objc == 4) ? objv[3] : NULL,
		    busyPtr->tkBusy);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }







|
<


|
|



|









|










<
<
<
<
<
<
<
<
<
<
<
<
<










|











|








|







794
795
796
797
798
799
800
801

802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829













830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable;
    Busy *busyPtr;
    Tcl_Obj *objPtr;
    int index, result = TCL_OK;
    static const char *const optionStrings[] = {
	"cget", "configure", "current", "forget", "hold", "status", NULL

    };
    enum options {
	BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, BUSY_HOLD,
	BUSY_STATUS
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "options ?arg arg ...?");
	return TCL_ERROR;
    }

    /*
     * [tk busy <window>] command shortcut.
     */

    if (Tcl_GetString(objv[1])[0] == '.') {
	if (objc%2 == 1) {
	    Tcl_WrongNumArgs(interp, 1, objv, "window ?option value ...?");
	    return TCL_ERROR;
	}
	return HoldBusy(busyTablePtr, interp, objv[1], objc-2, objv+2);
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    switch ((enum options) index) {













    case BUSY_CGET:
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window option");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_Preserve(busyPtr);
	objPtr = Tk_GetOptionValue(interp, (char *) busyPtr,
		busyPtr->optionTable, objv[3], busyPtr->tkBusy);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, objPtr);
	}
	Tcl_Release(busyPtr);
	return result;

    case BUSY_CONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?option? ?value ...?");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_Preserve(busyPtr);
	if (objc <= 4) {
	    objPtr = Tk_GetOptionInfo(interp, (char *)busyPtr,
		    busyPtr->optionTable, (objc == 4) ? objv[3] : NULL,
		    busyPtr->tkBusy);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
	    }
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
	objPtr = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(busyTablePtr, &cursor); hPtr != NULL;
		hPtr = Tcl_NextHashEntry(&cursor)) {
	    busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
	    if (pattern == NULL ||
		    Tcl_StringCaseMatch(Tk_PathName(busyPtr->tkRef), pattern, 0)) {
		Tcl_ListObjAppendElement(interp, objPtr,
			Tk_NewWindowObj(busyPtr->tkRef));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }

    case BUSY_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	TkpHideBusyWindow(busyPtr);
	Tcl_EventuallyFree(busyPtr, (Tcl_FreeProc *)DestroyBusy);
	return TCL_OK;

    case BUSY_HOLD:
	if (objc < 3 || objc%2 != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?-option value ...?");
	    return TCL_ERROR;
	}
	return HoldBusy(busyTablePtr, interp, objv[2], objc-3, objv+3);

    case BUSY_STATUS:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");







|
















|




|







880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
	objPtr = Tcl_NewObj();
	for (hPtr = Tcl_FirstHashEntry(busyTablePtr, &cursor); hPtr != NULL;
		hPtr = Tcl_NextHashEntry(&cursor)) {
	    busyPtr = (Busy *)Tcl_GetHashValue(hPtr);
	    if (pattern == NULL ||
		    Tcl_StringCaseMatch(Tk_PathName(busyPtr->tkRef), pattern, 0)) {
		Tcl_ListObjAppendElement(interp, objPtr,
			TkNewWindowObj(busyPtr->tkRef));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	return TCL_OK;
    }

    case BUSY_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	busyPtr = GetBusy(interp, busyTablePtr, objv[2]);
	if (busyPtr == NULL) {
	    return TCL_ERROR;
	}
	TkpHideBusyWindow(busyPtr);
	Tcl_EventuallyFree(busyPtr, DestroyBusy);
	return TCL_OK;

    case BUSY_HOLD:
	if (objc < 3 || objc%2 != 1) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?option value ...?");
	    return TCL_ERROR;
	}
	return HoldBusy(busyTablePtr, interp, objv[2], objc-3, objv+3);

    case BUSY_STATUS:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
Changes to generic/tkButton.c.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
 * 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;
char tkDefLabelHighlightWidth[TCL_INTEGER_SPACE] = DEF_LABEL_HIGHLIGHT_WIDTH;
char tkDefLabelPadx[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADX;
char tkDefLabelPady[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADY;

/*
 * Information used for parsing configuration options.  There is a
 * separate table for each of the four widget classes.
 */

static const Tk_OptionSpec labelOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefLabelHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_LABEL_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec buttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
        DEF_BUTTON_DEFAULT, TCL_INDEX_NONE, offsetof(TkButton, defaultState),
	0, defaultStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefButtonPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefButtonPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	 DEF_BUTTON_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(TkButton, repeatDelay),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	 DEF_BUTTON_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(TkButton, repeatInterval),
	 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "Value",
	DEF_BUTTON_OFF_VALUE, offsetof(TkButton, offValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "Value",
	DEF_BUTTON_ON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_CHECKBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, TCL_INDEX_NONE, offsetof(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, TCL_INDEX_NONE, offsetof(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, offsetof(TkButton, borderWidthPtr),
	offsetof(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, offsetof(TkButton, commandPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, TCL_INDEX_NONE, offsetof(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, TCL_INDEX_NONE, offsetof(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, offsetof(TkButton, heightPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkButton, highlightBorder), 0,
	(ClientData) DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, TCL_INDEX_NONE, offsetof(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	offsetof(TkButton, highlightWidthPtr),
	offsetof(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, offsetof(TkButton, imagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, offsetof(TkButton, padXPtr),
	offsetof(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, offsetof(TkButton, padYPtr),
	offsetof(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, TCL_INDEX_NONE, offsetof(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, TCL_INDEX_NONE, offsetof(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, offsetof(TkButton, selectImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, TCL_INDEX_NONE, offsetof(TkButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, offsetof(TkButton, takeFocusPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, offsetof(TkButton, textPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, offsetof(TkButton, textVarNamePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, offsetof(TkButton, tristateImagePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, offsetof(TkButton, tristateValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-value", "value", "Value",
	DEF_BUTTON_VALUE, offsetof(TkButton, onValuePtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_RADIOBUTTON_VARIABLE, offsetof(TkButton, selVarNamePtr), TCL_INDEX_NONE,
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, offsetof(TkButton, widthPtr), TCL_INDEX_NONE, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, offsetof(TkButton, wrapLengthPtr),
	offsetof(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * The following table maps from one of the type values defined in tkButton.h,
 * such as TYPE_LABEL, to the option template for that class of widgets.
 */








|
<
<
<
<
<
<
<
<
<
|


|








|


















|


|


|

|


|

|

|


|
|

|
|

|



|
|

|

|

|

|


|
|

|



|
|

|


|

|
|

|
|

|

|
|

|


|

|


|

|

|
|





|


|


|

|


|

|

|


|
|

|


|
|

|


|
|


|
|

|

|

|

|


|
|

|



|
|

|


|

|


|
|

|
|

|


|


|


|
|

|


|

|


|

|

|
|
|




|


|


|

|


|

|

|


|
|

|


|
|

|



|
|

|

|

|

|


|
|

|



|
|

|


|

|

|

|

|

|
|

|
|

|
|

|

|


|


|
|

|


|

|


|


|

|

|


|

|
|
|




|


|


|

|


|

|

|


|
|

|


|
|

|



|
|

|

|

|

|


|
|

|



|
|

|


|


|

|

|


|
|

|
|

|

|


|


|
|

|


|

|


|


|

|

|

|


|

|
|
|







25
26
27
28
29
30
31
32









33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
 * Class names for buttons, indexed by one of the type values defined in
 * tkButton.h.
 */

static const char *const classNames[] = {"Label", "Button", "Checkbutton", "Radiobutton"};

/*
 * The following table defines the legal values for the -default/-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;
char tkDefLabelHighlightWidth[TCL_INTEGER_SPACE] = DEF_LABEL_HIGHLIGHT_WIDTH;
char tkDefLabelPadx[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADX;
char tkDefLabelPady[TCL_INTEGER_SPACE] = DEF_LABCHKRAD_PADY;

/*
 * Information used for parsing configuration options.  There is a
 * separate table for each of the four widget classes.
 */

static const Tk_OptionSpec labelOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_LABEL_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefLabelHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_LABEL_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec buttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_BUTTON_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-default", "default", "Default",
	DEF_BUTTON_DEFAULT, -1, Tk_Offset(TkButton, defaultState),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_BUTTON_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefButtonPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefButtonPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, relief),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	 DEF_BUTTON_REPEAT_DELAY, -1, Tk_Offset(TkButton, repeatDelay),
	 0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	 DEF_BUTTON_REPEAT_INTERVAL, -1, Tk_Offset(TkButton, repeatInterval),
	 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

static const Tk_OptionSpec checkbuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-offvalue", "offValue", "Value",
	DEF_BUTTON_OFF_VALUE, Tk_Offset(TkButton, offValuePtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-onvalue", "onValue", "Value",
	DEF_BUTTON_ON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_CHECKBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

static const Tk_OptionSpec radiobuttonOptionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(TkButton, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_CHKRAD_ACTIVE_FG_COLOR, -1, Tk_Offset(TkButton, activeFg),
	TK_OPTION_NULL_OK, DEF_BUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_BUTTON_ANCHOR, -1, Tk_Offset(TkButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(TkButton, normalBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_BUTTON_BITMAP, -1, Tk_Offset(TkButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	tkDefButtonBorderWidth, Tk_Offset(TkButton, borderWidthPtr),
	Tk_Offset(TkButton, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_BUTTON_COMMAND, Tk_Offset(TkButton, commandPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(TkButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_BUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkButton, disabledFg), TK_OPTION_NULL_OK,
	DEF_BUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_BUTTON_FONT, -1, Tk_Offset(TkButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_CHKRAD_FG, -1, Tk_Offset(TkButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_BUTTON_HEIGHT, Tk_Offset(TkButton, heightPtr), -1, 0, 0, 0},
    {TK_OPTION_BORDER, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_BUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkButton, highlightBorder), 0,
	DEF_BUTTON_HIGHLIGHT_BG_MONO, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_BUTTON_HIGHLIGHT, -1, Tk_Offset(TkButton, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", tkDefButtonHighlightWidth,
	Tk_Offset(TkButton, highlightWidthPtr),
	Tk_Offset(TkButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, imagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_BUTTON_INDICATOR, -1, Tk_Offset(TkButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_BUTTON_JUSTIFY, -1, Tk_Offset(TkButton, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-offrelief", "offRelief", "OffRelief",
	 DEF_BUTTON_RELIEF, -1, Tk_Offset(TkButton, offRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-overrelief", "overRelief", "OverRelief",
	 DEF_BUTTON_OVER_RELIEF, -1, Tk_Offset(TkButton, overRelief),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	tkDefLabelPadx, Tk_Offset(TkButton, padXPtr),
	Tk_Offset(TkButton, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	tkDefLabelPady, Tk_Offset(TkButton, padYPtr),
	Tk_Offset(TkButton, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABCHKRAD_RELIEF, -1, Tk_Offset(TkButton, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectcolor", "selectColor", "Background",
	DEF_BUTTON_SELECT_COLOR, -1, Tk_Offset(TkButton, selectBorder),
	TK_OPTION_NULL_OK, DEF_BUTTON_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-selectimage", "selectImage", "SelectImage",
	DEF_BUTTON_SELECT_IMAGE, Tk_Offset(TkButton, selectImagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_BUTTON_STATE, -1, Tk_Offset(TkButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_BUTTON_TAKE_FOCUS, Tk_Offset(TkButton, takeFocusPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_BUTTON_TEXT, Tk_Offset(TkButton, textPtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_BUTTON_TEXT_VARIABLE, Tk_Offset(TkButton, textVarNamePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristateimage", "tristateImage", "TristateImage",
	DEF_BUTTON_IMAGE, Tk_Offset(TkButton, tristateImagePtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-tristatevalue", "tristateValue", "TristateValue",
	DEF_BUTTON_TRISTATE_VALUE, Tk_Offset(TkButton, tristateValuePtr), -1, 0, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_BUTTON_UNDERLINE, -1, Tk_Offset(TkButton, underline), 0, 0, 0},
    {TK_OPTION_STRING, "-value", "value", "Value",
	DEF_BUTTON_VALUE, Tk_Offset(TkButton, onValuePtr), -1, 0, 0, 0},
    {TK_OPTION_STRING, "-variable", "variable", "Variable",
	DEF_RADIOBUTTON_VARIABLE, Tk_Offset(TkButton, selVarNamePtr), -1,
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_BUTTON_WIDTH, Tk_Offset(TkButton, widthPtr), -1, 0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_BUTTON_WRAP_LENGTH, Tk_Offset(TkButton, wrapLengthPtr),
	Tk_Offset(TkButton, wrapLength), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * The following table maps from one of the type values defined in tkButton.h,
 * such as TYPE_LABEL, to the option template for that class of widgets.
 */

624
625
626
627
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) {







|












<







615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634

635
636
637
638
639
640
641
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
ButtonCreate(
    TCL_UNUSED(void *),	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument values. */
    int type)			/* Type of button to create: TYPE_LABEL,
				 * TYPE_BUTTON, TYPE_CHECK_BUTTON, or
				 * TYPE_RADIO_BUTTON. */
{
    TkButton *butPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    if (!tsdPtr->defaultsInitialized) {
	TkpButtonSetDefaults();
	tsdPtr->defaultsInitialized = 1;
    }

    if (objc < 2) {
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
    butPtr->commandPtr = NULL;
    butPtr->flags = 0;

    Tk_CreateEventHandler(butPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ButtonEventProc, butPtr);

    if (Tk_InitOptions(interp, butPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureButton(interp, butPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(butPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonWidgetCmd --







|









|







736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
    butPtr->commandPtr = NULL;
    butPtr->flags = 0;

    Tk_CreateEventHandler(butPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ButtonEventProc, butPtr);

    if (Tk_InitOptions(interp, (char *) butPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureButton(interp, butPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(butPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(butPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ButtonWidgetCmd --
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831

    switch (map[butPtr->type][index]) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}
	objPtr = Tk_GetOptionValue(interp, butPtr,
		butPtr->optionTable, objv[2], butPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, butPtr,
		    butPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    butPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {







|









|







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821

    switch (map[butPtr->type][index]) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}
	objPtr = Tk_GetOptionValue(interp, (char *) butPtr,
		butPtr->optionTable, objv[2], butPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) butPtr,
		    butPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    butPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, butPtr,
		    butPtr->optionTable, objc, objv,
		    butPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|







1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) butPtr,
		    butPtr->optionTable, objc, objv,
		    butPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
	}

	if (butPtr->type >= TYPE_CHECK_BUTTON) {
	    Tcl_Obj *valuePtr, *namePtr;

	    if (butPtr->selVarNamePtr == NULL) {
		butPtr->selVarNamePtr = Tcl_NewStringObj(
			Tk_Name(butPtr->tkwin), TCL_INDEX_NONE);
		Tcl_IncrRefCount(butPtr->selVarNamePtr);
	    }
	    namePtr = butPtr->selVarNamePtr;

	    /*
	     * Select the button if the associated variable has the
	     * appropriate value, initialize the variable if it doesn't exist,







|







1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
	}

	if (butPtr->type >= TYPE_CHECK_BUTTON) {
	    Tcl_Obj *valuePtr, *namePtr;

	    if (butPtr->selVarNamePtr == NULL) {
		butPtr->selVarNamePtr = Tcl_NewStringObj(
			Tk_Name(butPtr->tkwin), -1);
		Tcl_IncrRefCount(butPtr->selVarNamePtr);
	    }
	    namePtr = butPtr->selVarNamePtr;

	    /*
	     * Select the button if the associated variable has the
	     * appropriate value, initialize the variable if it doesn't exist,
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
    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







<
<









|






|







1601
1602
1603
1604
1605
1606
1607


1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkButton *butPtr = (TkButton *)clientData;
    const char *value;
    Tcl_Obj *valuePtr;



    /*
     * 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
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
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    TkButton *butPtr = (TkButton *)clientData;
    Tcl_Obj *valuePtr;
    (void)name1;
    (void)name2;

    if (butPtr->flags & BUTTON_DELETED) {
	return NULL;
    }

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
	if (!Tcl_InterpDeleted(interp) && butPtr->textVarNamePtr != NULL) {

	    /*
	     * An unset trace on some variable brought us here, but is it
	     * the variable we have stored in butPtr->textVarNamePtr ?
	     */

	    ClientData probe = NULL;

	    do {
		probe = Tcl_VarTraceInfo(interp,
			Tcl_GetString(butPtr->textVarNamePtr),
			TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
			ButtonTextVarProc, probe);
		if (probe == (ClientData)butPtr) {
		    break;
		}
	    } while (probe);
	    if (probe) {
		/*
		 * We were able to fetch the unset trace for our
		 * textVarNamePtr, which means it is not unset and not







<
<


















|






|







1709
1710
1711
1712
1713
1714
1715


1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    TkButton *butPtr = (TkButton *)clientData;
    Tcl_Obj *valuePtr;



    if (butPtr->flags & BUTTON_DELETED) {
	return NULL;
    }

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
	if (!Tcl_InterpDeleted(interp) && butPtr->textVarNamePtr != NULL) {

	    /*
	     * An unset trace on some variable brought us here, but is it
	     * the variable we have stored in butPtr->textVarNamePtr ?
	     */

	    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
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
	if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	    butPtr->flags |= REDRAW_PENDING;
	}







<
<
<
<
<
<







1803
1804
1805
1806
1807
1808
1809






1810
1811
1812
1813
1814
1815
1816
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;







    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
	if (Tk_IsMapped(butPtr->tkwin) && !(butPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayButton, butPtr);
	    butPtr->flags |= REDRAW_PENDING;
	}
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

#ifdef MAC_OSX_TK
    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
    }
#else
    /*







<
<
<
<
<
<







1841
1842
1843
1844
1845
1846
1847






1848
1849
1850
1851
1852
1853
1854
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;







#ifdef MAC_OSX_TK
    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
    }
#else
    /*
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

#ifdef MAC_OSX_TK
    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
    }
#else
    /*







<
<
<
<
<
<







1888
1889
1890
1891
1892
1893
1894






1895
1896
1897
1898
1899
1900
1901
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkButton *butPtr = (TkButton *)clientData;







#ifdef MAC_OSX_TK
    if (butPtr->tkwin != NULL) {
	TkpComputeButtonGeometry(butPtr);
    }
#else
    /*
Changes to generic/tkButton.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * 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 (c) 1996-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKBUTTON
#define _TKBUTTON
Changes to generic/tkCanvArc.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

#include "float.h"

/*
 * The structure below defines the record for each arc item.
 */

typedef enum {
    PIESLICE_STYLE, CHORD_STYLE, ARC_STYLE
} Style;







<
<







10
11
12
13
14
15
16


17
18
19
20
21
22
23
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"



/*
 * The structure below defines the record for each arc item.
 */

typedef enum {
    PIESLICE_STYLE, CHORD_STYLE, ARC_STYLE
} Style;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
    Style style;		/* How to draw arc: arc, chord, or
				 * pieslice. */
    GC fillGC;			/* Graphics context for filling item. */
    double center1[2];		/* Coordinates of center of arc outline at
				 * start (see ComputeArcOutline). */
    double center2[2];		/* Coordinates of center of arc outline at
				 * start+extent (see ComputeArcOutline). */
    double height;              /* Distance from the arc's chord to its
				 * mid-point. */
    double startPoint[2];       /* Start point of arc used when specifying
				 * height. */
    double endPoint[2];         /* End point of arc used when specifying
				 * height. */
} ArcItem;

/*
 * The definitions below define the sizes of the polygons used to display
 * outline information for various styles of arcs:
 */

#define CHORD_OUTLINE_PTS	7
#define PIE_OUTLINE1_PTS	6
#define PIE_OUTLINE2_PTS	7

/*
 * Information used for parsing configuration specs:
 */

static int	StyleParseProc(ClientData clientData, Tcl_Interp *interp,
		    Tk_Window tkwin, const char *value,
		    char *widgRec, TkSizeT offset);
static const char * StylePrintProc(ClientData clientData, Tk_Window tkwin,
		    char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr);

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption styleOption = {
    StyleParseProc, StylePrintProc, NULL
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};
static const Tk_CustomOption pixelOption = {
    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(ArcItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(ArcItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(ArcItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_DOUBLE, "-extent", NULL, NULL,
	"90", offsetof(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(ArcItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-height", NULL, NULL,
	0, offsetof(ArcItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(ArcItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(ArcItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(ArcItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, offsetof(ArcItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-start", NULL, NULL,
	"0", offsetof(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(ArcItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-style", NULL, NULL,
	NULL, offsetof(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
	&styleOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", offsetof(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT,
	&pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr);
static int		ConfigureArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static void		ComputeArcParametersFromHeight(ArcItem *arcPtr);
static int		CreateArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,







<
<
<
<
<
<

















|

|








|













|


|

|

|

|

|


|


|

|


|

|

|

|

|


|

|
<
<

|


|

|


|

|

|

|

|




|












<







59
60
61
62
63
64
65






66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143


144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178

179
180
181
182
183
184
185
    Style style;		/* How to draw arc: arc, chord, or
				 * pieslice. */
    GC fillGC;			/* Graphics context for filling item. */
    double center1[2];		/* Coordinates of center of arc outline at
				 * start (see ComputeArcOutline). */
    double center2[2];		/* Coordinates of center of arc outline at
				 * start+extent (see ComputeArcOutline). */






} ArcItem;

/*
 * The definitions below define the sizes of the polygons used to display
 * outline information for various styles of arcs:
 */

#define CHORD_OUTLINE_PTS	7
#define PIE_OUTLINE1_PTS	6
#define PIE_OUTLINE2_PTS	7

/*
 * Information used for parsing configuration specs:
 */

static int	StyleParseProc(ClientData clientData, Tcl_Interp *interp,
		    Tk_Window tkwin, const char *value,
		    char *widgRec, int offset);
static const char * StylePrintProc(ClientData clientData, Tk_Window tkwin,
		    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr);

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption styleOption = {
    StyleParseProc, StylePrintProc, NULL
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};
static const Tk_CustomOption pixelOption = {
    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", Tk_Offset(ArcItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", Tk_Offset(ArcItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(ArcItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_DOUBLE, "-extent", NULL, NULL,
	"90", Tk_Offset(ArcItem, extent), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, Tk_Offset(ArcItem, fillColor), TK_CONFIG_NULL_OK, NULL},


    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	DEF_CANVITEM_OUTLINE, Tk_Offset(ArcItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", Tk_Offset(ArcItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-start", NULL, NULL,
	"0", Tk_Offset(ArcItem, start), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, Tk_Offset(ArcItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-style", NULL, NULL,
	NULL, Tk_Offset(ArcItem, style), TK_CONFIG_DONT_SET_DEFAULT,
	&styleOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", Tk_Offset(ArcItem, outline.width), TK_CONFIG_DONT_SET_DEFAULT,
	&pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeArcBbox(Tk_Canvas canvas, ArcItem *arcPtr);
static int		ConfigureArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);

static int		CreateArc(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayArc(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
static void		ComputeArcOutline(Tk_Canvas canvas, ArcItem *arcPtr);
static int		HorizLineToArc(double x1, double x2,
			    double y, double rx, double ry,
			    double start, double extent);
static int		VertLineToArc(double x, double y1,
			    double y2, double rx, double ry,
			    double start, double extent);
static void		RotateArc(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);

/*
 * The structures below defines the arc item types by means of functions that
 * can be invoked by generic item code.
 */

Tk_ItemType tkArcType = {







<
<







202
203
204
205
206
207
208


209
210
211
212
213
214
215
static void		ComputeArcOutline(Tk_Canvas canvas, ArcItem *arcPtr);
static int		HorizLineToArc(double x1, double x2,
			    double y, double rx, double ry,
			    double start, double extent);
static int		VertLineToArc(double x, double y1,
			    double y2, double rx, double ry,
			    double start, double extent);



/*
 * The structures below defines the arc item types by means of functions that
 * can be invoked by generic item code.
 */

Tk_ItemType tkArcType = {
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
    TranslateArc,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateArc,			/* rotateProc */
    0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateArc --
 *







<
|







229
230
231
232
233
234
235

236
237
238
239
240
241
242
243
    TranslateArc,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */

    NULL, 0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateArc --
 *
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
    arcPtr->activeFillColor = NULL;
    arcPtr->disabledFillColor = NULL;
    arcPtr->fillStipple = None;
    arcPtr->activeFillStipple = None;
    arcPtr->disabledFillStipple = None;
    arcPtr->style = PIESLICE_STYLE;
    arcPtr->fillGC = NULL;
    arcPtr->height = 0;

    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	const char *arg = Tcl_GetString(objv[i]);







<







288
289
290
291
292
293
294

295
296
297
298
299
300
301
    arcPtr->activeFillColor = NULL;
    arcPtr->disabledFillColor = NULL;
    arcPtr->fillStipple = None;
    arcPtr->activeFillStipple = None;
    arcPtr->disabledFillStipple = None;
    arcPtr->style = PIESLICE_STYLE;
    arcPtr->fillGC = NULL;


    /*
     * Process the arguments to fill in the item record.
     */

    for (i = 1; i < objc; i++) {
	const char *arg = Tcl_GetString(objv[i]);
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
			"wrong # coordinates: expected 4, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
 		    &arcPtr->bbox[0]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		    &arcPtr->bbox[1]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
			&arcPtr->bbox[2]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
			&arcPtr->bbox[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}

	/*
	 * Store bbox as start and end points so they can be used if either
	 * radius or height is specified.
	 */

	arcPtr->startPoint[0] = arcPtr->bbox[0];
	arcPtr->startPoint[1] = arcPtr->bbox[1];
	arcPtr->endPoint[0] = arcPtr->bbox[2];
	arcPtr->endPoint[1] = arcPtr->bbox[3];

	ComputeArcBbox(canvas, arcPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL);
	return TCL_ERROR;
    }







|








<
<
<
<
<
<
<
<
<
<
<







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377











378
379
380
381
382
383
384
			"wrong # coordinates: expected 4, got %d", objc));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC",
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		    &arcPtr->bbox[0]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		    &arcPtr->bbox[1]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[2],
			&arcPtr->bbox[2]) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3],
			&arcPtr->bbox[3]) != TCL_OK)) {
	    return TCL_ERROR;
	}











	ComputeArcBbox(canvas, arcPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 4, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "ARC", NULL);
	return TCL_ERROR;
    }
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508








509
510
511
512
513
514
515
	    arcPtr->activeFillColor != NULL ||
	    arcPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

    /*
     * Override the start and extent if the height is given.
     */

    ComputeArcParametersFromHeight(arcPtr);

    ComputeArcBbox(canvas, arcPtr);

    i = (int) (arcPtr->start/360.0);
    arcPtr->start -= i*360.0;
    if (arcPtr->start < 0) {
	arcPtr->start += 360.0;
    }
    i = (int) (arcPtr->extent/360.0);
    arcPtr->extent -= i*360.0;

    tsoffset = &arcPtr->outline.tsoffset;
    flags = tsoffset->flags;
    if (flags & TK_OFFSET_LEFT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
    } else if (flags & TK_OFFSET_CENTER) {
	tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
    } else if (flags & TK_OFFSET_RIGHT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);
    }
    if (flags & TK_OFFSET_TOP) {
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }









    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
















>
>
>
>
>
>
>
>







444
445
446
447
448
449
450
















451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	    arcPtr->activeFillColor != NULL ||
	    arcPtr->activeFillStipple != None) {
	itemPtr->redraw_flags |= TK_ITEM_STATE_DEPENDANT;
    } else {
	itemPtr->redraw_flags &= ~TK_ITEM_STATE_DEPENDANT;
    }

















    tsoffset = &arcPtr->outline.tsoffset;
    flags = tsoffset->flags;
    if (flags & TK_OFFSET_LEFT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[0] + 0.5);
    } else if (flags & TK_OFFSET_CENTER) {
	tsoffset->xoffset = (int) ((arcPtr->bbox[0]+arcPtr->bbox[2]+1)/2);
    } else if (flags & TK_OFFSET_RIGHT) {
	tsoffset->xoffset = (int) (arcPtr->bbox[2] + 0.5);
    }
    if (flags & TK_OFFSET_TOP) {
	tsoffset->yoffset = (int) (arcPtr->bbox[1] + 0.5);
    } else if (flags & TK_OFFSET_MIDDLE) {
	tsoffset->yoffset = (int) ((arcPtr->bbox[1]+arcPtr->bbox[3]+1)/2);
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[2] + 0.5);
    }

    i = (int) (arcPtr->start/360.0);
    arcPtr->start -= i*360.0;
    if (arcPtr->start < 0) {
	arcPtr->start += 360.0;
    }
    i = (int) (arcPtr->extent/360.0);
    arcPtr->extent -= i*360.0;

    mask = Tk_ConfigOutlineGC(&gcValues, canvas, itemPtr, &(arcPtr->outline));
    if (mask) {
	gcValues.cap_style = CapButt;
	mask |= GCCapStyle;
	newGC = Tk_GetGC(tkwin, mask, &gcValues);
    } else {
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[3] + 0.5);
    }

    ComputeArcBbox(canvas, arcPtr);
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * ComputeArcParametersFromHeight --
 *
 *	This function calculates the arc parameters given start-point,
 *	end-point and height (!= 0).
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The height parameter is set to 0 on exit.
 *
 *--------------------------------------------------------------
 */

static void
ComputeArcParametersFromHeight(
    ArcItem* arcPtr)
{
    double chordLen, chordDir[2], chordCen[2], arcCen[2], d, radToDeg, radius;

    /*
     * Do nothing if no height has been specified.
     */

    if (arcPtr->height == 0)
        return;

    /*
     * Calculate the chord length, return early if it is too small.
     */

    chordLen = hypot(arcPtr->endPoint[1] - arcPtr->startPoint[1],
	    arcPtr->startPoint[0] - arcPtr->endPoint[0]);

    if (chordLen < DBL_EPSILON) {
        arcPtr->start = arcPtr->extent = arcPtr->height = 0;
        return;
    }

    chordDir[0] = (arcPtr->endPoint[0] - arcPtr->startPoint[0]) / chordLen;
    chordDir[1] = (arcPtr->endPoint[1] - arcPtr->startPoint[1]) / chordLen;
    chordCen[0] = (arcPtr->startPoint[0] + arcPtr->endPoint[0]) / 2;
    chordCen[1] = (arcPtr->startPoint[1] + arcPtr->endPoint[1]) / 2;

    /*
     * Calculate the radius (assumes height != 0).
     */

    radius = (4*pow(arcPtr->height, 2) + pow(chordLen, 2))
	    / (8 * arcPtr->height);

    /*
     * The arc centre.
     */

    d = radius - arcPtr->height;
    arcCen[0] = chordCen[0] - d * chordDir[1];
    arcCen[1] = chordCen[1] + d * chordDir[0];

    /*
     * The arc start and span. Angles are negated because the coordinate
     * system is left-handed.
     */

    radToDeg = 45 / atan(1);
    arcPtr->start = atan2(arcCen[1] - arcPtr->startPoint[1],
	    arcPtr->startPoint[0] - arcCen[0]) * radToDeg;
    arcPtr->extent = -2 * asin(chordLen / (2 * radius)) * radToDeg;

    /*
     * Handle spans > 180.
     */

    if (fabs(2 * arcPtr->height) > chordLen) {
	arcPtr->extent = arcPtr->extent > 0 ? (360 - arcPtr->extent)
		: -(360 + arcPtr->extent);
    }

    /*
     * Create the bounding box.
     */

    arcPtr->bbox[0] = arcCen[0] - radius;
    arcPtr->bbox[1] = arcCen[1] - radius;
    arcPtr->bbox[2] = arcCen[0] + radius;
    arcPtr->bbox[3] = arcCen[1] + radius;

    /*
     * Set the height to 0 so that itemcget -height returns 0.
     */

    arcPtr->height = 0;
}

/*
 *--------------------------------------------------------------
 *
 * DeleteArc --
 *
 *	This function is called to clean up the data structure associated with







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







552
553
554
555
556
557
558

































































































559
560
561
562
563
564
565
    } else if (flags & TK_OFFSET_BOTTOM) {
	tsoffset->yoffset = (int) (arcPtr->bbox[3] + 0.5);
    }

    ComputeArcBbox(canvas, arcPtr);
    return TCL_OK;
}


































































































/*
 *--------------------------------------------------------------
 *
 * DeleteArc --
 *
 *	This function is called to clean up the data structure associated with
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
    arcPtr->bbox[3] = originY + scaleY*(arcPtr->bbox[3] - originY);
    ComputeArcBbox(canvas, arcPtr);
}

/*
 *--------------------------------------------------------------
 *
 * RotateArc --
 *
 *	This function is called to rotate an arc by a given amount.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the arc is rotated by angleRad radians about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateArc(
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ArcItem *arcPtr = (ArcItem *) itemPtr;
    double newX, newY, oldX, oldY;

    /*
     * Compute the centre of the box, then rotate that about the origin.
     */

    newX = oldX = (arcPtr->bbox[0] + arcPtr->bbox[2]) / 2.0;
    newY = oldY = (arcPtr->bbox[1] + arcPtr->bbox[3]) / 2.0;
    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &newX, &newY);

    /*
     * Apply the translation to the box.
     */

    arcPtr->bbox[0] += newX - oldX;
    arcPtr->bbox[1] += newY - oldY;
    arcPtr->bbox[2] += newX - oldX;
    arcPtr->bbox[3] += newY - oldY;

    /*
     * TODO: update the arc endpoints?
     */

    ComputeArcBbox(canvas, arcPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateArc --
 *
 *	This function is called to move an arc by a given amount.
 *
 * Results:
 *	None.
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1375
1376
1377
1378
1379
1380
1381






















































1382
1383
1384
1385
1386
1387
1388
    arcPtr->bbox[3] = originY + scaleY*(arcPtr->bbox[3] - originY);
    ComputeArcBbox(canvas, arcPtr);
}

/*
 *--------------------------------------------------------------
 *






















































 * TranslateArc --
 *
 *	This function is called to move an arc by a given amount.
 *
 * Results:
 *	None.
 *
2079
2080
2081
2082
2083
2084
2085
2086


2087
2088
2089
2090
2091
2092
2093


2094
2095
2096
2097
2098
2099
2100
	    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);







|
>
>






|
>
>







1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
	    Tcl_AppendToObj(psObj, "0 0 moveto ", -1);
	}
	Tcl_AppendPrintfToObj(psObj,
		"0 0 1 %.15g %.15g arc closepath\nsetmatrix\n",
		ang1, ang2);

	Tcl_ResetResult(interp);
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (arcPtr->outline.gc != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
2112
2113
2114
2115
2116
2117
2118
2119


2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132


2133
2134
2135
2136
2137
2138
2139


2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151


2152
2153
2154
2155
2156
2157
2158


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





2174
2175
2176
2177
2178
2179
2180
		(arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,
		(arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);
	Tcl_AppendPrintfToObj(psObj,
		"0 0 1 %.15g %.15g arc\nsetmatrix\n0 setlinecap\n",
		ang1, ang2);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &arcPtr->outline);


	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (arcPtr->style != ARC_STYLE) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

	    Tcl_ResetResult(interp);
	    if (arcPtr->style == CHORD_STYLE) {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			CHORD_OUTLINE_PTS);
	    } else {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			PIE_OUTLINE1_PTS);
		Tk_CanvasPsColor(interp, canvas, color);


		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

		if (stipple != None) {
		    Tcl_AppendToObj(psObj, "clip ", -1);

		    Tcl_ResetResult(interp);
		    Tk_CanvasPsStipple(interp, canvas, stipple);


		    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
		} else {
		    Tcl_AppendToObj(psObj, "fill\n", -1);
		}
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

		Tcl_ResetResult(interp);
		Tk_CanvasPsPath(interp, canvas,
			arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
			PIE_OUTLINE2_PTS);
	    }
	    Tk_CanvasPsColor(interp, canvas, color);


	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (stipple != None) {
		Tcl_AppendToObj(psObj, "clip ", -1);

		Tcl_ResetResult(interp);
		Tk_CanvasPsStipple(interp, canvas, stipple);


		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    } else {
		Tcl_AppendToObj(psObj, "fill\n", -1);
	    }
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;





}

/*
 *--------------------------------------------------------------
 *
 * StyleParseProc --
 *







|
>
>












|
>
>






|
>
>











|
>
>






|
>
>















>
>
>
>
>







1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
		(arcPtr->bbox[0] + arcPtr->bbox[2])/2, (y1 + y2)/2,
		(arcPtr->bbox[2] - arcPtr->bbox[0])/2, (y1 - y2)/2);
	Tcl_AppendPrintfToObj(psObj,
		"0 0 1 %.15g %.15g arc\nsetmatrix\n0 setlinecap\n",
		ang1, ang2);

	Tcl_ResetResult(interp);
	if (Tk_CanvasPsOutline(canvas, itemPtr, &arcPtr->outline) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (arcPtr->style != ARC_STYLE) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

	    Tcl_ResetResult(interp);
	    if (arcPtr->style == CHORD_STYLE) {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			CHORD_OUTLINE_PTS);
	    } else {
		Tk_CanvasPsPath(interp, canvas, arcPtr->outlinePtr,
			PIE_OUTLINE1_PTS);
		if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
		    goto error;
		}
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

		if (stipple != None) {
		    Tcl_AppendToObj(psObj, "clip ", -1);

		    Tcl_ResetResult(interp);
		    if (Tk_CanvasPsStipple(interp, canvas, stipple) !=TCL_OK){
			goto error;
		    }
		    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
		} else {
		    Tcl_AppendToObj(psObj, "fill\n", -1);
		}
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);

		Tcl_ResetResult(interp);
		Tk_CanvasPsPath(interp, canvas,
			arcPtr->outlinePtr + 2*PIE_OUTLINE1_PTS,
			PIE_OUTLINE2_PTS);
	    }
	    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (stipple != None) {
		Tcl_AppendToObj(psObj, "clip ", -1);

		Tcl_ResetResult(interp);
		if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		    goto error;
		}
		Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	    } else {
		Tcl_AppendToObj(psObj, "fill\n", -1);
	    }
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * StyleParseProc --
 *
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
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;







|







2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
static int
StyleParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    int offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Style *stylePtr = (Style *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*stylePtr = PIESLICE_STYLE;
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
 */

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







|







2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
 */

static const char *
StylePrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Ignored. */
    char *widgRec,		/* Pointer to record for item. */
    int offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Style *stylePtr = (Style *) (widgRec + offset);

    if (*stylePtr == ARC_STYLE) {
Changes to generic/tkCanvBmap.c.
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activebackground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeforeground", NULL, NULL,
	NULL, offsetof(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-background", NULL, NULL,
	NULL, offsetof(BitmapItem, bgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-bitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, bitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledbackground", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledBgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledbitmap", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledBitmap),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledforeground", NULL, NULL,
	NULL, offsetof(BitmapItem, disabledFgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-foreground", NULL, NULL,
	DEF_CANVBMAP_FG, offsetof(BitmapItem, fgColor), 0, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK,
	&stateOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*







|




|

|

|

|

|

|

|


|


|


|

|







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activebackground", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, activeBgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activebitmap", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, activeBitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeforeground", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, activeFgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", Tk_Offset(BitmapItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-background", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, bgColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-bitmap", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, bitmap), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledbackground", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, disabledBgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledbitmap", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, disabledBitmap),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledforeground", NULL, NULL,
	NULL, Tk_Offset(BitmapItem, disabledFgColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-foreground", NULL, NULL,
	DEF_CANVBMAP_FG, Tk_Offset(BitmapItem, fgColor), 0, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK,
	&stateOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double deltaX, double deltaY);

/*







<
<







102
103
104
105
106
107
108


109
110
111
112
113
114
115
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);


static void		ScaleBitmap(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateBitmap(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double deltaX, double deltaY);

/*
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    TranslateBitmap,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateBitmap,		/* rotateProc */
    0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * TkcCreateBitmap --
 *







<
|







134
135
136
137
138
139
140

141
142
143
144
145
146
147
148
    TranslateBitmap,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */

    NULL, 0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * TkcCreateBitmap --
 *
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
static void
DeleteBitmap(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    (void)canvas;

    if (bmapPtr->bitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->bitmap);
    }
    if (bmapPtr->activeBitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->activeBitmap);
    }







<







415
416
417
418
419
420
421

422
423
424
425
426
427
428
static void
DeleteBitmap(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;


    if (bmapPtr->bitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->bitmap);
    }
    if (bmapPtr->activeBitmap != None) {
	Tk_FreeBitmap(display, bmapPtr->activeBitmap);
    }
470
471
472
473
474
475
476

477
478
479
480
481
482
483
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */


static void
ComputeBitmapBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    BitmapItem *bmapPtr)	/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;







>







466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
ComputeBitmapBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    BitmapItem *bmapPtr)	/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;
667
668
669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static double
BitmapToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *coordPtr)		/* Pointer to x and y coordinates. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;
    (void)canvas;

    x1 = bmapPtr->header.x1;
    y1 = bmapPtr->header.y1;
    x2 = bmapPtr->header.x2;
    y2 = bmapPtr->header.y2;

    /*







>








<







664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679

680
681
682
683
684
685
686
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static double
BitmapToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *coordPtr)		/* Pointer to x and y coordinates. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;


    x1 = bmapPtr->header.x1;
    y1 = bmapPtr->header.y1;
    x2 = bmapPtr->header.x2;
    y2 = bmapPtr->header.y2;

    /*
724
725
726
727
728
729
730

731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */


static int
BitmapToArea(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;
    (void)canvas;

    if ((rectPtr[2] <= bmapPtr->header.x1)
	    || (rectPtr[0] >= bmapPtr->header.x2)
	    || (rectPtr[3] <= bmapPtr->header.y1)
	    || (rectPtr[1] >= bmapPtr->header.y2)) {
	return -1;
    }







>









<







721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static int
BitmapToArea(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;


    if ((rectPtr[2] <= bmapPtr->header.x1)
	    || (rectPtr[0] >= bmapPtr->header.x2)
	    || (rectPtr[3] <= bmapPtr->header.y1)
	    || (rectPtr[1] >= bmapPtr->header.y2)) {
	return -1;
    }
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
    double scaleX,		/* Amount to scale in X direction. */
    double scaleY)		/* Amount to scale in Y direction. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    bmapPtr->x = originX + scaleX*(bmapPtr->x - originX);
    bmapPtr->y = originY + scaleY*(bmapPtr->y - originY);
    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * RotateBitmap --
 *
 *	This function is called to rotate a bitmap's origin by a given amount.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the bitmap is rotated by angleRad radians about
 *	(originX, originY), and the bounding box is updated in the generic
 *	part of the item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateBitmap(
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &bmapPtr->x, &bmapPtr->y);
    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateBitmap --







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







781
782
783
784
785
786
787

































788
789
790
791
792
793
794
    double scaleX,		/* Amount to scale in X direction. */
    double scaleY)		/* Amount to scale in Y direction. */
{
    BitmapItem *bmapPtr = (BitmapItem *) itemPtr;

    bmapPtr->x = originX + scaleX*(bmapPtr->x - originX);
    bmapPtr->y = originY + scaleY*(bmapPtr->y - originY);

































    ComputeBitmapBbox(canvas, bmapPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslateBitmap --
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
    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;







<







853
854
855
856
857
858
859

860
861
862
863
864
865
866
    int curRow;
    XColor *fgColor;
    XColor *bgColor;
    Pixmap bitmap;
    Tk_State state = itemPtr->state;
    Tcl_Obj *psObj;
    Tcl_InterpState interpState;


    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }
    fgColor = bmapPtr->fgColor;
    bgColor = bmapPtr->bgColor;
    bitmap = bmapPtr->bitmap;
962
963
964
965
966
967
968
969


970
971
972
973
974
975
976
977
978
979
980
981
982
983
984


985
986
987
988
989
990
991
    if (bgColor != NULL) {
	Tcl_AppendPrintfToObj(psObj,
		"%.15g %.15g moveto %d 0 rlineto 0 %d rlineto "
		"%d 0 rlineto closepath\n",
		x, y, width, height, -width);

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, bgColor);


	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	Tcl_AppendToObj(psObj, "fill\n", -1);
    }

    /*
     * Draw the bitmap, if there is a foreground color. If the bitmap is very
     * large, then chop it up into multiple bitmaps, each consisting of one or
     * more rows. This is needed because Postscript can't handle single
     * strings longer than 64 KBytes long.
     */

    if (fgColor != NULL) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, fgColor);


	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (width > 60000) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't generate Postscript for bitmaps more than 60000"
		    " pixels wide", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);







|
>
>














|
>
>







925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
    if (bgColor != NULL) {
	Tcl_AppendPrintfToObj(psObj,
		"%.15g %.15g moveto %d 0 rlineto 0 %d rlineto "
		"%d 0 rlineto closepath\n",
		x, y, width, height, -width);

	Tcl_ResetResult(interp);
	if (Tk_CanvasPsColor(interp, canvas, bgColor) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	Tcl_AppendToObj(psObj, "fill\n", -1);
    }

    /*
     * Draw the bitmap, if there is a foreground color. If the bitmap is very
     * large, then chop it up into multiple bitmaps, each consisting of one or
     * more rows. This is needed because Postscript can't handle single
     * strings longer than 64 KBytes long.
     */

    if (fgColor != NULL) {
	Tcl_ResetResult(interp);
	if (Tk_CanvasPsColor(interp, canvas, fgColor) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (width > 60000) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't generate Postscript for bitmaps more than 60000"
		    " pixels wide", -1));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "PS", "MEMLIMIT", NULL);
1006
1007
1008
1009
1010
1011
1012
1013
1014


1015
1016
1017
1018
1019
1020
1021
	    }

	    Tcl_AppendPrintfToObj(psObj,
		    "0 -%.15g translate\n%d %d true matrix {\n",
		    (double) rowsThisTime, width, rowsThisTime);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsBitmap(interp, canvas, bitmap, 0, curRow, width,
		    rowsThisTime);


	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    Tcl_AppendToObj(psObj, "\n} imagemask\n", -1);
	}
    }

    /*







|
|
>
>







973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
	    }

	    Tcl_AppendPrintfToObj(psObj,
		    "0 -%.15g translate\n%d %d true matrix {\n",
		    (double) rowsThisTime, width, rowsThisTime);

	    Tcl_ResetResult(interp);
	    if (Tk_CanvasPsBitmap(interp, canvas, bitmap,
		    0, curRow, width, rowsThisTime) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    Tcl_AppendToObj(psObj, "\n} imagemask\n", -1);
	}
    }

    /*
Changes to generic/tkCanvImg.c.
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-activeimage", NULL, NULL,
	NULL, offsetof(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_STRING, "-disabledimage", NULL, NULL,
	NULL, offsetof(ImageItem, disabledImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-image", NULL, NULL,
	NULL, offsetof(ImageItem, imageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ImageChangedProc(ClientData clientData,
			    int x, int y, int width, int height, int imgWidth,
			    int imgHeight);
static int		ImageCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *const argv[]);
static int		ImageToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		ImageToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		ImageToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ComputeImageBbox(Tk_Canvas canvas, ImageItem *imgPtr);
static int		ConfigureImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *const argv[], int flags);
static int		CreateImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const argv[]);
static void		DeleteImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateImage(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*







|




|

|

|

|

|













|
|








|
|


|





<
<







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


97
98
99
100
101
102
103
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-activeimage", NULL, NULL,
	NULL, Tk_Offset(ImageItem, activeImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", Tk_Offset(ImageItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_STRING, "-disabledimage", NULL, NULL,
	NULL, Tk_Offset(ImageItem, disabledImageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-image", NULL, NULL,
	NULL, Tk_Offset(ImageItem, imageString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_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 objc,
			    Tcl_Obj *const objv[]);
static int		ImageToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		ImageToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		ImageToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		ComputeImageBbox(Tk_Canvas canvas, ImageItem *imgPtr);
static int		ConfigureImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateImage(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);


static void		ScaleImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateImage(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
    TranslateImage,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateImage,		/* rotateProc */
    0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateImage --
 *







<
|







122
123
124
125
126
127
128

129
130
131
132
133
134
135
136
    TranslateImage,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* icursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */

    NULL, 0, NULL, NULL
};

/*
 *--------------------------------------------------------------
 *
 * CreateImage --
 *
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
			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);







|







249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
			NULL);
		return TCL_ERROR;
	    }
	}
	if ((Tk_CanvasGetCoordFromObj(interp, canvas, objv[0],
		    &imgPtr->x) != TCL_OK)
		|| (Tk_CanvasGetCoordFromObj(interp, canvas, objv[1],
		    &imgPtr->y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	ComputeImageBbox(canvas, imgPtr);
    } else {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"wrong # coordinates: expected 0 or 2, got %d", objc));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "COORDS", "IMAGE", NULL);
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
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);
    }







<
<







378
379
380
381
382
383
384


385
386
387
388
389
390
391
static void
DeleteImage(
    Tk_Canvas canvas,		/* Info about overall canvas widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;



    if (imgPtr->imageString != NULL) {
	ckfree(imgPtr->imageString);
    }
    if (imgPtr->activeImageString != NULL) {
	ckfree(imgPtr->activeImageString);
    }
422
423
424
425
426
427
428

429
430
431
432
433
434
435
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */


static void
ComputeImageBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    ImageItem *imgPtr)		/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;







>







417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
 *
 * Side effects:
 *	The fields x1, y1, x2, and y2 are updated in the header for itemPtr.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
ComputeImageBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    ImageItem *imgPtr)		/* Item whose bbox is to be recomputed. */
{
    int width, height;
    int x, y;
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    short drawableX, drawableY;
    Tk_Image image;
    Tk_State state = itemPtr->state;
    (void)display;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    image = imgPtr->image;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {







<







530
531
532
533
534
535
536

537
538
539
540
541
542
543
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    short drawableX, drawableY;
    Tk_Image image;
    Tk_State state = itemPtr->state;


    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    image = imgPtr->image;
    if (Canvas(canvas)->currentItemPtr == itemPtr) {
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
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;

    /*







<







588
589
590
591
592
593
594

595
596
597
598
599
600
601
ImageToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *coordPtr)		/* Pointer to x and y coordinates. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;


    x1 = imgPtr->header.x1;
    y1 = imgPtr->header.y1;
    x2 = imgPtr->header.x2;
    y2 = imgPtr->header.y2;

    /*
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;
    (void)canvas;

    if ((rectPtr[2] <= imgPtr->header.x1)
	    || (rectPtr[0] >= imgPtr->header.x2)
	    || (rectPtr[3] <= imgPtr->header.y1)
	    || (rectPtr[1] >= imgPtr->header.y2)) {
	return -1;
    }







<







645
646
647
648
649
650
651

652
653
654
655
656
657
658
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area. */
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;


    if ((rectPtr[2] <= imgPtr->header.x1)
	    || (rectPtr[0] >= imgPtr->header.x2)
	    || (rectPtr[3] <= imgPtr->header.y1)
	    || (rectPtr[1] >= imgPtr->header.y2)) {
	return -1;
    }
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
	}
    }
    if (image == NULL) {
	/*
	 * Image item without actual image specified.
	 */

        return TCL_OK;
    }
    Tk_SizeOfImage(image, &width, &height);

    /*
     * Compute the coordinates of the lower-left corner of the image, taking
     * into account the anchor position for the image.
     */







|







715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
	}
    }
    if (image == NULL) {
	/*
	 * Image item without actual image specified.
	 */

	return TCL_OK;
    }
    Tk_SizeOfImage(image, &width, &height);

    /*
     * Compute the coordinates of the lower-left corner of the image, taking
     * into account the anchor position for the image.
     */
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807

	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate\n", x, y);
    }

    return Tk_PostscriptImage(image, interp, canvasWin,
	    ((TkCanvas *) canvas)->psInfo, 0, 0, width, height, prepass);
}

/*
 *--------------------------------------------------------------
 *
 * RotateImage --
 *
 *	This function is called to rotate an image's origin by a given amount.
 *	This does *not* rotate the contents of the image.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the image anchor is rotated by angleRad radians about
 *	(originX, originY), and the bounding box is updated in the generic
 *	part of the item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateImage(
    Tk_Canvas canvas,
    Tk_Item *itemPtr,
    double originX,
    double originY,
    double angleRad)
{
    ImageItem *imgPtr = (ImageItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &imgPtr->x, &imgPtr->y);
    ComputeImageBbox(canvas, imgPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleImage --
 *
 *	This function is invoked to rescale an item.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







753
754
755
756
757
758
759


































760
761
762
763
764
765
766

	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate\n", x, y);
    }

    return Tk_PostscriptImage(image, interp, canvasWin,
	    ((TkCanvas *) canvas)->psInfo, 0, 0, width, height, prepass);
}



































/*
 *--------------------------------------------------------------
 *
 * ScaleImage --
 *
 *	This function is invoked to rescale an item.
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
    ClientData clientData,	/* Pointer to canvas item for image. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    ImageItem *imgPtr = (ImageItem *)clientData;

    /*
     * If the image's size changed and it's not anchored at its northwest
     * corner then just redisplay the entire area of the image. This is a bit
     * over-conservative, but we need to do something because a size change
     * also means a position change.
     */







|







847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
    ClientData clientData,	/* Pointer to canvas item for image. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    ImageItem *imgPtr = clientData;

    /*
     * If the image's size changed and it's not anchored at its northwest
     * corner then just redisplay the entire area of the image. This is a bit
     * over-conservative, but we need to do something because a size change
     * also means a position change.
     */
Changes to generic/tkCanvLine.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16




17
18
19
20
21
22
23
/*
 * 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







|








>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
 * tkCanvLine.c --
 *
 *	This file implements line items for canvas widgets.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The structure below defines the record for each line item.
 */

typedef enum {
    ARROWS_NONE, ARROWS_FIRST, ARROWS_LAST, ARROWS_BOTH
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
static void		DeleteLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetLineIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static int		LineCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		LineDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		LineInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
static int		LineToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		LineToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		LineToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static int		ArrowParseProc(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, TkSizeT offset);
static const char * ArrowPrintProc(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    Tcl_FreeProc **freeProcPtr);
static int		ParseArrowShape(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, TkSizeT offset);
static const char * PrintArrowShape(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, TkSizeT offset,
			    Tcl_FreeProc **freeProcPtr);
static void		RotateLine(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*







|




|

|








|

|



|

|

<
<







92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124


125
126
127
128
129
130
131
static void		DeleteLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetLineIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, int *indexPtr);
static int		LineCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		LineDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int first, int last);
static void		LineInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj);
static int		LineToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		LineToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *coordPtr);
static int		LineToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static int		ArrowParseProc(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, int offset);
static const char * ArrowPrintProc(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, int offset,
			    Tcl_FreeProc **freeProcPtr);
static int		ParseArrowShape(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    const char *value, char *recordPtr, int offset);
static const char * PrintArrowShape(ClientData clientData,
			    Tk_Window tkwin, char *recordPtr, int offset,
			    Tcl_FreeProc **freeProcPtr);


static void		ScaleLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateLine(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static const Tk_CustomOption pixelOption = {
    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(LineItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-arrow", NULL, NULL,
	"none", offsetof(LineItem, arrow),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowOption},
    {TK_CONFIG_CUSTOM, "-arrowshape", NULL, NULL,
	"8 10 3", offsetof(LineItem, arrowShapeA),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption},
    {TK_CONFIG_CAP_STYLE, "-capstyle", NULL, NULL,
	"butt", offsetof(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(LineItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(LineItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(LineItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(LineItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", offsetof(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(LineItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", offsetof(LineItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", offsetof(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(LineItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", offsetof(LineItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * The structures below defines the line item type by means of functions that
 * can be invoked by generic item code.







|














|


|

|

|


|


|


|

|

|


|

|


|

|

|


|

|


|


|

|

|



|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static const Tk_CustomOption pixelOption = {
    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", Tk_Offset(LineItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-arrow", NULL, NULL,
	"none", Tk_Offset(LineItem, arrow),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowOption},
    {TK_CONFIG_CUSTOM, "-arrowshape", NULL, NULL,
	"8 10 3", Tk_Offset(LineItem, arrowShapeA),
	TK_CONFIG_DONT_SET_DEFAULT, &arrowShapeOption},
    {TK_CONFIG_CAP_STYLE, "-capstyle", NULL, NULL,
	"butt", Tk_Offset(LineItem, capStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, Tk_Offset(LineItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", Tk_Offset(LineItem, outline.offset), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(LineItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", Tk_Offset(LineItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(LineItem, outline.tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", Tk_Offset(LineItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", Tk_Offset(LineItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, Tk_Offset(LineItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", Tk_Offset(LineItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * The structures below defines the line item type by means of functions that
 * can be invoked by generic item code.
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
    TranslateLine,			/* translateProc */
    GetLineIndex,			/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    LineInsert,				/* insertProc */
    LineDeleteCoords,			/* dTextProc */
    NULL,				/* nextPtr */
    RotateLine,				/* rotateProc */
    0, NULL, NULL
};

/*
 * The definition below determines how large are static arrays used to hold
 * spline points (splines larger than this have to have their arrays
 * malloc-ed).
 */







<
|







240
241
242
243
244
245
246

247
248
249
250
251
252
253
254
    TranslateLine,			/* translateProc */
    GetLineIndex,			/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    LineInsert,				/* insertProc */
    LineDeleteCoords,			/* dTextProc */
    NULL,				/* nextPtr */

    NULL, 0, NULL, NULL
};

/*
 * The definition below determines how large are static arrays used to hold
 * spline points (splines larger than this have to have their arrays
 * malloc-ed).
 */
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
	TkIncludePoint((Tk_Item *) linePtr, coordPtr);
    }
    width = linePtr->outline.width;
    if (width < 1.0) {
	width = 1.0;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	if (linePtr->arrow != ARROWS_LAST) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->firstArrowPtr);
	}
	if (linePtr->arrow != ARROWS_FIRST) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr);
	}
    }

    tsoffset = &linePtr->outline.tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	coordPtr = linePtr->coordPtr







|


|







696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
	TkIncludePoint((Tk_Item *) linePtr, coordPtr);
    }
    width = linePtr->outline.width;
    if (width < 1.0) {
	width = 1.0;
    }
    if (linePtr->arrow != ARROWS_NONE) {
	if (linePtr->arrow != ARROWS_LAST && linePtr->firstArrowPtr) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->firstArrowPtr);
	}
	if (linePtr->arrow != ARROWS_FIRST && linePtr->lastArrowPtr) {
	    TkIncludePoint((Tk_Item *) linePtr, linePtr->lastArrowPtr);
	}
    }

    tsoffset = &linePtr->outline.tsoffset;
    if (tsoffset->flags & TK_OFFSET_INDEX) {
	coordPtr = linePtr->coordPtr
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    TCL_UNUSED(int),		/* Describes region of canvas that must be */
    TCL_UNUSED(int),		/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    LineItem *linePtr = (LineItem *)itemPtr;
    XPoint staticPoints[MAX_STATIC_POINTS*3];
    XPoint *pointPtr;
    double linewidth;
    int numPoints;
    Tk_State state = itemPtr->state;

    if (!linePtr->numPoints || (linePtr->outline.gc == NULL)) {







|







835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
    Display *display,		/* Display on which to draw item. */
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    TCL_UNUSED(int),		/* Describes region of canvas that must be */
    TCL_UNUSED(int),		/* redisplayed (not used). */
    TCL_UNUSED(int),
    TCL_UNUSED(int))
{
    LineItem *linePtr = (LineItem *) itemPtr;
    XPoint staticPoints[MAX_STATIC_POINTS*3];
    XPoint *pointPtr;
    double linewidth;
    int numPoints;
    Tk_State state = itemPtr->state;

    if (!linePtr->numPoints || (linePtr->outline.gc == NULL)) {
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975

976

977
978
979
980
981
982






983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021


1022
1023
1024
1025




1026
1027
1028
1029
1030
1031
1032
1033




1034
1035








1036
1037

1038
1039
1040
1041


































1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069


1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
 *--------------------------------------------------------------
 */

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







|




|












>

>
|


|


>
>
>
>
>
>









|















|








|




>
>




>
>
>
>
|
|
|
|
|
<
|
|
>
>
>
>
|

>
>
>
>
>
>
>
>
|
|
>
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|

|
|
|
|
|
|
|
|
|
|
|
>
>
















|









|

|







952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045

1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
 *--------------------------------------------------------------
 */

static void
LineInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    int beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int length, 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=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 == -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 -= beforeThis % 6;
		    objc += 4;
		}

	    } else {
		/*
		 * Custom smoothing method. No optimization is possible.
		 */

		itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    }
	}

	if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	    if (beforeThis < 0) {
		beforeThis = 0;
	    }
	    if (beforeThis + objc > length) {
		objc = length - beforeThis;
	    }

	    itemPtr->x1 = itemPtr->x2 = (int) linePtr->coordPtr[beforeThis];
	    itemPtr->y1 = itemPtr->y2 = (int) linePtr->coordPtr[beforeThis+1];
	    if ((linePtr->firstArrowPtr != NULL) && (beforeThis < 2)) {
		/*
		 * Include old first arrow.
		 */

		for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
			i++, coordPtr += 2) {
		    TkIncludePoint(itemPtr, coordPtr);
		}
	    }
	    if ((linePtr->lastArrowPtr != NULL) && (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) && (beforeThis < 2)) {
	    /*
	     * Include new first arrow.
	     */

	    for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		    i++, coordPtr += 2) {
		TkIncludePoint(itemPtr, coordPtr);
	    }
	}
	if ((linePtr->lastArrowPtr != NULL) && (beforeThis+objc >= length)) {
	    /*
	     * 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);







|
|


|
>
>








|


|


|
|

|


>
>
>
>
>
>










>
|
>
>
>
>
>
|
>
|
>
|
>
>
>
>
>
>
>
|
|
>
>
>
>
|
|
>
>
>
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
>
>
>
>

>
>
>
>
>
>
>
>
>
>
>
|







>
>















|







1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
 *--------------------------------------------------------------
 */

static void
LineDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    int first,			/* Index of first character to delete. */
    int last)			/* Index of last character to delete. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    int count, i, first1, last1, 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 (first < 0) {
	first = 0;
    }
    if (last >= length) {
	last = length - 2;
    }
    if (first > last) {
	return;
    }

    /*
     * With arrows, the end points of the line are adjusted so that a thick
     * line doesn't stick out past the arrowheads (see ConfigureArrows).
     */

    if (linePtr->firstArrowPtr != NULL) {
	linePtr->coordPtr[0] = linePtr->firstArrowPtr[0];
	linePtr->coordPtr[1] = linePtr->firstArrowPtr[1];
    }
    if (linePtr->lastArrowPtr != NULL) {
	linePtr->coordPtr[length-2] = linePtr->lastArrowPtr[0];
	linePtr->coordPtr[length-1] = linePtr->lastArrowPtr[1];
    }
    first1 = first;
    last1 = last;
    nbDelPoints = (last - first) / 2 + 1;

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







|









|

|







1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
    if (linePtr->arrow != ARROWS_NONE) {
	ConfigureArrows(canvas, linePtr);
    }
    if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	double width;
	int intWidth;

	if ((linePtr->firstArrowPtr != NULL) && (first1 < 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);
	    }
	}
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
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);







|

<

|
<

<
|
<
<
>
|

<
<
<
<
<
|
<
|
|







1862
1863
1864
1865
1866
1867
1868
1869
1870

1871
1872

1873

1874


1875
1876
1877





1878

1879
1880
1881
1882
1883
1884
1885
1886
1887
GetLineIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular coord in
				 * itemPtr's line. */
    int *indexPtr)		/* Where to store converted index. */
{

    LineItem *linePtr = (LineItem *) itemPtr;
    const char *string = Tcl_GetString(obj);



    if (string[0] == 'e') {


	if (strncmp(string, "end", obj->length) == 0) {
	    *indexPtr = 2*linePtr->numPoints;
	} else {





	    goto badIndex;

	}
    } else if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
1786
1787
1788
1789
1790
1791
1792


1793









1794
1795
1796
1797
1798
1799

1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
	    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;
}

/*
 *--------------------------------------------------------------
 *
 * TranslateLine --
 *







>
>
|
>
>
>
>
>
>
>
>
>
|
|
|
|

|
>
|
|
|
<
<







1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929


1930
1931
1932
1933
1934
1935
1936
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
	    goto badIndex;
	}
	*indexPtr &= -2;	/* If index is odd, make it even. */
	if (*indexPtr < 0){
	    *indexPtr = 0;
	} else if (*indexPtr > (2*linePtr->numPoints)) {
	    *indexPtr = (2*linePtr->numPoints);
	}
    }
    return TCL_OK;

    /*
     * Some of the paths here leave messages in interp->result, so we have to
     * clear it out before storing our own message.
     */

  badIndex:
    Tcl_ResetResult(interp);
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "LINE", NULL);
    return TCL_ERROR;


}

/*
 *--------------------------------------------------------------
 *
 * TranslateLine --
 *
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------
 *
 * RotateLine --
 *
 *	This function is called to rotate a line by a given amount about a
 *	point.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the line is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateLine(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    LineItem *linePtr = (LineItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = linePtr->coordPtr; i < linePtr->numPoints;
	    i++, coordPtr += 2) {
	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    if (linePtr->firstArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->firstArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    if (linePtr->lastArrowPtr != NULL) {
	for (i = 0, coordPtr = linePtr->lastArrowPtr; i < PTS_IN_ARROW;
		i++, coordPtr += 2) {
	    TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
	}
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------
 *
 * ParseArrowShape --
 *
 *	This function is called back during option parsing to parse arrow
 *	shape information.
 *
 * Results:
 *	The return value is a standard Tcl result: TCL_OK means that the arrow







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1978
1979
1980
1981
1982
1983
1984


















































1985
1986
1987
1988
1989
1990
1991
    }
    ComputeLineBbox(canvas, linePtr);
}

/*
 *--------------------------------------------------------------
 *


















































 * ParseArrowShape --
 *
 *	This function is called back during option parsing to parse arrow
 *	shape information.
 *
 * Results:
 *	The return value is a standard Tcl result: TCL_OK means that the arrow
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
ParseArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Not used. */
    const char *value,		/* Textual specification of arrow shape. */
    char *recordPtr,		/* Pointer to item record in which to store
				 * arrow information. */
    TkSizeT offset)			/* Offset of shape information in widget
				 * record. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    double a, b, c;
    int argc;
    const char **argv = NULL;

    if ((size_t)offset != offsetof(LineItem, arrowShapeA)) {
	Tcl_Panic("ParseArrowShape received bogus offset");
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	goto syntaxError;
    } else if (argc != 3) {
	goto syntaxError;







|







|







2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
ParseArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Window),		/* Not used. */
    const char *value,		/* Textual specification of arrow shape. */
    char *recordPtr,		/* Pointer to item record in which to store
				 * arrow information. */
    int offset)			/* Offset of shape information in widget
				 * record. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    double a, b, c;
    int argc;
    const char **argv = NULL;

    if (offset != Tk_Offset(LineItem, arrowShapeA)) {
	Tcl_Panic("ParseArrowShape received bogus offset");
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	goto syntaxError;
    } else if (argc != 3) {
	goto syntaxError;
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014

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







|






|







2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089

static const char *
PrintArrowShape(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(Tk_Window),		/* Window associated with linePtr's widget. */
    char *recordPtr,		/* Pointer to item record containing current
				 * shape information. */
    TCL_UNUSED(int),			/* Offset of arrow information in record. */
    Tcl_FreeProc **freeProcPtr)	/* Store address of function to call to free
				 * string here. */
{
    LineItem *linePtr = (LineItem *) recordPtr;
    char *buffer = (char *)ckalloc(120);

    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;







|







2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
static int
ArrowParseProc(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Used for reporting errors. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    int offset)			/* Offset into item. */
{
    int c;
    size_t length;
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    if (value == NULL || *value == 0) {
	*arrowPtr = ARROWS_NONE;
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
 */

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







|







2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
 */

static const char *
ArrowPrintProc(
    TCL_UNUSED(void *),	/* Ignored. */
    TCL_UNUSED(Tk_Window),		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    int offset,			/* Offset into item. */
    TCL_UNUSED(Tcl_FreeProc **))	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Arrows *arrowPtr = (Arrows *) (widgRec + offset);

    switch (*arrowPtr) {
2362
2363
2364
2365
2366
2367
2368
2369


2370
2371
2372
2373
2374
2375


2376
2377
2378
2379
2380
2381
2382
	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;
    }








|
>
>





|
>
>







2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
	Tcl_AppendPrintfToObj(psObj, "%.15g %.15g translate %.15g %.15g",
		linePtr->coordPtr[0], Tk_CanvasPsY(canvas, linePtr->coordPtr[1]),
		width/2.0, width/2.0);
	Tcl_AppendToObj(psObj,
		" scale 1 0 moveto 0 0 1 0 360 arc\nsetmatrix\n", -1);

	Tcl_ResetResult(interp);
	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);
	    Tcl_ResetResult(interp);
	    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;
    }

2437
2438
2439
2440
2441
2442
2443
2444


2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456


2457
2458
2459
2460
2461
2462
2463


2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474





2475
2476
2477
2478
2479
2480
2481
	style = 2;
    } else {
	style = 0;
    }
    Tcl_AppendPrintfToObj(psObj, "%d setlinejoin\n", style);

    Tcl_ResetResult(interp);
    Tk_CanvasPsOutline(canvas, itemPtr, &linePtr->outline);


    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    /*
     * Output polygons for the arrowheads, if there are any.
     */

    if (linePtr->firstArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->firstArrowPtr, psObj);


    }
    if (linePtr->lastArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr, psObj);


    }

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;





}

/*
 *--------------------------------------------------------------
 *
 * ArrowheadPostscript --
 *







|
>
>










|
|
>
>





|
|
>
>











>
>
>
>
>







2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
	style = 2;
    } else {
	style = 0;
    }
    Tcl_AppendPrintfToObj(psObj, "%d setlinejoin\n", style);

    Tcl_ResetResult(interp);
    if (Tk_CanvasPsOutline(canvas, itemPtr, &linePtr->outline) != TCL_OK) {
	goto error;
    }
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    /*
     * Output polygons for the arrowheads, if there are any.
     */

    if (linePtr->firstArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	if (ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->firstArrowPtr, psObj) != TCL_OK) {
	    goto error;
	}
    }
    if (linePtr->lastArrowPtr != NULL) {
	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	}
	if (ArrowheadPostscript(interp, canvas, linePtr,
		linePtr->lastArrowPtr, psObj) != TCL_OK) {
	    goto error;
	}
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 *--------------------------------------------------------------
 *
 * ArrowheadPostscript --
 *
2527
2528
2529
2530
2531
2532
2533
2534


2535
2536
2537
2538
2539
2540
2541
    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;
}








|
>
>







2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
    Tk_CanvasPsPath(interp, canvas, arrowPtr, PTS_IN_ARROW);
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (stipple != None) {
	Tcl_AppendToObj(psObj, "clip ", -1);

	Tcl_ResetResult(interp);
	if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    } else {
	Tcl_AppendToObj(psObj, "fill\n", -1);
    }
    return TCL_OK;
}

Changes to generic/tkCanvPoly.c.
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static const Tk_CustomOption pixelOption = {
    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.activeStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", offsetof(PolygonItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", offsetof(PolygonItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", offsetof(PolygonItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},

    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	NULL, offsetof(PolygonItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", offsetof(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(PolygonItem, tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(PolygonItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", offsetof(PolygonItem, outline.tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, offsetof(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", offsetof(PolygonItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", offsetof(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(PolygonItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", offsetof(PolygonItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */







|














|


|

|

|


|

|


|


|


|


|

|


|


|

|

>

|

|

|


|

|


|

|


|

|

|



|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
static const Tk_CustomOption smoothOption = {
    TkSmoothParseProc, TkSmoothPrintProc, NULL
};
static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption dashOption = {
    TkCanvasDashParseProc, TkCanvasDashPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc,
    INT2PTR(TK_OFFSET_RELATIVE|TK_OFFSET_INDEX)
};
static const Tk_CustomOption pixelOption = {
    TkPixelParseProc, TkPixelPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_CUSTOM, "-activedash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.activeDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, activeFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-activeoutline", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activeoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.activeStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, activeFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-activewidth", NULL, NULL,
	"0.0", Tk_Offset(PolygonItem, outline.activeWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_CUSTOM, "-dash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.dash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_PIXELS, "-dashoffset", NULL, NULL,
	"0", Tk_Offset(PolygonItem, outline.offset),
	TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-disableddash", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledDash),
	TK_CONFIG_NULL_OK, &dashOption},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, disabledFillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-disabledoutline", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledColor),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledoutlinestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.disabledStipple),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, disabledFillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-disabledwidth", NULL, NULL,
	"0.0", Tk_Offset(PolygonItem, outline.disabledWidth),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    /* Remark: Default for -fill should be NULL, see [2860519]. Will be fixed in Tk 8.7 */
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, Tk_Offset(PolygonItem, fillColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_JOIN_STYLE, "-joinstyle", NULL, NULL,
	"round", Tk_Offset(PolygonItem, joinStyle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(PolygonItem, tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_COLOR, "-outline", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-outlineoffset", NULL, NULL,
	"0,0", Tk_Offset(PolygonItem, outline.tsoffset),
	TK_CONFIG_NULL_OK, &offsetOption},
    {TK_CONFIG_BITMAP, "-outlinestipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, outline.stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-smooth", NULL, NULL,
	"0", Tk_Offset(PolygonItem, smooth),
	TK_CONFIG_DONT_SET_DEFAULT, &smoothOption},
    {TK_CONFIG_INT, "-splinesteps", NULL, NULL,
	"12", Tk_Offset(PolygonItem, splineSteps), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, Tk_Offset(PolygonItem, fillStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_CUSTOM, "-width", NULL, NULL,
	"1.0", Tk_Offset(PolygonItem, outline.width),
	TK_CONFIG_DONT_SET_DEFAULT, &pixelOption},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
static void		DeletePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr,  Display *display);
static void		DisplayPolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetPolygonIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static int		PolygonCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		PolygonDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		PolygonInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
static int		PolygonToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		PolygonToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		PolygonToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		RotatePolygon(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScalePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslatePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*







|




|

|






<
<







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


181
182
183
184
185
186
187
static void		DeletePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr,  Display *display);
static void		DisplayPolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static int		GetPolygonIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, int *indexPtr);
static int		PolygonCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		PolygonDeleteCoords(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int first, int last);
static void		PolygonInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int beforeThis, Tcl_Obj *obj);
static int		PolygonToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		PolygonToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		PolygonToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);


static void		ScalePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslatePolygon(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
    TranslatePolygon,			/* translateProc */
    GetPolygonIndex,	/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    PolygonInsert,		/* insertProc */
    PolygonDeleteCoords,		/* dTextProc */
    NULL,				/* nextPtr */
    RotatePolygon,			/* rotateProc */
    0, NULL, NULL
};

/*
 * The definition below determines how large are static arrays used to hold
 * spline points (splines larger than this have to have their arrays
 * malloc-ed).
 */







<
|







206
207
208
209
210
211
212

213
214
215
216
217
218
219
220
    TranslatePolygon,			/* translateProc */
    GetPolygonIndex,	/* indexProc */
    NULL,				/* icursorProc */
    NULL,				/* selectionProc */
    PolygonInsert,		/* insertProc */
    PolygonDeleteCoords,		/* dTextProc */
    NULL,				/* nextPtr */

    NULL, 0, NULL, NULL
};

/*
 * The definition below determines how large are static arrays used to hold
 * spline points (splines larger than this have to have their arrays
 * malloc-ed).
 */
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
		index = 0;
	    }
	}
	index %= (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	if (index < 0) {
	    index += (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	}
 	tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
	tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
    } else {
	if (tsoffset->flags & TK_OFFSET_LEFT) {
	    tsoffset->xoffset = polyPtr->header.x1;
	} else if (tsoffset->flags & TK_OFFSET_CENTER) {
	    tsoffset->xoffset = (polyPtr->header.x1 + polyPtr->header.x2)/2;
	} else if (tsoffset->flags & TK_OFFSET_RIGHT) {







|







673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
		index = 0;
	    }
	}
	index %= (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	if (index < 0) {
	    index += (polyPtr->numPoints - polyPtr->autoClosed) * 2;
	}
	tsoffset->xoffset = (int) (polyPtr->coordPtr[index] + 0.5);
	tsoffset->yoffset = (int) (polyPtr->coordPtr[index+1] + 0.5);
    } else {
	if (tsoffset->flags & TK_OFFSET_LEFT) {
	    tsoffset->xoffset = polyPtr->header.x1;
	} else if (tsoffset->flags & TK_OFFSET_CENTER) {
	    tsoffset->xoffset = (polyPtr->header.x1 + polyPtr->header.x2)/2;
	} else if (tsoffset->flags & TK_OFFSET_RIGHT) {
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036

1037

1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
 *--------------------------------------------------------------
 */

static void
PolygonInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    TkSizeT beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int length, objc, i;
    Tcl_Obj **objv;
    double *newCoordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }

    length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while ((int)beforeThis > length) {
	beforeThis -= length;
    }
    while ((int)beforeThis < 0) {
	beforeThis += length;
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + 2 + objc));
    for (i=0; i<(int)beforeThis; i++) {
	newCoordPtr[i] = polyPtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i+beforeThis]) != TCL_OK){
	    ckfree(newCoordPtr);
	    return;
	}
    }

    for (i=(int)beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = polyPtr->coordPtr[i];
    }
    if (polyPtr->coordPtr) {
	ckfree(polyPtr->coordPtr);
    }
    length += objc;
    polyPtr->coordPtr = newCoordPtr;







|




|












>

>
|


|



|










|







1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
 *--------------------------------------------------------------
 */

static void
PolygonInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Line item to be modified. */
    int beforeThis,		/* Index before which new coordinates are to
				 * be inserted. */
    Tcl_Obj *obj)		/* New coordinates to be inserted. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int length, oriNumPoints, objc, nbInsPoints, i;
    Tcl_Obj **objv;
    double *newCoordPtr;
    Tk_State state = itemPtr->state;

    if (state == TK_STATE_NULL) {
	state = Canvas(canvas)->canvas_state;
    }

    if (!obj || (Tcl_ListObjGetElements(NULL, obj, &objc, &objv) != TCL_OK)
	    || !objc || objc&1) {
	return;
    }
    oriNumPoints = polyPtr->numPoints - polyPtr->autoClosed;
    length = 2*(polyPtr->numPoints - polyPtr->autoClosed);
    nbInsPoints = objc / 2;
    while (beforeThis > length) {
	beforeThis -= length;
    }
    while (beforeThis < 0) {
	beforeThis += length;
    }
    newCoordPtr = (double *)ckalloc(sizeof(double) * (length + 2 + objc));
    for (i=0; i<beforeThis; i++) {
	newCoordPtr[i] = polyPtr->coordPtr[i];
    }
    for (i=0; i<objc; i++) {
	if (Tcl_GetDoubleFromObj(NULL, objv[i],
		&newCoordPtr[i+beforeThis]) != TCL_OK){
	    ckfree(newCoordPtr);
	    return;
	}
    }

    for (i=beforeThis; i<length; i++) {
	newCoordPtr[i+objc] = polyPtr->coordPtr[i];
    }
    if (polyPtr->coordPtr) {
	ckfree(polyPtr->coordPtr);
    }
    length += objc;
    polyPtr->coordPtr = newCoordPtr;
1088
1089
1090
1091
1092
1093
1094


1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110

1111
1112

1113





1114
1115
1116




1117

1118





















1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146

1147
1148
1149
1150
1151
1152
1153
	/*
	 * 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);
}

/*
 *--------------------------------------------------------------







>
>


|













>


>

>
>
>
>
>
|
|
|
>
>
>
>

>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
	/*
	 * This is some optimizing code that will result that only the part of
	 * the polygon that changed (and the objects that are overlapping with
	 * that part) need to be redrawn. A special flag is set that instructs
	 * the general canvas code not to redraw the whole object. If this
	 * flag is not set, the canvas will do the redrawing, otherwise I have
	 * to do it here.
	 * Rationale for the optimization code can be found in Tk ticket
	 * [5fb8145997].
	 */

	double width;
	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(beforeThis) % 6;
		    objc += 4;
		}

	    } else {
		/*
		 * Custom smoothing method. No optimization is possible.
		 */

		itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    }
	}

	if (itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW) {
	    /*
	     * Be careful; beforeThis could now be negative
	     */

	    for (i=beforeThis; i<beforeThis+objc; i+=2) {
		j = i;
		if (j < 0) {
		    j += length;
		} else if (j >= length) {
		    j -= length;
		}
		TkIncludePoint(itemPtr, polyPtr->coordPtr+j);
	    }
	    width = polyPtr->outline.width;
	    if (Canvas(canvas)->currentItemPtr == itemPtr) {
		if (polyPtr->outline.activeWidth > width) {
		    width = polyPtr->outline.activeWidth;
		}
	    } else if (state == TK_STATE_DISABLED) {
		if (polyPtr->outline.disabledWidth > 0.0) {
		    width = polyPtr->outline.disabledWidth;
		}
	    }
	    itemPtr->x1 -= (int) width;
	    itemPtr->y1 -= (int) width;
	    itemPtr->x2 += (int) width;
	    itemPtr->y2 += (int) width;
	    Tk_CanvasEventuallyRedraw(canvas,
		    itemPtr->x1, itemPtr->y1, itemPtr->x2, itemPtr->y2);
	}
    }

    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
 *--------------------------------------------------------------
 */

static void
PolygonDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Index of first character to delete. */
    TkSizeT last)			/* Index of last character to delete. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int count, i;
    int length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while ((int)first >= length) {
	first -= length;
    }
    while ((int)first < 0) {
	first += length;
    }
    while ((int)last >= length) {
	last -= length;
    }
    while ((int)last < 0) {
	last += length;
    }

    first &= -2;
    last &= -2;

    count = last + 2 - first;







|
|





|


|


|


|







1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
 *--------------------------------------------------------------
 */

static void
PolygonDeleteCoords(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    int first,			/* Index of first character to delete. */
    int last)			/* Index of last character to delete. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    int count, i;
    int length = 2*(polyPtr->numPoints - polyPtr->autoClosed);

    while (first >= length) {
	first -= length;
    }
    while (first < 0) {
	first += length;
    }
    while (last >= length) {
	last -= length;
    }
    while (last < 0) {
	last += length;
    }

    first &= -2;
    last &= -2;

    count = last + 2 - first;
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
    }

    if (last >= first) {
	for (i=last+2; i<length; i++) {
	    polyPtr->coordPtr[i-count] = polyPtr->coordPtr[i];
	}
    } else {
	for (i=last; i<=(int)first; i++) {
	    polyPtr->coordPtr[i-last] = polyPtr->coordPtr[i];
	}
    }
    polyPtr->coordPtr[length-count] = polyPtr->coordPtr[0];
    polyPtr->coordPtr[length-count+1] = polyPtr->coordPtr[1];
    polyPtr->numPoints -= count/2;
    ComputePolygonBbox(canvas, polyPtr);







|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
    }

    if (last >= first) {
	for (i=last+2; i<length; i++) {
	    polyPtr->coordPtr[i-count] = polyPtr->coordPtr[i];
	}
    } else {
	for (i=last; i<=first; i++) {
	    polyPtr->coordPtr[i-last] = polyPtr->coordPtr[i];
	}
    }
    polyPtr->coordPtr[length-count] = polyPtr->coordPtr[0];
    polyPtr->coordPtr[length-count+1] = polyPtr->coordPtr[1];
    polyPtr->numPoints -= count/2;
    ComputePolygonBbox(canvas, polyPtr);
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
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);







|

<

|
<

<
|
|
<
<
<
|
<
|
|
<
<
|







1705
1706
1707
1708
1709
1710
1711
1712
1713

1714
1715

1716

1717
1718



1719

1720
1721


1722
1723
1724
1725
1726
1727
1728
1729
GetPolygonIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular coord in
				 * itemPtr's line. */
    int *indexPtr)		/* Where to store converted index. */
{

    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    const char *string = Tcl_GetString(obj);



    if (string[0] == 'e') {
	if (strncmp(string, "end", obj->length) != 0) {



	    goto badIndex;

	}
	*indexPtr = 2*(polyPtr->numPoints - polyPtr->autoClosed);


    } else if (string[0] == '@') {
	int i;
	double x, y, bestDist, dist, *coordPtr;
	char *end;
	const char *p;

	p = string+1;
	x = strtod(p, &end);
1716
1717
1718
1719
1720
1721
1722
















1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
















	/*
	 * Some of the paths here leave messages in interp->result, so we have to
	 * clear it out before storing our own message.
	 */

    badIndex:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
	Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "POLY", NULL);
	return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * RotatePolygon --
 *
 *	This function is called to rotate a polygon by a given amount about a
 *	point.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the polygon is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotatePolygon(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being moved. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    PolygonItem *polyPtr = (PolygonItem *) itemPtr;
    double *coordPtr;
    int i;
    double s = sin(angleRad), c = cos(angleRad);

    for (i = 0, coordPtr = polyPtr->coordPtr; i < polyPtr->numPoints;
	    i++, coordPtr += 2) {
	TkRotatePoint(originX, originY, s, c, &coordPtr[0], &coordPtr[1]);
    }
    ComputePolygonBbox(canvas, polyPtr);
}

/*
 *--------------------------------------------------------------
 *
 * TranslatePolygon --
 *







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|

|
|
|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774








































1775
1776
1777
1778
1779
1780
1781
	    if (dist < bestDist) {
		bestDist = dist;
		*indexPtr = 2*i;
	    }
	    coordPtr += 2;
	}
    } else {
	int count = 2*(polyPtr->numPoints - polyPtr->autoClosed);

	if (Tcl_GetIntFromObj(interp, obj, indexPtr) != TCL_OK) {
	    goto badIndex;
	}
	*indexPtr &= -2; /* if odd, make it even */
	if (!count) {
	    *indexPtr = 0;
	} else if (*indexPtr > 0) {
	    *indexPtr = ((*indexPtr - 2) % count) + 2;
	} else {
	    *indexPtr = -((-(*indexPtr)) % count);
	}
    }
    return TCL_OK;

    /*
     * Some of the paths here leave messages in interp->result, so we have to
     * clear it out before storing our own message.
     */

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM_INDEX", "POLY", NULL);
    return TCL_ERROR;








































}

/*
 *--------------------------------------------------------------
 *
 * TranslatePolygon --
 *
1921
1922
1923
1924
1925
1926
1927
1928


1929
1930
1931
1932
1933
1934
1935


1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956


1957
1958
1959
1960
1961
1962
1963


1964
1965
1966
1967
1968
1969
1970
		width/2.0, width/2.0);

	/*
	 * Color it in.
	 */

	Tcl_ResetResult(interp);
	Tk_CanvasPsColor(interp, canvas, color);


	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, stipple);


	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;
    }

    /*
     * Fill the area of the polygon.
     */

    if (fillColor != NULL && polyPtr->numPoints > 3) {
	Tcl_ResetResult(interp);
	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	Tk_CanvasPsColor(interp, canvas, fillColor);


	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "eoclip ", -1);

	    Tcl_ResetResult(interp);
	    Tk_CanvasPsStipple(interp, canvas, fillStipple);


	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "eofill\n", -1);







|
>
>






|
>
>




















|
>
>






|
>
>







1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
		width/2.0, width/2.0);

	/*
	 * Color it in.
	 */

	Tcl_ResetResult(interp);
	if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (stipple != None) {
	    Tcl_AppendToObj(psObj, "clip ", -1);

	    Tcl_ResetResult(interp);
	    if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	} else {
	    Tcl_AppendToObj(psObj, "fill\n", -1);
	}
	goto done;
    }

    /*
     * Fill the area of the polygon.
     */

    if (fillColor != NULL && polyPtr->numPoints > 3) {
	Tcl_ResetResult(interp);
	if (!polyPtr->smooth || !polyPtr->smooth->postscriptProc) {
	    Tk_CanvasPsPath(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints);
	} else {
	    polyPtr->smooth->postscriptProc(interp, canvas, polyPtr->coordPtr,
		    polyPtr->numPoints, polyPtr->splineSteps);
	}
	if (Tk_CanvasPsColor(interp, canvas, fillColor) != TCL_OK) {
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	if (fillStipple != None) {
	    Tcl_AppendToObj(psObj, "eoclip ", -1);

	    Tcl_ResetResult(interp);
	    if (Tk_CanvasPsStipple(interp, canvas, fillStipple) != TCL_OK) {
		goto error;
	    }
	    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

	    if (color != NULL) {
		Tcl_AppendToObj(psObj, "grestore gsave\n", -1);
	    }
	} else {
	    Tcl_AppendToObj(psObj, "eofill\n", -1);
1992
1993
1994
1995
1996
1997
1998
1999


2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011





2012
2013
2014
2015
2016
2017
2018
2019
2020
	    style = 2;
	} else {
	    style = 0;
	}
	Tcl_AppendPrintfToObj(psObj, "%d setlinejoin 1 setlinecap\n", style);

	Tcl_ResetResult(interp);
	Tk_CanvasPsOutline(canvas, itemPtr, &polyPtr->outline);


	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;





}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
>
>












>
>
>
>
>









2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
	    style = 2;
	} else {
	    style = 0;
	}
	Tcl_AppendPrintfToObj(psObj, "%d setlinejoin 1 setlinecap\n", style);

	Tcl_ResetResult(interp);
	if (Tk_CanvasPsOutline(canvas, itemPtr, &polyPtr->outline) != TCL_OK){
	    goto error;
	}
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
    }

    /*
     * Plug the accumulated postscript back into the result.
     */

  done:
    (void) Tcl_RestoreInterpState(interp, interpState);
    Tcl_AppendObjToObj(Tcl_GetObjResult(interp), psObj);
    Tcl_DecrRefCount(psObj);
    return TCL_OK;

  error:
    Tcl_DiscardInterpState(interpState);
    Tcl_DecrRefCount(psObj);
    return TCL_ERROR;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkCanvPs.c.
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * The table below provides a template that's used to process arguments to the
 * canvas "postscript" command and fill in TkPostscriptInfo structures.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-colormap", NULL, NULL,
	"", offsetof(TkPostscriptInfo, colorVar), 0, NULL},
    {TK_CONFIG_STRING, "-colormode", NULL, NULL,
	"", offsetof(TkPostscriptInfo, colorMode), 0, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	"", offsetof(TkPostscriptInfo, fileName), 0, NULL},
    {TK_CONFIG_STRING, "-channel", NULL, NULL,
	"", offsetof(TkPostscriptInfo, channelName), 0, NULL},
    {TK_CONFIG_STRING, "-fontmap", NULL, NULL,
	"", offsetof(TkPostscriptInfo, fontVar), 0, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"", offsetof(TkPostscriptInfo, height), 0, NULL},
    {TK_CONFIG_ANCHOR, "-pageanchor", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageAnchor), 0, NULL},
    {TK_CONFIG_STRING, "-pageheight", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageHeightString), 0, NULL},
    {TK_CONFIG_STRING, "-pagewidth", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageWidthString), 0, NULL},
    {TK_CONFIG_STRING, "-pagex", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageXString), 0, NULL},
    {TK_CONFIG_STRING, "-pagey", NULL, NULL,
	"", offsetof(TkPostscriptInfo, pageYString), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-prolog", NULL, NULL,
	"", offsetof(TkPostscriptInfo, prolog), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-rotate", NULL, NULL,
	"", offsetof(TkPostscriptInfo, rotate), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"", offsetof(TkPostscriptInfo, width), 0, NULL},
    {TK_CONFIG_PIXELS, "-x", NULL, NULL,
	"", offsetof(TkPostscriptInfo, x), 0, NULL},
    {TK_CONFIG_PIXELS, "-y", NULL, NULL,
	"", offsetof(TkPostscriptInfo, y), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations for functions defined later in this file:
 */








|

|

|

|

|

|

|

|

|

|

|

|

|

|

|

|







90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/*
 * The table below provides a template that's used to process arguments to the
 * canvas "postscript" command and fill in TkPostscriptInfo structures.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-colormap", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, colorVar), 0, NULL},
    {TK_CONFIG_STRING, "-colormode", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, colorMode), 0, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, fileName), 0, NULL},
    {TK_CONFIG_STRING, "-channel", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, channelName), 0, NULL},
    {TK_CONFIG_STRING, "-fontmap", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, fontVar), 0, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, height), 0, NULL},
    {TK_CONFIG_ANCHOR, "-pageanchor", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageAnchor), 0, NULL},
    {TK_CONFIG_STRING, "-pageheight", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageHeightString), 0, NULL},
    {TK_CONFIG_STRING, "-pagewidth", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageWidthString), 0, NULL},
    {TK_CONFIG_STRING, "-pagex", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageXString), 0, NULL},
    {TK_CONFIG_STRING, "-pagey", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, pageYString), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-prolog", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, prolog), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-rotate", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, rotate), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, width), 0, NULL},
    {TK_CONFIG_PIXELS, "-x", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, x), 0, NULL},
    {TK_CONFIG_PIXELS, "-y", NULL, NULL,
	"", Tk_Offset(TkPostscriptInfo, y), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations for functions defined later in this file:
 */

153
154
155
156
157
158
159

160
161
162
163
164
165
166
 *
 * 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







>







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
 *
 * Side effects:
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

    /* ARGSUSED */
int
TkCanvPostscriptCmd(
    TkCanvas *canvasPtr,	/* Information about canvas widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char **argv)		/* Argument strings. Caller has already parsed
				 * this command enough to know that argv[1] is
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
	/*
	 * Insert the prolog
	 */

	Tcl_AppendObjToObj(psObj, preambleObj);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
	    channelWriteFailed:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"problem writing postscript data to channel: %s",
			Tcl_PosixError(interp)));
		result = TCL_ERROR;
		goto cleanup;
	    }







|







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
	/*
	 * Insert the prolog
	 */

	Tcl_AppendObjToObj(psObj, preambleObj);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
	    channelWriteFailed:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"problem writing postscript data to channel: %s",
			Tcl_PosixError(interp)));
		result = TCL_ERROR;
		goto cleanup;
	    }
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
		psInfo.x2, Tk_PostscriptY((double)psInfo.y,
			(Tk_PostscriptInfo)psInfoPtr),
		psInfo.x2, Tk_PostscriptY((double)psInfo.y2,
			(Tk_PostscriptInfo)psInfoPtr),
		psInfo.x, Tk_PostscriptY((double)psInfo.y2,
			(Tk_PostscriptInfo)psInfoPtr));
	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);
	    psObj = Tcl_NewObj();
	}
    }








|







541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
		psInfo.x2, Tk_PostscriptY((double)psInfo.y,
			(Tk_PostscriptInfo)psInfoPtr),
		psInfo.x2, Tk_PostscriptY((double)psInfo.y2,
			(Tk_PostscriptInfo)psInfoPtr),
		psInfo.x, Tk_PostscriptY((double)psInfo.y2,
			(Tk_PostscriptInfo)psInfoPtr));
	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);
	    psObj = Tcl_NewObj();
	}
    }

572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
	}

	result = itemPtr->typePtr->postscriptProc(interp,
		(Tk_Canvas) canvasPtr, itemPtr, 0);
	if (result != TCL_OK) {
	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (generating Postscript for item %d)",
		    (int)itemPtr->id));
	    goto cleanup;
	}

	Tcl_AppendToObj(psObj, "gsave\n", -1);
	Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));
	Tcl_AppendToObj(psObj, "grestore\n", -1);
	Tcl_ResetResult(interp);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);
	    psObj = Tcl_NewObj();
	}
    }

    /*
     * Output page-end information, such as commands to print the page and
     * document trailer stuff.
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"restore showpage\n\n"
		"%%Trailer\n"
		"end\n"
		"%%EOF\n", -1);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) {
		goto channelWriteFailed;
	    }
	}
    }

    if (psInfo.chan == NULL) {
	Tcl_SetObjResult(interp, psObj);







|









|




















|







573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
	}

	result = itemPtr->typePtr->postscriptProc(interp,
		(Tk_Canvas) canvasPtr, itemPtr, 0);
	if (result != TCL_OK) {
	    Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		    "\n    (generating Postscript for item %d)",
		    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) == -1) {
		goto channelWriteFailed;
	    }
	    Tcl_DecrRefCount(psObj);
	    psObj = Tcl_NewObj();
	}
    }

    /*
     * Output page-end information, such as commands to print the page and
     * document trailer stuff.
     */

    if (psInfo.prolog) {
	Tcl_AppendToObj(psObj,
		"restore showpage\n\n"
		"%%Trailer\n"
		"end\n"
		"%%EOF\n", -1);

	if (psInfo.chan != NULL) {
	    if (Tcl_WriteObj(psInfo.chan, psObj) == -1) {
		goto channelWriteFailed;
	    }
	}
    }

    if (psInfo.chan == NULL) {
	Tcl_SetObjResult(interp, psObj);
899
900
901
902
903
904
905












906
907
908
909
910
911
912

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







>
>
>
>
>
>
>
>
>
>
>
>







900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925

    XGetGeometry(Tk_Display(tkwin), bitmap, &dummyRoot,
	    (int *) &dummyX, (int *) &dummyY, (unsigned int *) &totalWidth,
	    (unsigned int *) &totalHeight, &dummyBorderwidth, &dummyDepth);
    imagePtr = XGetImage(Tk_Display(tkwin), bitmap, 0, 0,
	    totalWidth, totalHeight, 1, XYPixmap);


    if (!imagePtr) {
	/*
	 * The XGetImage() function is apparently not implemented on this
	 * system. Just skip the pixels, the Postscript will still be
	 * syntactically correct.
	 */

	Tcl_AppendToObj(psObj, "<>", -1);
	return;
    }

    Tcl_AppendToObj(psObj, "<", -1);
    mask = 0x80;
    value = 0;
    charsInLine = 0;
    lastX = startX + width - 1;
    lastY = startY + height - 1;
    for (y = lastY; y >= startY; y--) {
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
static void
TkImageGetColor(
    TkColormapData *cdata,	/* Colormap data */
    unsigned long pixel,	/* Pixel value to look up */
    double *red, double *green, double *blue)
				/* Color data to return */
{
    (void)cdata;

    *red   = (double) GetRValue(pixel) / 255.0;
    *green = (double) GetGValue(pixel) / 255.0;
    *blue  = (double) GetBValue(pixel) / 255.0;
}
#else /* ! (_WIN32 || MAC_OSX_TK) */
static void
TkImageGetColor(







<
<







1202
1203
1204
1205
1206
1207
1208


1209
1210
1211
1212
1213
1214
1215
static void
TkImageGetColor(
    TkColormapData *cdata,	/* Colormap data */
    unsigned long pixel,	/* Pixel value to look up */
    double *red, double *green, double *blue)
				/* Color data to return */
{


    *red   = (double) GetRValue(pixel) / 255.0;
    *green = (double) GetGValue(pixel) / 255.0;
    *blue  = (double) GetBValue(pixel) / 255.0;
}
#else /* ! (_WIN32 || MAC_OSX_TK) */
static void
TkImageGetColor(
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
    int bytesPerLine = 0, maxWidth = 0;
    int level = psInfoPtr->colorLevel;
    Colormap cmap;
    int i, ncolors;
    Visual *visual;
    TkColormapData cdata;
    Tcl_Obj *psObj;
    (void)y;

    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    cmap = Tk_Colormap(tkwin);
    visual = Tk_Visual(tkwin);

    /*
     * Obtain information about the colormap, ie the mapping between pixel
     * values and RGB values. The code below should work for all Visual types.
     */

    ncolors = visual->map_entries;
    cdata.colors = (XColor *)ckalloc(sizeof(XColor) * ncolors);
    cdata.ncolors = ncolors;

    if (visual->c_class == DirectColor || visual->c_class == TrueColor) {
	cdata.separated = 1;
	cdata.red_mask = visual->red_mask;
	cdata.green_mask = visual->green_mask;
	cdata.blue_mask = visual->blue_mask;







<














|







1270
1271
1272
1273
1274
1275
1276

1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
    int bytesPerLine = 0, maxWidth = 0;
    int level = psInfoPtr->colorLevel;
    Colormap cmap;
    int i, ncolors;
    Visual *visual;
    TkColormapData cdata;
    Tcl_Obj *psObj;


    if (psInfoPtr->prepass) {
	return TCL_OK;
    }

    cmap = Tk_Colormap(tkwin);
    visual = Tk_Visual(tkwin);

    /*
     * Obtain information about the colormap, ie the mapping between pixel
     * values and RGB values. The code below should work for all Visual types.
     */

    ncolors = visual->map_entries;
    cdata.colors = ckalloc(sizeof(XColor) * ncolors);
    cdata.ncolors = ncolors;

    if (visual->c_class == DirectColor || visual->c_class == TrueColor) {
	cdata.separated = 1;
	cdata.red_mask = visual->red_mask;
	cdata.green_mask = visual->green_mask;
	cdata.blue_mask = visual->blue_mask;
Changes to generic/tkCanvText.c.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
				 * (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). */







|







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
				 * (and shared with) the generic canvas
				 * code. */
    /*
     * Fields that are set by widget commands other than "configure".
     */

    double x, y;		/* Positioning point for text. */
    int insertPos;		/* Character index of character just before
				 * which the insertion cursor is displayed. */

    /*
     * Configuration settings that are updated by Tk_ConfigureWidget.
     */

    Tk_Anchor anchor;		/* Where to anchor text relative to (x,y). */
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
				 * 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. */







|
|







58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
				 * at. */

    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    int numChars;		/* Length of text in characters. */
    int numBytes;		/* Length of text in bytes. */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int actualWidth;		/* Width of text as computed. Used to make
				 * selections of wrapped text display
				 * right. */
    double drawOrigin[2];	/* Where we start drawing from. */
    GC gc;			/* Graphics context for drawing text. */
    GC selTextGC;		/* Graphics context for selected text. */
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, offsetof(TextItem, activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, offsetof(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_DOUBLE, "-angle", NULL, NULL,
	"0.0", offsetof(TextItem, angle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, offsetof(TextItem, disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, offsetof(TextItem, disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, offsetof(TextItem, color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_FONT, "-font", NULL, NULL,
	DEF_CANVTEXT_FONT, offsetof(TextItem, tkfont), 0, NULL},
    {TK_CONFIG_JUSTIFY, "-justify", NULL, NULL,
	"left", offsetof(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", offsetof(TextItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, offsetof(TextItem, stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_STRING, "-text", NULL, NULL,
	"", offsetof(TextItem, text), 0, NULL},
    {TK_CONFIG_INT, "-underline", NULL, NULL,
	"-1", offsetof(TextItem, underline), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", offsetof(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeTextBbox(Tk_Canvas canvas, TextItem *textPtr);
static int		ConfigureText(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateText(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const objv[]);
static void		DeleteText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayCanvText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static TkSizeT	GetSelText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT offset, char *buffer,
			    TkSizeT maxBytes);
static int		GetTextIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, TkSizeT *indexPtr);
static void		ScaleText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		SetTextCursor(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT index);
static int		TextCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int argc, Tcl_Obj *const objv[]);
static void		TextDeleteChars(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT first, TkSizeT last);
static void		TextInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, TkSizeT beforeThis, Tcl_Obj *obj);
static int		TextToArea(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *rectPtr);
static double		TextToPoint(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double *pointPtr);
static int		TextToPostscript(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int prepass);
static void		RotateText(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		TranslateText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
 * The structures below defines the rectangle and oval item types by means of
 * functions that can be invoked by generic item code.
 */







|







|

|

|

|

|

|

|

|

|

|


|

|



|

|

|













|





|
|
|


|




|


|

|

|






<
<







83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172


173
174
175
176
177
178
179
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};
static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_COLOR, "-activefill", NULL, NULL,
	NULL, Tk_Offset(TextItem, activeColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-activestipple", NULL, NULL,
	NULL, Tk_Offset(TextItem, activeStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", Tk_Offset(TextItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_DOUBLE, "-angle", NULL, NULL,
	"0.0", Tk_Offset(TextItem, angle), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_COLOR, "-disabledfill", NULL, NULL,
	NULL, Tk_Offset(TextItem, disabledColor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BITMAP, "-disabledstipple", NULL, NULL,
	NULL, Tk_Offset(TextItem, disabledStipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-fill", NULL, NULL,
	DEF_CANVITEM_OUTLINE, Tk_Offset(TextItem, color), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_FONT, "-font", NULL, NULL,
	DEF_CANVTEXT_FONT, Tk_Offset(TextItem, tkfont), 0, NULL},
    {TK_CONFIG_JUSTIFY, "-justify", NULL, NULL,
	"left", Tk_Offset(TextItem, justify), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-offset", NULL, NULL,
	"0,0", Tk_Offset(TextItem, tsoffset),
	TK_CONFIG_DONT_SET_DEFAULT, &offsetOption},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_BITMAP, "-stipple", NULL, NULL,
	NULL, Tk_Offset(TextItem, stipple), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_STRING, "-text", NULL, NULL,
	"", Tk_Offset(TextItem, text), 0, NULL},
    {TK_CONFIG_INT, "-underline", NULL, NULL,
	"-1", Tk_Offset(TextItem, underline), 0, NULL},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", Tk_Offset(TextItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeTextBbox(Tk_Canvas canvas, TextItem *textPtr);
static int		ConfigureText(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int argc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateText(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int 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 int		GetSelText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int offset, char *buffer,
			    int maxBytes);
static int		GetTextIndex(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    Tcl_Obj *obj, int *indexPtr);
static void		ScaleText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		SetTextCursor(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int index);
static int		TextCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		TextDeleteChars(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int first, int last);
static void		TextInsert(Tk_Canvas canvas,
			    Tk_Item *itemPtr, int beforeThis, 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		TranslateText(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);

/*
 * The structures below defines the rectangle and oval item types by means of
 * functions that can be invoked by generic item code.
 */
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
    TranslateText,		/* translateProc */
    GetTextIndex,		/* indexProc */
    SetTextCursor,		/* icursorProc */
    GetSelText,			/* selectionProc */
    TextInsert,			/* insertProc */
    TextDeleteChars,		/* dTextProc */
    NULL,			/* nextPtr */
    RotateText,			/* rotateProc */
    0, NULL, NULL
};

#define ROUND(d) ((int) floor((d) + 0.5))

/*
 *--------------------------------------------------------------
 *







<
|







195
196
197
198
199
200
201

202
203
204
205
206
207
208
209
    TranslateText,		/* translateProc */
    GetTextIndex,		/* indexProc */
    SetTextCursor,		/* icursorProc */
    GetSelText,			/* selectionProc */
    TextInsert,			/* insertProc */
    TextDeleteChars,		/* dTextProc */
    NULL,			/* nextPtr */

    NULL, 0, NULL, NULL
};

#define ROUND(d) ((int) floor((d) + 0.5))

/*
 *--------------------------------------------------------------
 *
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
     * 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.







|


|



|




|







503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
     * keep them inside the item.
     */

    textPtr->numBytes = strlen(textPtr->text);
    textPtr->numChars = Tcl_NumUtfChars(textPtr->text, textPtr->numBytes);
    if (textInfoPtr->selItemPtr == itemPtr) {

	if (textInfoPtr->selectFirst >= 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);
    }







|




<







558
559
560
561
562
563
564
565
566
567
568
569

570
571
572
573
574
575
576
 *	Resources associated with itemPtr are released.
 *
 *--------------------------------------------------------------
 */

static void
DeleteText(
    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;
    }








|







625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

static void
ComputeTextBbox(
    Tk_Canvas canvas,		/* Canvas that contains item. */
    TextItem *textPtr)		/* Item whose bbox is to be recomputed. */
{
    Tk_CanvasTextInfo *textInfoPtr;
    int 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;







<
<









|
|
|
<

|



|
<
<
<

|









|
|
|
<

|



<
<
<
|

|







647
648
649
650
651
652
653


654
655
656
657
658
659
660
661
662
663
664
665

666
667
668
669
670
671



672
673
674
675
676
677
678
679
680
681
682
683
684
685

686
687
688
689
690



691
692
693
694
695
696
697
698
699
700
    }

    /*
     * Use overall geometry information to compute the top-left corner of the
     * bounding box for the text item.
     */



    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;








|







784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
    Drawable drawable,		/* Pixmap or window in which to draw item. */
    int x, int y, int width, int height)
				/* Describes region of canvas that must be
				 * redisplayed (not used). */
{
    TextItem *textPtr;
    Tk_CanvasTextInfo *textInfoPtr;
    int selFirstChar, selLastChar;
    short drawableX, drawableY;
    Pixmap stipple;
    Tk_State state = itemPtr->state;

    textPtr = (TextItem *) itemPtr;
    textInfoPtr = textPtr->textInfoPtr;

834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
     * read-only.
     */

    if (stipple != None) {
	Tk_CanvasSetOffset(canvas, textPtr->gc, &textPtr->tsoffset);
    }

    selFirstChar = TCL_INDEX_NONE;
    selLastChar = 0;
    Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0],
	    textPtr->drawOrigin[1], &drawableX, &drawableY);

    if (textInfoPtr->selItemPtr == itemPtr) {
	selFirstChar = textInfoPtr->selectFirst;
	selLastChar = textInfoPtr->selectLast;
	if (selLastChar + 1 > textPtr->numChars + 1 ) {
	    selLastChar = textPtr->numChars - 1;
	}
	if (((int)selFirstChar >= 0) && (selFirstChar + 1 <= selLastChar + 1 )) {
	    int xFirst, yFirst, hFirst;
	    int xLast, yLast, wLast;

	    /*
	     * Draw a special background under the selection.
	     */








|







|


|







820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
     * read-only.
     */

    if (stipple != None) {
	Tk_CanvasSetOffset(canvas, textPtr->gc, &textPtr->tsoffset);
    }

    selFirstChar = -1;
    selLastChar = 0;
    Tk_CanvasDrawableCoords(canvas, textPtr->drawOrigin[0],
	    textPtr->drawOrigin[1], &drawableX, &drawableY);

    if (textInfoPtr->selItemPtr == itemPtr) {
	selFirstChar = textInfoPtr->selectFirst;
	selLastChar = textInfoPtr->selectLast;
	if (selLastChar > 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.
	     */

956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
     * there is selected text and the foregrounds differ, draw the regular
     * text up to the selection, draw the selection, then draw the rest of the
     * regular text. Drawing the regular text and then the selected text over
     * it would causes problems with anti-aliased text because the two
     * anti-aliasing colors would blend together.
     */

    if ((selFirstChar != TCL_INDEX_NONE) && (textPtr->selTextGC != textPtr->gc)) {
	if (0 < selFirstChar) {
	    TkDrawAngledTextLayout(display, drawable, textPtr->gc,
		    textPtr->textLayout, drawableX, drawableY, textPtr->angle,
		    0, selFirstChar);
	}
	TkDrawAngledTextLayout(display, drawable, textPtr->selTextGC,
		textPtr->textLayout, drawableX, drawableY, textPtr->angle,







|







942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
     * there is selected text and the foregrounds differ, draw the regular
     * text up to the selection, draw the selection, then draw the rest of the
     * regular text. Drawing the regular text and then the selected text over
     * it would causes problems with anti-aliased text because the two
     * anti-aliasing colors would blend together.
     */

    if ((selFirstChar >= 0) && (textPtr->selTextGC != textPtr->gc)) {
	if (0 < selFirstChar) {
	    TkDrawAngledTextLayout(display, drawable, textPtr->gc,
		    textPtr->textLayout, drawableX, drawableY, textPtr->angle,
		    0, selFirstChar);
	}
	TkDrawAngledTextLayout(display, drawable, textPtr->selTextGC,
		textPtr->textLayout, drawableX, drawableY, textPtr->angle,
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
 *----------------------------------------------------------------------
 */

static void
TextInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Text item to be modified. */
    TkSizeT index,			/* Character index before which string is to
				 * be inserted. */
    Tcl_Obj *obj)		/* New characters to be inserted. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, charsAdded;
    TkSizeT byteCount;
    char *newStr, *text;
    const char *string;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    string = TkGetStringFromObj(obj, &byteCount);

    text = textPtr->text;

    if (index == TCL_INDEX_NONE) {
	index = 0;
    }
    if (index + 1 > textPtr->numChars + 1) {
	index = textPtr->numChars;
    }
    byteIndex = Tcl_UtfAtIndex(text, index) - text;
    byteCount = strlen(string);
    if (byteCount == 0) {
	return;
    }

    newStr = (char *)ckalloc(textPtr->numBytes + byteCount + 1);
    memcpy(newStr, text, byteIndex);







|





|




|



|


|


|







991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
 *----------------------------------------------------------------------
 */

static void
TextInsert(
    Tk_Canvas canvas,		/* Canvas containing text item. */
    Tk_Item *itemPtr,		/* Text item to be modified. */
    int index,			/* Character index before which string is to
				 * be inserted. */
    Tcl_Obj *obj)		/* New characters to be inserted. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, charsAdded;
    int 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 = TkUtfAtIndex(text, index) - text;
    byteCount = strlen(string);
    if (byteCount == 0) {
	return;
    }

    newStr = (char *)ckalloc(textPtr->numBytes + byteCount + 1);
    memcpy(newStr, text, byteIndex);
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074

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







|


|



|



|







1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060

    /*
     * Inserting characters invalidates indices such as those for the
     * selection and cursor. Update the indices appropriately.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst >= index) {
	    textInfoPtr->selectFirst += charsAdded;
	}
	if (textInfoPtr->selectLast >= index) {
	    textInfoPtr->selectLast += charsAdded;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor >= index)) {
	    textInfoPtr->selectAnchor += charsAdded;
	}
    }
    if (textPtr->insertPos >= index) {
	textPtr->insertPos += charsAdded;
    }
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
 *--------------------------------------------------------------
 */

static void
TextDeleteChars(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    TkSizeT first,			/* Character index of first character to
				 * delete. */
    TkSizeT last)			/* Character index of last character to delete
				 * (inclusive). */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, byteCount, charsRemoved;
    char *newStr, *text;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    text = textPtr->text;
    if ((int)first < 0) {
	first = 0;
    }
    if (last + 1 >= textPtr->numChars + 1) {
	last = textPtr->numChars - 1;
    }
    if (first + 1 > last + 1) {
	return;
    }
    charsRemoved = last + 1 - first;

    byteIndex = Tcl_UtfAtIndex(text, first) - text;
    byteCount = Tcl_UtfAtIndex(text + byteIndex, charsRemoved)
	- (text + byteIndex);

    newStr = (char *)ckalloc(textPtr->numBytes + 1 - byteCount);
    memcpy(newStr, text, byteIndex);
    strcpy(newStr + byteIndex, text + byteIndex + byteCount);

    ckfree(text);
    textPtr->text = newStr;
    textPtr->numChars -= charsRemoved;
    textPtr->numBytes -= byteCount;

    /*
     * Update indexes for the selection and cursor to reflect the renumbering
     * of the remaining characters.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst + 1 > first + 1) {
	    textInfoPtr->selectFirst -= charsRemoved;
	    if ((int)textInfoPtr->selectFirst + 1 < (int)first + 1) {
		textInfoPtr->selectFirst = first;
	    }
	}
	if (textInfoPtr->selectLast + 1 >= first + 1) {
	    textInfoPtr->selectLast -= charsRemoved;
	    if (textInfoPtr->selectLast + 1 < first) {
		textInfoPtr->selectLast = first - 1;
	    }
	}
	if ((int)textInfoPtr->selectFirst + 1 > (int)textInfoPtr->selectLast + 1) {
	    textInfoPtr->selItemPtr = NULL;
	}
	if ((textInfoPtr->anchorItemPtr == itemPtr)
		&& (textInfoPtr->selectAnchor + 1 > first + 1)) {
	    textInfoPtr->selectAnchor -= charsRemoved;
	    if (textInfoPtr->selectAnchor + 1 < first + 1) {
		textInfoPtr->selectAnchor = first;
	    }
	}
    }
    if (textPtr->insertPos + 1 > first + 1) {
	textPtr->insertPos -= charsRemoved;
	if ((int)textPtr->insertPos + 1 < (int)first + 1) {
	    textPtr->insertPos = first;
	}
    }
    ComputeTextBbox(canvas, textPtr);
    return;
}








|

|








|


|


|




|
|

















|

|



|

|



|



|

|




|

|







1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
 *--------------------------------------------------------------
 */

static void
TextDeleteChars(
    Tk_Canvas canvas,		/* Canvas containing itemPtr. */
    Tk_Item *itemPtr,		/* Item in which to delete characters. */
    int first,			/* Character index of first character to
				 * delete. */
    int last)			/* Character index of last character to delete
				 * (inclusive). */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteIndex, byteCount, charsRemoved;
    char *newStr, *text;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    text = textPtr->text;
    if (first < 0) {
	first = 0;
    }
    if (last >= textPtr->numChars) {
	last = textPtr->numChars - 1;
    }
    if (first > last) {
	return;
    }
    charsRemoved = last + 1 - first;

    byteIndex = TkUtfAtIndex(text, first) - text;
    byteCount = TkUtfAtIndex(text + byteIndex, charsRemoved)
	- (text + byteIndex);

    newStr = (char *)ckalloc(textPtr->numBytes + 1 - byteCount);
    memcpy(newStr, text, byteIndex);
    strcpy(newStr + byteIndex, text + byteIndex + byteCount);

    ckfree(text);
    textPtr->text = newStr;
    textPtr->numChars -= charsRemoved;
    textPtr->numBytes -= byteCount;

    /*
     * Update indexes for the selection and cursor to reflect the renumbering
     * of the remaining characters.
     */

    if (textInfoPtr->selItemPtr == itemPtr) {
	if (textInfoPtr->selectFirst > 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;
}

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
	    (int) (rectPtr[3] - rectPtr[1] + 0.5),
	    textPtr->angle);
}

/*
 *--------------------------------------------------------------
 *
 * RotateText --
 *
 *	This function is called to rotate a text item by a given amount about a
 *	point. Note that this does *not* rotate the text of the item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the text anchor is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateText(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &textPtr->x, &textPtr->y);
    ComputeTextBbox(canvas, textPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleText --
 *
 *	This function is invoked to rescale a text item.
 *
 * Results:
 *	None.
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1240
1241
1242
1243
1244
1245
1246

































1247
1248
1249
1250
1251
1252
1253
	    (int) (rectPtr[3] - rectPtr[1] + 0.5),
	    textPtr->angle);
}

/*
 *--------------------------------------------------------------
 *

































 * ScaleText --
 *
 *	This function is invoked to rescale a text item.
 *
 * Results:
 *	None.
 *
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397

1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
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));







|



|


|

<
<
|
<
<
|
>
|
<
<
<
<
<
<
|







1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344


1345


1346
1347
1348






1349
1350
1351
1352
1353
1354
1355
1356
GetTextIndex(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item for which the index is being
				 * specified. */
    Tcl_Obj *obj,		/* Specification of a particular character in
				 * itemPtr's text. */
    int *indexPtr)		/* Where to store converted character
				 * index. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int length;
    int c;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;
    const char *string = Tcl_GetStringFromObj(obj, &length);



    c = string[0];



    if ((c == 'e') && (strncmp(string, "end", length) == 0)) {
	*indexPtr = textPtr->numChars;






    } else if ((c == 'i')
	    && (strncmp(string, "insert", length) == 0)) {
	*indexPtr = textPtr->insertPos;
    } else if ((c == 's') && (length >= 5)
	    && (strncmp(string, "sel.first", length) == 0)) {
	if (textInfoPtr->selItemPtr != itemPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "selection isn't in item", -1));
1441
1442
1443
1444
1445
1446
1447






1448
1449
1450
1451
1452
1453
1454
	    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:







>
>
>
>
>
>







1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
	    goto badIndex;
	}
	y = (int) ((tmp < 0) ? tmp - 0.5 : tmp + 0.5);
	x -= (int) textPtr->drawOrigin[0];
	y -= (int) textPtr->drawOrigin[1];
	*indexPtr = Tk_PointToChar(textPtr->textLayout,
		(int) (x*cs - y*s), (int) (y*cs + x*s));
    } else if (Tcl_GetIntFromObj(NULL, obj, indexPtr) == TCL_OK) {
	if (*indexPtr < 0) {
	    *indexPtr = 0;
	} else if (*indexPtr > textPtr->numChars) {
	    *indexPtr = textPtr->numChars;
	}
    } else {
	/*
	 * Some of the paths here leave messages in the interp's result, so we
	 * have to clear it out before storing our own message.
	 */

    badIndex:
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
 */

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







|




|







1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
 */

static void
SetTextCursor(
    TCL_UNUSED(Tk_Canvas),		/* Record describing canvas widget. */
    Tk_Item *itemPtr,		/* Text item in which cursor position is to be
				 * set. */
    int index)			/* Character index of character just before
				 * which cursor is to be positioned. */
{
    TextItem *textPtr = (TextItem *) itemPtr;

    if (index < 0) {
	textPtr->insertPos = 0;
    } else if (index > textPtr->numChars) {
	textPtr->insertPos = textPtr->numChars;
    } else {
	textPtr->insertPos = index;
    }
}
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548



1549
1550
1551
1552
1553
1554
1555
1556
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static TkSizeT
GetSelText(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing selection. */
    Tk_Item *itemPtr,		/* Text item containing selection. */
    TkSizeT offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    TkSizeT byteCount;
    char *text;
    const char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    if (((int)textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst + 1 > textInfoPtr->selectLast + 1)) {
	return 0;
    }
    text = textPtr->text;
    selStart = Tcl_UtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst);
    if (selEnd  <= selStart + offset) {
	return 0;
    }
    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }



    memcpy(buffer, selStart + offset, byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
 *--------------------------------------------------------------
 *







|



|


|




|




|
|



|
|

<
<
<




>
>
>
|







1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491



1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
GetSelText(
    TCL_UNUSED(Tk_Canvas),		/* Canvas containing selection. */
    Tk_Item *itemPtr,		/* Text item containing selection. */
    int offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TextItem *textPtr = (TextItem *) itemPtr;
    int byteCount;
    char *text;
    const char *selStart, *selEnd;
    Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr;

    if ((textInfoPtr->selectFirst < 0) ||
	    (textInfoPtr->selectFirst > textInfoPtr->selectLast)) {
	return 0;
    }
    text = textPtr->text;
    selStart = TkUtfAtIndex(text, textInfoPtr->selectFirst);
    selEnd = TkUtfAtIndex(selStart,
	    textInfoPtr->selectLast + 1 - textInfoPtr->selectFirst);



    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }
    if (byteCount <= 0) {
	return 0;
    }
    memcpy(buffer, selStart + offset, (size_t) byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
 *--------------------------------------------------------------
 *
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
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (prepass != 0) {
	goto done;
    }

    Tcl_ResetResult(interp);
    Tk_CanvasPsColor(interp, canvas, color);


    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (stipple != None) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendPrintfToObj(psObj, "/StippleText {\n    %s} bind def\n",
		Tcl_GetString(Tcl_GetObjResult(interp)));
    }

    x = 0;  y = 0;  justify = NULL;
    switch (textPtr->anchor) {
    case TK_ANCHOR_NW:	   x = 0; y = 0; break;
    case TK_ANCHOR_N:	   x = 1; y = 0; break;
    case TK_ANCHOR_NE:	   x = 2; y = 0; break;
    case TK_ANCHOR_E:	   x = 2; y = 1; break;
    case TK_ANCHOR_SE:	   x = 2; y = 2; break;
    case TK_ANCHOR_S:	   x = 1; y = 2; break;
    case TK_ANCHOR_SW:	   x = 0; y = 2; break;
    case TK_ANCHOR_W:	   x = 0; y = 1; break;
    case TK_ANCHOR_CENTER: x = 1; y = 1; break;
    }
    switch (textPtr->justify) {
    case TK_JUSTIFY_LEFT:   justify = "0";   break;
    case TK_JUSTIFY_CENTER: justify = "0.5"; break;
    case TK_JUSTIFY_RIGHT:  justify = "1";   break;

    }

    Tk_GetFontMetrics(textPtr->tkfont, &fm);

    Tcl_AppendPrintfToObj(psObj, "%.15g %.15g %.15g [\n",
	    textPtr->angle, textPtr->x, Tk_CanvasPsY(canvas, textPtr->y));
    Tcl_ResetResult(interp);







|
>
>









<









|


<


>







1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599

1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611

1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (prepass != 0) {
	goto done;
    }

    Tcl_ResetResult(interp);
    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	goto error;
    }
    Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp));

    if (stipple != None) {
	Tcl_ResetResult(interp);
	Tk_CanvasPsStipple(interp, canvas, stipple);
	Tcl_AppendPrintfToObj(psObj, "/StippleText {\n    %s} bind def\n",
		Tcl_GetString(Tcl_GetObjResult(interp)));
    }


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




16
17
18
19
20
21
22
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"





/*
 * Structures defined only in this file.
 */

typedef struct SmoothAssocData {
    struct SmoothAssocData *nextPtr;
				/* Pointer to next SmoothAssocData. */







>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkCanvas.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Structures defined only in this file.
 */

typedef struct SmoothAssocData {
    struct SmoothAssocData *nextPtr;
				/* Pointer to next SmoothAssocData. */
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
 *	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_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to which coordinate applies. */
    const char *string,		/* Describes coordinate (any screen coordinate
				 * form may be used here). */
    double *doublePtr)		/* Place to store converted coordinate. */
{


    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_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Canvas canvas,		/* Canvas to which coordinate applies. */
    Tcl_Obj *obj,		/* Describes coordinate (any screen coordinate
				 * form may be used here). */
    double *doublePtr)		/* Place to store converted coordinate. */
{


    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(
    ClientData clientData,	/* Not used.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    const char *value,		/* Value of option (list of tag names). */
    char *widgRec,		/* Pointer to record for item. */
    int offset)			/* Offset into item (ignored). */
{
    Tk_Item *itemPtr = (Tk_Item *) widgRec;
    int argc, i;
    const char **argv;
    Tk_Uid *newPtr;




    /*
     * Break the value up into the individual tag names.
     */

    if (Tcl_SplitList(interp, value, &argc, &argv) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Make sure that there's enough space in the item to hold the tag names.
     */

    if (itemPtr->tagSpace < argc) {
	newPtr = (Tk_Uid *)ckalloc(argc * sizeof(Tk_Uid));
	for (i = itemPtr->numTags - 1; i >= 0; i--) {
	    newPtr[i] = itemPtr->tagPtr[i];
	}
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newPtr;
	itemPtr->tagSpace = argc;
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
 * 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(
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    int offset,			/* Ignored. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_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(
    ClientData clientData,	/* Not used.*/
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    int offset)			/* Offset into item. */
{



    return Tk_GetDash(interp, value, (Tk_Dash *) (widgRec+offset));
}

/*
 *--------------------------------------------------------------
 *
 * TkCanvasDashPrintProc --
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
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(
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    int offset,			/* Offset in record for item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    Tk_Dash *dash = (Tk_Dash *) (widgRec+offset);
    char *buffer, *p;
    int i = dash->number;



    if (i < 0) {
	i = -i;
	*freeProcPtr = TCL_DYNAMIC;
	buffer = ckalloc(i + 1);
	p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
	memcpy(buffer, p, (unsigned int) i);
	buffer[i] = 0;
	return buffer;
    } else if (!i) {
	*freeProcPtr = NULL;
	return "";
    }
    buffer = ckalloc(4 * i);
    *freeProcPtr = TCL_DYNAMIC;

    p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
    snprintf(buffer, 4 * i, "%d", *p++ & 0xff);
    while (--i) {
	snprintf(buffer + strlen(buffer), 4 * i - strlen(buffer), " %d", *p++ & 0xff);
    }
    return buffer;
}

/*
 *--------------------------------------------------------------
 *
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632

static SmoothAssocData *
InitSmoothMethods(
    Tcl_Interp *interp)
{
    SmoothAssocData *methods, *ptr;

    methods = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    methods->smooth.name = tkRawSmoothMethod.name;
    methods->smooth.coordProc = tkRawSmoothMethod.coordProc;
    methods->smooth.postscriptProc = tkRawSmoothMethod.postscriptProc;

    ptr = methods->nextPtr = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    ptr->smooth.name = tkBezierSmoothMethod.name;
    ptr->smooth.coordProc = tkBezierSmoothMethod.coordProc;
    ptr->smooth.postscriptProc = tkBezierSmoothMethod.postscriptProc;
    ptr->nextPtr = NULL;

    Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,methods);
    return methods;







|




|







602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621

static SmoothAssocData *
InitSmoothMethods(
    Tcl_Interp *interp)
{
    SmoothAssocData *methods, *ptr;

    methods = ckalloc(sizeof(SmoothAssocData));
    methods->smooth.name = tkRawSmoothMethod.name;
    methods->smooth.coordProc = tkRawSmoothMethod.coordProc;
    methods->smooth.postscriptProc = tkRawSmoothMethod.postscriptProc;

    ptr = methods->nextPtr = ckalloc(sizeof(SmoothAssocData));
    ptr->smooth.name = tkBezierSmoothMethod.name;
    ptr->smooth.coordProc = tkBezierSmoothMethod.coordProc;
    ptr->smooth.postscriptProc = tkBezierSmoothMethod.postscriptProc;
    ptr->nextPtr = NULL;

    Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc,methods);
    return methods;
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666

void
Tk_CreateSmoothMethod(
    Tcl_Interp *interp,
    const Tk_SmoothMethod *smooth)
{
    SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;
    methods = (SmoothAssocData *)Tcl_GetAssocData(interp, "smoothMethod", NULL);

    /*
     * Initialize if we were not previously initialized.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);







|







641
642
643
644
645
646
647
648
649
650
651
652
653
654
655

void
Tk_CreateSmoothMethod(
    Tcl_Interp *interp,
    const Tk_SmoothMethod *smooth)
{
    SmoothAssocData *methods, *typePtr2, *prevPtr, *ptr;
    methods = Tcl_GetAssocData(interp, "smoothMethod", NULL);

    /*
     * Initialize if we were not previously initialized.
     */

    if (methods == NULL) {
	methods = InitSmoothMethods(interp);
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
	    } else {
		prevPtr->nextPtr = typePtr2->nextPtr;
	    }
	    ckfree(typePtr2);
	    break;
	}
    }
    ptr = (SmoothAssocData *)ckalloc(sizeof(SmoothAssocData));
    ptr->smooth.name = smooth->name;
    ptr->smooth.coordProc = smooth->coordProc;
    ptr->smooth.postscriptProc = smooth->postscriptProc;
    ptr->nextPtr = methods;
    Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, ptr);
}








|







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
	    } else {
		prevPtr->nextPtr = typePtr2->nextPtr;
	    }
	    ckfree(typePtr2);
	    break;
	}
    }
    ptr = ckalloc(sizeof(SmoothAssocData));
    ptr->smooth.name = smooth->name;
    ptr->smooth.coordProc = smooth->coordProc;
    ptr->smooth.postscriptProc = smooth->postscriptProc;
    ptr->nextPtr = methods;
    Tcl_SetAssocData(interp, "smoothMethod", SmoothMethodCleanupProc, ptr);
}

707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
 *----------------------------------------------------------------------
 */

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







|

|
<







696
697
698
699
700
701
702
703
704
705

706
707
708
709
710
711
712
 *----------------------------------------------------------------------
 */

static void
SmoothMethodCleanupProc(
    ClientData clientData,	/* Points to "smoothMethod" AssocData for the
				 * interpreter. */
    Tcl_Interp *interp)		/* Interpreter that is being deleted. */
{
    SmoothAssocData *ptr, *methods = 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(
    ClientData clientData,	/* Ignored. */
    Tcl_Interp *interp,		/* Used for reporting errors. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    const char *value,		/* Value of option. */
    char *widgRec,		/* Pointer to record for item. */
    int offset)			/* Offset into item. */
{
    const Tk_SmoothMethod **smoothPtr =
	    (const Tk_SmoothMethod **) (widgRec + offset);
    const Tk_SmoothMethod *smooth = NULL;
    int b;
    size_t length;
    SmoothAssocData *methods;



    if (value == NULL || *value == 0) {
	*smoothPtr = NULL;
	return TCL_OK;
    }
    length = strlen(value);
    methods = 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(
    ClientData clientData,	/* Ignored. */
    Tk_Window tkwin,		/* Window containing canvas widget. */
    char *widgRec,		/* Pointer to record for item. */
    int offset,			/* Offset into item. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to variable to fill in with
				 * information about how to reclaim storage
				 * for return string. */
{
    const Tk_SmoothMethod *smoothPtr =
	    * (Tk_SmoothMethod **) (widgRec + offset);




    return smoothPtr ? smoothPtr->name : "0";
}
/*
 *--------------------------------------------------------------
 *
 * Tk_GetDash
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
    case '.': case ',': case '-': case '_':
	i = DashConvert(NULL, value, -1, 0.0);
	if (i <= 0) {
	    goto badDashList;
	}
	i = strlen(value);
	if (i > (int) sizeof(char *)) {
	    dash->pattern.pt = pt = (char *)ckalloc(strlen(value));
	} else {
	    pt = dash->pattern.array;
	}
	memcpy(pt, value, (unsigned) i);
	dash->number = -i;
	return TCL_OK;
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	Tcl_ResetResult(interp);
	goto badDashList;
    }

    if ((unsigned) ABS(dash->number) > sizeof(char *)) {
	ckfree(dash->pattern.pt);
    }
    if (argc > (int) sizeof(char *)) {
	dash->pattern.pt = pt = (char *)ckalloc(argc);
    } else {
	pt = dash->pattern.array;
    }
    dash->number = argc;

    largv = argv;
    while (argc > 0) {







|

















|







877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
    case '.': case ',': case '-': case '_':
	i = DashConvert(NULL, value, -1, 0.0);
	if (i <= 0) {
	    goto badDashList;
	}
	i = strlen(value);
	if (i > (int) sizeof(char *)) {
	    dash->pattern.pt = pt = ckalloc(strlen(value));
	} else {
	    pt = dash->pattern.array;
	}
	memcpy(pt, value, (unsigned) i);
	dash->number = -i;
	return TCL_OK;
    }

    if (Tcl_SplitList(interp, (char *) value, &argc, &argv) != TCL_OK) {
	Tcl_ResetResult(interp);
	goto badDashList;
    }

    if ((unsigned) ABS(dash->number) > sizeof(char *)) {
	ckfree(dash->pattern.pt);
    }
    if (argc > (int) sizeof(char *)) {
	dash->pattern.pt = pt = ckalloc(argc);
    } else {
	pt = dash->pattern.array;
    }
    dash->number = argc;

    largv = argv;
    while (argc > 0) {
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257

    if ((dash->number<-1) ||
	    ((dash->number == -1) && (dash->pattern.array[0] != ','))) {
	char *q;
	int i = -dash->number;

	p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
	q = (char *)ckalloc(2 * i);
	i = DashConvert(q, p, i, width);
	XSetDashes(Canvas(canvas)->display, outline->gc, outline->offset, q,i);
	ckfree(q);
    } else if (dash->number>2 || (dash->number==2 &&
	    (dash->pattern.array[0]!=dash->pattern.array[1]))) {
	p = (dash->number > (int) sizeof(char *))
		? dash->pattern.pt : dash->pattern.array;







|







1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240

    if ((dash->number<-1) ||
	    ((dash->number == -1) && (dash->pattern.array[0] != ','))) {
	char *q;
	int i = -dash->number;

	p = (i > (int)sizeof(char *)) ? dash->pattern.pt : dash->pattern.array;
	q = ckalloc(2 * i);
	i = DashConvert(q, p, i, width);
	XSetDashes(Canvas(canvas)->display, outline->gc, outline->offset, q,i);
	ckfree(q);
    } else if (dash->number>2 || (dash->number==2 &&
	    (dash->pattern.array[0]!=dash->pattern.array[1]))) {
	p = (dash->number > (int) sizeof(char *))
		? dash->pattern.pt : dash->pattern.array;
1282
1283
1284
1285
1286
1287
1288

1289
1290
1291
1292
1293
1294
1295
	Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
	return 1;
    }
    return 0;
}


/*
 *--------------------------------------------------------------
 *
 * Tk_ResetOutlineGC
 *
 *	Restores the GC to the situation before Tk_ChangeOutlineGC() was







>







1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
	Tk_CanvasSetOffset(canvas, outline->gc, tsoffset);
	tsoffset->xoffset += w;
	tsoffset->yoffset += h;
	return 1;
    }
    return 0;
}


/*
 *--------------------------------------------------------------
 *
 * Tk_ResetOutlineGC
 *
 *	Restores the GC to the situation before Tk_ChangeOutlineGC() was
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492






1493
1494
1495
1496


1497
1498
1499
1500
1501
1502
1503
	    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;
}








|




















|
>
>
>
>
>
>



|
>
>







1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
	    Tcl_AppendToObj(psObj, " ", -1);
	    Tcl_AppendObjToObj(psObj, converted);
	}
	Tcl_DecrRefCount(converted);
	Tcl_AppendPrintfToObj(psObj, "] %d setdash\n", outline->offset);
    } else if (dash->number < 0) {
	if (dash->number < -5) {
	    lptr = 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);
    }

    if (Tk_CanvasPsColor(interp, canvas, color) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Note that psObj might hold an invalid reference now.
     */

    if (stipple != None) {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "StrokeClip ", -1);
	if (Tk_CanvasPsStipple(interp, canvas, stipple) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	Tcl_AppendToObj(GetPostscriptBuffer(interp), "stroke\n", -1);
    }

    return TCL_OK;
}

1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
    double top, btm;		/* Top and bottom sizes of the bounding box */
    double *tempArr;		/* Temporary storage used by the clipper */
    double *a, *b, *t;		/* Pointers to parts of the temporary
				 * storage */
    int i, j;			/* Loop counters */
    double limit[4];		/* Boundries at which clipping occurs */
    double staticSpace[480];	/* Temp space from the stack */
    (void)closedPath;

    /*
     * Constrain all vertices of the path to be within a box that is no larger
     * than 32000 pixels wide or height. The top-left corner of this clipping
     * box is 1000 pixels above and to the left of the top left corner of the
     * window on which the canvas is displayed.
     *







<







1661
1662
1663
1664
1665
1666
1667

1668
1669
1670
1671
1672
1673
1674
    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.
     *
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
     * coordArr[] requires. Divide this space into two separate arrays a[] and
     * b[]. Initialize a[] to be equal to coordArr[].
     */

    if (numVertex*12 <= (int) (sizeof(staticSpace) / sizeof(double))) {
	tempArr = staticSpace;
    } else {
	tempArr = (double *)ckalloc(numVertex * 12 * sizeof(double));
    }
    for (i=0; i<numVertex*2; i++){
	tempArr[i] = coordArr[i];
    }
    a = tempArr;
    b = &tempArr[numVertex*6];








|







1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
     * coordArr[] requires. Divide this space into two separate arrays a[] and
     * b[]. Initialize a[] to be equal to coordArr[].
     */

    if (numVertex*12 <= (int) (sizeof(staticSpace) / sizeof(double))) {
	tempArr = staticSpace;
    } else {
	tempArr = ckalloc(numVertex * 12 * sizeof(double));
    }
    for (i=0; i<numVertex*2; i++){
	tempArr[i] = coordArr[i];
    }
    a = tempArr;
    b = &tempArr[numVertex*6];

1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
	TranslateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i);
    }
    if (tempArr != staticSpace) {
	ckfree(tempArr);
    }
    return numOutput;
}

/*
 *--------------------------------------------------------------
 *
 * TkRotatePoint --
 *
 *	Rotate a point about another point. The angle should be converted into
 *	its sine and cosine before calling this function.
 *
 * Results:
 *	None
 *
 * Side effects:
 *	The point in (*xPtr,*yPtr) is updated to be rotated about
 *	(originX,originY) by the amount given by the sine and cosine of the
 *	angle to rotate.
 *
 *--------------------------------------------------------------
 */

void
TkRotatePoint(
    double originX, double originY,	/* The point about which to rotate. */
    double sine, double cosine,		/* How much to rotate? */
    double *xPtr, double *yPtr)		/* The point to be rotated. (INOUT) */
{
    double x = *xPtr - originX;
    double y = *yPtr - originY;

    /*
     * Beware! The canvas coordinate space is flipped vertically, so rotations
     * go the "wrong" way with respect to mathematics.
     */

    *xPtr = originX + x * cosine + y * sine;
    *yPtr = originY - x * sine + y * cosine;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<








1863
1864
1865
1866
1867
1868
1869





































1870
1871
1872
1873
1874
1875
1876
1877
	TranslateAndAppendCoords(canvPtr, a[i*2], a[i*2+1], outArr, i);
    }
    if (tempArr != staticSpace) {
	ckfree(tempArr);
    }
    return numOutput;
}






































/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkCanvWind.c.
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    TkCanvasTagsParseProc, TkCanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", offsetof(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"0", offsetof(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, offsetof(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", offsetof(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_WINDOW, "-window", NULL, NULL,
	NULL, offsetof(WindowItem, tkwin), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeWindowBbox(Tk_Canvas canvas,
			    WindowItem *winItemPtr);
static int		ConfigureWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);
static void		RotateWinItem(Tk_Canvas canvas, Tk_Item *itemPtr,
			    double originX, double originY, double angleRad);
static void		ScaleWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);
static int		WinItemCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,







|




|

|

|



|

|




















<
<







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79


80
81
82
83
84
85
86
 * Information used for parsing configuration specs:
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc, INT2PTR(2)
};
static const Tk_CustomOption tagsOption = {
    Tk_CanvasTagsParseProc, Tk_CanvasTagsPrintProc, NULL
};

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_ANCHOR, "-anchor", NULL, NULL,
	"center", Tk_Offset(WindowItem, anchor), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_PIXELS, "-height", NULL, NULL,
	"0", Tk_Offset(WindowItem, height), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_CUSTOM, "-state", NULL, NULL,
	NULL, Tk_Offset(Tk_Item, state), TK_CONFIG_NULL_OK, &stateOption},
    {TK_CONFIG_CUSTOM, "-tags", NULL, NULL,
	NULL, 0, TK_CONFIG_NULL_OK, &tagsOption},
    {TK_CONFIG_PIXELS, "-width", NULL, NULL,
	"0", Tk_Offset(WindowItem, width), TK_CONFIG_DONT_SET_DEFAULT, NULL},
    {TK_CONFIG_WINDOW, "-window", NULL, NULL,
	NULL, Tk_Offset(WindowItem, tkwin), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Prototypes for functions defined in this file:
 */

static void		ComputeWindowBbox(Tk_Canvas canvas,
			    WindowItem *winItemPtr);
static int		ConfigureWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		CreateWinItem(Tcl_Interp *interp,
			    Tk_Canvas canvas, struct Tk_Item *itemPtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display);
static void		DisplayWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, Display *display, Drawable dst,
			    int x, int y, int width, int height);


static void		ScaleWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double originX, double originY,
			    double scaleX, double scaleY);
static void		TranslateWinItem(Tk_Canvas canvas,
			    Tk_Item *itemPtr, double deltaX, double deltaY);
static int		WinItemCoords(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tk_Item *itemPtr, int objc,
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
    TranslateWinItem,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */
    RotateWinItem,		/* rotateProc */
    0, NULL, NULL
};

/*
 * The structure below defines the official type record for the canvas (as
 * geometry manager):
 */

static const Tk_GeomMgr canvasGeomType = {
    "canvas",				/* name */
    WinItemRequestProc,			/* requestProc */
    WinItemLostContentProc,		/* lostContentProc */
};

/*
 *--------------------------------------------------------------
 *
 * CreateWinItem --
 *







<
|










|







126
127
128
129
130
131
132

133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
    TranslateWinItem,		/* translateProc */
    NULL,			/* indexProc */
    NULL,			/* cursorProc */
    NULL,			/* selectionProc */
    NULL,			/* insertProc */
    NULL,			/* dTextProc */
    NULL,			/* nextPtr */

    NULL, 0, NULL, NULL
};

/*
 * The structure below defines the official type record for the canvas (as
 * geometry manager):
 */

static const Tk_GeomMgr canvasGeomType = {
    "canvas",				/* name */
    WinItemRequestProc,			/* requestProc */
    WinItemLostContentProc,		/* lostSlaveProc */
};

/*
 *--------------------------------------------------------------
 *
 * CreateWinItem --
 *
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
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);







<







401
402
403
404
405
406
407

408
409
410
411
412
413
414
DeleteWinItem(
    Tk_Canvas canvas,		/* Overall info about widget. */
    Tk_Item *itemPtr,		/* Item that is being deleted. */
    Display *display)		/* Display containing window for canvas. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);


    if (winItemPtr->tkwin != NULL) {
	Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
		WinItemStructureProc, winItemPtr);
	Tk_ManageGeometry(winItemPtr->tkwin, NULL, NULL);
	if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582



583
584
585
586
587
588
589
590
591
592
593
594
595
596

597
598
599
600
601
602
603
				 * 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;








<
<
<
<
<




>
>
>














>







563
564
565
566
567
568
569





570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
				 * redisplayed (not used). */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    int width, height;
    short x, y;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(canvas);
    Tk_State state = itemPtr->state;






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







>














>
>
|
>
>




>







606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
    if (((x + width) <= 0) || ((y + height) <= 0)
	    || (x >= Tk_Width(canvasTkwin)) || (y >= Tk_Height(canvasTkwin))) {
	if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	    Tk_UnmapWindow(winItemPtr->tkwin);
	} else {
	    Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
	}
	Tcl_Release(canvas);
	return;
    }

    /*
     * Reposition and map the window (but in different ways depending on
     * whether the canvas is the window's parent).
     */

    if (canvasTkwin == Tk_Parent(winItemPtr->tkwin)) {
	if ((x != Tk_X(winItemPtr->tkwin)) || (y != Tk_Y(winItemPtr->tkwin))
		|| (width != Tk_Width(winItemPtr->tkwin))
		|| (height != Tk_Height(winItemPtr->tkwin))) {
	    Tk_MoveResizeWindow(winItemPtr->tkwin, x, y, width, height);
	}

	if (winItemPtr->tkwin) {
	    Tk_MapWindow(winItemPtr->tkwin);
	}

    } else {
	Tk_MaintainGeometry(winItemPtr->tkwin, canvasTkwin, x, y,
		width, height);
    }
    Tcl_Release(canvas);
}

/*
 *--------------------------------------------------------------
 *
 * WinItemToPoint --
 *
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
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;

    /*







<







661
662
663
664
665
666
667

668
669
670
671
672
673
674
WinItemToPoint(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against point. */
    double *pointPtr)		/* Pointer to x and y coordinates. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    double x1, x2, y1, y2, xDiff, yDiff;


    x1 = winItemPtr->header.x1;
    y1 = winItemPtr->header.y1;
    x2 = winItemPtr->header.x2;
    y2 = winItemPtr->header.y2;

    /*
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area.  */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    (void)canvas;

    if ((rectPtr[2] <= winItemPtr->header.x1)
	    || (rectPtr[0] >= winItemPtr->header.x2)
	    || (rectPtr[3] <= winItemPtr->header.y1)
	    || (rectPtr[1] >= winItemPtr->header.y2)) {
	return -1;
    }







<







718
719
720
721
722
723
724

725
726
727
728
729
730
731
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item to check against rectangle. */
    double *rectPtr)		/* Pointer to array of four coordinates
				 * (x1,y1,x2,y2) describing rectangular
				 * area.  */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;


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







|


<
<
<







754
755
756
757
758
759
760
761
762
763



764
765
766
767
768
769
770
 *
 *--------------------------------------------------------------
 */

#ifdef X_GetImage
static int
xerrorhandler(
    ClientData clientData,
    XErrorEvent *e)
{



    return 0;
}
#endif /* X_GetImage */

/*
 *--------------------------------------------------------------
 *
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    double x, y;
    int width, height;
    Tk_Window tkwin = winItemPtr->tkwin;

    if (prepass || winItemPtr->tkwin == NULL) {
        return TCL_OK;
    }

    width = Tk_Width(tkwin);
    height = Tk_Height(tkwin);

    /*
     * Compute the coordinates of the lower-left corner of the window, taking







|







795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;
    double x, y;
    int width, height;
    Tk_Window tkwin = winItemPtr->tkwin;

    if (prepass || winItemPtr->tkwin == NULL) {
	return TCL_OK;
    }

    width = Tk_Width(tkwin);
    height = Tk_Height(tkwin);

    /*
     * Compute the coordinates of the lower-left corner of the window, taking
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
    Tcl_DecrRefCount(psObj);
    return result;
}

/*
 *--------------------------------------------------------------
 *
 * RotateWinItem --
 *
 *	This function is called to rotate a window item by a given amount
 *	about a point. Note that this does *not* rotate the window of the
 *	item.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The position of the window anchor is rotated by angleRad about (originX,
 *	originY), and the bounding box is updated in the generic part of the
 *	item structure.
 *
 *--------------------------------------------------------------
 */

static void
RotateWinItem(
    Tk_Canvas canvas,		/* Canvas containing item. */
    Tk_Item *itemPtr,		/* Item that is being rotated. */
    double originX, double originY,
    double angleRad)		/* Amount by which item is to be rotated. */
{
    WindowItem *winItemPtr = (WindowItem *) itemPtr;

    TkRotatePoint(originX, originY, sin(angleRad), cos(angleRad),
	    &winItemPtr->x, &winItemPtr->y);
    ComputeWindowBbox(canvas, winItemPtr);
}

/*
 *--------------------------------------------------------------
 *
 * ScaleWinItem --
 *
 *	This function is invoked to rescale a window item.
 *
 * Results:
 *	None.
 *







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







921
922
923
924
925
926
927


































928
929
930
931
932
933
934
    Tcl_DecrRefCount(psObj);
    return result;
}

/*
 *--------------------------------------------------------------
 *


































 * ScaleWinItem --
 *
 *	This function is invoked to rescale a window item.
 *
 * Results:
 *	None.
 *
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
 */

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







|







1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
 */

static void
WinItemStructureProc(
    ClientData clientData,	/* Pointer to record describing window item. */
    XEvent *eventPtr)		/* Describes what just happened. */
{
    WindowItem *winItemPtr = clientData;

    if (eventPtr->type == DestroyNotify) {
	winItemPtr->tkwin = NULL;
    }
}

/*
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
 */

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.







|
<







1043
1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
 */

static void
WinItemRequestProc(
    ClientData clientData,	/* Pointer to record for window item. */
    Tk_Window tkwin)		/* Window that changed its desired size. */
{
    WindowItem *winItemPtr = 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.
1112
1113
1114
1115
1116
1117
1118

1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
 *
 * Side effects:
 *	Forgets all canvas-related information about the content window.
 *
 *--------------------------------------------------------------
 */


static void
WinItemLostContentProc(
    ClientData clientData,	/* WindowItem structure for content window window that
				 * was stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    WindowItem *winItemPtr = (WindowItem *)clientData;
    Tk_Window canvasTkwin = Tk_CanvasTkwin(winItemPtr->canvas);
    (void)tkwin;

    Tk_DeleteEventHandler(winItemPtr->tkwin, StructureNotifyMask,
	    WinItemStructureProc, winItemPtr);
    if (canvasTkwin != Tk_Parent(winItemPtr->tkwin)) {
	Tk_UnmaintainGeometry(winItemPtr->tkwin, canvasTkwin);
    }
    Tk_UnmapWindow(winItemPtr->tkwin);







>


|



|

<







1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088

1089
1090
1091
1092
1093
1094
1095
 *
 * Side effects:
 *	Forgets all canvas-related information about the content window.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static void
WinItemLostContentProc(
    ClientData clientData,	/* WindowItem structure for content window that
				 * was stolen away. */
    Tk_Window tkwin)		/* Tk's handle for the content window. */
{
    WindowItem *winItemPtr = 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
31
32
33
34
35
/*
 * 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
 * progress. No field should be accessed by anyone other than TagSearchScan,
 * TagSearchFirst, TagSearchNext, TagSearchScanExpr, TagSearchEvalExpr,
 * TagSearchExprInit, TagSearchExprDestroy, TagSearchDestroy.
 * (
 *   Not quite accurate: the TagSearch structure is also accessed from:









|





>
>
|
|
|










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
/*
 * tkCanvas.c --
 *
 *	This module implements canvas widgets for the Tk toolkit. A canvas
 *	displays a background and a collection of graphical objects such as
 *	rectangles, lines, and texts.
 *
 * Copyright (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/* #define USE_OLD_TAG_SEARCH 1 */

#include "default.h"
#include "tkInt.h"
#include "tkCanvas.h"
#ifdef TK_NO_DOUBLE_BUFFERING
#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#endif
#endif /* TK_NO_DOUBLE_BUFFERING */

/*
 * See tkCanvas.h for key data structures used to implement canvases.
 */

#ifdef USE_OLD_TAG_SEARCH
/*
 * The structure defined below is used to keep track of a tag search in
 * progress. No field should be accessed by anyone other than StartTagSearch
 * and NextItem.
 */

typedef struct TagSearch {
    TkCanvas *canvasPtr;	/* Canvas widget being searched. */
    Tk_Uid tag;			/* Tag to search for. 0 means return all
				 * items. */
    Tk_Item *currentPtr;	/* Pointer to last item returned. */
    Tk_Item *lastPtr;		/* The item right before the currentPtr is
				 * tracked so if the currentPtr is deleted we
				 * don't have to start from the beginning. */
    int searchOver;		/* Non-zero means NextItem should always
				 * return NULL. */
} TagSearch;

#else /* USE_OLD_TAG_SEARCH */
/*
 * The structure defined below is used to keep track of a tag search in
 * progress. No field should be accessed by anyone other than TagSearchScan,
 * TagSearchFirst, TagSearchNext, TagSearchScanExpr, TagSearchEvalExpr,
 * TagSearchExprInit, TagSearchExprDestroy, TagSearchDestroy.
 * (
 *   Not quite accurate: the TagSearch structure is also accessed from:
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73


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

194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253

254
255




256
257

258
259
260
261
262



263
264
265






266
267
268
269
270
271
272
273
274
275
276
277
278

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











296
297
298
299
300
301
302
303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
    Tk_Item *currentPtr;	/* Pointer to last item returned. */
    Tk_Item *lastPtr;		/* The item right before the currentPtr is
				 * tracked so if the currentPtr is deleted we
				 * don't have to start from the beginning. */
    int searchOver;		/* Non-zero means NextItem should always
				 * return NULL. */
    int type;			/* Search type (see #defs below) */
    TkSizeT id;			/* Item id for searches by id */
    const char *string;		/* Tag expression string */
    int stringIndex;		/* Current position in string scan */
    int stringLength;		/* Length of tag expression string */
    char *rewritebuffer;	/* Tag string (after removing escapes) */
    unsigned int rewritebufferAllocated;
				/* Available space for rewrites. */
    TagSearchExpr *expr;	/* Compiled tag expression. */
} TagSearch;

/*
 * Values for the TagSearch type field.
 */

#define SEARCH_TYPE_EMPTY	0	/* Looking for empty tag */
#define SEARCH_TYPE_ID		1	/* Looking for an item by id */
#define SEARCH_TYPE_ALL		2	/* Looking for all items */
#define SEARCH_TYPE_TAG		3	/* Looking for an item by simple tag */
#define SEARCH_TYPE_EXPR	4	/* Compound search */



/*
 * Custom option for handling "-state" and "-offset"
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc,
    NULL		/* Only "normal" and "disabled". */
};

static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};

/*
 * Information used for argv parsing.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_COLOR, offsetof(TkCanvas, bgBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_MONO, offsetof(TkCanvas, bgBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_CANVAS_BORDER_WIDTH, offsetof(TkCanvas, borderWidth), 0, NULL},
    {TK_CONFIG_DOUBLE, "-closeenough", "closeEnough", "CloseEnough",
	DEF_CANVAS_CLOSE_ENOUGH, offsetof(TkCanvas, closeEnough), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-confine", "confine", "Confine",
	DEF_CANVAS_CONFINE, offsetof(TkCanvas, confine), 0, NULL},
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_CANVAS_CURSOR, offsetof(TkCanvas, cursor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-height", "height", "Height",
	DEF_CANVAS_HEIGHT, offsetof(TkCanvas, height), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_CANVAS_HIGHLIGHT_BG,
	offsetof(TkCanvas, highlightBgColorPtr), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_CANVAS_HIGHLIGHT, offsetof(TkCanvas, highlightColorPtr), 0, NULL},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_CANVAS_HIGHLIGHT_WIDTH, offsetof(TkCanvas, highlightWidth), 0, NULL},
    {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_CANVAS_INSERT_BG, offsetof(TkCanvas, textInfo.insertBorder), 0, NULL},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_COLOR,
	offsetof(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_MONO,
	offsetof(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_CANVAS_INSERT_OFF_TIME, offsetof(TkCanvas, insertOffTime), 0, NULL},
    {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_CANVAS_INSERT_ON_TIME, offsetof(TkCanvas, insertOnTime), 0, NULL},
    {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_CANVAS_INSERT_WIDTH, offsetof(TkCanvas, textInfo.insertWidth), 0, NULL},
    {TK_CONFIG_CUSTOM, "-offset", "offset", "Offset", "0,0",
	offsetof(TkCanvas, tsoffset),TK_CONFIG_DONT_SET_DEFAULT,
	&offsetOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_CANVAS_RELIEF, offsetof(TkCanvas, relief), 0, NULL},
    {TK_CONFIG_STRING, "-scrollregion", "scrollRegion", "ScrollRegion",
	DEF_CANVAS_SCROLL_REGION, offsetof(TkCanvas, regionString),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_COLOR, offsetof(TkCanvas, textInfo.selBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_MONO, offsetof(TkCanvas, textInfo.selBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_COLOR,
	offsetof(TkCanvas, textInfo.selBorderWidth), TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_MONO, offsetof(TkCanvas, textInfo.selBorderWidth),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_COLOR, offsetof(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_MONO, offsetof(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", "state", "State",
	"normal", offsetof(TkCanvas, canvas_state), TK_CONFIG_DONT_SET_DEFAULT,
	&stateOption},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_CANVAS_TAKE_FOCUS, offsetof(TkCanvas, takeFocus),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	DEF_CANVAS_WIDTH, offsetof(TkCanvas, width), 0, NULL},
    {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_CANVAS_X_SCROLL_CMD, offsetof(TkCanvas, xScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-xscrollincrement", "xScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_X_SCROLL_INCREMENT, offsetof(TkCanvas, xScrollIncrement),
	0, NULL},
    {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	DEF_CANVAS_Y_SCROLL_CMD, offsetof(TkCanvas, yScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-yscrollincrement", "yScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_Y_SCROLL_INCREMENT, offsetof(TkCanvas, yScrollIncrement),
	0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * List of all the item types known at present. This is *global* and is
 * protected by typeListMutex.
 */

static Tk_ItemType *typeList = NULL;
				/* NULL means initialization hasn't been done
				 * yet. */
TCL_DECLARE_MUTEX(typeListMutex)


/*
 * Uids for operands in compiled advanced tag search expressions.
 * Initialization is done by GetStaticUids()
 */

typedef struct {
    Tk_Uid allUid;
    Tk_Uid currentUid;
    Tk_Uid andUid;
    Tk_Uid orUid;
    Tk_Uid xorUid;
    Tk_Uid parenUid;
    Tk_Uid negparenUid;
    Tk_Uid endparenUid;
    Tk_Uid tagvalUid;
    Tk_Uid negtagvalUid;
} SearchUids;

static Tcl_ThreadDataKey dataKey;
static SearchUids *	GetStaticUids(void);


/*
 * Prototypes for functions defined later in this file:
 */

static void		CanvasBindProc(ClientData clientData,
			    XEvent *eventPtr);
static void		CanvasBlinkProc(ClientData clientData);
static void		CanvasCmdDeletedProc(ClientData clientData);
static void		CanvasDoEvent(TkCanvas *canvasPtr, XEvent *eventPtr);
static void		CanvasEventProc(ClientData clientData,
			    XEvent *eventPtr);
static TkSizeT	CanvasFetchSelection(ClientData clientData, TkSizeT offset,
			    char *buffer, TkSizeT maxBytes);
static Tk_Item *	CanvasFindClosest(TkCanvas *canvasPtr,
			    double coords[2]);
static void		CanvasFocusProc(TkCanvas *canvasPtr, int gotFocus);
static void		CanvasLostSelection(ClientData clientData);
static void		CanvasSelectTo(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, TkSizeT index);
static void		CanvasSetOrigin(TkCanvas *canvasPtr,
			    int xOrigin, int yOrigin);
static void		CanvasUpdateScrollbars(TkCanvas *canvasPtr);
static int		CanvasWidgetCmd(ClientData clientData,
			    Tcl_Interp *interp, int argc,
			    Tcl_Obj *const *argv);
static void		CanvasWorldChanged(ClientData instanceData);
static int		ConfigureCanvas(Tcl_Interp *interp,
			    TkCanvas *canvasPtr, int argc,
			    Tcl_Obj *const *argv, int flags);
static void		DefaultRotateImplementation(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, double x, double y,
			    double angleRadians);
static void		DestroyCanvas(void *memPtr);
static int		DrawCanvas(Tcl_Interp *interp, ClientData clientData, Tk_PhotoHandle photohandle, int subsample, int zoom);
static void		DisplayCanvas(ClientData clientData);
static void		DoItem(Tcl_Obj *accumObj,
			    Tk_Item *itemPtr, Tk_Uid tag);
static void		EventuallyRedrawItem(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr);

static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    int argc, Tcl_Obj *const *argv,




			    Tcl_Obj *newTagObj, int first,
			    TagSearch **searchPtrPtr);

static int		FindArea(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    Tcl_Obj *const *argv, Tk_Uid uid, int enclosed);
static double		GridAlign(double coord, double spacing);
static const char**	TkGetStringsFromObjs(int argc, Tcl_Obj *const *objv);
static void		InitCanvas(void);



static void		PickCurrentItem(TkCanvas *canvasPtr, XEvent *eventPtr);
static Tcl_Obj *	ScrollFractions(int screen1,
			    int screen2, int object1, int object2);






static int		RelinkItems(TkCanvas *canvasPtr, Tcl_Obj *tag,
			    Tk_Item *prevPtr, TagSearch **searchPtrPtr);
static void 		TagSearchExprInit(TagSearchExpr **exprPtrPtr);
static void		TagSearchExprDestroy(TagSearchExpr *expr);
static void		TagSearchDestroy(TagSearch *searchPtr);
static int		TagSearchScan(TkCanvas *canvasPtr,
			    Tcl_Obj *tag, TagSearch **searchPtrPtr);
static int		TagSearchScanExpr(Tcl_Interp *interp,
			    TagSearch *searchPtr, TagSearchExpr *expr);
static int		TagSearchEvalExpr(TagSearchExpr *expr,
			    Tk_Item *itemPtr);
static Tk_Item *	TagSearchFirst(TagSearch *searchPtr);
static Tk_Item *	TagSearchNext(TagSearch *searchPtr);


/*
 * The structure below defines canvas class behavior by means of functions
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs canvasClass = {
    sizeof(Tk_ClassProcs),	/* size */
    CanvasWorldChanged,		/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 * Macros that significantly simplify all code that finds items.
 */












#define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
    if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \
	errorExitClause; \
    } \
    itemPtr = TagSearchFirst(*(searchPtrPtr));
#define FOR_EVERY_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
    if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \
	errorExitClause; \
    } \
    for (itemPtr = TagSearchFirst(*(searchPtrPtr)); \
	    itemPtr != NULL; itemPtr = TagSearchNext(*(searchPtrPtr)))
#define FIND_ITEMS(objPtr, n) \
    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n), &searchPtr)
#define RELINK_ITEMS(objPtr, itemPtr) \
    result = RelinkItems(canvasPtr, (objPtr), (itemPtr), &searchPtr)


/*
 * ----------------------------------------------------------------------
 *
 * AlwaysRedraw, ItemConfigure, ItemCoords, etc. --
 *
 *	Helper functions that make access to canvas item functions simpler.







|


















>
>




















|


|




|

|

|

|

|


|

|


|

|


|


|

|

|

|

|


|

|


|


|



|

|


|


|


|


|


|

|



|


|



|














>




















>












|
|





|




|
|


|
|
<
<
<
|
<





>


>
>
>
>


>

|

|

>
>
>



>
>
>
>
>
>


|










>

















>
>
>
>
>
>
>
>
>
>
>















>







70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269



270

271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
    Tk_Item *currentPtr;	/* Pointer to last item returned. */
    Tk_Item *lastPtr;		/* The item right before the currentPtr is
				 * tracked so if the currentPtr is deleted we
				 * don't have to start from the beginning. */
    int searchOver;		/* Non-zero means NextItem should always
				 * return NULL. */
    int type;			/* Search type (see #defs below) */
    int id;			/* Item id for searches by id */
    const char *string;		/* Tag expression string */
    int stringIndex;		/* Current position in string scan */
    int stringLength;		/* Length of tag expression string */
    char *rewritebuffer;	/* Tag string (after removing escapes) */
    unsigned int rewritebufferAllocated;
				/* Available space for rewrites. */
    TagSearchExpr *expr;	/* Compiled tag expression. */
} TagSearch;

/*
 * Values for the TagSearch type field.
 */

#define SEARCH_TYPE_EMPTY	0	/* Looking for empty tag */
#define SEARCH_TYPE_ID		1	/* Looking for an item by id */
#define SEARCH_TYPE_ALL		2	/* Looking for all items */
#define SEARCH_TYPE_TAG		3	/* Looking for an item by simple tag */
#define SEARCH_TYPE_EXPR	4	/* Compound search */

#endif /* USE_OLD_TAG_SEARCH */

/*
 * Custom option for handling "-state" and "-offset"
 */

static const Tk_CustomOption stateOption = {
    TkStateParseProc, TkStatePrintProc,
    NULL		/* Only "normal" and "disabled". */
};

static const Tk_CustomOption offsetOption = {
    TkOffsetParseProc, TkOffsetPrintProc, INT2PTR(TK_OFFSET_RELATIVE)
};

/*
 * Information used for argv parsing.
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_COLOR, Tk_Offset(TkCanvas, bgBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-background", "background", "Background",
	DEF_CANVAS_BG_MONO, Tk_Offset(TkCanvas, bgBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_SYNONYM, "-bd", "borderWidth", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_SYNONYM, "-bg", "background", NULL, NULL, 0, 0, NULL},
    {TK_CONFIG_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_CANVAS_BORDER_WIDTH, Tk_Offset(TkCanvas, borderWidth), 0, NULL},
    {TK_CONFIG_DOUBLE, "-closeenough", "closeEnough", "CloseEnough",
	DEF_CANVAS_CLOSE_ENOUGH, Tk_Offset(TkCanvas, closeEnough), 0, NULL},
    {TK_CONFIG_BOOLEAN, "-confine", "confine", "Confine",
	DEF_CANVAS_CONFINE, Tk_Offset(TkCanvas, confine), 0, NULL},
    {TK_CONFIG_ACTIVE_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_CANVAS_CURSOR, Tk_Offset(TkCanvas, cursor), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-height", "height", "Height",
	DEF_CANVAS_HEIGHT, Tk_Offset(TkCanvas, height), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_CANVAS_HIGHLIGHT_BG,
	Tk_Offset(TkCanvas, highlightBgColorPtr), 0, NULL},
    {TK_CONFIG_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_CANVAS_HIGHLIGHT, Tk_Offset(TkCanvas, highlightColorPtr), 0, NULL},
    {TK_CONFIG_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness",
	DEF_CANVAS_HIGHLIGHT_WIDTH, Tk_Offset(TkCanvas, highlightWidth), 0, NULL},
    {TK_CONFIG_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_CANVAS_INSERT_BG, Tk_Offset(TkCanvas, textInfo.insertBorder), 0, NULL},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_COLOR,
	Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-insertborderwidth", "insertBorderWidth", "BorderWidth",
	DEF_CANVAS_INSERT_BD_MONO,
	Tk_Offset(TkCanvas, textInfo.insertBorderWidth), TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_CANVAS_INSERT_OFF_TIME, Tk_Offset(TkCanvas, insertOffTime), 0, NULL},
    {TK_CONFIG_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_CANVAS_INSERT_ON_TIME, Tk_Offset(TkCanvas, insertOnTime), 0, NULL},
    {TK_CONFIG_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_CANVAS_INSERT_WIDTH, Tk_Offset(TkCanvas, textInfo.insertWidth), 0, NULL},
    {TK_CONFIG_CUSTOM, "-offset", "offset", "Offset", "0,0",
	Tk_Offset(TkCanvas, tsoffset),TK_CONFIG_DONT_SET_DEFAULT,
	&offsetOption},
    {TK_CONFIG_RELIEF, "-relief", "relief", "Relief",
	DEF_CANVAS_RELIEF, Tk_Offset(TkCanvas, relief), 0, NULL},
    {TK_CONFIG_STRING, "-scrollregion", "scrollRegion", "ScrollRegion",
	DEF_CANVAS_SCROLL_REGION, Tk_Offset(TkCanvas, regionString),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_COLOR, Tk_Offset(TkCanvas, textInfo.selBorder),
	TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_CANVAS_SELECT_MONO, Tk_Offset(TkCanvas, textInfo.selBorder),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_COLOR,
	Tk_Offset(TkCanvas, textInfo.selBorderWidth), TK_CONFIG_COLOR_ONLY, NULL},
    {TK_CONFIG_PIXELS, "-selectborderwidth", "selectBorderWidth", "BorderWidth",
	DEF_CANVAS_SELECT_BD_MONO, Tk_Offset(TkCanvas, textInfo.selBorderWidth),
	TK_CONFIG_MONO_ONLY, NULL},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_COLOR, Tk_Offset(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_COLOR_ONLY|TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_CANVAS_SELECT_FG_MONO, Tk_Offset(TkCanvas, textInfo.selFgColorPtr),
	TK_CONFIG_MONO_ONLY|TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_CUSTOM, "-state", "state", "State",
	"normal", Tk_Offset(TkCanvas, canvas_state), TK_CONFIG_DONT_SET_DEFAULT,
	&stateOption},
    {TK_CONFIG_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_CANVAS_TAKE_FOCUS, Tk_Offset(TkCanvas, takeFocus),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-width", "width", "Width",
	DEF_CANVAS_WIDTH, Tk_Offset(TkCanvas, width), 0, NULL},
    {TK_CONFIG_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_CANVAS_X_SCROLL_CMD, Tk_Offset(TkCanvas, xScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-xscrollincrement", "xScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_X_SCROLL_INCREMENT, Tk_Offset(TkCanvas, xScrollIncrement),
	0, NULL},
    {TK_CONFIG_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	DEF_CANVAS_Y_SCROLL_CMD, Tk_Offset(TkCanvas, yScrollCmd),
	TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_PIXELS, "-yscrollincrement", "yScrollIncrement",
	"ScrollIncrement",
	DEF_CANVAS_Y_SCROLL_INCREMENT, Tk_Offset(TkCanvas, yScrollIncrement),
	0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * List of all the item types known at present. This is *global* and is
 * protected by typeListMutex.
 */

static Tk_ItemType *typeList = NULL;
				/* NULL means initialization hasn't been done
				 * yet. */
TCL_DECLARE_MUTEX(typeListMutex)

#ifndef USE_OLD_TAG_SEARCH
/*
 * Uids for operands in compiled advanced tag search expressions.
 * Initialization is done by GetStaticUids()
 */

typedef struct {
    Tk_Uid allUid;
    Tk_Uid currentUid;
    Tk_Uid andUid;
    Tk_Uid orUid;
    Tk_Uid xorUid;
    Tk_Uid parenUid;
    Tk_Uid negparenUid;
    Tk_Uid endparenUid;
    Tk_Uid tagvalUid;
    Tk_Uid negtagvalUid;
} SearchUids;

static Tcl_ThreadDataKey dataKey;
static SearchUids *	GetStaticUids(void);
#endif /* USE_OLD_TAG_SEARCH */

/*
 * Prototypes for functions defined later in this file:
 */

static void		CanvasBindProc(ClientData clientData,
			    XEvent *eventPtr);
static void		CanvasBlinkProc(ClientData clientData);
static void		CanvasCmdDeletedProc(ClientData clientData);
static void		CanvasDoEvent(TkCanvas *canvasPtr, XEvent *eventPtr);
static void		CanvasEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int		CanvasFetchSelection(ClientData clientData, int offset,
			    char *buffer, int maxBytes);
static Tk_Item *	CanvasFindClosest(TkCanvas *canvasPtr,
			    double coords[2]);
static void		CanvasFocusProc(TkCanvas *canvasPtr, int gotFocus);
static void		CanvasLostSelection(ClientData clientData);
static void		CanvasSelectTo(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr, int index);
static void		CanvasSetOrigin(TkCanvas *canvasPtr,
			    int xOrigin, int yOrigin);
static void		CanvasUpdateScrollbars(TkCanvas *canvasPtr);
static int		CanvasWidgetCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const *objv);
static void		CanvasWorldChanged(ClientData instanceData);
static int		ConfigureCanvas(Tcl_Interp *interp,
			    TkCanvas *canvasPtr, int objc,
			    Tcl_Obj *const *objv, int flags);



static Tcl_FreeProc	DestroyCanvas;

static void		DisplayCanvas(ClientData clientData);
static void		DoItem(Tcl_Obj *accumObj,
			    Tk_Item *itemPtr, Tk_Uid tag);
static void		EventuallyRedrawItem(TkCanvas *canvasPtr,
			    Tk_Item *itemPtr);
#ifdef USE_OLD_TAG_SEARCH
static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    int argc, Tcl_Obj *const *argv,
			    Tcl_Obj *newTagObj, int first);
#else /* USE_OLD_TAG_SEARCH */
static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    int objc, Tcl_Obj *const *objv,
			    Tcl_Obj *newTagObj, int first,
			    TagSearch **searchPtrPtr);
#endif /* USE_OLD_TAG_SEARCH */
static int		FindArea(Tcl_Interp *interp, TkCanvas *canvasPtr,
			    Tcl_Obj *const *objv, Tk_Uid uid, int enclosed);
static double		GridAlign(double coord, double spacing);
static const char**	TkGetStringsFromObjs(int objc, Tcl_Obj *const *objv);
static void		InitCanvas(void);
#ifdef USE_OLD_TAG_SEARCH
static Tk_Item *	NextItem(TagSearch *searchPtr);
#endif /* USE_OLD_TAG_SEARCH */
static void		PickCurrentItem(TkCanvas *canvasPtr, XEvent *eventPtr);
static Tcl_Obj *	ScrollFractions(int screen1,
			    int screen2, int object1, int object2);
#ifdef USE_OLD_TAG_SEARCH
static void		RelinkItems(TkCanvas *canvasPtr,
			    Tcl_Obj *tag, Tk_Item *prevPtr);
static Tk_Item *	StartTagSearch(TkCanvas *canvasPtr,
			    Tcl_Obj *tag, TagSearch *searchPtr);
#else /* USE_OLD_TAG_SEARCH */
static int		RelinkItems(TkCanvas *canvasPtr, Tcl_Obj *tag,
			    Tk_Item *prevPtr, TagSearch **searchPtrPtr);
static void		TagSearchExprInit(TagSearchExpr **exprPtrPtr);
static void		TagSearchExprDestroy(TagSearchExpr *expr);
static void		TagSearchDestroy(TagSearch *searchPtr);
static int		TagSearchScan(TkCanvas *canvasPtr,
			    Tcl_Obj *tag, TagSearch **searchPtrPtr);
static int		TagSearchScanExpr(Tcl_Interp *interp,
			    TagSearch *searchPtr, TagSearchExpr *expr);
static int		TagSearchEvalExpr(TagSearchExpr *expr,
			    Tk_Item *itemPtr);
static Tk_Item *	TagSearchFirst(TagSearch *searchPtr);
static Tk_Item *	TagSearchNext(TagSearch *searchPtr);
#endif /* USE_OLD_TAG_SEARCH */

/*
 * The structure below defines canvas class behavior by means of functions
 * that can be invoked from generic window code.
 */

static const Tk_ClassProcs canvasClass = {
    sizeof(Tk_ClassProcs),	/* size */
    CanvasWorldChanged,		/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};

/*
 * Macros that significantly simplify all code that finds items.
 */

#ifdef USE_OLD_TAG_SEARCH
#define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
    itemPtr = StartTagSearch(canvasPtr,(objPtr),&search)
#define FOR_EVERY_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
    for (itemPtr = StartTagSearch(canvasPtr, (objPtr), &search); \
	    itemPtr != NULL; itemPtr = NextItem(&search))
#define FIND_ITEMS(objPtr, n) \
    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n))
#define RELINK_ITEMS(objPtr, itemPtr) \
    RelinkItems(canvasPtr, (objPtr), (itemPtr))
#else /* USE_OLD_TAG_SEARCH */
#define FIRST_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
    if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \
	errorExitClause; \
    } \
    itemPtr = TagSearchFirst(*(searchPtrPtr));
#define FOR_EVERY_CANVAS_ITEM_MATCHING(objPtr,searchPtrPtr,errorExitClause) \
    if ((result=TagSearchScan(canvasPtr,(objPtr),(searchPtrPtr))) != TCL_OK){ \
	errorExitClause; \
    } \
    for (itemPtr = TagSearchFirst(*(searchPtrPtr)); \
	    itemPtr != NULL; itemPtr = TagSearchNext(*(searchPtrPtr)))
#define FIND_ITEMS(objPtr, n) \
    FindItems(interp, canvasPtr, objc, objv, (objPtr), (n), &searchPtr)
#define RELINK_ITEMS(objPtr, itemPtr) \
    result = RelinkItems(canvasPtr, (objPtr), (itemPtr), &searchPtr)
#endif /* USE_OLD_TAG_SEARCH */

/*
 * ----------------------------------------------------------------------
 *
 * AlwaysRedraw, ItemConfigure, ItemCoords, etc. --
 *
 *	Helper functions that make access to canvas item functions simpler.
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
}

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,







|







518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
}

static int
ItemIndex(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    Tcl_Obj *objPtr,
    int *indexPtr)
{
    Tcl_Interp *interp = canvasPtr->interp;

    if (itemPtr->typePtr->indexProc == NULL) {
	return TCL_OK;
    } else if (itemPtr->typePtr->alwaysRedraw & TK_CONFIG_OBJS) {
	return itemPtr->typePtr->indexProc(interp, (Tk_Canvas) canvasPtr,
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
    Tk_Item *itemPtr,
    double xDelta,
    double yDelta)
{
    itemPtr->typePtr->translateProc((Tk_Canvas) canvasPtr, itemPtr,
	    xDelta, yDelta);
}

static inline void
ItemRotate(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double x,
    double y,
    double angleRadians)
{
    if (itemPtr->typePtr->rotateProc != NULL) {
	itemPtr->typePtr->rotateProc((Tk_Canvas) canvasPtr,
		itemPtr, x, y, angleRadians);
    } else {
	DefaultRotateImplementation(canvasPtr, itemPtr, x, y, angleRadians);
    }
}

/*
 *--------------------------------------------------------------
 *
 * DefaultRotateImplementation --
 *
 *	The default implementation of the rotation operation, used when items
 *	do not provide their own version.
 *
 *--------------------------------------------------------------
 */

static void
DefaultRotateImplementation(
    TkCanvas *canvasPtr,
    Tk_Item *itemPtr,
    double x,
    double y,
    double angleRadians)
{
    int objc, i, ok = 1;
    Tcl_Obj **objv, **newObjv;
    double *coordv;
    double s = sin(angleRadians);
    double c = cos(angleRadians);
    Tcl_Interp *interp = canvasPtr->interp;

    /*
     * Get the coordinates out of the item.
     */

    if (ItemCoords(canvasPtr, itemPtr, 0, NULL) == TCL_OK &&
	    Tcl_ListObjGetElements(NULL, Tcl_GetObjResult(interp),
		    &objc, &objv) == TCL_OK) {
	coordv = (double *) ckalloc(sizeof(double) * objc);
	for (i=0 ; i<objc ; i++) {
	    if (Tcl_GetDoubleFromObj(NULL, objv[i], &coordv[i]) != TCL_OK) {
		ok = 0;
		break;
	    }
	}
	if (ok) {
	    /*
	     * Apply the rotation.
	     */

	    for (i=0 ; i<objc ; i+=2) {
		double px = coordv[i+0] - x;
		double py = coordv[i+1] - y;
		double nx = px * c - py * s;
		double ny = px * s + py * c;

		coordv[i+0] = nx + x;
		coordv[i+1] = ny + y;
	    }

	    /*
	     * Write the coordinates back into the item.
	     */

	    newObjv = (Tcl_Obj **) ckalloc(sizeof(Tcl_Obj *) * objc);
	    for (i=0 ; i<objc ; i++) {
		newObjv[i] = Tcl_NewDoubleObj(coordv[i]);
		Tcl_IncrRefCount(newObjv[i]);
	    }
	    ItemCoords(canvasPtr, itemPtr, objc, newObjv);
	    for (i=0 ; i<objc ; i++) {
		Tcl_DecrRefCount(newObjv[i]);
	    }
	    ckfree((char *) newObjv);
	}
	ckfree((char *) coordv);
    }

    /*
     * The interpreter result was (probably) modified above; reset it.
     */

    Tcl_ResetResult(interp);
}

/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasObjCmd --
 *
 *	This function is invoked to process the "canvas" Tcl command. See the







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







609
610
611
612
613
614
615
































































































616
617
618
619
620
621
622
    Tk_Item *itemPtr,
    double xDelta,
    double yDelta)
{
    itemPtr->typePtr->translateProc((Tk_Canvas) canvasPtr, itemPtr,
	    xDelta, yDelta);
}

































































































/*
 *--------------------------------------------------------------
 *
 * Tk_CanvasObjCmd --
 *
 *	This function is invoked to process the "canvas" Tcl command. See the
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
 *--------------------------------------------------------------
 */

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







|
|









|
|



|







631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
 *--------------------------------------------------------------
 */

int
Tk_CanvasObjCmd(
    ClientData clientData,	/* Main window associated with interpreter. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int 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
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
    canvasPtr->bgBorder = NULL;
    canvasPtr->relief = TK_RELIEF_FLAT;
    canvasPtr->highlightWidth = 0;
    canvasPtr->highlightBgColorPtr = NULL;
    canvasPtr->highlightColorPtr = NULL;
    canvasPtr->inset = 0;
    canvasPtr->pixmapGC = NULL;
    canvasPtr->width = None;
    canvasPtr->height = None;
    canvasPtr->confine = 0;
    canvasPtr->textInfo.selBorder = NULL;
    canvasPtr->textInfo.selBorderWidth = 0;
    canvasPtr->textInfo.selFgColorPtr = NULL;
    canvasPtr->textInfo.selItemPtr = NULL;
    canvasPtr->textInfo.selectFirst = TCL_INDEX_NONE;
    canvasPtr->textInfo.selectLast = TCL_INDEX_NONE;
    canvasPtr->textInfo.anchorItemPtr = NULL;
    canvasPtr->textInfo.selectAnchor = 0;
    canvasPtr->textInfo.insertBorder = NULL;
    canvasPtr->textInfo.insertWidth = 0;
    canvasPtr->textInfo.insertBorderWidth = 0;
    canvasPtr->textInfo.focusItemPtr = NULL;
    canvasPtr->textInfo.gotFocus = 0;







|
|





|
|







675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
    canvasPtr->bgBorder = NULL;
    canvasPtr->relief = TK_RELIEF_FLAT;
    canvasPtr->highlightWidth = 0;
    canvasPtr->highlightBgColorPtr = NULL;
    canvasPtr->highlightColorPtr = NULL;
    canvasPtr->inset = 0;
    canvasPtr->pixmapGC = NULL;
    canvasPtr->width = 0;
    canvasPtr->height = 0;
    canvasPtr->confine = 0;
    canvasPtr->textInfo.selBorder = NULL;
    canvasPtr->textInfo.selBorderWidth = 0;
    canvasPtr->textInfo.selFgColorPtr = NULL;
    canvasPtr->textInfo.selItemPtr = NULL;
    canvasPtr->textInfo.selectFirst = -1;
    canvasPtr->textInfo.selectLast = -1;
    canvasPtr->textInfo.anchorItemPtr = NULL;
    canvasPtr->textInfo.selectAnchor = 0;
    canvasPtr->textInfo.insertBorder = NULL;
    canvasPtr->textInfo.insertWidth = 0;
    canvasPtr->textInfo.insertBorderWidth = 0;
    canvasPtr->textInfo.focusItemPtr = NULL;
    canvasPtr->textInfo.gotFocus = 0;
777
778
779
780
781
782
783

784

785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
    canvasPtr->flags = 0;
    canvasPtr->nextId = 1;
    canvasPtr->psInfo = NULL;
    canvasPtr->canvas_state = TK_STATE_NORMAL;
    canvasPtr->tsoffset.flags = 0;
    canvasPtr->tsoffset.xoffset = 0;
    canvasPtr->tsoffset.yoffset = 0;

    canvasPtr->bindTagExprs = NULL;

    Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS);

    Tk_SetClass(canvasPtr->tkwin, "Canvas");
    Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    CanvasEventProc, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    CanvasBindProc, canvasPtr);
    Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
	    CanvasFetchSelection, canvasPtr, XA_STRING);
    if (ConfigureCanvas(interp, canvasPtr, argc-2, argv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(canvasPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(canvasPtr->tkwin);
    return TCL_ERROR;
}








>

>













|



|







731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
    canvasPtr->flags = 0;
    canvasPtr->nextId = 1;
    canvasPtr->psInfo = NULL;
    canvasPtr->canvas_state = TK_STATE_NORMAL;
    canvasPtr->tsoffset.flags = 0;
    canvasPtr->tsoffset.xoffset = 0;
    canvasPtr->tsoffset.yoffset = 0;
#ifndef USE_OLD_TAG_SEARCH
    canvasPtr->bindTagExprs = NULL;
#endif
    Tcl_InitHashTable(&canvasPtr->idTable, TCL_ONE_WORD_KEYS);

    Tk_SetClass(canvasPtr->tkwin, "Canvas");
    Tk_SetClassProcs(canvasPtr->tkwin, &canvasClass, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    CanvasEventProc, canvasPtr);
    Tk_CreateEventHandler(canvasPtr->tkwin, KeyPressMask|KeyReleaseMask
	    |ButtonPressMask|ButtonReleaseMask|EnterWindowMask
	    |LeaveWindowMask|PointerMotionMask|VirtualEventMask,
	    CanvasBindProc, canvasPtr);
    Tk_CreateSelHandler(canvasPtr->tkwin, XA_PRIMARY, XA_STRING,
	    CanvasFetchSelection, canvasPtr, XA_STRING);
    if (ConfigureCanvas(interp, canvasPtr, objc-2, objv+2, 0) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(canvasPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(canvasPtr->tkwin);
    return TCL_ERROR;
}

832
833
834
835
836
837
838



839
840

841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    int c, result;
    Tk_Item *itemPtr = NULL;	/* Initialization needed only to prevent
				 * compiler warning. */



    TagSearch *searchPtr = NULL;/* Allocated by first TagSearchScan, freed by
				 * TagSearchDestroy */


    int idx;
    static const char *const canvasOptionStrings[] = {
	"addtag",	"bbox",		"bind",		"canvasx",
	"canvasy",	"cget",		"configure",	"coords",
	"create",	"dchars",	"delete",	"dtag",
	"find",		"focus",	"gettags",	"icursor",
        "image",	"imove",	"index",	"insert",
	"itemcget",	"itemconfigure",
	"lower",	"move",		"moveto",	"postscript",
	"raise",	"rchars",	"rotate",	"scale",
	"scan",		"select",	"type",		"xview",
	"yview",	NULL
    };
    enum canvasOptionStringsEnum {
	CANV_ADDTAG,	CANV_BBOX,	CANV_BIND,	CANV_CANVASX,
	CANV_CANVASY,	CANV_CGET,	CANV_CONFIGURE,	CANV_COORDS,
	CANV_CREATE,	CANV_DCHARS,	CANV_DELETE,	CANV_DTAG,
	CANV_FIND,	CANV_FOCUS,	CANV_GETTAGS,	CANV_ICURSOR,
        CANV_IMAGE,	CANV_IMOVE,	CANV_INDEX,	CANV_INSERT,
	CANV_ITEMCGET,	CANV_ITEMCONFIGURE,
	CANV_LOWER,	CANV_MOVE,	CANV_MOVETO,	CANV_POSTSCRIPT,
	CANV_RAISE,	CANV_RCHARS,	CANV_ROTATE,	CANV_SCALE,
	CANV_SCAN,	CANV_SELECT,	CANV_TYPE,	CANV_XVIEW,
	CANV_YVIEW
    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], canvasOptionStrings, "option", 0,
	    &idx) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(canvasPtr);

    result = TCL_OK;
    switch ((enum canvasOptionStringsEnum)idx) {
    case CANV_ADDTAG:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	result = FIND_ITEMS(objv[2], 3);







>
>
>


>

|
|




|
|

|
|
|

|




|
|

|
|
<






|
|





|







788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824

825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    int c, result;
    Tk_Item *itemPtr = NULL;	/* Initialization needed only to prevent
				 * compiler warning. */
#ifdef USE_OLD_TAG_SEARCH
    TagSearch search;
#else /* USE_OLD_TAG_SEARCH */
    TagSearch *searchPtr = NULL;/* Allocated by first TagSearchScan, freed by
				 * TagSearchDestroy */
#endif /* USE_OLD_TAG_SEARCH */

    int index;
    static const char *const optionStrings[] = {
	"addtag",	"bbox",		"bind",		"canvasx",
	"canvasy",	"cget",		"configure",	"coords",
	"create",	"dchars",	"delete",	"dtag",
	"find",		"focus",	"gettags",	"icursor",
	"imove",	"index",	"insert",	"itemcget",
	"itemconfigure",
	"lower",	"move",		"moveto",	"postscript",
	"raise",	"rchars",	"scale",	"scan",
	"select",	"type",		"xview",	"yview",
	NULL
    };
    enum options {
	CANV_ADDTAG,	CANV_BBOX,	CANV_BIND,	CANV_CANVASX,
	CANV_CANVASY,	CANV_CGET,	CANV_CONFIGURE,	CANV_COORDS,
	CANV_CREATE,	CANV_DCHARS,	CANV_DELETE,	CANV_DTAG,
	CANV_FIND,	CANV_FOCUS,	CANV_GETTAGS,	CANV_ICURSOR,
	CANV_IMOVE,	CANV_INDEX,	CANV_INSERT,	CANV_ITEMCGET,
	CANV_ITEMCONFIGURE,
	CANV_LOWER,	CANV_MOVE,	CANV_MOVETO,	CANV_POSTSCRIPT,
	CANV_RAISE,	CANV_RCHARS,	CANV_SCALE,	CANV_SCAN,
	CANV_SELECT,	CANV_TYPE,	CANV_XVIEW,	CANV_YVIEW

    };

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "option", 0,
	    &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(canvasPtr);

    result = TCL_OK;
    switch ((enum options)index) {
    case CANV_ADDTAG:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tag searchCommand ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	result = FIND_ITEMS(objv[2], 3);
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954





























955
956
957
958
959
960
961
		    }
		}
	    }
	}
	if (gotAny) {
	    Tcl_Obj *resultObjs[4];

	    resultObjs[0] = Tcl_NewWideIntObj(x1);
	    resultObjs[1] = Tcl_NewWideIntObj(y1);
	    resultObjs[2] = Tcl_NewWideIntObj(x2);
	    resultObjs[3] = Tcl_NewWideIntObj(y2);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, resultObjs));
	}
	break;
    }
    case CANV_BIND: {
	void *object;

	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?sequence? ?command?");
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * Figure out what object to use for the binding (individual item vs.
	 * tag).
	 */

	object = NULL;





























	result = TagSearchScan(canvasPtr, objv[2], &searchPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	if (searchPtr->type == SEARCH_TYPE_ID) {
	    Tcl_HashEntry *entryPtr;








|
|
|
|



















>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
		    }
		}
	    }
	}
	if (gotAny) {
	    Tcl_Obj *resultObjs[4];

	    resultObjs[0] = Tcl_NewIntObj(x1);
	    resultObjs[1] = Tcl_NewIntObj(y1);
	    resultObjs[2] = Tcl_NewIntObj(x2);
	    resultObjs[3] = Tcl_NewIntObj(y2);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(4, resultObjs));
	}
	break;
    }
    case CANV_BIND: {
	void *object;

	if ((objc < 3) || (objc > 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId ?sequence? ?command?");
	    result = TCL_ERROR;
	    goto done;
	}

	/*
	 * Figure out what object to use for the binding (individual item vs.
	 * tag).
	 */

	object = NULL;
#ifdef USE_OLD_TAG_SEARCH
	if (isdigit(UCHAR(Tcl_GetString(objv[2])[0]))) {
	    int id;
	    char *end;
	    Tcl_HashEntry *entryPtr;

	    id = strtoul(Tcl_GetString(objv[2]), &end, 0);
	    if (*end != 0) {
		goto bindByTag;
	    }
	    entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char *) id);
	    if (entryPtr != NULL) {
		itemPtr = Tcl_GetHashValue(entryPtr);
		object = itemPtr;
	    }

	    if (object == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"item \"%s\" doesn't exist", Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM",
			Tcl_GetString(objv[2]), NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	bindByTag:
	    object = Tk_GetUid(Tcl_GetString(objv[2]));
	}
#else /* USE_OLD_TAG_SEARCH */
	result = TagSearchScan(canvasPtr, objv[2], &searchPtr);
	if (result != TCL_OK) {
	    goto done;
	}
	if (searchPtr->type == SEARCH_TYPE_ID) {
	    Tcl_HashEntry *entryPtr;

971
972
973
974
975
976
977
978
979

980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998

999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
			"item \"%s\" doesn't exist", Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM",
			Tcl_GetString(objv[2]), NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    object = (char *)searchPtr->expr->uid;
	}


	/*
	 * Make a binding table if the canvas doesn't already have one.
	 */

	if (canvasPtr->bindingTable == NULL) {
	    canvasPtr->bindingTable = Tk_CreateBindingTable(interp);
	}

	if (objc == 5) {
	    int append = 0;
	    unsigned int mask;
	    const char *argv4 = Tcl_GetString(objv[4]);

	    if (argv4[0] == 0) {
		result = Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		goto done;
	    }

	    if (searchPtr->type == SEARCH_TYPE_EXPR) {
		/*
		 * If new tag expression, then insert in linked list.
		 */

	    	TagSearchExpr *expr, **lastPtr;

		lastPtr = &(canvasPtr->bindTagExprs);
		while ((expr = *lastPtr) != NULL) {
		    if (expr->uid == searchPtr->expr->uid) {
			break;
		    }
		    lastPtr = &(expr->next);







|

>



















>





|







959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
			"item \"%s\" doesn't exist", Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "CANVAS_ITEM",
			Tcl_GetString(objv[2]), NULL);
		result = TCL_ERROR;
		goto done;
	    }
	} else {
	    object = (void *)searchPtr->expr->uid;
	}
#endif /* USE_OLD_TAG_SEARCH */

	/*
	 * Make a binding table if the canvas doesn't already have one.
	 */

	if (canvasPtr->bindingTable == NULL) {
	    canvasPtr->bindingTable = Tk_CreateBindingTable(interp);
	}

	if (objc == 5) {
	    int append = 0;
	    unsigned int mask;
	    const char *argv4 = Tcl_GetString(objv[4]);

	    if (argv4[0] == 0) {
		result = Tk_DeleteBinding(interp, canvasPtr->bindingTable,
			object, Tcl_GetString(objv[3]));
		goto done;
	    }
#ifndef USE_OLD_TAG_SEARCH
	    if (searchPtr->type == SEARCH_TYPE_EXPR) {
		/*
		 * If new tag expression, then insert in linked list.
		 */

		TagSearchExpr *expr, **lastPtr;

		lastPtr = &(canvasPtr->bindTagExprs);
		while ((expr = *lastPtr) != NULL) {
		    if (expr->uid == searchPtr->expr->uid) {
			break;
		    }
		    lastPtr = &(expr->next);
1022
1023
1024
1025
1026
1027
1028

1029
1030
1031
1032
1033
1034
1035
		     * Flag in TagSearch that expr has changed ownership so
		     * that TagSearchDestroy doesn't try to free it.
		     */

		    searchPtr->expr = NULL;
		}
	    }

	    if (argv4[0] == '+') {
		argv4++;
		append = 1;
	    }
	    mask = Tk_CreateBinding(interp, canvasPtr->bindingTable,
		    object, Tcl_GetString(objv[3]), argv4, append);
	    if (mask == 0) {







>







1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
		     * Flag in TagSearch that expr has changed ownership so
		     * that TagSearchDestroy doesn't try to free it.
		     */

		    searchPtr->expr = NULL;
		}
	    }
#endif /* not USE_OLD_TAG_SEARCH */
	    if (argv4[0] == '+') {
		argv4++;
		append = 1;
	    }
	    mask = Tk_CreateBinding(interp, canvasPtr->bindingTable,
		    object, Tcl_GetString(objv[3]), argv4, append);
	    if (mask == 0) {
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
	 * 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.







<







1181
1182
1183
1184
1185
1186
1187

1188
1189
1190
1191
1192
1193
1194
	 * Make a temporary object here that we can reuse for all the
	 * modifications in the loop.
	 */

	tmpObj = Tcl_NewListObj(2, objv+4);

	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) {

	    int x1, x2, y1, y2;
	    int dontRedraw1, dontRedraw2;

	    /*
	     * The TK_MOVABLE_POINTS flag should only be set for types that
	     * support the same semantics of index, dChars and insert methods
	     * as lines and canvases.
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260

1261
1262
1263
1264
1265
1266
1267
    }
    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.
	 */







|






|
>







1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
    }
    case CANV_CREATE: {
	Tk_ItemType *typePtr;
	Tk_ItemType *matchPtr = NULL;
	int isNew = 0;
	Tcl_HashEntry *entryPtr;
	const char *arg;
	size_t length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?");
	    result = TCL_ERROR;
	    goto done;
	}
	arg = Tcl_GetString(objv[2]);
	length = objv[2]->length;
	c = arg[0];

	/*
	 * Lock because the list of types is a global resource that could be
	 * updated by another thread. That's fairly unlikely, but not
	 * impossible.
	 */
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
	} else {
	    canvasPtr->lastItemPtr->nextPtr = itemPtr;
	}
	canvasPtr->lastItemPtr = itemPtr;
	itemPtr->redraw_flags |= FORCE_REDRAW;
	EventuallyRedrawItem(canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(itemPtr->id));
	break;
    }
    case CANV_DCHARS: {
	TkSizeT first, last;
	int x1, x2, y1, y2;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
	    result = TCL_ERROR;
	    goto done;
	}







|



|







1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
	} else {
	    canvasPtr->lastItemPtr->nextPtr = itemPtr;
	}
	canvasPtr->lastItemPtr = itemPtr;
	itemPtr->redraw_flags |= FORCE_REDRAW;
	EventuallyRedrawItem(canvasPtr, itemPtr);
	canvasPtr->flags |= REPICK_NEEDED;
	Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id));
	break;
    }
    case CANV_DCHARS: {
	int first, last;
	int x1, x2, y1, y2;

	if ((objc != 4) && (objc != 5)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
	    result = TCL_ERROR;
	    goto done;
	}
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
	}
	if (objc == 4) {
	    tag = Tk_GetUid(Tcl_GetString(objv[3]));
	} else {
	    tag = Tk_GetUid(Tcl_GetString(objv[2]));
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    for (i = (int)itemPtr->numTags-1; i >= 0; i--) {
		if (itemPtr->tagPtr[i] == tag) {

                    /*
                     * Don't shuffle the tags sequence: memmove the tags.
                     */

                    memmove((void *)(itemPtr->tagPtr + i),
                            itemPtr->tagPtr + i + 1,
                            (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;

                    /*
                     * There must be no break here: all tags with the same name must
                     * be deleted.
                     */

 		}
	    }
	}
	break;
    }
    case CANV_FIND:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "searchCommand ?arg ...?");







|


|
|
|

|
|
|


|
|
|
|

|







1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
	}
	if (objc == 4) {
	    tag = Tk_GetUid(Tcl_GetString(objv[3]));
	} else {
	    tag = Tk_GetUid(Tcl_GetString(objv[2]));
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    for (i = itemPtr->numTags-1; i >= 0; i--) {
		if (itemPtr->tagPtr[i] == tag) {

		    /*
		     * Don't shuffle the tags sequence: memmove the tags.
		     */

		    memmove((void *)(itemPtr->tagPtr + i),
			    itemPtr->tagPtr + i + 1,
			    (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;

		    /*
		     * There must be no break here: all tags with the same name must
		     * be deleted.
		     */

		}
	    }
	}
	break;
    }
    case CANV_FIND:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "searchCommand ?arg ...?");
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
	    Tcl_WrongNumArgs(interp, 2, objv, "?tagOrId?");
	    result = TCL_ERROR;
	    goto done;
	}
	itemPtr = canvasPtr->textInfo.focusItemPtr;
	if (objc == 2) {
	    if (itemPtr != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(itemPtr->id));
	    }
	    goto done;
	}
	if (canvasPtr->textInfo.gotFocus) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	}
	if (Tcl_GetString(objv[2])[0] == 0) {







|







1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
	    Tcl_WrongNumArgs(interp, 2, objv, "?tagOrId?");
	    result = TCL_ERROR;
	    goto done;
	}
	itemPtr = canvasPtr->textInfo.focusItemPtr;
	if (objc == 2) {
	    if (itemPtr != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id));
	    }
	    goto done;
	}
	if (canvasPtr->textInfo.gotFocus) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	}
	if (Tcl_GetString(objv[2])[0] == 0) {
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    int i;
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (i = 0; i < (int)itemPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(itemPtr->tagPtr[i], -1));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    case CANV_ICURSOR: {
	TkSizeT index;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {







|







<







1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530

1531
1532
1533
1534
1535
1536
1537
	    goto done;
	}
	FIRST_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done);
	if (itemPtr != NULL) {
	    int i;
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (i = 0; i < itemPtr->numTags; i++) {
		Tcl_ListObjAppendElement(NULL, resultObj,
			Tcl_NewStringObj(itemPtr->tagPtr[i], -1));
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;
    case CANV_ICURSOR: {


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







<







1548
1549
1550
1551
1552
1553
1554

1555
1556
1557
1558
1559
1560
1561
		    && (canvasPtr->textInfo.cursorOn)) {
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	}
	break;
    }
    case CANV_INDEX: {


	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId string");
	    result = TCL_ERROR;
	    goto done;
	}
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
	    result = TCL_ERROR;
	    goto done;
	}
	result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);
	if (result != TCL_OK) {
	    goto done;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	break;
    }
    case CANV_INSERT: {
	TkSizeT beforeThis;
	int x1, x2, y1, y2;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
	    result = TCL_ERROR;
	    goto done;
	}







|



|







1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
	    result = TCL_ERROR;
	    goto done;
	}
	result = ItemIndex(canvasPtr, itemPtr, objv[3], &index);
	if (result != TCL_OK) {
	    goto done;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	break;
    }
    case CANV_INSERT: {
	int beforeThis;
	int x1, x2, y1, y2;

	if (objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
	    result = TCL_ERROR;
	    goto done;
	}
1674
1675
1676
1677
1678
1679
1680





1681
1682
1683
1684
1685
1686
1687
	 */

	if (objc == 3) {
	    itemPtr = NULL;
	} else {
	    FIRST_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done);
	    if (itemPtr == NULL) {





		goto done;
	    }
	    itemPtr = itemPtr->prevPtr;
	}
	RELINK_ITEMS(objv[2], itemPtr);
	break;
    }







>
>
>
>
>







1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
	 */

	if (objc == 3) {
	    itemPtr = NULL;
	} else {
	    FIRST_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done);
	    if (itemPtr == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"tagOrId \"%s\" doesn't match any items",
			Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    itemPtr = itemPtr->prevPtr;
	}
	RELINK_ITEMS(objv[2], itemPtr);
	break;
    }
1796
1797
1798
1799
1800
1801
1802





1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
	    prevPtr = canvasPtr->lastItemPtr;
	} else {
	    prevPtr = NULL;
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
		prevPtr = itemPtr;
	    }
	    if (prevPtr == NULL) {





		goto done;
	    }
	}
	RELINK_ITEMS(objv[2], prevPtr);
	break;
    }
    case CANV_RCHARS: {
	TkSizeT first, last;
	int x1, x2, y1, y2;
	int dontRedraw1, dontRedraw2;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
	    result = TCL_ERROR;
	    goto done;







>
>
>
>
>







|







1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
	    prevPtr = canvasPtr->lastItemPtr;
	} else {
	    prevPtr = NULL;
	    FOR_EVERY_CANVAS_ITEM_MATCHING(objv[3], &searchPtr, goto done) {
		prevPtr = itemPtr;
	    }
	    if (prevPtr == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"tagOrId \"%s\" doesn't match any items",
			Tcl_GetString(objv[3])));
		Tcl_SetErrorCode(interp, "TK", "CANVAS", "ITEM", NULL);
		result = TCL_ERROR;
		goto done;
	    }
	}
	RELINK_ITEMS(objv[2], prevPtr);
	break;
    }
    case CANV_RCHARS: {
	int first, last;
	int x1, x2, y1, y2;
	int dontRedraw1, dontRedraw2;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
	    result = TCL_ERROR;
	    goto done;
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
	     * Except if the dCharsProc or insertProc sets the
	     * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
	     */

	    x1 = itemPtr->x1; y1 = itemPtr->y1;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;

            itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemDelChars(canvasPtr, itemPtr, first, last);
	    dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

            itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemInsert(canvasPtr, itemPtr, first, objv[5]);
	    dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

            if (!(dontRedraw1 && dontRedraw2)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
	break;
    }
    case CANV_ROTATE: {
	double x, y, angle;
	Tk_Canvas canvas = (Tk_Canvas) canvasPtr;

	if (objc != 6) {
	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId x y angle");
	    result = TCL_ERROR;
	    goto done;
	}
	if (Tk_CanvasGetCoordFromObj(interp, canvas, objv[3], &x) != TCL_OK ||
		Tk_CanvasGetCoordFromObj(interp, canvas, objv[4], &y) != TCL_OK ||
		Tcl_GetDoubleFromObj(interp, objv[5], &angle) != TCL_OK) {
	    result = TCL_ERROR;
	    goto done;
	}
	angle = angle * 3.1415927 / 180.0;
	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    ItemRotate(canvasPtr, itemPtr, x, y, angle);
	    EventuallyRedrawItem(canvasPtr, itemPtr);
	    canvasPtr->flags |= REPICK_NEEDED;
	}
	break;
    }
    case CANV_SCALE: {
	double xOrigin, yOrigin, xScale, yScale;

	if (objc != 7) {
	    Tcl_WrongNumArgs(interp, 2, objv,







|



|



|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
























1858
1859
1860
1861
1862
1863
1864
	     * Except if the dCharsProc or insertProc sets the
	     * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
	     */

	    x1 = itemPtr->x1; y1 = itemPtr->y1;
	    x2 = itemPtr->x2; y2 = itemPtr->y2;

	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemDelChars(canvasPtr, itemPtr, first, last);
	    dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	    ItemInsert(canvasPtr, itemPtr, first, objv[5]);
	    dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;

	    if (!(dontRedraw1 && dontRedraw2)) {
		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
			x1, y1, x2, y2);
		EventuallyRedrawItem(canvasPtr, itemPtr);
	    }
	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
	}
























	break;
    }
    case CANV_SCALE: {
	double xOrigin, yOrigin, xScale, yScale;

	if (objc != 7) {
	    Tcl_WrongNumArgs(interp, 2, objv,
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
	    "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;








|

|
|







|







1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
	    "mark", "dragto", NULL
	};

	if (objc < 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "mark|dragto x y ?dragGain?");
	    result = TCL_ERROR;
	} else if (Tcl_GetIndexFromObj(interp, objv[2], optionStrings,
		"scan option", 0, &index) != TCL_OK) {
	    result = TCL_ERROR;
	} else if ((objc != 5) && (objc != 5+index)) {
	    Tcl_WrongNumArgs(interp, 3, objv, index?"x y ?gain?":"x y");
	    result = TCL_ERROR;
	} else if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)){
	    result = TCL_ERROR;
	} else if ((objc == 6) &&
		(Tcl_GetIntFromObj(interp, objv[5], &gain) != TCL_OK)) {
	    result = TCL_ERROR;
	} else if (!index) {
	    canvasPtr->scanX = x;
	    canvasPtr->scanXOrigin = canvasPtr->xOrigin;
	    canvasPtr->scanY = y;
	    canvasPtr->scanYOrigin = canvasPtr->yOrigin;
	} else {
	    int newXOrigin, newYOrigin, tmp;

1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
		    - 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
	};







<







1931
1932
1933
1934
1935
1936
1937

1938
1939
1940
1941
1942
1943
1944
		    - canvasPtr->scrollY1;
	    newYOrigin = canvasPtr->scrollY1 + tmp;
	    CanvasSetOrigin(canvasPtr, newXOrigin, newYOrigin);
	}
	break;
    }
    case CANV_SELECT: {

	int optionindex;
	static const char *const optionStrings[] = {
	    "adjust", "clear", "from", "item", "to", NULL
	};
	enum options {
	    CANV_ADJUST, CANV_CLEAR, CANV_FROM, CANV_ITEM, CANV_TO
	};
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
	case CANV_ADJUST:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr == itemPtr) {
		if (index + 1 <= ((canvasPtr->textInfo.selectFirst
			+ canvasPtr->textInfo.selectLast)/2)) {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectLast + 1;
		} else {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectFirst;
		}
	    }







|
|







1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
	case CANV_ADJUST:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr == itemPtr) {
		if (index < (canvasPtr->textInfo.selectFirst
			+ canvasPtr->textInfo.selectLast)/2) {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectLast + 1;
		} else {
		    canvasPtr->textInfo.selectAnchor =
			    canvasPtr->textInfo.selectFirst;
		}
	    }
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewWideIntObj(canvasPtr->textInfo.selItemPtr->id));
	    }
	    break;
	case CANV_TO:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;







|







2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		result = TCL_ERROR;
		goto done;
	    }
	    if (canvasPtr->textInfo.selItemPtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewIntObj(canvasPtr->textInfo.selItemPtr->id));
	    }
	    break;
	case CANV_TO:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 2, objv, "tagOrId index");
		result = TCL_ERROR;
		goto done;
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117



2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209

2210

2211
2212
2213
2214
2215
2216
2217
	}
	break;
    case CANV_XVIEW: {
	int count, type;
	int newX = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;
	const char **args;

	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->xOrigin + canvasPtr->inset,
		    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)
		    - canvasPtr->inset, canvasPtr->scrollX1,
		    canvasPtr->scrollX2));
	    break;
	}

	args = TkGetStringsFromObjs(objc, objv);
	type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	if (args != NULL) {
	    ckfree(args);
	}
	switch (type) {
	case TK_SCROLL_ERROR:
	    result = TCL_ERROR;
	    goto done;
	case TK_SCROLL_MOVETO:
	    newX = canvasPtr->scrollX1 - canvasPtr->inset
		    + (int) (fraction * (canvasPtr->scrollX2
			    - canvasPtr->scrollX1) + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    newX = (int) (canvasPtr->xOrigin + count * .9
		    * (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    break;
	case TK_SCROLL_UNITS:
	    if (canvasPtr->xScrollIncrement > 0) {
		newX = canvasPtr->xOrigin + count*canvasPtr->xScrollIncrement;
	    } else {
		newX = (int) (canvasPtr->xOrigin + count * .1
			* (Tk_Width(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    }
	    break;



	}
	CanvasSetOrigin(canvasPtr, newX, canvasPtr->yOrigin);
	break;
    }
    case CANV_YVIEW: {
	int count, type;
	int newY = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;
	const char **args;

	if (objc == 2) {
	    Tcl_SetObjResult(interp, ScrollFractions(
		    canvasPtr->yOrigin + canvasPtr->inset,
		    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)
		    - canvasPtr->inset,
		    canvasPtr->scrollY1, canvasPtr->scrollY2));
	    break;
	}

	args = TkGetStringsFromObjs(objc, objv);
	type = Tk_GetScrollInfo(interp, objc, args, &fraction, &count);
	if (args != NULL) {
	    ckfree(args);
	}
	switch (type) {
	case TK_SCROLL_ERROR:
	    result = TCL_ERROR;
	    goto done;
	case TK_SCROLL_MOVETO:
	    newY = canvasPtr->scrollY1 - canvasPtr->inset + (int) (
		    fraction*(canvasPtr->scrollY2-canvasPtr->scrollY1) + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    newY = (int) (canvasPtr->yOrigin + count * .9
		    * (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    break;
	case TK_SCROLL_UNITS:
	    if (canvasPtr->yScrollIncrement > 0) {
		newY = canvasPtr->yOrigin + count*canvasPtr->yScrollIncrement;
	    } else {
		newY = (int) (canvasPtr->yOrigin + count * .1
			* (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset));
	    }
	    break;
	}
	CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
	break;
    }
    case CANV_IMAGE: {
        Tk_PhotoHandle photohandle;
        int subsample = 1, zoom = 1;

        if (objc < 3 || objc > 5) {
            Tcl_WrongNumArgs(interp, 2, objv, "imagename ?subsample? ?zoom?");
            result = TCL_ERROR;
            goto done;
        }

        if ((photohandle = Tk_FindPhoto(interp, Tcl_GetString(objv[2]) )) == 0) {
            result = TCL_ERROR;
            goto done;
        }

        /*
         * If we are given a subsample or a zoom then grab them.
         */

        if (objc >= 4 && Tcl_GetIntFromObj(interp, objv[3], &subsample) != TCL_OK) {
            result = TCL_ERROR;
            goto done;
        }
        if (objc >= 5 && Tcl_GetIntFromObj(interp, objv[4], &zoom) != TCL_OK) {
            result = TCL_ERROR;
            goto done;
        }

        /*
         * Set the image size to zero, which allows the DrawCanvas() function
         * to expand the image automatically when it copies the pixmap into it.
         */

        if (Tk_PhotoSetSize(interp, photohandle, 0, 0) != TCL_OK) {
            result = TCL_ERROR;
            goto done;
        }

        result = DrawCanvas(interp, clientData, photohandle, subsample, zoom);
    }
    }

  done:

    TagSearchDestroy(searchPtr);

    Tcl_Release(canvasPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *







<










<
|
<
<
<

<
<
<

















>
>
>









<










<
|
<
<
<

<
<
<
















<
<
<
<
<
<
<
|
<
<
|
|
|
|
<
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>

>







2048
2049
2050
2051
2052
2053
2054

2055
2056
2057
2058
2059
2060
2061
2062
2063
2064

2065



2066



2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095

2096
2097
2098
2099
2100
2101
2102
2103
2104
2105

2106



2107



2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123







2124


2125
2126
2127
2128




2129



2130



2131



2132















2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
	}
	break;
    case CANV_XVIEW: {
	int count, type;
	int newX = 0;		/* Initialization needed only to prevent gcc
				 * warnings. */
	double fraction;


	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;



    }



    }



















  done:
#ifndef USE_OLD_TAG_SEARCH
    TagSearchDestroy(searchPtr);
#endif /* not USE_OLD_TAG_SEARCH */
    Tcl_Release(canvasPtr);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238

2239

2240
2241
2242
2243
2244
2245
2246
 *	Everything associated with the canvas is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyCanvas(
    void *memPtr)		/* Info about canvas widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)memPtr;
    Tk_Item *itemPtr;

    TagSearchExpr *expr, *next;


    /*
     * Free up all of the items in the canvas.
     */

    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = canvasPtr->firstItemPtr) {







|



>

>







2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
 *	Everything associated with the canvas is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyCanvas(
    char *memPtr)		/* Info about canvas widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)memPtr;
    Tk_Item *itemPtr;
#ifndef USE_OLD_TAG_SEARCH
    TagSearchExpr *expr, *next;
#endif

    /*
     * Free up all of the items in the canvas.
     */

    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    itemPtr = canvasPtr->firstItemPtr) {
2257
2258
2259
2260
2261
2262
2263

2264
2265
2266
2267
2268
2269

2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    Tcl_DeleteHashTable(&canvasPtr->idTable);
    if (canvasPtr->pixmapGC != NULL) {
	Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);
    }

    expr = canvasPtr->bindTagExprs;
    while (expr) {
	next = expr->next;
	TagSearchExprDestroy(expr);
	expr = next;
    }

    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (canvasPtr->bindingTable != NULL) {
	Tk_DeleteBindingTable(canvasPtr->bindingTable);
    }
    Tk_FreeOptions(configSpecs, (char *) canvasPtr, canvasPtr->display, 0);
    canvasPtr->tkwin = NULL;
    ckfree(canvasPtr);
}

/*
 *----------------------------------------------------------------------
 *







>






>




|







2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
     * Tk_FreeOptions handle all the standard option-related stuff.
     */

    Tcl_DeleteHashTable(&canvasPtr->idTable);
    if (canvasPtr->pixmapGC != NULL) {
	Tk_FreeGC(canvasPtr->display, canvasPtr->pixmapGC);
    }
#ifndef USE_OLD_TAG_SEARCH
    expr = canvasPtr->bindTagExprs;
    while (expr) {
	next = expr->next;
	TagSearchExprDestroy(expr);
	expr = next;
    }
#endif /* USE_OLD_TAG_SEARCH */
    Tcl_DeleteTimerHandler(canvasPtr->insertBlinkHandler);
    if (canvasPtr->bindingTable != NULL) {
	Tk_DeleteBindingTable(canvasPtr->bindingTable);
    }
    Tk_FreeOptions(configSpecs, (char *)canvasPtr, canvasPtr->display, 0);
    canvasPtr->tkwin = NULL;
    ckfree(canvasPtr);
}

/*
 *----------------------------------------------------------------------
 *
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
     */

    if ( old_canvas_state != canvasPtr->canvas_state ) {
	Tk_Item *itemPtr;
	int result;

	for ( itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    	    	    itemPtr = itemPtr->nextPtr) {
	    if ( itemPtr->state == TK_STATE_NULL ) {
		result = (*itemPtr->typePtr->configProc)(canvasPtr->interp,
			(Tk_Canvas) canvasPtr, itemPtr, 0, NULL,
			TK_CONFIG_ARGV_ONLY);
		if (result != TCL_OK) {
		    Tcl_ResetResult(canvasPtr->interp);
		}







|







2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
     */

    if ( old_canvas_state != canvasPtr->canvas_state ) {
	Tk_Item *itemPtr;
	int result;

	for ( itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
		itemPtr = itemPtr->nextPtr) {
	    if ( itemPtr->state == TK_STATE_NULL ) {
		result = (*itemPtr->typePtr->configProc)(canvasPtr->interp,
			(Tk_Canvas) canvasPtr, itemPtr, 0, NULL,
			TK_CONFIG_ARGV_ONLY);
		if (result != TCL_OK) {
		    Tcl_ResetResult(canvasPtr->interp);
		}
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
	if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString,
		&argc2, &argv2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (argc2 != 4) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scrollRegion \"%s\"", canvasPtr->regionString));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SCROLL_REGION", NULL);
	badRegion:
	    ckfree(canvasPtr->regionString);
	    ckfree(argv2);
	    canvasPtr->regionString = NULL;
	    return TCL_ERROR;
	}
	if ((Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,







|







2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
	if (Tcl_SplitList(canvasPtr->interp, canvasPtr->regionString,
		&argc2, &argv2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (argc2 != 4) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad scrollRegion \"%s\"", canvasPtr->regionString));
	    Tcl_SetErrorCode(interp, "TK", "CANVAS", "SCROLL_REGION", (char *)NULL);
	badRegion:
	    ckfree(canvasPtr->regionString);
	    ckfree(argv2);
	    canvasPtr->regionString = NULL;
	    return TCL_ERROR;
	}
	if ((Tk_GetPixels(canvasPtr->interp, canvasPtr->tkwin,
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
}

/*
 *----------------------------------------------------------------------
 *
 * DecomposeMaskToShiftAndBits --
 *
 *      Given a 32 bit pixel mask, we find the position of the lowest bit and the
 *      width of the mask bits.
 *
 * Results:
 *	None.
 *
 * Side effects:
*       None.
 *
 *----------------------------------------------------------------------
 */
static void
DecomposeMaskToShiftAndBits(
    unsigned int mask,     /* The pixel mask to examine */
    int *shift,             /* Where to put the shift count (position of lowest bit) */
    int *bits)              /* Where to put the bit count (width of the pixel mask) */
{
    int i;

    *shift = 0;
    *bits = 0;

    /*
     * Find the lowest '1' bit in the mask.
     */

    for (i = 0; i < 32; ++i) {
        if (mask & 1 << i)
            break;
    }
    if (i < 32) {
        *shift = i;

        /*
        * Now find the next '0' bit and the width of the mask.
        */

        for ( ; i < 32; ++i) {
            if ((mask & 1 << i) == 0)
                break;
            else
                ++*bits;
        }

        /*
        * Limit to the top 8 bits if the mask was wider than 8.
        */

        if (*bits > 8) {
            *shift += *bits - 8;
            *bits = 8;
        }
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DrawCanvas --
 *
 *      This function draws the contents of a canvas into the given Photo image.
 *      This function is called from the widget "image" subcommand.
 *      The canvas does not need to be mapped (one of it's ancestors must be)
 *      in order for this function to work.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *      Canvas contents from within the -scrollregion or widget size are rendered
 *      into the Photo. Any errors are left in the result.
 *
 *----------------------------------------------------------------------
 */

#define OVERDRAW_PIXELS 32        /* How much larger we make the pixmap
                                   * that the canvas objects are drawn into */

/* From stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine */
#define IS_BIG_ENDIAN (*(unsigned short *)"\0\xff" < 0x100)

#define BYTE_SWAP16(n) ((((unsigned short)n)>>8) | (((unsigned short)n)<<8))
#define BYTE_SWAP32(n) (((n>>24)&0x000000FF) | ((n<<8)&0x00FF0000) | ((n>>8)&0x0000FF00) | ((n<<24)&0xFF000000))

static int
DrawCanvas(
    Tcl_Interp *interp,           /* As passed to the widget command, and we will leave errors here */
    ClientData clientData,
    Tk_PhotoHandle photohandle,   /* The photo we are rendering into */
    int subsample,                /* If either subsample or zoom are not 1 then we call Tk_PhotoPutZoomedBlock() */
    int zoom)
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin;
    Display *displayPtr;
    Tk_PhotoImageBlock blockPtr = {0,0,0,0,0,{0,0,0,0}};
    Window wid;
    Tk_Item *itemPtr;
    Pixmap pixmap = 0;
    XImage *ximagePtr = NULL;
    Visual *visualPtr;
    GC xgc = 0;
    XGCValues xgcValues;
    int canvasX1, canvasY1, canvasX2, canvasY2, cWidth, cHeight,
        pixmapX1, pixmapY1, pixmapX2, pixmapY2, pmWidth, pmHeight,
        bitsPerPixel, bytesPerPixel, x, y, result = TCL_OK,
        rshift, gshift, bshift, rbits, gbits, bbits;

#ifdef DEBUG_DRAWCANVAS
    char buffer[128];
#endif

    if ((tkwin = canvasPtr->tkwin) == NULL) {
        Tcl_AppendResult(interp, "canvas tkwin is NULL!", NULL);
        result = TCL_ERROR;
        goto done;
    }

    /*
     * If this canvas is unmapped, then we won't have a window id, so we will
     * try the ancestors of the canvas until we find a window that has a
     * valid window id. The Tk_GetPixmap() call requires a valid window id.
     */

    do {

        if ((displayPtr = Tk_Display(tkwin)) == NULL) {
            Tcl_AppendResult(interp, "canvas (or parent) display is NULL!", NULL);
            result = TCL_ERROR;
            goto done;
        }

        if ((wid = Tk_WindowId(tkwin)) != 0) {
            continue;
        }

        if ((tkwin = Tk_Parent(tkwin)) == NULL) {
            Tcl_AppendResult(interp, "canvas has no parent with a valid window id! Is the toplevel window mapped?", NULL);
            result = TCL_ERROR;
            goto done;
        }

    } while (wid == 0);

    bitsPerPixel = Tk_Depth(tkwin);
    visualPtr = Tk_Visual(tkwin);

    if (subsample == 0) {
        Tcl_AppendResult(interp, "subsample cannot be zero", NULL);
        result = TCL_ERROR;
        goto done;
    }

    /*
    * Scan through the item list, registering the bounding box for all items
    * that didn't do that for the final coordinates yet. This can be
    * determined by the FORCE_REDRAW flag.
    */

    for (itemPtr = canvasPtr -> firstItemPtr; itemPtr != NULL;
            itemPtr = itemPtr -> nextPtr) {
        if (itemPtr -> redraw_flags & FORCE_REDRAW) {
            itemPtr -> redraw_flags &= ~FORCE_REDRAW;
            EventuallyRedrawItem(canvasPtr, itemPtr);
            itemPtr -> redraw_flags &= ~FORCE_REDRAW;
        }
    }

    /*
     * The DisplayCanvas() function works out the region that needs redrawing,
     * but we don't do this. We grab the whole scrollregion or canvas window
     * area. If we have a defined -scrollregion we use that as the drawing
     * region, otherwise use the canvas window height and width with an origin
     * of 0,0.
     */
    if (canvasPtr->scrollX1 != 0 || canvasPtr->scrollY1 != 0 ||
            canvasPtr->scrollX2 != 0 || canvasPtr->scrollY2 != 0) {

        canvasX1 = canvasPtr->scrollX1;
        canvasY1 = canvasPtr->scrollY1;
        canvasX2 = canvasPtr->scrollX2;
        canvasY2 = canvasPtr->scrollY2;
        cWidth = canvasX2 - canvasX1 + 1;
        cHeight = canvasY2 - canvasY1 + 1;

    } else {

        cWidth = Tk_Width(tkwin);
        cHeight = Tk_Height(tkwin);
        canvasX1 = 0;
        canvasY1 = 0;
        canvasX2 = canvasX1 + cWidth - 1;
        canvasY2 = canvasY1 + cHeight - 1;
    }

    /*
     * Allocate a pixmap to draw into. We add OVERDRAW_PIXELS in the same way
     * that DisplayCanvas() does to avoid problems on some systems when objects
     * are being drawn too close to the edge.
     */

    pixmapX1 = canvasX1 - OVERDRAW_PIXELS;
    pixmapY1 = canvasY1 - OVERDRAW_PIXELS;
    pixmapX2 = canvasX2 + OVERDRAW_PIXELS;
    pixmapY2 = canvasY2 + OVERDRAW_PIXELS;
    pmWidth = pixmapX2 - pixmapX1 + 1;
    pmHeight = pixmapY2 - pixmapY1 + 1;
    if ((pixmap = Tk_GetPixmap(displayPtr, Tk_WindowId(tkwin), pmWidth, pmHeight,
            bitsPerPixel)) == 0) {
        Tcl_AppendResult(interp, "failed to create drawing Pixmap", NULL);
        result = TCL_ERROR;
        goto done;
    }

    /*
     * Before we can draw the canvas objects into the pixmap it's background
     * should be filled with canvas background colour.
     */

    xgcValues.function = GXcopy;
    xgcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;
    xgc = XCreateGC(displayPtr, pixmap, GCFunction|GCForeground, &xgcValues);
    XFillRectangle(displayPtr,pixmap,xgc,0,0,pmWidth,pmHeight);

    /*
     * Draw all the cavas items into the pixmap
     */

    canvasPtr->drawableXOrigin = pixmapX1;
    canvasPtr->drawableYOrigin = pixmapY1;
    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
            itemPtr = itemPtr->nextPtr) {
        if ((itemPtr->x1 >= pixmapX2) || (itemPtr->y1 >= pixmapY2) ||
                (itemPtr->x2 < pixmapX1) || (itemPtr->y2 < pixmapY1)) {
            if (!AlwaysRedraw(itemPtr)) {
                continue;
            }
        }
        if (itemPtr->state == TK_STATE_HIDDEN ||
                (itemPtr->state == TK_STATE_NULL && canvasPtr->canvas_state
                == TK_STATE_HIDDEN)) {
            continue;
        }
        ItemDisplay(canvasPtr, itemPtr, pixmap, pixmapX1, pixmapY1, pmWidth,
                pmHeight);
    }

    /*
     * Copy the Pixmap into an ZPixmap format XImage so we can copy it across
     * to the photo image. This seems to be the only way to get Pixmap image
     * data out of an image. Note we have to account for the OVERDRAW_PIXELS
     * border width.
     */

    if ((ximagePtr = XGetImage(displayPtr, pixmap, -pixmapX1, -pixmapY1, cWidth,
            cHeight, AllPlanes, ZPixmap)) == NULL) {
        Tcl_AppendResult(interp, "failed to copy Pixmap to XImage", NULL);
        result = TCL_ERROR;
        goto done;
    }

#ifdef DEBUG_DRAWCANVAS
    Tcl_AppendResult(interp, "ximagePtr {", NULL);
    sprintf(buffer,"%d",ximagePtr->width);   Tcl_AppendResult(interp, " width ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->height);  Tcl_AppendResult(interp, " height ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->xoffset); Tcl_AppendResult(interp, " xoffset ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->format);  Tcl_AppendResult(interp, " format ", buffer, NULL);
                                             Tcl_AppendResult(interp, " ximagePtr->data", NULL);
    if (ximagePtr->data != NULL) {
	int ix, iy;

        Tcl_AppendResult(interp, " {", NULL);
	for (iy = 0; iy < ximagePtr->height; ++ iy) {
	    Tcl_AppendResult(interp, " {", NULL);
	    for (ix = 0; ix < ximagePtr->bytes_per_line; ++ ix) {
	        if (ix > 0) {
                    if (ix % 4 == 0)
                        Tcl_AppendResult(interp, "-", NULL);
                    else
                        Tcl_AppendResult(interp, " ", NULL);
                }
	        sprintf(buffer,"%2.2x",ximagePtr->data[ximagePtr->bytes_per_line * iy + ix]&0xFF);
	        Tcl_AppendResult(interp, buffer, NULL);
	    }
	    Tcl_AppendResult(interp, " }", NULL);
	}
	Tcl_AppendResult(interp, " }", NULL);
    } else
	sprintf(buffer," NULL");
    sprintf(buffer,"%d",ximagePtr->byte_order);       Tcl_AppendResult(interp, " byte_order ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_unit);      Tcl_AppendResult(interp, " bitmap_unit ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_bit_order); Tcl_AppendResult(interp, " bitmap_bit_order ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bitmap_pad);       Tcl_AppendResult(interp, " bitmap_pad ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->depth);            Tcl_AppendResult(interp, " depth ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bytes_per_line);   Tcl_AppendResult(interp, " bytes_per_line ", buffer, NULL);
    sprintf(buffer,"%d",ximagePtr->bits_per_pixel);   Tcl_AppendResult(interp, " bits_per_pixel ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",ximagePtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

    Tcl_AppendResult(interp, "\nvisualPtr {", NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
    sprintf(buffer,"0x%8.8lx",visualPtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
    Tcl_AppendResult(interp, " }", NULL);

#endif

    /*
     * Fill in the PhotoImageBlock structure abd allocate a block of memory
     * for the converted image data. Note we allocate an alpha channel even
     * though we don't use one, because this layout helps Tk_PhotoPutBlock()
     * use memcpy() instead of the slow pixel or line copy.
     */

    blockPtr.width = cWidth;
    blockPtr.height = cHeight;
    blockPtr.pixelSize = 4;
    blockPtr.pitch = blockPtr.pixelSize * blockPtr.width;
    blockPtr.offset[0] = 0;
    blockPtr.offset[1] = 1;
    blockPtr.offset[2] = 2;
    blockPtr.offset[3] = 3;
    blockPtr.pixelPtr = (unsigned char *)ckalloc(blockPtr.pixelSize * blockPtr.height * blockPtr.width);

    /*
     * Now convert the image data pixel by pixel from XImage to 32bit RGBA
     * format suitable for Tk_PhotoPutBlock().
     */

    DecomposeMaskToShiftAndBits(visualPtr->red_mask,&rshift,&rbits);
    DecomposeMaskToShiftAndBits(visualPtr->green_mask,&gshift,&gbits);
    DecomposeMaskToShiftAndBits(visualPtr->blue_mask,&bshift,&bbits);

#ifdef DEBUG_DRAWCANVAS
    sprintf(buffer,"%d",rshift); Tcl_AppendResult(interp, "\nbits { rshift ", buffer, NULL);
    sprintf(buffer,"%d",gshift); Tcl_AppendResult(interp, " gshift ", buffer, NULL);
    sprintf(buffer,"%d",bshift); Tcl_AppendResult(interp, " bshift ", buffer, NULL);
    sprintf(buffer,"%d",rbits);  Tcl_AppendResult(interp, " rbits ", buffer, NULL);
    sprintf(buffer,"%d",gbits);  Tcl_AppendResult(interp, " gbits ", buffer, NULL);
    sprintf(buffer,"%d",bbits);  Tcl_AppendResult(interp, " bbits ", buffer, " }", NULL);
    Tcl_AppendResult(interp, "\nConverted_image {", NULL);
#endif

    /* Ok, had to use ximagePtr->bits_per_pixel here and in the switch (...)
     * below to get this to work on Windows. X11 correctly sets the bitmap
     *_pad and bitmap_unit fields to 32, but on Windows they are 0 and 8
     * respectively!
     */

    bytesPerPixel = ximagePtr->bits_per_pixel/8;
    for (y = 0; y < blockPtr.height; ++y) {

#ifdef DEBUG_DRAWCANVAS
        Tcl_AppendResult(interp, " {", NULL);
#endif

        for(x = 0; x < blockPtr.width; ++x) {
            unsigned int pixel = 0;

            switch (ximagePtr->bits_per_pixel) {

                /*
                 * Get an 8 bit pixel from the XImage.
                 */

                case 8 :
                    pixel = *((unsigned char *)(ximagePtr->data + bytesPerPixel * x
                            + ximagePtr->bytes_per_line * y));
                    break;

                /*
                 * Get a 16 bit pixel from the XImage, and correct the
                 * byte order as necessary.
                 */

                case 16 :
                    pixel = *((unsigned short *)(ximagePtr->data + bytesPerPixel * x
                            + ximagePtr->bytes_per_line * y));
                    if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
                            || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
                        pixel = BYTE_SWAP16(pixel);
                    break;

                /*
                 * Grab a 32 bit pixel from the XImage, and correct the
                 * byte order as necessary.
                 */

                case 32 :
                    pixel = *((unsigned int *)(ximagePtr->data + bytesPerPixel * x
                            + ximagePtr->bytes_per_line * y));
                    if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
                            || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
                        pixel = BYTE_SWAP32(pixel);
                    break;
            }

            /*
             * We have a pixel with the correct byte order, so pull out the
             * colours and place them in the photo block. Perhaps we could
             * just not bother with the alpha byte because we are using
             * TK_PHOTO_COMPOSITE_SET later?
             * ***Windows: We have to swap the red and blue values. The
             * XImage storage is B - G - R - A which becomes a 32bit ARGB
             * quad. However the visual mask is a 32bit ABGR quad. And
             * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad.
             * If the visual mask was correct there would be no need to
             * swap anything here.
             */

#ifdef _WIN32
#define   R_OFFSET 2
#define   B_OFFSET 0
#else
#define   R_OFFSET 0
#define   B_OFFSET 2
#endif
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + R_OFFSET] =
                    (unsigned char)((pixel & visualPtr->red_mask) >> rshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +1] =
                    (unsigned char)((pixel & visualPtr->green_mask) >> gshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + B_OFFSET] =
                    (unsigned char)((pixel & visualPtr->blue_mask) >> bshift);
            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +3] = 0xFF;

#ifdef DEBUG_DRAWCANVAS
            {
		int ix;
                if (x > 0)
                    Tcl_AppendResult(interp, "-", NULL);
	        for (ix = 0; ix < 4; ++ix) {
                    if (ix > 0)
                        Tcl_AppendResult(interp, " ", NULL);
		    sprintf(buffer,"%2.2x",blockPtr.pixelPtr[blockPtr.pitch * y
                            + blockPtr.pixelSize * x + ix]&0xFF);
                    Tcl_AppendResult(interp, buffer, NULL);
                }
            }
#endif

        }

#ifdef DEBUG_DRAWCANVAS
        Tcl_AppendResult(interp, " }", NULL);
#endif

    }

#ifdef DEBUG_DRAWCANVAS
    Tcl_AppendResult(interp, " }", NULL);
#endif

    /*
     * Now put the copied pixmap into the photo.
     * If either zoom or subsample are not 1, we use the zoom function.
     */

    if (subsample != 1 || zoom != 1) {
        if ((result = Tk_PhotoPutZoomedBlock(interp, photohandle, &blockPtr,
                0, 0, cWidth * zoom / subsample, cHeight * zoom / subsample,
                zoom, zoom, subsample, subsample, TK_PHOTO_COMPOSITE_SET))
                != TCL_OK) {
            goto done;
        }
    } else {
        if ((result = Tk_PhotoPutBlock(interp, photohandle, &blockPtr, 0, 0,
            cWidth, cHeight, TK_PHOTO_COMPOSITE_SET)) != TCL_OK) {
            goto done;
        }
    }

    /*
     * Clean up anything we have allocated and exit.
     */

done:
    if (blockPtr.pixelPtr)
        ckfree(blockPtr.pixelPtr);
    if (pixmap)
        Tk_FreePixmap(Tk_Display(tkwin), pixmap);
    if (ximagePtr)
        XDestroyImage(ximagePtr);
    if (xgc)
        XFreeGC(displayPtr,xgc);
    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * DisplayCanvas --
 *
 *	This function redraws the contents of a canvas window. It is invoked
 *	as a do-when-idle handler, so it only runs when there's nothing else
 *	for the application to do.
 *
 * Results:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







2412
2413
2414
2415
2416
2417
2418














































































































































































































































































































































































































































































































2419
2420
2421
2422
2423
2424
2425
	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
}

/*
 *----------------------------------------------------------------------
 *














































































































































































































































































































































































































































































































 * DisplayCanvas --
 *
 *	This function redraws the contents of a canvas window. It is invoked
 *	as a do-when-idle handler, so it only runs when there's nothing else
 *	for the application to do.
 *
 * Results:
3000
3001
3002
3003
3004
3005
3006




3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
    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

    /*







>
>
>
>














|
|







2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
    ClientData clientData)	/* Information about widget. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;
    Tk_Window tkwin = canvasPtr->tkwin;
    Tk_Item *itemPtr;
    Pixmap pixmap;
    int screenX1, screenX2, screenY1, screenY2, width, height;
#ifdef MAC_OSX_TK
    TkWindow *winPtr;
    MacDrawable *macWin;
#endif

    if (canvasPtr->tkwin == NULL) {
	return;
    }

    if (!Tk_IsMapped(tkwin)) {
	goto done;
    }

#ifdef MAC_OSX_TK
    /*
     * If drawing is disabled, all we need to do is
     * clear the REDRAW_PENDING flag.
     */
    winPtr = (TkWindow *)(canvasPtr->tkwin);
    macWin = winPtr->privatePtr;
    if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
	canvasPtr->flags &= ~REDRAW_PENDING;
	return;
    }
#endif

    /*
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
	    Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin),
		    canvasPtr->bgBorder, canvasPtr->highlightWidth,
		    canvasPtr->highlightWidth,
		    Tk_Width(tkwin) - 2*canvasPtr->highlightWidth,
		    Tk_Height(tkwin) - 2*canvasPtr->highlightWidth,
		    canvasPtr->borderWidth, canvasPtr->relief);
	}
	if (canvasPtr->highlightWidth != 0) {
	    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);







|







|


|







2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
	    Tk_Draw3DRectangle(tkwin, Tk_WindowId(tkwin),
		    canvasPtr->bgBorder, canvasPtr->highlightWidth,
		    canvasPtr->highlightWidth,
		    Tk_Width(tkwin) - 2*canvasPtr->highlightWidth,
		    Tk_Height(tkwin) - 2*canvasPtr->highlightWidth,
		    canvasPtr->borderWidth, canvasPtr->relief);
	}
	if (canvasPtr->highlightWidth > 0) {
	    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);
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.
	 */







|







2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
	    canvasPtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(canvasPtr->interp,
		    canvasPtr->widgetCmd);
	}
	if (canvasPtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayCanvas, canvasPtr);
	}
	Tcl_EventuallyFree(canvasPtr, DestroyCanvas);
    } else if (eventPtr->type == ConfigureNotify) {
	canvasPtr->flags |= UPDATE_SCROLLBARS;

	/*
	 * The call below is needed in order to recenter the canvas if it's
	 * confined and its scroll region is smaller than the window.
	 */
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
     */

    if (canvasPtr->tkwin == NULL) {
	return;
    }

    if ((x1 >= x2) || (y1 >= y2) ||
 	    (x2 < canvasPtr->xOrigin) || (y2 < canvasPtr->yOrigin) ||
	    (x1 >= canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)) ||
	    (y1 >= canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin))) {
	return;
    }
    if (canvasPtr->flags & BBOX_NOT_EMPTY) {
	if (x1 <= canvasPtr->redrawX1) {
	    canvasPtr->redrawX1 = x1;







|







2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
     */

    if (canvasPtr->tkwin == NULL) {
	return;
    }

    if ((x1 >= x2) || (y1 >= y2) ||
	    (x2 < canvasPtr->xOrigin) || (y2 < canvasPtr->yOrigin) ||
	    (x1 >= canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin)) ||
	    (y1 >= canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin))) {
	return;
    }
    if (canvasPtr->flags & BBOX_NOT_EMPTY) {
	if (x1 <= canvasPtr->redrawX1) {
	    canvasPtr->redrawX1 = x1;
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
    Tk_Item *itemPtr)		/* Item to be redrawn. May be NULL, in which
				 * case nothing happens. */
{
    if (itemPtr == NULL || canvasPtr->tkwin == NULL) {
	return;
    }
    if ((itemPtr->x1 >= itemPtr->x2) || (itemPtr->y1 >= itemPtr->y2) ||
 	    (itemPtr->x2 < canvasPtr->xOrigin) ||
	    (itemPtr->y2 < canvasPtr->yOrigin) ||
	    (itemPtr->x1 >= canvasPtr->xOrigin+Tk_Width(canvasPtr->tkwin)) ||
	    (itemPtr->y1 >= canvasPtr->yOrigin+Tk_Height(canvasPtr->tkwin))) {
	if (!AlwaysRedraw(itemPtr)) {
	    return;
	}
    }







|







2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
    Tk_Item *itemPtr)		/* Item to be redrawn. May be NULL, in which
				 * case nothing happens. */
{
    if (itemPtr == NULL || canvasPtr->tkwin == NULL) {
	return;
    }
    if ((itemPtr->x1 >= itemPtr->x2) || (itemPtr->y1 >= itemPtr->y2) ||
	    (itemPtr->x2 < canvasPtr->xOrigin) ||
	    (itemPtr->y2 < canvasPtr->yOrigin) ||
	    (itemPtr->x1 >= canvasPtr->xOrigin+Tk_Width(canvasPtr->tkwin)) ||
	    (itemPtr->y1 >= canvasPtr->yOrigin+Tk_Height(canvasPtr->tkwin))) {
	if (!AlwaysRedraw(itemPtr)) {
	    return;
	}
    }
3607
3608
3609
3610
3611
3612
3613










































































































































































































3614
3615
3616
3617
3618
3619
3620
    tkOvalType.nextPtr = &tkBitmapType;
    tkBitmapType.nextPtr = &tkArcType;
    tkArcType.nextPtr = &tkWindowType;
    tkWindowType.nextPtr = NULL;
    Tcl_MutexUnlock(&typeListMutex);
}











































































































































































































/*
 *----------------------------------------------------------------------
 *
 * GetStaticUids --
 *
 *	This function is invoked to return a structure filled with the Uids
 *	used when doing tag searching. If it was never before called in the







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076
3077
3078
3079
3080
3081
3082
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
    tkOvalType.nextPtr = &tkBitmapType;
    tkBitmapType.nextPtr = &tkArcType;
    tkArcType.nextPtr = &tkWindowType;
    tkWindowType.nextPtr = NULL;
    Tcl_MutexUnlock(&typeListMutex);
}

#ifdef USE_OLD_TAG_SEARCH
/*
 *--------------------------------------------------------------
 *
 * StartTagSearch --
 *
 *	This function is called to initiate an enumeration of all items in a
 *	given canvas that contain a given tag.
 *
 * Results:
 *	The return value is a pointer to the first item in canvasPtr that
 *	matches tag, or NULL if there is no such item. The information at
 *	*searchPtr is initialized such that successive calls to NextItem will
 *	return successive items that match tag.
 *
 * Side effects:
 *	SearchPtr is linked into a list of searches in progress on canvasPtr,
 *	so that elements can safely be deleted while the search is in
 *	progress. EndTagSearch must be called at the end of the search to
 *	unlink searchPtr from this list.
 *
 *--------------------------------------------------------------
 */

static Tk_Item *
StartTagSearch(
    TkCanvas *canvasPtr,	/* Canvas whose items are to be searched. */
    Tcl_Obj *tagObj,		/* Object giving tag value. */
    TagSearch *searchPtr)	/* Record describing tag search; will be
				 * initialized here. */
{
    int id;
    Tk_Item *itemPtr, *lastPtr;
    Tk_Uid *tagPtr;
    Tk_Uid uid;
    char *tag = Tcl_GetString(tagObj);
    int count;
    TkWindow *tkwin = (TkWindow *) canvasPtr->tkwin;
    TkDisplay *dispPtr = tkwin->dispPtr;

    /*
     * Initialize the search.
     */

    searchPtr->canvasPtr = canvasPtr;
    searchPtr->searchOver = 0;

    /*
     * Find the first matching item in one of several ways. If the tag is a
     * number then it selects the single item with the matching identifier.
     * In this case see if the item being requested is the hot item, in which
     * case the search can be skipped.
     */

    if (isdigit(UCHAR(*tag))) {
	char *end;
	Tcl_HashEntry *entryPtr;

	dispPtr->numIdSearches++;
	id = strtoul(tag, &end, 0);
	if (*end == 0) {
	    itemPtr = canvasPtr->hotPtr;
	    lastPtr = canvasPtr->hotPrevPtr;
	    if ((itemPtr == NULL) || (itemPtr->id != id) || (lastPtr == NULL)
		    || (lastPtr->nextPtr != itemPtr)) {
		dispPtr->numSlowSearches++;
		entryPtr = Tcl_FindHashEntry(&canvasPtr->idTable, (char*) id);
		if (entryPtr != NULL) {
		    itemPtr = Tcl_GetHashValue(entryPtr);
		    lastPtr = itemPtr->prevPtr;
		} else {
		    lastPtr = itemPtr = NULL;
		}
	    }
	    searchPtr->lastPtr = lastPtr;
	    searchPtr->searchOver = 1;
	    canvasPtr->hotPtr = itemPtr;
	    canvasPtr->hotPrevPtr = lastPtr;
	    return itemPtr;
	}
    }

    searchPtr->tag = uid = Tk_GetUid(tag);
    if (uid == Tk_GetUid("all")) {
	/*
	 * All items match.
	 */

	searchPtr->tag = NULL;
	searchPtr->lastPtr = NULL;
	searchPtr->currentPtr = canvasPtr->firstItemPtr;
	return canvasPtr->firstItemPtr;
    }

    /*
     * None of the above. Search for an item with a matching tag.
     */

    for (lastPtr = NULL, itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
	    lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
	for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
		count > 0; tagPtr++, count--) {
	    if (*tagPtr == uid) {
		searchPtr->lastPtr = lastPtr;
		searchPtr->currentPtr = itemPtr;
		return itemPtr;
	    }
	}
    }
    searchPtr->lastPtr = lastPtr;
    searchPtr->searchOver = 1;
    return NULL;
}

/*
 *--------------------------------------------------------------
 *
 * NextItem --
 *
 *	This function returns successive items that match a given tag; it
 *	should be called only after StartTagSearch has been used to begin a
 *	search.
 *
 * Results:
 *	The return value is a pointer to the next item that matches the tag
 *	specified to StartTagSearch, or NULL if no such item exists.
 *	*SearchPtr is updated so that the next call to this function will
 *	return the next item.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static Tk_Item *
NextItem(
    TagSearch *searchPtr)	/* Record describing search in progress. */
{
    Tk_Item *itemPtr, *lastPtr;
    int count;
    Tk_Uid uid;
    Tk_Uid *tagPtr;

    /*
     * Find next item in list (this may not actually be a suitable one to
     * return), and return if there are no items left.
     */

    lastPtr = searchPtr->lastPtr;
    if (lastPtr == NULL) {
	itemPtr = searchPtr->canvasPtr->firstItemPtr;
    } else {
	itemPtr = lastPtr->nextPtr;
    }
    if ((itemPtr == NULL) || (searchPtr->searchOver)) {
	searchPtr->searchOver = 1;
	return NULL;
    }
    if (itemPtr != searchPtr->currentPtr) {
	/*
	 * The structure of the list has changed. Probably the previously-
	 * returned item was removed from the list. In this case, don't
	 * advance lastPtr; just return its new successor (i.e. do nothing
	 * here).
	 */
    } else {
	lastPtr = itemPtr;
	itemPtr = lastPtr->nextPtr;
    }

    /*
     * Handle special case of "all" search by returning next item.
     */

    uid = searchPtr->tag;
    if (uid == NULL) {
	searchPtr->lastPtr = lastPtr;
	searchPtr->currentPtr = itemPtr;
	return itemPtr;
    }

    /*
     * Look for an item with a particular tag.
     */

    for ( ; itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
	for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
		count > 0; tagPtr++, count--) {
	    if (*tagPtr == uid) {
		searchPtr->lastPtr = lastPtr;
		searchPtr->currentPtr = itemPtr;
		return itemPtr;
	    }
	}
    }
    searchPtr->lastPtr = lastPtr;
    searchPtr->searchOver = 1;
    return NULL;
}

#else /* !USE_OLD_TAG_SEARCH */
/*
 *----------------------------------------------------------------------
 *
 * GetStaticUids --
 *
 *	This function is invoked to return a structure filled with the Uids
 *	used when doing tag searching. If it was never before called in the
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
 */

static void
TagSearchExprDestroy(
    TagSearchExpr *expr)
{
    if (expr != NULL) {
    	if (expr->uids) {
	    ckfree(expr->uids);
	}
	ckfree(expr);
    }
}

/*







|







3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
3351
3352
3353
3354
 */

static void
TagSearchExprDestroy(
    TagSearchExpr *expr)
{
    if (expr != NULL) {
	if (expr->uids) {
	    ckfree(expr->uids);
	}
	ckfree(expr);
    }
}

/*
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
4249
4250
4251
		uid = expr->uids[expr->index++];
		result = 0;

		/*
		 * set result 1 if tag is found in item's tags
		 */

		for (tagPtr = itemPtr->tagPtr, count = (int)itemPtr->numTags;
			count > 0; tagPtr++, count--) {
		    if (*tagPtr == uid) {
			result = 1;
			break;
		    }
		}

	    } else if (uid == searchUids->negtagvalUid) {
		negate_result = ! negate_result;
/*
 *		assert(expr->index < expr->length);
 */
		uid = expr->uids[expr->index++];
		result = 0;

		/*
		 * set result 1 if tag is found in item's tags.
		 */

		for (tagPtr = itemPtr->tagPtr, count = (int)itemPtr->numTags;
			count > 0; tagPtr++, count--) {
		    if (*tagPtr == uid) {
			result = 1;
			break;
		    }
		}








|



















|







3859
3860
3861
3862
3863
3864
3865
3866
3867
3868
3869
3870
3871
3872
3873
3874
3875
3876
3877
3878
3879
3880
3881
3882
3883
3884
3885
3886
3887
3888
3889
3890
3891
3892
3893
		uid = expr->uids[expr->index++];
		result = 0;

		/*
		 * set result 1 if tag is found in item's tags
		 */

		for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
			count > 0; tagPtr++, count--) {
		    if (*tagPtr == uid) {
			result = 1;
			break;
		    }
		}

	    } else if (uid == searchUids->negtagvalUid) {
		negate_result = ! negate_result;
/*
 *		assert(expr->index < expr->length);
 */
		uid = expr->uids[expr->index++];
		result = 0;

		/*
		 * set result 1 if tag is found in item's tags.
		 */

		for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
			count > 0; tagPtr++, count--) {
		    if (*tagPtr == uid) {
			result = 1;
			break;
		    }
		}

4403
4404
4405
4406
4407
4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
	/*
	 * Optimized single-tag search
	 */

	uid = searchPtr->expr->uid;
	for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr;
		itemPtr != NULL; lastPtr=itemPtr, itemPtr=itemPtr->nextPtr) {
	    for (tagPtr = itemPtr->tagPtr, count = (int)itemPtr->numTags;
		    count > 0; tagPtr++, count--) {
		if (*tagPtr == uid) {
		    searchPtr->lastPtr = lastPtr;
		    searchPtr->currentPtr = itemPtr;
		    return itemPtr;
		}
	    }







|







4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
4059
	/*
	 * Optimized single-tag search
	 */

	uid = searchPtr->expr->uid;
	for (lastPtr = NULL, itemPtr = searchPtr->canvasPtr->firstItemPtr;
		itemPtr != NULL; lastPtr=itemPtr, itemPtr=itemPtr->nextPtr) {
	    for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
		    count > 0; tagPtr++, count--) {
		if (*tagPtr == uid) {
		    searchPtr->lastPtr = lastPtr;
		    searchPtr->currentPtr = itemPtr;
		    return itemPtr;
		}
	    }
4505
4506
4507
4508
4509
4510
4511
4512
4513
4514
4515
4516
4517
4518
4519
    if (searchPtr->type == SEARCH_TYPE_TAG) {
	/*
	 * Optimized single-tag search
	 */

	uid = searchPtr->expr->uid;
	for (; itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
	    for (tagPtr = itemPtr->tagPtr, count = (int)itemPtr->numTags;
		    count > 0; tagPtr++, count--) {
		if (*tagPtr == uid) {
		    searchPtr->lastPtr = lastPtr;
		    searchPtr->currentPtr = itemPtr;
		    return itemPtr;
		}
	    }







|







4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
4158
4159
4160
4161
    if (searchPtr->type == SEARCH_TYPE_TAG) {
	/*
	 * Optimized single-tag search
	 */

	uid = searchPtr->expr->uid;
	for (; itemPtr != NULL; lastPtr = itemPtr, itemPtr = itemPtr->nextPtr) {
	    for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
		    count > 0; tagPtr++, count--) {
		if (*tagPtr == uid) {
		    searchPtr->lastPtr = lastPtr;
		    searchPtr->currentPtr = itemPtr;
		    return itemPtr;
		}
	    }
4535
4536
4537
4538
4539
4540
4541

4542
4543
4544
4545
4546
4547
4548
	    return itemPtr;
	}
    }
    searchPtr->lastPtr = lastPtr;
    searchPtr->searchOver = 1;
    return NULL;
}


/*
 *--------------------------------------------------------------
 *
 * DoItem --
 *
 *	This is a utility function called by FindItems. It either adds







>







4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
	    return itemPtr;
	}
    }
    searchPtr->lastPtr = lastPtr;
    searchPtr->searchOver = 1;
    return NULL;
}
#endif /* USE_OLD_TAG_SEARCH */

/*
 *--------------------------------------------------------------
 *
 * DoItem --
 *
 *	This is a utility function called by FindItems. It either adds
4571
4572
4573
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584
4585
4586
4587
4588
4589
4590
4591
4592
4593
4594
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605
    int count;

    /*
     * Handle the "add-to-result" case and return, if appropriate.
     */

    if (tag == NULL) {
	Tcl_ListObjAppendElement(NULL, accumObj, Tcl_NewWideIntObj(itemPtr->id));
	return;
    }

    for (tagPtr = itemPtr->tagPtr, count = (int)itemPtr->numTags;
	    count > 0; tagPtr++, count--) {
	if (tag == *tagPtr) {
	    return;
	}
    }

    /*
     * Grow the tag space if there's no more room left in the current block.
     */

    if (itemPtr->tagSpace == itemPtr->numTags) {
	Tk_Uid *newTagPtr;

	itemPtr->tagSpace += 5;
	newTagPtr = (Tk_Uid *)ckalloc(itemPtr->tagSpace * sizeof(Tk_Uid));
	memcpy((void *) newTagPtr, itemPtr->tagPtr,
		itemPtr->numTags * sizeof(Tk_Uid));
	if (itemPtr->tagPtr != itemPtr->staticTagSpace) {
	    ckfree(itemPtr->tagPtr);
	}
	itemPtr->tagPtr = newTagPtr;
	tagPtr = &itemPtr->tagPtr[itemPtr->numTags];
    }







|



|















|







4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
4228
4229
4230
4231
4232
4233
4234
4235
4236
4237
4238
4239
4240
4241
4242
4243
4244
4245
4246
4247
4248
    int count;

    /*
     * Handle the "add-to-result" case and return, if appropriate.
     */

    if (tag == NULL) {
	Tcl_ListObjAppendElement(NULL, accumObj, Tcl_NewIntObj(itemPtr->id));
	return;
    }

    for (tagPtr = itemPtr->tagPtr, count = itemPtr->numTags;
	    count > 0; tagPtr++, count--) {
	if (tag == *tagPtr) {
	    return;
	}
    }

    /*
     * Grow the tag space if there's no more room left in the current block.
     */

    if (itemPtr->tagSpace == itemPtr->numTags) {
	Tk_Uid *newTagPtr;

	itemPtr->tagSpace += 5;
	newTagPtr = (Tk_Uid *)ckalloc(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];
    }
4647
4648
4649
4650
4651
4652
4653

4654

4655
4656



4657
4658
4659
4660
4661
4662
4663
    Tcl_Obj *newTag,		/* If non-NULL, gives new tag to set on all
				 * found items; if NULL, then ids of found
				 * items are returned in the interp's
				 * result. */
    int first			/* For error messages: gives number of
				 * elements of objv which are already
				 * handled. */

    ,TagSearch **searchPtrPtr	/* From CanvasWidgetCmd local vars*/

    )
{



    Tk_Item *itemPtr;
    Tk_Uid uid;
    int index, result;
    Tcl_Obj *resultObj;
    static const char *const optionStrings[] = {
	"above", "all", "below", "closest",
	"enclosed", "overlapping", "withtag", NULL







>

>


>
>
>







4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
4309
4310
4311
    Tcl_Obj *newTag,		/* If non-NULL, gives new tag to set on all
				 * found items; if NULL, then ids of found
				 * items are returned in the interp's
				 * result. */
    int first			/* For error messages: gives number of
				 * elements of objv which are already
				 * handled. */
#ifndef USE_OLD_TAG_SEARCH
    ,TagSearch **searchPtrPtr	/* From CanvasWidgetCmd local vars*/
#endif /* not USE_OLD_TAG_SEARCH */
    )
{
#ifdef USE_OLD_TAG_SEARCH
    TagSearch search;
#endif /* USE_OLD_TAG_SEARCH */
    Tk_Item *itemPtr;
    Tk_Uid uid;
    int index, result;
    Tcl_Obj *resultObj;
    static const char *const optionStrings[] = {
	"above", "all", "below", "closest",
	"enclosed", "overlapping", "withtag", NULL
4966
4967
4968
4969
4970
4971
4972










4973
4974
4975
4976
4977
4978
4979
4980
4981

4982
4983



4984
4985
4986
4987
4988
4989
4990
 *	The items identified by "tag" are moved so that they are all together
 *	in the display list and immediately after prevPtr. The order of the
 *	moved items relative to each other is not changed.
 *
 *--------------------------------------------------------------
 */











static int
RelinkItems(
    TkCanvas *canvasPtr,	/* Canvas to be modified. */
    Tcl_Obj *tag,		/* Tag identifying items to be moved in the
				 * redisplay list. */
    Tk_Item *prevPtr,		/* Reposition the items so that they go just
				 * after this item (NULL means put at
				 * beginning of list). */
    TagSearch **searchPtrPtr)	/* From CanvasWidgetCmd local vars */

{
    Tk_Item *itemPtr;



    Tk_Item *firstMovePtr, *lastMovePtr;
    int result;

    /*
     * Find all of the items to be moved and remove them from the list, making
     * an auxiliary list running from firstMovePtr to lastMovePtr. Record
     * their areas for redisplay.







>
>
>
>
>
>
>
>
>
>









>


>
>
>







4614
4615
4616
4617
4618
4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642
4643
4644
4645
4646
4647
4648
4649
4650
4651
4652
 *	The items identified by "tag" are moved so that they are all together
 *	in the display list and immediately after prevPtr. The order of the
 *	moved items relative to each other is not changed.
 *
 *--------------------------------------------------------------
 */

#ifdef USE_OLD_TAG_SEARCH
static void
RelinkItems(
    TkCanvas *canvasPtr,	/* Canvas to be modified. */
    Tcl_Obj *tag,		/* Tag identifying items to be moved in the
				 * redisplay list. */
    Tk_Item *prevPtr)		/* Reposition the items so that they go just
				 * after this item (NULL means put at
				 * beginning of list). */
#else /* USE_OLD_TAG_SEARCH */
static int
RelinkItems(
    TkCanvas *canvasPtr,	/* Canvas to be modified. */
    Tcl_Obj *tag,		/* Tag identifying items to be moved in the
				 * redisplay list. */
    Tk_Item *prevPtr,		/* Reposition the items so that they go just
				 * after this item (NULL means put at
				 * beginning of list). */
    TagSearch **searchPtrPtr)	/* From CanvasWidgetCmd local vars */
#endif /* USE_OLD_TAG_SEARCH */
{
    Tk_Item *itemPtr;
#ifdef USE_OLD_TAG_SEARCH
    TagSearch search;
#endif /* USE_OLD_TAG_SEARCH */
    Tk_Item *firstMovePtr, *lastMovePtr;
    int result;

    /*
     * Find all of the items to be moved and remove them from the list, making
     * an auxiliary list running from firstMovePtr to lastMovePtr. Record
     * their areas for redisplay.
5028
5029
5030
5031
5032
5033
5034



5035

5036
5037
5038
5039
5040
5041
5042
5043
5044
5045
5046
5047
5048
5049
5050
5051
5052
5053
5054
5055

5056

5057
5058
5059
5060
5061
5062
5063

    /*
     * Insert the list of to-be-moved items back into the canvas's at the
     * desired position.
     */

    if (firstMovePtr == NULL) {



	return TCL_OK;

    }
    if (prevPtr == NULL) {
	if (canvasPtr->firstItemPtr != NULL) {
	    canvasPtr->firstItemPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = canvasPtr->firstItemPtr;
	canvasPtr->firstItemPtr = firstMovePtr;
    } else {
	if (prevPtr->nextPtr != NULL) {
	    prevPtr->nextPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = prevPtr->nextPtr;
	if (firstMovePtr != NULL) {
	    firstMovePtr->prevPtr = prevPtr;
	}
	prevPtr->nextPtr = firstMovePtr;
    }
    if (canvasPtr->lastItemPtr == prevPtr) {
	canvasPtr->lastItemPtr = lastMovePtr;
    }

    return TCL_OK;

}

/*
 *--------------------------------------------------------------
 *
 * CanvasBindProc --
 *







>
>
>

>




















>

>







4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728
4729
4730
4731

    /*
     * Insert the list of to-be-moved items back into the canvas's at the
     * desired position.
     */

    if (firstMovePtr == NULL) {
#ifdef USE_OLD_TAG_SEARCH
	return;
#else /* USE_OLD_TAG_SEARCH */
	return TCL_OK;
#endif /* USE_OLD_TAG_SEARCH */
    }
    if (prevPtr == NULL) {
	if (canvasPtr->firstItemPtr != NULL) {
	    canvasPtr->firstItemPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = canvasPtr->firstItemPtr;
	canvasPtr->firstItemPtr = firstMovePtr;
    } else {
	if (prevPtr->nextPtr != NULL) {
	    prevPtr->nextPtr->prevPtr = lastMovePtr;
	}
	lastMovePtr->nextPtr = prevPtr->nextPtr;
	if (firstMovePtr != NULL) {
	    firstMovePtr->prevPtr = prevPtr;
	}
	prevPtr->nextPtr = firstMovePtr;
    }
    if (canvasPtr->lastItemPtr == prevPtr) {
	canvasPtr->lastItemPtr = lastMovePtr;
    }
#ifndef USE_OLD_TAG_SEARCH
    return TCL_OK;
#endif /* not USE_OLD_TAG_SEARCH */
}

/*
 *--------------------------------------------------------------
 *
 * CanvasBindProc --
 *
5089
5090
5091
5092
5093
5094
5095
5096
5097
5098
5099
5100
5101
5102
5103
     * canvasPtr>state. This information is used to defer repicks of the
     * current item while buttons are down.
     */

    switch (eventPtr->type) {
    case ButtonPress:
    case ButtonRelease:
	mask = Tk_GetButtonMask(eventPtr->xbutton.button);

	/*
	 * For button press events, repick the current item using the button
	 * state before the event, then process the event. For button release
	 * events, first process the event, then repick the current item using
	 * the button state *after* the event (the button has logically gone
	 * up before we change the current item).







|







4757
4758
4759
4760
4761
4762
4763
4764
4765
4766
4767
4768
4769
4770
4771
     * canvasPtr>state. This information is used to defer repicks of the
     * current item while buttons are down.
     */

    switch (eventPtr->type) {
    case ButtonPress:
    case ButtonRelease:
	mask = TkGetButtonMask(eventPtr->xbutton.button);

	/*
	 * For button press events, repick the current item using the button
	 * state before the event, then process the event. For button release
	 * events, first process the event, then repick the current item using
	 * the button state *after* the event (the button has logically gone
	 * up before we change the current item).
5174
5175
5176
5177
5178
5179
5180

5181

5182
5183
5184
5185
5186
5187
5188
    XEvent *eventPtr)		/* Event describing location of mouse cursor.
				 * Must be EnterWindow, LeaveWindow,
				 * ButtonRelease, or MotionNotify. */
{
    double coords[2];
    unsigned int buttonDown;
    Tk_Item *prevItemPtr;

    SearchUids *searchUids = GetStaticUids();


    /*
     * Check whether or not a button is down. If so, we'll log entry and exit
     * into and out of the current item, but not entry into any other item.
     * This implements a form of grabbing equivalent to what the X server does
     * for windows.
     */







>

>







4842
4843
4844
4845
4846
4847
4848
4849
4850
4851
4852
4853
4854
4855
4856
4857
4858
    XEvent *eventPtr)		/* Event describing location of mouse cursor.
				 * Must be EnterWindow, LeaveWindow,
				 * ButtonRelease, or MotionNotify. */
{
    double coords[2];
    unsigned int buttonDown;
    Tk_Item *prevItemPtr;
#ifndef USE_OLD_TAG_SEARCH
    SearchUids *searchUids = GetStaticUids();
#endif

    /*
     * Check whether or not a button is down. If so, we'll log entry and exit
     * into and out of the current item, but not entry into any other item.
     * This implements a form of grabbing equivalent to what the X server does
     * for windows.
     */
5279
5280
5281
5282
5283
5284
5285

5286
5287
5288







5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302



5303

5304
5305
5306
5307
5308
5309
5310
5311
5312
5313
5314
	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;
		}
	    }
	}

	/*







>
|
|
|
>
>
>
>
>
>
>













|
>
>
>

>

|
|
|







4949
4950
4951
4952
4953
4954
4955
4956
4957
4958
4959
4960
4961
4962
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973
4974
4975
4976
4977
4978
4979
4980
4981
4982
4983
4984
4985
4986
4987
4988
4989
4990
4991
4992
4993
4994
4995
4996
	Tk_Item *itemPtr = canvasPtr->currentItemPtr;
	int i;

	event = canvasPtr->pickEvent;
	event.type = LeaveNotify;

	/*
	 * Behaviour before ticket #47d4f29159:
	 *    If the event's detail happens to be NotifyInferior the binding
	 *    mechanism will discard the event. To be consistent, always use
	 *    NotifyAncestor.
	 *
	 * 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 >= 0; i--) {
#ifdef USE_OLD_TAG_SEARCH
		if (itemPtr->tagPtr[i] == Tk_GetUid("current"))
#else /* USE_OLD_TAG_SEARCH */
		if (itemPtr->tagPtr[i] == searchUids->currentUid)
#endif /* USE_OLD_TAG_SEARCH */
		    /* then */ {
		    memmove((void *)(itemPtr->tagPtr + i),
			    itemPtr->tagPtr + i + 1,
			    (itemPtr->numTags - (i+1)) * sizeof(Tk_Uid));
		    itemPtr->numTags--;
		    break;
		}
	    }
	}

	/*
5335
5336
5337
5338
5339
5340
5341



5342

5343
5344
5345
5346
5347
5348
5349
	    (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) {
	EventuallyRedrawItem(canvasPtr, prevItemPtr);
	ItemConfigure(canvasPtr, prevItemPtr, 0, NULL);
    }
    if (canvasPtr->currentItemPtr != NULL) {
	XEvent event;




	DoItem(NULL, canvasPtr->currentItemPtr, searchUids->currentUid);

	if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT
		&& prevItemPtr != canvasPtr->currentItemPtr)) {
	    ItemConfigure(canvasPtr, canvasPtr->currentItemPtr, 0, NULL);
	    EventuallyRedrawItem(canvasPtr, canvasPtr->currentItemPtr);
	}
	event = canvasPtr->pickEvent;
	event.type = EnterNotify;







>
>
>

>







5017
5018
5019
5020
5021
5022
5023
5024
5025
5026
5027
5028
5029
5030
5031
5032
5033
5034
5035
	    (prevItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT)) {
	EventuallyRedrawItem(canvasPtr, prevItemPtr);
	ItemConfigure(canvasPtr, prevItemPtr, 0, NULL);
    }
    if (canvasPtr->currentItemPtr != NULL) {
	XEvent event;

#ifdef USE_OLD_TAG_SEARCH
	DoItem(NULL, canvasPtr->currentItemPtr, Tk_GetUid("current"));
#else /* USE_OLD_TAG_SEARCH */
	DoItem(NULL, canvasPtr->currentItemPtr, searchUids->currentUid);
#endif /* USE_OLD_TAG_SEARCH */
	if ((canvasPtr->currentItemPtr->redraw_flags & TK_ITEM_STATE_DEPENDANT
		&& prevItemPtr != canvasPtr->currentItemPtr)) {
	    ItemConfigure(canvasPtr, canvasPtr->currentItemPtr, 0, NULL);
	    EventuallyRedrawItem(canvasPtr, canvasPtr->currentItemPtr);
	}
	event = canvasPtr->pickEvent;
	event.type = EnterNotify;
5433
5434
5435
5436
5437
5438
5439

5440
5441
5442

5443
5444
5445
5446
5447
5448
5449
5450
5451
5452
5453
5454
5455










5456
5457
5458
5459
5460
5461
5462
5463
5464
5465
5466
5467
5468
5469
5470
5471
5472
5473
5474
5475
5476
5477
5478
5479
5480
5481
5482
5483

5484
5485
5486
5487
5488



5489

5490
5491
5492
5493
5494

5495
5496
5497
5498
5499
5500
5501
5502
5503
5504
5505
5506

5507
5508
5509
5510
5511
5512
5513
				 * processed. */
{
#define NUM_STATIC 3
    void *staticObjects[NUM_STATIC];
    void **objectPtr;
    int numObjects, i;
    Tk_Item *itemPtr;

    TagSearchExpr *expr;
    int numExprs;
    SearchUids *searchUids = GetStaticUids();


    if (canvasPtr->bindingTable == NULL) {
	return;
    }

    itemPtr = canvasPtr->currentItemPtr;
    if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
	itemPtr = canvasPtr->textInfo.focusItemPtr;
    }
    if (itemPtr == NULL) {
	return;
    }











    /*
     * Set up an array with all the relevant objects for processing this
     * event. The relevant objects are:
     * (a) the event's item,
     * (b) the tags associated with the event's item,
     * (c) the expressions that are true for the event's item's tags, and
     * (d) the tag "all".
     *
     * If there are a lot of tags then malloc an array to hold all of the
     * objects.
     */

    /*
     * Flag and count all expressions that match item's tags.
     */

    numExprs = 0;
    expr = canvasPtr->bindTagExprs;
    while (expr) {
	expr->index = 0;
    	expr->match = TagSearchEvalExpr(expr, itemPtr);
	if (expr->match) {
	    numExprs++;
	}
	expr = expr->next;
    }

    numObjects = itemPtr->numTags + numExprs + 2;

    if (numObjects <= NUM_STATIC) {
	objectPtr = staticObjects;
    } else {
	objectPtr = (void **)ckalloc(numObjects * sizeof(void *));
    }



    objectPtr[0] = (char *)searchUids->allUid;

    for (i = (int)itemPtr->numTags - 1; i >= 0; i--) {
	objectPtr[i+1] = (char *)itemPtr->tagPtr[i];
    }
    objectPtr[itemPtr->numTags + 1] = itemPtr;


    /*
     * Copy uids of matching expressions into object array
     */

    i = itemPtr->numTags+2;
    expr = canvasPtr->bindTagExprs;
    while (expr) {
    	if (expr->match) {
	    objectPtr[i++] = (int *) expr->uid;
	}
	expr = expr->next;
    }


    /*
     * Invoke the binding system, then free up the object array if it was
     * malloc-ed.
     */

    if (canvasPtr->tkwin != NULL) {







>



>













>
>
>
>
>
>
>
>
>
>




















|







>





>
>
>
|
>
|
|



>







|




>







5119
5120
5121
5122
5123
5124
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137
5138
5139
5140
5141
5142
5143
5144
5145
5146
5147
5148
5149
5150
5151
5152
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182
5183
5184
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
				 * processed. */
{
#define NUM_STATIC 3
    void *staticObjects[NUM_STATIC];
    void **objectPtr;
    int numObjects, i;
    Tk_Item *itemPtr;
#ifndef USE_OLD_TAG_SEARCH
    TagSearchExpr *expr;
    int numExprs;
    SearchUids *searchUids = GetStaticUids();
#endif /* not USE_OLD_TAG_SEARCH */

    if (canvasPtr->bindingTable == NULL) {
	return;
    }

    itemPtr = canvasPtr->currentItemPtr;
    if ((eventPtr->type == KeyPress) || (eventPtr->type == KeyRelease)) {
	itemPtr = canvasPtr->textInfo.focusItemPtr;
    }
    if (itemPtr == NULL) {
	return;
    }

#ifdef USE_OLD_TAG_SEARCH
    /*
     * Set up an array with all the relevant objects for processing this
     * event. The relevant objects are (a) the event's item, (b) the tags
     * associated with the event's item, and (c) the tag "all". If there are a
     * lot of tags then malloc an array to hold all of the objects.
     */

    numObjects = itemPtr->numTags + 2;
#else /* USE_OLD_TAG_SEARCH */
    /*
     * Set up an array with all the relevant objects for processing this
     * event. The relevant objects are:
     * (a) the event's item,
     * (b) the tags associated with the event's item,
     * (c) the expressions that are true for the event's item's tags, and
     * (d) the tag "all".
     *
     * If there are a lot of tags then malloc an array to hold all of the
     * objects.
     */

    /*
     * Flag and count all expressions that match item's tags.
     */

    numExprs = 0;
    expr = canvasPtr->bindTagExprs;
    while (expr) {
	expr->index = 0;
	expr->match = TagSearchEvalExpr(expr, itemPtr);
	if (expr->match) {
	    numExprs++;
	}
	expr = expr->next;
    }

    numObjects = itemPtr->numTags + numExprs + 2;
#endif /* not USE_OLD_TAG_SEARCH */
    if (numObjects <= NUM_STATIC) {
	objectPtr = staticObjects;
    } else {
	objectPtr = (void **)ckalloc(numObjects * sizeof(void *));
    }
#ifdef USE_OLD_TAG_SEARCH
    objectPtr[0] = (void *)Tk_GetUid("all");
#else /* USE_OLD_TAG_SEARCH */
    objectPtr[0] = (void *)searchUids->allUid;
#endif /* USE_OLD_TAG_SEARCH */
    for (i = itemPtr->numTags - 1; i >= 0; i--) {
	objectPtr[i+1] = (void *)itemPtr->tagPtr[i];
    }
    objectPtr[itemPtr->numTags + 1] = itemPtr;

#ifndef USE_OLD_TAG_SEARCH
    /*
     * Copy uids of matching expressions into object array
     */

    i = itemPtr->numTags+2;
    expr = canvasPtr->bindTagExprs;
    while (expr) {
	if (expr->match) {
	    objectPtr[i++] = (int *) expr->uid;
	}
	expr = expr->next;
    }
#endif /* not USE_OLD_TAG_SEARCH */

    /*
     * Invoke the binding system, then free up the object array if it was
     * malloc-ed.
     */

    if (canvasPtr->tkwin != NULL) {
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
5636
5637
5638
5639
 *----------------------------------------------------------------------
 */

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;

    /*







|


|







5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
 *----------------------------------------------------------------------
 */

static void
CanvasSelectTo(
    TkCanvas *canvasPtr,	/* Information about widget. */
    Tk_Item *itemPtr,		/* Item that is to hold selection. */
    int index)			/* Index of element that is to become the
				 * "other" end of the selection. */
{
    int oldFirst, oldLast;
    Tk_Item *oldSelPtr;

    oldFirst = canvasPtr->textInfo.selectFirst;
    oldLast = canvasPtr->textInfo.selectLast;
    oldSelPtr = canvasPtr->textInfo.selItemPtr;

    /*
5648
5649
5650
5651
5652
5653
5654
5655
5656
5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
    }
    canvasPtr->textInfo.selItemPtr = itemPtr;

    if (canvasPtr->textInfo.anchorItemPtr != itemPtr) {
	canvasPtr->textInfo.anchorItemPtr = itemPtr;
	canvasPtr->textInfo.selectAnchor = index;
    }
    if (canvasPtr->textInfo.selectAnchor + 1 <= index + 1) {
	canvasPtr->textInfo.selectFirst = canvasPtr->textInfo.selectAnchor;
	canvasPtr->textInfo.selectLast = index;
    } else {
	canvasPtr->textInfo.selectFirst = ((int)index < 0) ? TCL_INDEX_NONE : index;
	canvasPtr->textInfo.selectLast = canvasPtr->textInfo.selectAnchor - 1;
    }
    if ((canvasPtr->textInfo.selectFirst != oldFirst)
	    || (canvasPtr->textInfo.selectLast != oldLast)
	    || (itemPtr != oldSelPtr)) {
	EventuallyRedrawItem(canvasPtr, itemPtr);
    }







|



|







5353
5354
5355
5356
5357
5358
5359
5360
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
    }
    canvasPtr->textInfo.selItemPtr = itemPtr;

    if (canvasPtr->textInfo.anchorItemPtr != itemPtr) {
	canvasPtr->textInfo.anchorItemPtr = itemPtr;
	canvasPtr->textInfo.selectAnchor = index;
    }
    if (canvasPtr->textInfo.selectAnchor <= index) {
	canvasPtr->textInfo.selectFirst = canvasPtr->textInfo.selectAnchor;
	canvasPtr->textInfo.selectLast = index;
    } else {
	canvasPtr->textInfo.selectFirst = index;
	canvasPtr->textInfo.selectLast = canvasPtr->textInfo.selectAnchor - 1;
    }
    if ((canvasPtr->textInfo.selectFirst != oldFirst)
	    || (canvasPtr->textInfo.selectLast != oldLast)
	    || (itemPtr != oldSelPtr)) {
	EventuallyRedrawItem(canvasPtr, itemPtr);
    }
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);







|


|


|







5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
CanvasFetchSelection(
    ClientData clientData,	/* Information about canvas widget. */
    int offset,			/* Offset within selection of first character
				 * to be returned. */
    char *buffer,		/* Location in which to place selection. */
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    TkCanvas *canvasPtr = (TkCanvas *)clientData;

    return ItemSelection(canvasPtr, canvasPtr->textInfo.selItemPtr, offset,
	    buffer, maxBytes);
Changes to generic/tkCanvas.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/*
 * 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 (c) 1991-1994 The Regents of the University of California.
 * Copyright (c) 1994-1995 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 _TKCANVAS
#define _TKCANVAS
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
				 * of the previous current item. */
    double closeEnough;		/* The mouse is assumed to be inside an item
				 * if it is this close to it. */
    XEvent pickEvent;		/* The event upon which the current choice of
				 * currentItem is based. Must be saved so that
				 * if the currentItem is deleted, can pick
				 * another. */
    unsigned int state;		/* Last known modifier state. Used to defer
				 * picking a new current object while buttons
				 * are down. */

    /*
     * Information used for managing scrollbars:
     */








|







143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
				 * of the previous current item. */
    double closeEnough;		/* The mouse is assumed to be inside an item
				 * if it is this close to it. */
    XEvent pickEvent;		/* The event upon which the current choice of
				 * currentItem is based. Must be saved so that
				 * if the currentItem is deleted, can pick
				 * another. */
    int state;			/* Last known modifier state. Used to defer
				 * picking a new current object while buttons
				 * are down. */

    /*
     * Information used for managing scrollbars:
     */

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    double pixelsPerMM;		/* Scale factor between MM and pixels; used
				 * when converting coordinates. */
    int flags;			/* Various flags; see below for
				 * definitions. */
    TkSizeT nextId;			/* Number to use as id for next item created
				 * in widget. */
    Tk_PostscriptInfo psInfo;	/* Pointer to information used for generating
				 * Postscript for the canvas. NULL means no
				 * Postscript is currently being generated. */
    Tcl_HashTable idTable;	/* Table of integer indices. */

    /*







|







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
				 * scripts. Malloc'ed, but may be NULL. */
    double pixelsPerMM;		/* Scale factor between MM and pixels; used
				 * when converting coordinates. */
    int flags;			/* Various flags; see below for
				 * definitions. */
    int nextId;			/* Number to use as id for next item created
				 * in widget. */
    Tk_PostscriptInfo psInfo;	/* Pointer to information used for generating
				 * Postscript for the canvas. NULL means no
				 * Postscript is currently being generated. */
    Tcl_HashTable idTable;	/* Table of integer indices. */

    /*
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
} TkCanvas;

/*
 * Flag bits for canvases:
 *
 * REDRAW_PENDING -		1 means a DoWhenIdle handler has already been
 *				created to redraw some or all of the canvas.
 * REDRAW_BORDERS - 		1 means that the borders need to be redrawn
 *				during the next redisplay operation.
 * REPICK_NEEDED -		1 means DisplayCanvas should pick a new
 *				current item before redrawing the canvas.
 * GOT_FOCUS -			1 means the focus is currently in this widget,
 *				so should draw the insertion cursor and
 *				traversal highlight.
 * CURSOR_ON -			1 means the insertion cursor is in the "on"







|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
} TkCanvas;

/*
 * Flag bits for canvases:
 *
 * REDRAW_PENDING -		1 means a DoWhenIdle handler has already been
 *				created to redraw some or all of the canvas.
 * REDRAW_BORDERS -		1 means that the borders need to be redrawn
 *				during the next redisplay operation.
 * REPICK_NEEDED -		1 means DisplayCanvas should pick a new
 *				current item before redrawing the canvas.
 * GOT_FOCUS -			1 means the focus is currently in this widget,
 *				so should draw the insertion cursor and
 *				traversal highlight.
 * CURSOR_ON -			1 means the insertion cursor is in the "on"
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/*
 * Canvas-related functions that are shared among Tk modules but not exported
 * to the outside world:
 */

MODULE_SCOPE int	TkCanvPostscriptCmd(TkCanvas *canvasPtr,
			    Tcl_Interp *interp, int argc, const char **argv);
MODULE_SCOPE int 	TkCanvTranslatePath(TkCanvas *canvPtr,
			    int numVertex, double *coordPtr, int closed,
			    XPoint *outPtr);
/*
 * Standard item types provided by Tk:
 */

MODULE_SCOPE Tk_ItemType tkArcType, tkBitmapType, tkImageType, tkLineType;







|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
/*
 * Canvas-related functions that are shared among Tk modules but not exported
 * to the outside world:
 */

MODULE_SCOPE int	TkCanvPostscriptCmd(TkCanvas *canvasPtr,
			    Tcl_Interp *interp, int argc, const char **argv);
MODULE_SCOPE int	TkCanvTranslatePath(TkCanvas *canvPtr,
			    int numVertex, double *coordPtr, int closed,
			    XPoint *outPtr);
/*
 * Standard item types provided by Tk:
 */

MODULE_SCOPE Tk_ItemType tkArcType, tkBitmapType, tkImageType, tkLineType;
Changes to generic/tkClipboard.c.
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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);

/*
 *----------------------------------------------------------------------
 *







|
|
|
|
|
|







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#include "tkInt.h"
#include "tkSelect.h"

/*
 * Prototypes for functions used only in this file:
 */

static int		ClipboardAppHandler(ClientData clientData,
			    int offset, char *buffer, int maxBytes);
static int		ClipboardHandler(ClientData clientData,
			    int offset, char *buffer, int maxBytes);
static int		ClipboardWindowHandler(ClientData clientData,
			    int offset, char *buffer, int maxBytes);
static void		ClipboardLostSel(ClientData clientData);
static int		ClipboardGetProc(ClientData clientData,
			    Tcl_Interp *interp, const char *portion);

/*
 *----------------------------------------------------------------------
 *
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
 *
 * 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 int
ClipboardHandler(
    ClientData clientData,	/* Information about data to fetch. */
    int offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    int maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkClipboardTarget *targetPtr = (TkClipboardTarget *)clientData;
    TkClipboardBuffer *cbPtr;
    char *srcPtr, *destPtr;
    size_t count = 0;
    int scanned = 0;
    size_t length, freeCount;

    /*
     * Skip to buffer containing offset byte
     */

    for (cbPtr = targetPtr->firstBufferPtr; ; cbPtr = cbPtr->nextPtr) {
	if (cbPtr == NULL) {
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	cbPtr = cbPtr->nextPtr;
	if (cbPtr == NULL) {
	    break;
	}
	srcPtr = cbPtr->buffer;
	length = cbPtr->length;
    }
    return count;
}

/*
 *----------------------------------------------------------------------
 *
 * ClipboardAppHandler --
 *







|







98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
	cbPtr = cbPtr->nextPtr;
	if (cbPtr == NULL) {
	    break;
	}
	srcPtr = cbPtr->buffer;
	length = cbPtr->length;
    }
    return (int)count;
}

/*
 *----------------------------------------------------------------------
 *
 * ClipboardAppHandler --
 *
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
 *
 * 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 int
ClipboardAppHandler(
    ClientData clientData,	/* Pointer to TkDisplay structure. */
    int offset,			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    int maxBytes)		/* Maximum # of bytes to store at buffer. */
{
    TkDisplay *dispPtr = (TkDisplay *)clientData;
    int length;
    const char *p;

    p = dispPtr->clipboardAppPtr->winPtr->nameUid;
    length = strlen(p);
    if (length <= offset) {
	return 0;
    }
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
ClipboardWindowHandler(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(TkSizeT),			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TCL_UNUSED(TkSizeT))		/* Maximum # of bytes to store at buffer. */
{
    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*







|


|


|







167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ClipboardWindowHandler(
    TCL_UNUSED(void *),	/* Not used. */
    TCL_UNUSED(int),			/* Return selection bytes starting at this
				 * offset. */
    char *buffer,		/* Place to store converted selection. */
    TCL_UNUSED(int))		/* Maximum # of bytes to store at buffer. */
{
    buffer[0] = '.';
    buffer[1] = 0;
    return 1;
}

/*
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
	const char *targetName = NULL;
	const char *formatName = NULL;
	const char *string;
	static const char *const appendOptionStrings[] = {
	    "-displayof", "-format", "-type", NULL
	};
	enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
	int subIndex;
	TkSizeT length;

	for (i = 2; i < objc - 1; i++) {
	    string = TkGetStringFromObj(objv[i], &length);
	    if (string[0] != '-') {
		break;
	    }

	    /*
	     * If the argument is "--", it signifies the end of arguments.
	     */







|
<


|







446
447
448
449
450
451
452
453

454
455
456
457
458
459
460
461
462
463
	const char *targetName = NULL;
	const char *formatName = NULL;
	const char *string;
	static const char *const appendOptionStrings[] = {
	    "-displayof", "-format", "-type", NULL
	};
	enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE };
	int subIndex, 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.
	     */
705
706
707
708
709
710
711




712


713
714
715
716
717
718
719
720
721
722
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:
 */







>
>
>
>
|
>
>










704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
ClipboardGetProc(
    ClientData clientData,	/* Dynamic string holding partially assembled
				 * selection. */
    TCL_UNUSED(Tcl_Interp *),		/* Interpreter used for error reporting (not
				 * used). */
    const char *portion)	/* New information to be appended. */
{
    Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
    Tcl_DString ds;

    Tcl_ExternalToUtfDString(utf8, portion, -1, &ds);
    Tcl_DStringAppend((Tcl_DString *) clientData, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds));
    Tcl_DStringFree(&ds);
    Tcl_FreeEncoding(utf8);
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkCmds.c.
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776

777
778
779
780
781
782
783
784
	 * Return all the current values
	 */

	objPtr = Tcl_NewObj();
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-height", 7));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->height));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-x", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->x));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-y", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewWideIntObj(caretPtr->y));
	Tcl_SetObjResult(interp, objPtr);
    } else if (objc == 3) {
	int value;

	/*
	 * Return the current value of the selected option
	 */

	if (Tcl_GetIndexFromObj(interp, objv[2], caretStrings,
		"caret option", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == TK_CARET_X) {
	    value = caretPtr->x;
	} else if (index == TK_CARET_Y) {
	    value = caretPtr->y;
	} else /* if (index == TK_CARET_HEIGHT) -- last case */ {
	    value = caretPtr->height;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(value));
    } else {

	int i, value, x = 0, y = 0, height = -1;

	for (i = 2; i < objc; i += 2) {
	    if ((Tcl_GetIndexFromObj(interp, objv[i], caretStrings,
		    "caret option", 0, &index) != TCL_OK) ||
		    Tcl_GetIntFromObj(interp,objv[i+1],&value) != TCL_OK) {
		return TCL_ERROR;
	    }







|



|



|



















|

>
|







740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
	 * Return all the current values
	 */

	objPtr = Tcl_NewObj();
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-height", 7));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewIntObj(caretPtr->height));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-x", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewIntObj(caretPtr->x));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewStringObj("-y", 2));
	Tcl_ListObjAppendElement(interp, objPtr,
		Tcl_NewIntObj(caretPtr->y));
	Tcl_SetObjResult(interp, objPtr);
    } else if (objc == 3) {
	int value;

	/*
	 * Return the current value of the selected option
	 */

	if (Tcl_GetIndexFromObj(interp, objv[2], caretStrings,
		"caret option", 0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (index == TK_CARET_X) {
	    value = caretPtr->x;
	} else if (index == TK_CARET_Y) {
	    value = caretPtr->y;
	} else /* if (index == TK_CARET_HEIGHT) -- last case */ {
	    value = caretPtr->height;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(value));
    } else {
	int 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;
	    }
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829





830
831
832
833
834
835
836
    Tcl_Obj *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) {







<
<
<
<
<
<
<










>
>
>
>
>







807
808
809
810
811
812
813







814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Screen *screenPtr;
    int skip, width, height;
    double d;








    skip = TkGetDisplayOf(interp, objc - 1, objv + 1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    screenPtr = Tk_Screen(tkwin);
    if (objc - skip == 1) {
	d = 25.4 / 72;
	d *= WidthOfScreen(screenPtr);
	d /= WidthMMOfScreen(screenPtr);
	Tcl_SetObjResult(interp, Tcl_NewDoubleObj(d));
    } else if (Tcl_IsSafe(interp)) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"setting the scaling not accessible in a safe interpreter", -1));
	Tcl_SetErrorCode(interp, "TK", "SAFE", "SCALING", NULL);
	return TCL_ERROR;
    } else if (objc - skip == 2) {
	if (Tcl_GetDoubleFromObj(interp, objv[1+skip], &d) != TCL_OK) {
	    return TCL_ERROR;
	}
	d = (25.4 / 72) / d;
	width = (int) (d * WidthOfScreen(screenPtr) + 0.5);
	if (width <= 0) {
869
870
871
872
873
874
875





876
877
878
879
880
881
882

883
884
885
886
887

888
889
890
891
892
893
894

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







>
>
>
>
>







>
|




>







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900

    skip = TkGetDisplayOf(interp, objc-1, objv+1, &tkwin);
    if (skip < 0) {
	return TCL_ERROR;
    }
    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if ((objc - skip) == 2) {
	/*
	 * In the case where TK_USE_INPUT_METHODS is not defined, this
	 * will be ignored and we will always return 0. That will indicate
	 * to the user that input methods are just not available.
	 */

	int boolVal;

	if (Tcl_GetBooleanFromObj(interp, objv[1+skip],
		&boolVal) != TCL_OK) {
	    return TCL_ERROR;
	}
#ifdef TK_USE_INPUT_METHODS
	if (boolVal) {
	    dispPtr->flags |= TK_DISPLAY_USE_IM;
	} else {
	    dispPtr->flags &= ~TK_DISPLAY_USE_IM;
	}
#endif /* TK_USE_INPUT_METHODS */
    } else if ((objc - skip) != 1) {
	Tcl_WrongNumArgs(interp, 1, objv,
		"?-displayof window? ?boolean?");
	return TCL_ERROR;
    }
    Tcl_SetObjResult(interp,
	    Tcl_NewBooleanObj(dispPtr->flags & TK_DISPLAY_USE_IM));
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123


1124
1125
1126
1127
1128
1129
1130

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







|
|






>
>







1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138

    return code;
}

static char *
WaitVariableProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    TCL_UNUSED(const char *),		/* Second part of variable name. */
    TCL_UNUSED(int))			/* Information about what happened. */
{
    int *donePtr = (int *)clientData;

    *donePtr = 1;
    Tcl_UntraceVar(interp, name1, TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
	    WaitVariableProc, clientData);
    return NULL;
}

static void
WaitVisibilityProc(
    ClientData clientData,	/* Pointer to integer to set to 1. */
    XEvent *eventPtr)		/* Information about event (not used). */
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
	}
    }
    winPtr = (TkWindow *) tkwin;

    switch ((enum options) index) {
    case WIN_CELLS:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(Tk_Visual(tkwin)->map_entries));
	break;
    case WIN_CHILDREN: {
	Tcl_Obj *strPtr, *resultPtr = Tcl_NewObj();

	winPtr = winPtr->childList;
	for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
	    if (!(winPtr->flags & TK_ANONYMOUS_WINDOW)) {







|







1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
	}
    }
    winPtr = (TkWindow *) tkwin;

    switch ((enum options) index) {
    case WIN_CELLS:
	Tcl_SetObjResult(interp,
		Tcl_NewIntObj(Tk_Visual(tkwin)->map_entries));
	break;
    case WIN_CHILDREN: {
	Tcl_Obj *strPtr, *resultPtr = Tcl_NewObj();

	winPtr = winPtr->childList;
	for ( ; winPtr != NULL; winPtr = winPtr->nextPtr) {
	    if (!(winPtr->flags & TK_ANONYMOUS_WINDOW)) {
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
	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));







|






|







1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
	Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_Class(tkwin), -1));
	break;
    case WIN_COLORMAPFULL:
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(TkpCmapStressed(tkwin,Tk_Colormap(tkwin))));
	break;
    case WIN_DEPTH:
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Depth(tkwin)));
	break;
    case WIN_GEOMETRY:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%dx%d+%d+%d",
		Tk_Width(tkwin), Tk_Height(tkwin), Tk_X(tkwin), Tk_Y(tkwin)));
	break;
    case WIN_HEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Height(tkwin)));
	break;
    case WIN_ID: {
	char buf[TCL_INTEGER_SPACE];

	Tk_MakeWindowExist(tkwin);
	TkpPrintWindowId(buf, Tk_WindowId(tkwin));
	Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
	    y = -1;
	} else {
	    TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
	}
	if (useX & useY) {
	    Tcl_Obj *xyObj[2];

	    xyObj[0] = Tcl_NewWideIntObj(x);
	    xyObj[1] = Tcl_NewWideIntObj(y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, xyObj));
	} else if (useX) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	}
	break;
    case WIN_REQHEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_ReqHeight(tkwin)));
	break;
    case WIN_REQWIDTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_ReqWidth(tkwin)));
	break;
    case WIN_ROOTX:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	break;
    case WIN_ROOTY:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	break;
    case WIN_SCREEN:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s.%d",
		Tk_DisplayName(tkwin), Tk_ScreenNumber(tkwin)));
	break;
    case WIN_SCREENCELLS:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(CellsOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENDEPTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(DefaultDepthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(HeightOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(WidthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(HeightMMOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewWideIntObj(WidthMMOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENVISUAL:
	c_class = DefaultVisualOfScreen(Tk_Screen(tkwin))->c_class;
	goto visual;
    case WIN_SERVER:
	TkGetServerInfo(interp, tkwin);
	break;







|
|


|

|



|


|



|



|







|



|



|



|



|



|







1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
	    y = -1;
	} else {
	    TkGetPointerCoords((Tk_Window) winPtr, &x, &y);
	}
	if (useX & useY) {
	    Tcl_Obj *xyObj[2];

	    xyObj[0] = Tcl_NewIntObj(x);
	    xyObj[1] = Tcl_NewIntObj(y);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, xyObj));
	} else if (useX) {
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(y));
	}
	break;
    case WIN_REQHEIGHT:
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_ReqHeight(tkwin)));
	break;
    case WIN_REQWIDTH:
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_ReqWidth(tkwin)));
	break;
    case WIN_ROOTX:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
	break;
    case WIN_ROOTY:
	Tk_GetRootCoords(tkwin, &x, &y);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(y));
	break;
    case WIN_SCREEN:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%s.%d",
		Tk_DisplayName(tkwin), Tk_ScreenNumber(tkwin)));
	break;
    case WIN_SCREENCELLS:
	Tcl_SetObjResult(interp,
		Tcl_NewIntObj(CellsOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENDEPTH:
	Tcl_SetObjResult(interp,
		Tcl_NewIntObj(DefaultDepthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewIntObj(HeightOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewIntObj(WidthOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMHEIGHT:
	Tcl_SetObjResult(interp,
		Tcl_NewIntObj(HeightMMOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENMMWIDTH:
	Tcl_SetObjResult(interp,
		Tcl_NewIntObj(WidthMMOfScreen(Tk_Screen(tkwin))));
	break;
    case WIN_SCREENVISUAL:
	c_class = DefaultVisualOfScreen(Tk_Screen(tkwin))->c_class;
	goto visual;
    case WIN_SERVER:
	TkGetServerInfo(interp, tkwin);
	break;
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
	break;
    case WIN_VISUALID:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", (unsigned)
		XVisualIDFromVisual(Tk_Visual(tkwin))));
	break;
    case WIN_VROOTHEIGHT:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(height));
	break;
    case WIN_VROOTWIDTH:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(width));
	break;
    case WIN_VROOTX:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(x));
	break;
    case WIN_VROOTY:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(y));
	break;
    case WIN_WIDTH:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Width(tkwin)));
	break;
    case WIN_X:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_X(tkwin)));
	break;
    case WIN_Y:
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(Tk_Y(tkwin)));
	break;

	/*
	 * Uses -displayof.
	 */

    case WIN_ATOM:







|



|



|



|


|


|


|







1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
	break;
    case WIN_VISUALID:
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("0x%x", (unsigned)
		XVisualIDFromVisual(Tk_Visual(tkwin))));
	break;
    case WIN_VROOTHEIGHT:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(height));
	break;
    case WIN_VROOTWIDTH:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(width));
	break;
    case WIN_VROOTX:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(x));
	break;
    case WIN_VROOTY:
	Tk_GetVRootGeometry(tkwin, &x, &y, &width, &height);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(y));
	break;
    case WIN_WIDTH:
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Width(tkwin)));
	break;
    case WIN_X:
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_X(tkwin)));
	break;
    case WIN_Y:
	Tcl_SetObjResult(interp, Tcl_NewIntObj(Tk_Y(tkwin)));
	break;

	/*
	 * Uses -displayof.
	 */

    case WIN_ATOM:
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) {
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
	if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixels));
	break;
    }
    case WIN_RGB: {
	XColor *colorPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window colorName");







|







1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin) != TCL_OK) {
	    return TCL_ERROR;
	}
	string = Tcl_GetString(objv[3]);
	if (Tk_GetPixels(interp, tkwin, string, &pixels) != TCL_OK) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(pixels));
	break;
    }
    case WIN_RGB: {
	XColor *colorPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window colorName");
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
	 * destroyed when we are through with it, so we do not get stale RGB
	 * values next time.
	 */

	{
	    Colormap temp = Tk_Colormap(tkwin);
	    Tk_Colormap(tkwin) = TK_DYNAMIC_COLORMAP;
	    colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
	    Tk_Colormap(tkwin) = temp;
	}
#else
	colorPtr = Tk_GetColor(interp, tkwin, Tcl_GetString(objv[3]));
#endif
	if (colorPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d",
		colorPtr->red, colorPtr->green, colorPtr->blue));
	Tk_FreeColor(colorPtr);







|



|







1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
	 * destroyed when we are through with it, so we do not get stale RGB
	 * values next time.
	 */

	{
	    Colormap temp = Tk_Colormap(tkwin);
	    Tk_Colormap(tkwin) = TK_DYNAMIC_COLORMAP;
	    colorPtr = Tk_AllocColorFromObj(interp, tkwin, objv[3]);
	    Tk_Colormap(tkwin) = temp;
	}
#else
	colorPtr = Tk_AllocColorFromObj(interp, tkwin, objv[3]);
#endif
	if (colorPtr == NULL) {
	    return TCL_ERROR;
	}
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("%d %d %d",
		colorPtr->red, colorPtr->green, colorPtr->blue));
	Tk_FreeColor(colorPtr);
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
	}
	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);







|


|







1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
	}
	resultPtr = Tcl_NewObj();
	for (i = 0; i < count; i++) {
	    string = TkFindStateString(visualMap, visInfoPtr[i].c_class);
	    if (string == NULL) {
		strcpy(buf, "unknown");
	    } else {
		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, -1);
	    Tcl_ListObjAppendElement(NULL, resultPtr, strPtr);
	}
	Tcl_SetObjResult(interp, resultPtr);
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
				 * 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;







|




|







1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
				 * application associated with interp. On
				 * output, filled with window specified as
				 * option to "-displayof" argument, or
				 * unmodified if "-displayof" argument was not
				 * present. */
{
    const char *string;
    int length;

    if (objc < 1) {
	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", -1));
	    Tcl_SetErrorCode(interp, "TK", "NO_VALUE", "DISPLAYOF", NULL);
	    return -1;
Changes to generic/tkColor.c.
11
12
13
14
15
16
17




18
19
20
21
22
23
24
 * 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 {
    int red, green, blue;	/* Values for desired color. */







>
>
>
>







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkColor.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Structures of the following following type are used as keys for
 * colorValueTable (in TkDisplay).
 */

typedef struct {
    int red, green, blue;	/* Values for desired color. */
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381

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







|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385

    if (tkColPtr->magic==COLOR_MAGIC && tkColPtr->type==TK_COLOR_BY_NAME) {
	return tkColPtr->hashPtr->key.string;
    } else {
	ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
		Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

	snprintf(tsdPtr->rgbString, sizeof(tsdPtr->rgbString), "#%04x%04x%04x", colorPtr->red,
		colorPtr->green, colorPtr->blue);

	/*
	 * If the string has the form #RSRSTUTUVWVW (where equal letters
	 * denote equal hexdigits) then this is equivalent to #RSTUVW. Then
	 * output the shorter form.
	 */
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
	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







|

|







818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
	if (tkColPtr == NULL) {
	    Tcl_Panic("TkDebugColor found empty hash table entry");
	}
	for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) {
	    Tcl_Obj *objPtr = Tcl_NewObj();

	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(tkColPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

#ifndef _WIN32
Changes to generic/tkColor.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * 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 (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKCOLOR
#define _TKCOLOR
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
				 * 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. */
    int resourceRefCount;	/* Number of active uses of this color (each
				 * active use corresponds to a call to
				 * Tk_AllocColorFromObj or Tk_GetColor). If
				 * this count is 0, then this TkColor
				 * structure is no longer valid and it isn't
				 * present in a hash table: it is being kept
				 * around only because there are objects
				 * referring to it. The structure is freed
				 * when resourceRefCount and objRefCount are
				 * both 0. */
    int objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    int type;			/* TK_COLOR_BY_NAME or TK_COLOR_BY_VALUE. */
    Tcl_HashEntry *hashPtr;	/* Pointer to hash table entry for this
				 * structure. (for use in deleting entry). */
    struct TkColor *nextPtr;	/* Points to the next TkColor structure with
				 * the same color name. Colors with the same
				 * name but different screens or colormaps are
Changes to generic/tkConfig.c.
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 TYPE_FLAGS:
 *
 * if sizeof(type) == sizeof(int)     =>    TYPE_FLAGS(type) = 0
 * if sizeof(type) == 1               =>    TYPE_FLAGS(type) = 64
 * if sizeof(type) == 2               =>    TYPE_FLAGS(type) = 128
 */
#define TYPE_FLAGS(type) (((int)(sizeof(type)&(sizeof(int)-1))<<6))
#define TYPE_MASK        (((((int)sizeof(int)-1))|3)<<6)

/*
 * The following definition keeps track of all of
 * the option tables that have been created for a thread.
 */

typedef struct {
    int initialized;		/* 0 means table below needs initializing. */
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132

/*
 * One of the following exists for each Tk_OptionSpec array that has been
 * passed to Tk_CreateOptionTable.
 */

typedef struct OptionTable {
    size_t refCount;		/* Counts the number of uses of this table
				 * (the number of times Tk_CreateOptionTable
				 * has returned it). This can be greater than
				 * 1 if it is shared along several option
				 * table chains, or if the same table is used
				 * for multiple purposes. */
    Tcl_HashEntry *hashEntryPtr;/* Hash table entry that refers to this table;
				 * used to delete the entry. */
    struct OptionTable *nextPtr;/* If templatePtr was part of a chain of
				 * templates, this points to the table
				 * corresponding to the next template in the
				 * chain. */
    size_t numOptions;		/* The number of items in the options array
				 * below. */
    Option options[1];		/* Information about the individual options in
				 * the table. This must be the last field in
				 * the structure: the actual size of the array
				 * will be numOptions, not 1. */
} OptionTable;

/*
 * Forward declarations for functions defined later in this file:
 */

static int		DoObjConfig(Tcl_Interp *interp, void *recordPtr,
			    Option *optionPtr, Tcl_Obj *valuePtr,
			    Tk_Window tkwin, Tk_SavedOption *savePtr);
static void		FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
			    void *internalPtr, Tk_Window tkwin);
static Tcl_Obj *	GetConfigList(void *recordPtr,
			    Option *optionPtr, Tk_Window tkwin);
static Tcl_Obj *	GetObjectForOption(void *recordPtr,
			    Option *optionPtr, Tk_Window tkwin);
static Option *		GetOption(const char *name, OptionTable *tablePtr);
static Option *		GetOptionFromObj(Tcl_Interp *interp,
			    Tcl_Obj *objPtr, OptionTable *tablePtr);
static int		ObjectIsEmpty(Tcl_Obj *objPtr);
static void		FreeOptionInternalRep(Tcl_Obj *objPtr);
static void		DupOptionInternalRep(Tcl_Obj *, Tcl_Obj *);







|











|











|



|
|

|







101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146

/*
 * One of the following exists for each Tk_OptionSpec array that has been
 * passed to Tk_CreateOptionTable.
 */

typedef struct OptionTable {
    int refCount;		/* Counts the number of uses of this table
				 * (the number of times Tk_CreateOptionTable
				 * has returned it). This can be greater than
				 * 1 if it is shared along several option
				 * table chains, or if the same table is used
				 * for multiple purposes. */
    Tcl_HashEntry *hashEntryPtr;/* Hash table entry that refers to this table;
				 * used to delete the entry. */
    struct OptionTable *nextPtr;/* If templatePtr was part of a chain of
				 * templates, this points to the table
				 * corresponding to the next template in the
				 * chain. */
    int numOptions;		/* The number of items in the options array
				 * below. */
    Option options[1];		/* Information about the individual options in
				 * the table. This must be the last field in
				 * the structure: the actual size of the array
				 * will be numOptions, not 1. */
} OptionTable;

/*
 * Forward declarations for functions defined later in this file:
 */

static int		DoObjConfig(Tcl_Interp *interp, char *recordPtr,
			    Option *optionPtr, Tcl_Obj *valuePtr,
			    Tk_Window tkwin, Tk_SavedOption *savePtr);
static void		FreeResources(Option *optionPtr, Tcl_Obj *objPtr,
			    char *internalPtr, Tk_Window tkwin);
static Tcl_Obj *	GetConfigList(char *recordPtr,
			    Option *optionPtr, Tk_Window tkwin);
static Tcl_Obj *	GetObjectForOption(char *recordPtr,
			    Option *optionPtr, Tk_Window tkwin);
static Option *		GetOption(const char *name, OptionTable *tablePtr);
static Option *		GetOptionFromObj(Tcl_Interp *interp,
			    Tcl_Obj *objPtr, OptionTable *tablePtr);
static int		ObjectIsEmpty(Tcl_Obj *objPtr);
static void		FreeOptionInternalRep(Tcl_Obj *objPtr);
static void		DupOptionInternalRep(Tcl_Obj *, Tcl_Obj *);
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
				 * options. */
{
    Tcl_HashEntry *hashEntryPtr;
    int newEntry;
    OptionTable *tablePtr;
    const Tk_OptionSpec *specPtr, *specPtr2;
    Option *optionPtr;
    size_t numOptions, i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * We use an TSD in the thread to keep a hash table of
     * all the option tables we've created for this application. This is
     * used for allowing us to share the tables (e.g. in several chains).







|







187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
				 * options. */
{
    Tcl_HashEntry *hashEntryPtr;
    int newEntry;
    OptionTable *tablePtr;
    const Tk_OptionSpec *specPtr, *specPtr2;
    Option *optionPtr;
    int numOptions, i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * We use an TSD in the thread to keep a hash table of
     * all the option tables we've created for this application. This is
     * used for allowing us to share the tables (e.g. in several chains).
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
		 * Get the custom parsing, etc., functions.
		 */

		optionPtr->extra.custom = (const Tk_ObjCustomOption *)specPtr->clientData;
	    }
	}
	if (((specPtr->type == TK_OPTION_STRING)
		&& (specPtr->internalOffset != TCL_INDEX_NONE))
		|| (specPtr->type == TK_OPTION_COLOR)
		|| (specPtr->type == TK_OPTION_FONT)
		|| (specPtr->type == TK_OPTION_BITMAP)
		|| (specPtr->type == TK_OPTION_BORDER)
		|| (specPtr->type == TK_OPTION_CURSOR)
		|| (specPtr->type == TK_OPTION_CUSTOM)) {
	    optionPtr->flags |= OPTION_NEEDS_FREEING;







|







289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
		 * Get the custom parsing, etc., functions.
		 */

		optionPtr->extra.custom = (const Tk_ObjCustomOption *)specPtr->clientData;
	    }
	}
	if (((specPtr->type == TK_OPTION_STRING)
		&& (specPtr->internalOffset >= 0))
		|| (specPtr->type == TK_OPTION_COLOR)
		|| (specPtr->type == TK_OPTION_FONT)
		|| (specPtr->type == TK_OPTION_BITMAP)
		|| (specPtr->type == TK_OPTION_BORDER)
		|| (specPtr->type == TK_OPTION_CURSOR)
		|| (specPtr->type == TK_OPTION_CUSTOM)) {
	    optionPtr->flags |= OPTION_NEEDS_FREEING;
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340

void
Tk_DeleteOptionTable(
    Tk_OptionTable optionTable)	/* The option table to delete. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    size_t count;

    if (tablePtr->refCount-- > 1) {
	return;
    }

    if (tablePtr->nextPtr != NULL) {
	Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr);







|







340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

void
Tk_DeleteOptionTable(
    Tk_OptionTable optionTable)	/* The option table to delete. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    int count;

    if (tablePtr->refCount-- > 1) {
	return;
    }

    if (tablePtr->nextPtr != NULL) {
	Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr);
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
 *--------------------------------------------------------------
 */

int
Tk_InitOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. NULL means
				 * don't leave an error message. */
    void *recordPtr,		/* Pointer to the record to configure. Note:
				 * the caller should have properly initialized
				 * the record with NULL pointers for each
				 * option value. */
    Tk_OptionTable optionTable,	/* The token which matches the config specs
				 * for the widget in question. */
    Tk_Window tkwin)		/* Certain options types (such as
				 * TK_OPTION_COLOR) need fields out of the







|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
 *--------------------------------------------------------------
 */

int
Tk_InitOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. NULL means
				 * don't leave an error message. */
    char *recordPtr,		/* Pointer to the record to configure. Note:
				 * the caller should have properly initialized
				 * the record with NULL pointers for each
				 * option value. */
    Tk_OptionTable optionTable,	/* The token which matches the config specs
				 * for the widget in question. */
    Tk_Window tkwin)		/* Certain options types (such as
				 * TK_OPTION_COLOR) need fields out of the
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
	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;
	}







|



|



|



|







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
	if (DoObjConfig(interp, recordPtr, optionPtr, valuePtr, tkwin,
		NULL) != TCL_OK) {
	    if (interp != NULL) {
		char msg[200];

		switch (source) {
		case OPTION_DATABASE:
		    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;
	}
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
 */

static int
DoObjConfig(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no message is left if an error
				 * occurs. */
    void *recordPtr,		/* The record to modify to hold the new option
				 * value. */
    Option *optionPtr,		/* Pointer to information about the option. */
    Tcl_Obj *valuePtr,		/* New value for option. */
    Tk_Window tkwin,		/* Window in which option will be used (needed
				 * to allocate resources for some options).
				 * May be NULL if the option doesn't require
				 * window-related resources. */
    Tk_SavedOption *savedOptionPtr)
				/* If NULL, the old value for the option will
				 * be freed. If non-NULL, the old value will
				 * be stored here, and it becomes the property
				 * of the caller (the caller must eventually
				 * free the old value). */
{
    Tcl_Obj **slotPtrPtr, *oldPtr;
    void *internalPtr;		/* Points to location in record where internal
				 * representation of value should be stored,
				 * or NULL. */
    void *oldInternalPtr;	/* Points to location in which to save old
				 * internal representation of value. */
    Tk_SavedOption internal;	/* Used to save the old internal
				 * representation of the value if
				 * savedOptionPtr is NULL. */
    const Tk_OptionSpec *specPtr;
    int nullOK;

    /*
     * Save the old object form for the value, if there is one.
     */

    specPtr = optionPtr->specPtr;
    if (specPtr->objOffset != TCL_INDEX_NONE) {
	slotPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
	oldPtr = *slotPtrPtr;
    } else {
	slotPtrPtr = NULL;
	oldPtr = NULL;
    }

    /*
     * Apply the new value in a type-specific way. Also remember the old
     * object and internal forms, if they exist.
     */

    if (specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + specPtr->internalOffset;
    } else {
	internalPtr = NULL;
    }
    if (savedOptionPtr != NULL) {
	savedOptionPtr->optionPtr = optionPtr;
	savedOptionPtr->valuePtr = oldPtr;
	oldInternalPtr = (char *) &savedOptionPtr->internalForm;
    } 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;
	}







|















|


|












|
|











|
|










|







562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
 */

static int
DoObjConfig(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no message is left if an error
				 * occurs. */
    char *recordPtr,		/* The record to modify to hold the new option
				 * value. */
    Option *optionPtr,		/* Pointer to information about the option. */
    Tcl_Obj *valuePtr,		/* New value for option. */
    Tk_Window tkwin,		/* Window in which option will be used (needed
				 * to allocate resources for some options).
				 * May be NULL if the option doesn't require
				 * window-related resources. */
    Tk_SavedOption *savedOptionPtr)
				/* If NULL, the old value for the option will
				 * be freed. If non-NULL, the old value will
				 * be stored here, and it becomes the property
				 * of the caller (the caller must eventually
				 * free the old value). */
{
    Tcl_Obj **slotPtrPtr, *oldPtr;
    char *internalPtr;		/* Points to location in record where internal
				 * representation of value should be stored,
				 * or NULL. */
    char *oldInternalPtr;	/* Points to location in which to save old
				 * internal representation of value. */
    Tk_SavedOption internal;	/* Used to save the old internal
				 * representation of the value if
				 * savedOptionPtr is NULL. */
    const Tk_OptionSpec *specPtr;
    int nullOK;

    /*
     * Save the old object form for the value, if there is one.
     */

    specPtr = optionPtr->specPtr;
    if (specPtr->objOffset >= 0) {
	slotPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset);
	oldPtr = *slotPtrPtr;
    } else {
	slotPtrPtr = NULL;
	oldPtr = NULL;
    }

    /*
     * Apply the new value in a type-specific way. Also remember the old
     * object and internal forms, if they exist.
     */

    if (specPtr->internalOffset >= 0) {
	internalPtr = recordPtr + specPtr->internalOffset;
    } else {
	internalPtr = NULL;
    }
    if (savedOptionPtr != NULL) {
	savedOptionPtr->optionPtr = optionPtr;
	savedOptionPtr->valuePtr = oldPtr;
	oldInternalPtr = (char *) &savedOptionPtr->internalForm;
    } else {
	oldInternalPtr = (char *) &internal.internalForm;
    }
    nullOK = (optionPtr->specPtr->flags & (TK_OPTION_NULL_OK|32 /* TCL_NULL_OK */));
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_BOOLEAN: {
	int newBool;

	if (Tcl_GetBooleanFromObj(interp, valuePtr, &newBool) != TCL_OK) {
	    return TCL_ERROR;
	}
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690











691
692

693
694
695
696
697
698
699
	    *((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)) {







|






|















|
|



|

|

>
>
>
>
>
>
>
>
>
>
>
|
|
>







666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
	    *((double *) internalPtr) = newDbl;
	}
	break;
    }
    case TK_OPTION_STRING: {
	char *newStr;
	const char *value;
	int 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, 0, &newValue) != TCL_OK) {
		return TCL_ERROR;
	    }
	}
	if (internalPtr != NULL) {
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) {
		    *((char *) oldInternalPtr) = *((char *) internalPtr);
		    *((char *) internalPtr) = newValue;
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) {
		    *((short *) oldInternalPtr) = *((short *) internalPtr);
		    *((short *) internalPtr) = newValue;
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		}
	    } else {
		*((int *) oldInternalPtr) = *((int *) internalPtr);
		*((int *) internalPtr) = newValue;
	    }
	}
	break;
    }
    case TK_OPTION_COLOR: {
	XColor *newPtr;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
    }
    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;
    }
    case TK_OPTION_CUSTOM: {
	const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

	if (custom->setProc(custom->clientData, interp, tkwin,
		&valuePtr, (char *)recordPtr, optionPtr->specPtr->internalOffset,
		(char *)oldInternalPtr, optionPtr->specPtr->flags) != TCL_OK) {
	    return TCL_ERROR;
	}
	break;
    }

    default:







<
|
|
|
<













<
|
|
|
<











|







871
872
873
874
875
876
877

878
879
880

881
882
883
884
885
886
887
888
889
890
891
892
893

894
895
896

897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
    }
    case TK_OPTION_PIXELS: {
	int newPixels;

	if (nullOK && ObjectIsEmpty(valuePtr)) {
	    valuePtr = NULL;
	    newPixels = 0;

	} else if (Tk_GetPixelsFromObj(interp, tkwin, valuePtr,
		&newPixels) != TCL_OK) {
	    return TCL_ERROR;

	}
	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;
    }
    case TK_OPTION_CUSTOM: {
	const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

	if (custom->setProc(custom->clientData, interp, tkwin,
		&valuePtr, recordPtr, optionPtr->specPtr->internalOffset,
		(char *)oldInternalPtr, optionPtr->specPtr->flags) != TCL_OK) {
	    return TCL_ERROR;
	}
	break;
    }

    default:
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
    const char *name,		/* String balue to be looked up in the option
				 * table. */
    OptionTable *tablePtr)	/* Table in which to look up name. */
{
    Option *bestPtr, *optionPtr;
    OptionTable *tablePtr2;
    const char *p1, *p2;
    size_t count;

    /*
     * Search through all of the option tables in the chain to find the best
     * match. Some tricky aspects:
     *
     * 1. We have to accept unique abbreviations.
     * 2. The same name could appear in different tables in the chain. If this







|







997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
    const char *name,		/* String balue to be looked up in the option
				 * table. */
    OptionTable *tablePtr)	/* Table in which to look up name. */
{
    Option *bestPtr, *optionPtr;
    OptionTable *tablePtr2;
    const char *p1, *p2;
    int count;

    /*
     * Search through all of the option tables in the chain to find the best
     * match. Some tricky aspects:
     *
     * 1. We have to accept unique abbreviations.
     * 2. The same name could appear in different tables in the chain. If this
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
 *--------------------------------------------------------------
 */

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







|







1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
 *--------------------------------------------------------------
 */

int
Tk_SetOptions(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is returned.*/
    char *recordPtr,	    	/* The record to configure. */
    Tk_OptionTable optionTable,	/* Describes valid options. */
    int objc,			/* The number of elements in objv. */
    Tcl_Obj *const objv[],	/* Contains one or more name-value pairs. */
    Tk_Window tkwin,		/* Window associated with the thing being
				 * configured; needed for some options (such
				 * as colors). */
    Tk_SavedOptions *savePtr,	/* If non-NULL, the old values of modified
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417









1418

1419
1420
1421
1422
1423
1424
1425
 */

void
Tk_RestoreSavedOptions(
    Tk_SavedOptions *savePtr)	/* Holds saved option information; must have
				 * been passed to Tk_SetOptions. */
{
    size_t i;
    Option *optionPtr;
    Tcl_Obj *newPtr;		/* New object value of option, which we
				 * replace with old value and free. Taken from
				 * record. */
    void *internalPtr;		/* Points to internal value of option in
				 * record. */
    const Tk_OptionSpec *specPtr;

    /*
     * Be sure to restore the options in the opposite order they were set.
     * This is important because it's possible that the same option name was
     * used twice in a single call to Tk_SetOptions.
     */

    if (savePtr->nextPtr != NULL) {
	Tk_RestoreSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
	savePtr->nextPtr = NULL;
    }
    for (i = savePtr->numItems - 1; i != (size_t)-1; i--) {
	optionPtr = savePtr->items[i].optionPtr;
	specPtr = optionPtr->specPtr;

	/*
	 * First free the new value of the option, which is currently in the
	 * record.
	 */

	if (specPtr->objOffset != TCL_INDEX_NONE) {
	    newPtr = *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset));
	} else {
	    newPtr = NULL;
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    internalPtr = (char *)savePtr->recordPtr + specPtr->internalOffset;
	} else {
	    internalPtr = NULL;
	}
	if (optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin);
	}
	if (newPtr != NULL) {
	    Tcl_DecrRefCount(newPtr);
	}

	/*
	 * Now restore the old value of the option.
	 */

	if (specPtr->objOffset != TCL_INDEX_NONE) {
	    *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset))
		    = savePtr->items[i].valuePtr;
	}
	if (specPtr->internalOffset != TCL_INDEX_NONE) {
	    char *ptr = (char *) &savePtr->items[i].internalForm;

	    CLANG_ASSERT(internalPtr);
	    switch (specPtr->type) {
	    case TK_OPTION_BOOLEAN:
	    case TK_OPTION_INT:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_DOUBLE:
		*((double *) internalPtr) = *((double *) ptr);
		break;
	    case TK_OPTION_STRING:
		*((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;







|




|














|








|
|



|
|














|
|


|















>
>
>
>
>
>
>
>
>
|
>







1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
 */

void
Tk_RestoreSavedOptions(
    Tk_SavedOptions *savePtr)	/* Holds saved option information; must have
				 * been passed to Tk_SetOptions. */
{
    int i;
    Option *optionPtr;
    Tcl_Obj *newPtr;		/* New object value of option, which we
				 * replace with old value and free. Taken from
				 * record. */
    char *internalPtr;		/* Points to internal value of option in
				 * record. */
    const Tk_OptionSpec *specPtr;

    /*
     * Be sure to restore the options in the opposite order they were set.
     * This is important because it's possible that the same option name was
     * used twice in a single call to Tk_SetOptions.
     */

    if (savePtr->nextPtr != NULL) {
	Tk_RestoreSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
	savePtr->nextPtr = NULL;
    }
    for (i = savePtr->numItems - 1; i >= 0; i--) {
	optionPtr = savePtr->items[i].optionPtr;
	specPtr = optionPtr->specPtr;

	/*
	 * First free the new value of the option, which is currently in the
	 * record.
	 */

	if (specPtr->objOffset >= 0) {
	    newPtr = *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset));
	} else {
	    newPtr = NULL;
	}
	if (specPtr->internalOffset >= 0) {
	    internalPtr = savePtr->recordPtr + specPtr->internalOffset;
	} else {
	    internalPtr = NULL;
	}
	if (optionPtr->flags & OPTION_NEEDS_FREEING) {
	    FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin);
	}
	if (newPtr != NULL) {
	    Tcl_DecrRefCount(newPtr);
	}

	/*
	 * Now restore the old value of the option.
	 */

	if (specPtr->objOffset >= 0) {
	    *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset))
		    = savePtr->items[i].valuePtr;
	}
	if (specPtr->internalOffset >= 0) {
	    char *ptr = (char *) &savePtr->items[i].internalForm;

	    CLANG_ASSERT(internalPtr);
	    switch (specPtr->type) {
	    case TK_OPTION_BOOLEAN:
	    case TK_OPTION_INT:
		*((int *) internalPtr) = *((int *) ptr);
		break;
	    case TK_OPTION_DOUBLE:
		*((double *) internalPtr) = *((double *) ptr);
		break;
	    case TK_OPTION_STRING:
		*((char **) internalPtr) = *((char **) ptr);
		break;
	    case TK_OPTION_STRING_TABLE:
		if (optionPtr->specPtr->flags & TYPE_MASK) {
		    if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) {
			*((char *) internalPtr) = *((char *) ptr);
		    } else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) {
			*((short *) internalPtr) = *((short *) ptr);
		    } else {
			Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		    }
		} else {
		    *((int *) internalPtr) = *((int *) ptr);
		}
		break;
	    case TK_OPTION_COLOR:
		*((XColor **) internalPtr) = *((XColor **) ptr);
		break;
	    case TK_OPTION_FONT:
		*((Tk_Font *) internalPtr) = *((Tk_Font *) ptr);
		break;
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
		*((Tk_Window *) internalPtr) = *((Tk_Window *) ptr);
		break;
	    case TK_OPTION_CUSTOM: {
		const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

		if (custom->restoreProc != NULL) {
		    custom->restoreProc(custom->clientData, savePtr->tkwin,
			    (char *)internalPtr, ptr);
		}
		break;
	    }
	    default:
		Tcl_Panic("bad option type in Tk_RestoreSavedOptions");
	    }
	}







|







1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
		*((Tk_Window *) internalPtr) = *((Tk_Window *) ptr);
		break;
	    case TK_OPTION_CUSTOM: {
		const Tk_ObjCustomOption *custom = optionPtr->extra.custom;

		if (custom->restoreProc != NULL) {
		    custom->restoreProc(custom->clientData, savePtr->tkwin,
			    internalPtr, ptr);
		}
		break;
	    }
	    default:
		Tcl_Panic("bad option type in Tk_RestoreSavedOptions");
	    }
	}
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
 */

void
Tk_FreeSavedOptions(
    Tk_SavedOptions *savePtr)	/* Contains options saved in a previous call
				 * to Tk_SetOptions. */
{
    size_t count;
    Tk_SavedOption *savedOptionPtr;

    if (savePtr->nextPtr != NULL) {
	Tk_FreeSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
    }
    for (count = savePtr->numItems; count > 0; count--) {







|







1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
 */

void
Tk_FreeSavedOptions(
    Tk_SavedOptions *savePtr)	/* Contains options saved in a previous call
				 * to Tk_SetOptions. */
{
    int count;
    Tk_SavedOption *savedOptionPtr;

    if (savePtr->nextPtr != NULL) {
	Tk_FreeSavedOptions(savePtr->nextPtr);
	ckfree(savePtr->nextPtr);
    }
    for (count = savePtr->numItems; count > 0; count--) {
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
 *	options in optionTable are freed.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeConfigOptions(
    void *recordPtr,		/* Record whose fields contain current values
				 * for options. */
    Tk_OptionTable optionTable,	/* Describes legal options. */
    Tk_Window tkwin)		/* Window associated with recordPtr; needed
				 * for freeing some options. */
{
    OptionTable *tablePtr;
    Option *optionPtr;
    size_t count;
    Tcl_Obj **oldPtrPtr, *oldPtr;
    void *oldInternalPtr;
    const Tk_OptionSpec *specPtr;

    for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL;
	    tablePtr = tablePtr->nextPtr) {
	for (optionPtr = tablePtr->options, count = tablePtr->numOptions;
		count > 0; optionPtr++, count--) {
	    specPtr = optionPtr->specPtr;
	    if (specPtr->type == TK_OPTION_SYNONYM) {
		continue;
	    }
	    if (specPtr->objOffset != TCL_INDEX_NONE) {
		oldPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset);
		oldPtr = *oldPtrPtr;
		*oldPtrPtr = NULL;
	    } else {
		oldPtr = NULL;
	    }
	    if (specPtr->internalOffset != TCL_INDEX_NONE) {
		oldInternalPtr = (char *)recordPtr + specPtr->internalOffset;
	    } else {
		oldInternalPtr = NULL;
	    }
	    if (optionPtr->flags & OPTION_NEEDS_FREEING) {
		FreeResources(optionPtr, oldPtr, oldInternalPtr, tkwin);
	    }
	    if (oldPtr != NULL) {







|







|

|










|
|





|
|







1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
 *	options in optionTable are freed.
 *
 *----------------------------------------------------------------------
 */

void
Tk_FreeConfigOptions(
    char *recordPtr,		/* Record whose fields contain current values
				 * for options. */
    Tk_OptionTable optionTable,	/* Describes legal options. */
    Tk_Window tkwin)		/* Window associated with recordPtr; needed
				 * for freeing some options. */
{
    OptionTable *tablePtr;
    Option *optionPtr;
    int count;
    Tcl_Obj **oldPtrPtr, *oldPtr;
    char *oldInternalPtr;
    const Tk_OptionSpec *specPtr;

    for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL;
	    tablePtr = tablePtr->nextPtr) {
	for (optionPtr = tablePtr->options, count = tablePtr->numOptions;
		count > 0; optionPtr++, count--) {
	    specPtr = optionPtr->specPtr;
	    if (specPtr->type == TK_OPTION_SYNONYM) {
		continue;
	    }
	    if (specPtr->objOffset >= 0) {
		oldPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset);
		oldPtr = *oldPtrPtr;
		*oldPtrPtr = NULL;
	    } else {
		oldPtr = NULL;
	    }
	    if (specPtr->internalOffset >= 0) {
		oldInternalPtr = recordPtr + specPtr->internalOffset;
	    } else {
		oldInternalPtr = NULL;
	    }
	    if (optionPtr->flags & OPTION_NEEDS_FREEING) {
		FreeResources(optionPtr, oldPtr, oldInternalPtr, tkwin);
	    }
	    if (oldPtr != NULL) {
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
 */

static void
FreeResources(
    Option *optionPtr,		/* Description of the configuration option. */
    Tcl_Obj *objPtr,		/* The current value of the option, specified
				 * as an object. */
    void *internalPtr,		/* A pointer to an internal representation for
				 * the option's value, such as an int or
				 * (XColor *). Only valid if
				 * optionPtr->specPtr->internalOffset != -1. */
    Tk_Window tkwin)		/* The window in which this option is used. */
{
    int internalFormExists;

    /*
     * If there exists an internal form for the value, use it to free
     * resources (also zero out the internal form). If there is no internal
     * form, then use the object form.
     */

    internalFormExists = optionPtr->specPtr->internalOffset != TCL_INDEX_NONE;
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_STRING:
	if (internalFormExists) {
	    if (*((char **) internalPtr) != NULL) {
		ckfree(*((char **) internalPtr));
		*((char **) internalPtr) = NULL;
	    }







|


|










|







1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
 */

static void
FreeResources(
    Option *optionPtr,		/* Description of the configuration option. */
    Tcl_Obj *objPtr,		/* The current value of the option, specified
				 * as an object. */
    char *internalPtr,		/* A pointer to an internal representation for
				 * the option's value, such as an int or
				 * (XColor *). Only valid if
				 * optionPtr->specPtr->internalOffset >= 0. */
    Tk_Window tkwin)		/* The window in which this option is used. */
{
    int internalFormExists;

    /*
     * If there exists an internal form for the value, use it to free
     * resources (also zero out the internal form). If there is no internal
     * form, then use the object form.
     */

    internalFormExists = optionPtr->specPtr->internalOffset >= 0;
    switch (optionPtr->specPtr->type) {
    case TK_OPTION_STRING:
	if (internalFormExists) {
	    if (*((char **) internalPtr) != NULL) {
		ckfree(*((char **) internalPtr));
		*((char **) internalPtr) = NULL;
	    }
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
	} else if (objPtr != NULL) {
	    Tk_FreeCursorFromObj(tkwin, objPtr);
	}
	break;
    case TK_OPTION_CUSTOM: {
	const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
	if (internalFormExists && custom->freeProc != NULL) {
	    custom->freeProc(custom->clientData, tkwin, (char *)internalPtr);
	}
	break;
    }
    default:
	break;
    }
}







|







1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
	} else if (objPtr != NULL) {
	    Tk_FreeCursorFromObj(tkwin, objPtr);
	}
	break;
    case TK_OPTION_CUSTOM: {
	const Tk_ObjCustomOption *custom = optionPtr->extra.custom;
	if (internalFormExists && custom->freeProc != NULL) {
	    custom->freeProc(custom->clientData, tkwin, internalPtr);
	}
	break;
    }
    default:
	break;
    }
}
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
 *--------------------------------------------------------------
 */

Tcl_Obj *
Tk_GetOptionInfo(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is created. */
    void *recordPtr,		/* Record whose fields contain current values
				 * for options. */
    Tk_OptionTable optionTable,	/* Describes all the legal options. */
    Tcl_Obj *namePtr,		/* If non-NULL, the string value selects a
				 * single option whose info is to be returned.
				 * Otherwise info is returned for all options
				 * in optionTable. */
    Tk_Window tkwin)		/* Window associated with recordPtr; needed to
				 * compute correct default value for some
				 * options. */
{
    Tcl_Obj *resultPtr;
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    size_t count;

    /*
     * If information is only wanted for a single configuration spec, then
     * handle that one spec specially.
     */

    if (namePtr != NULL) {







|













|







1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
 *--------------------------------------------------------------
 */

Tcl_Obj *
Tk_GetOptionInfo(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL,
				 * then no error message is created. */
    char *recordPtr,		/* Record whose fields contain current values
				 * for options. */
    Tk_OptionTable optionTable,	/* Describes all the legal options. */
    Tcl_Obj *namePtr,		/* If non-NULL, the string value selects a
				 * single option whose info is to be returned.
				 * Otherwise info is returned for all options
				 * in optionTable. */
    Tk_Window tkwin)		/* Window associated with recordPtr; needed to
				 * compute correct default value for some
				 * options. */
{
    Tcl_Obj *resultPtr;
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    int count;

    /*
     * If information is only wanted for a single configuration spec, then
     * handle that one spec specially.
     */

    if (namePtr != NULL) {
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
 *	Memory is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
GetConfigList(
    void *recordPtr,		/* Pointer to record holding current values of
				 * configuration options. */
    Option *optionPtr,		/* Pointer to information describing a
				 * particular option. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *listPtr, *elementPtr;








|







1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
 *	Memory is allocated.
 *
 *--------------------------------------------------------------
 */

static Tcl_Obj *
GetConfigList(
    char *recordPtr,		/* Pointer to record holding current values of
				 * configuration options. */
    Option *optionPtr,		/* Pointer to information describing a
				 * particular option. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *listPtr, *elementPtr;

1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
	} else if (optionPtr->defaultPtr != NULL) {
	    elementPtr = optionPtr->defaultPtr;
	} else {
	    elementPtr = Tcl_NewObj();
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if (optionPtr->specPtr->objOffset != TCL_INDEX_NONE) {
	    elementPtr = *((Tcl_Obj **) ((char *)recordPtr
		    + optionPtr->specPtr->objOffset));
	    if (elementPtr == NULL) {
		elementPtr = Tcl_NewObj();
	    }
	} else {
	    elementPtr = GetObjectForOption(recordPtr, optionPtr, tkwin);
	}







|
|







1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
	} else if (optionPtr->defaultPtr != NULL) {
	    elementPtr = optionPtr->defaultPtr;
	} else {
	    elementPtr = Tcl_NewObj();
	}
	Tcl_ListObjAppendElement(NULL, listPtr, elementPtr);

	if (optionPtr->specPtr->objOffset >= 0) {
	    elementPtr = *((Tcl_Obj **) (recordPtr
		    + optionPtr->specPtr->objOffset));
	    if (elementPtr == NULL) {
		elementPtr = Tcl_NewObj();
	    }
	} else {
	    elementPtr = GetObjectForOption(recordPtr, optionPtr, tkwin);
	}
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878


1879
1880
1881
1882
1883
1884
1885
1886
1887
1888













1889
1890

1891

1892
1893
1894
1895
1896
1897
1898
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetObjectForOption(
    void *recordPtr,		/* Pointer to record holding current values of
				 * configuration options. */
    Option *optionPtr,		/* Pointer to information describing an option
				 * whose internal value is stored in
				 * *recordPtr. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *objPtr;
    void *internalPtr;		/* Points to internal value of option in
				 * record. */

    objPtr = NULL;
    if (optionPtr->specPtr->internalOffset != TCL_INDEX_NONE) {
	internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset;
	switch (optionPtr->specPtr->type) {
	case TK_OPTION_BOOLEAN:


	case TK_OPTION_INT:
	    objPtr = Tcl_NewWideIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_DOUBLE:
	    objPtr = Tcl_NewDoubleObj(*((double *) internalPtr));
	    break;
	case TK_OPTION_STRING:
	    objPtr = Tcl_NewStringObj(*((char **)internalPtr), -1);
	    break;
	case TK_OPTION_STRING_TABLE:













	    objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
		    *((int *) internalPtr)], -1);

	    break;

	case TK_OPTION_COLOR: {
	    XColor *colorPtr = *((XColor **)internalPtr);

	    if (colorPtr != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
	    }
	    break;







|






|
|
<

<
|
|


>
>

|


|




|
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>

>







1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903

1904

1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
GetObjectForOption(
    char *recordPtr,		/* Pointer to record holding current values of
				 * configuration options. */
    Option *optionPtr,		/* Pointer to information describing an option
				 * whose internal value is stored in
				 * *recordPtr. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    Tcl_Obj *objPtr = NULL;
    char *internalPtr;		/* Points to internal value of option in record. */



    if (optionPtr->specPtr->internalOffset >= 0) {
	internalPtr = recordPtr + optionPtr->specPtr->internalOffset;
	switch (optionPtr->specPtr->type) {
	case TK_OPTION_BOOLEAN:
	    objPtr = Tcl_NewIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_INT:
	    objPtr = Tcl_NewIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_DOUBLE:
	    objPtr = Tcl_NewDoubleObj(*((double *)internalPtr));
	    break;
	case TK_OPTION_STRING:
	    objPtr = Tcl_NewStringObj(*((char **)internalPtr), -1);
	    break;
	case TK_OPTION_STRING_TABLE: {
	    int value = 0;
	    if (optionPtr->specPtr->flags & TYPE_MASK) {
		if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(char)) {
		    value = *((signed char *)internalPtr);
		} else if ((optionPtr->specPtr->flags & TYPE_MASK) == TYPE_FLAGS(short)) {
		    value = *((short *)internalPtr);
		} else {
		    Tcl_Panic("Invalid flags for %s", "TK_OPTION_STRING_TABLE");
		}
	    } else {
		value = *((int *)internalPtr);
	    }
	    if (value >= 0) {
		objPtr = Tcl_NewStringObj(((char **) optionPtr->specPtr->clientData)[
			value], -1);
	    }
	    break;
	}
	case TK_OPTION_COLOR: {
	    XColor *colorPtr = *((XColor **)internalPtr);

	    if (colorPtr != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOfColor(colorPtr), -1);
	    }
	    break;
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
	    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;







|



















|












|


|









|


|
|







1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
	    break;
	}
	case TK_OPTION_BITMAP: {
	    Pixmap pixmap = *((Pixmap *)internalPtr);

	    if (pixmap != None) {
		objPtr = Tcl_NewStringObj(
			Tk_NameOfBitmap(Tk_Display(tkwin), pixmap), -1);
	    }
	    break;
	}
	case TK_OPTION_BORDER: {
	    Tk_3DBorder border = *((Tk_3DBorder *)internalPtr);

	    if (border != NULL) {
		objPtr = Tcl_NewStringObj(Tk_NameOf3DBorder(border), -1);
	    }
	    break;
	}
	case TK_OPTION_RELIEF:
	    objPtr = Tcl_NewStringObj(Tk_NameOfRelief(*((int *)internalPtr)), -1);
	    break;
	case TK_OPTION_CURSOR: {
	    Tk_Cursor cursor = *((Tk_Cursor *)internalPtr);

	    if (cursor != NULL) {
		objPtr = Tcl_NewStringObj(
			Tk_NameOfCursor(Tk_Display(tkwin), cursor), -1);
	    }
	    break;
	}
	case TK_OPTION_JUSTIFY:
	    objPtr = Tcl_NewStringObj(Tk_NameOfJustify(
		    *((Tk_Justify *)internalPtr)), -1);
	    break;
	case TK_OPTION_ANCHOR:
	    objPtr = Tcl_NewStringObj(Tk_NameOfAnchor(
		    *((Tk_Anchor *)internalPtr)), -1);
	    break;
	case TK_OPTION_PIXELS:
	    objPtr = Tcl_NewIntObj(*((int *)internalPtr));
	    break;
	case TK_OPTION_WINDOW: {
	    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, recordPtr,
		    optionPtr->specPtr->internalOffset);
	    break;
	}
	default:
	    Tcl_Panic("bad option type in GetObjectForOption");
	}
    }
    if (objPtr == NULL) {
	objPtr = Tcl_NewObj();
    }
    return objPtr;
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
 */

Tcl_Obj *
Tk_GetOptionValue(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL
				 * then no messages are provided for
				 * errors. */
    void *recordPtr,		/* Record whose fields contain current values
				 * for options. */
    Tk_OptionTable optionTable,	/* Describes legal options. */
    Tcl_Obj *namePtr,		/* Gives the command-line name for the option
				 * whose value is to be returned. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    Tcl_Obj *resultPtr;

    optionPtr = GetOptionFromObj(interp, namePtr, tablePtr);
    if (optionPtr == NULL) {
	return NULL;
    }
    if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	optionPtr = optionPtr->extra.synonymPtr;
    }
    if (optionPtr->specPtr->objOffset != TCL_INDEX_NONE) {
	resultPtr = *((Tcl_Obj **) ((char *)recordPtr+optionPtr->specPtr->objOffset));
	if (resultPtr == NULL) {
	    /*
	     * This option has a null value and is represented by a null
	     * object pointer. We can't return the null pointer, since that
	     * would indicate an error. Instead, return a new empty object.
	     */








|

















|
|







2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
 */

Tcl_Obj *
Tk_GetOptionValue(
    Tcl_Interp *interp,		/* Interpreter for error reporting. If NULL
				 * then no messages are provided for
				 * errors. */
    char *recordPtr,		/* Record whose fields contain current values
				 * for options. */
    Tk_OptionTable optionTable,	/* Describes legal options. */
    Tcl_Obj *namePtr,		/* Gives the command-line name for the option
				 * whose value is to be returned. */
    Tk_Window tkwin)		/* Window corresponding to recordPtr. */
{
    OptionTable *tablePtr = (OptionTable *) optionTable;
    Option *optionPtr;
    Tcl_Obj *resultPtr;

    optionPtr = GetOptionFromObj(interp, namePtr, tablePtr);
    if (optionPtr == NULL) {
	return NULL;
    }
    if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) {
	optionPtr = optionPtr->extra.synonymPtr;
    }
    if (optionPtr->specPtr->objOffset >= 0) {
	resultPtr = *((Tcl_Obj **) (recordPtr+optionPtr->specPtr->objOffset));
	if (resultPtr == NULL) {
	    /*
	     * This option has a null value and is represented by a null
	     * object pointer. We can't return the null pointer, since that
	     * would indicate an error. Instead, return a new empty object.
	     */

2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103

    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;







|

|







2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150

    for (hashEntryPtr = Tcl_FirstHashEntry(&tsdPtr->hashTable, &search);
	    hashEntryPtr != NULL;
	    hashEntryPtr = Tcl_NextHashEntry(&search)) {
	if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) {
	    for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewIntObj(tablePtr->refCount));
		Tcl_ListObjAppendElement(NULL, objPtr,
			Tcl_NewIntObj(tablePtr->numOptions));
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj(
			tablePtr->options[0].specPtr->optionName, -1));
	    }
	    break;
	}
    }
    return objPtr;
Changes to generic/tkConsole.c.
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 * console.  A refCount permits the struct to be shared as instance data
 * by commands and by channels.
 */

typedef struct ConsoleInfo {
    Tcl_Interp *consoleInterp;	/* Interpreter displaying the console. */
    Tcl_Interp *interp;		/* Interpreter controlled by console. */
    size_t refCount;
} ConsoleInfo;

/*
 * Each console channel holds an instance of the ChannelData struct as
 * its instance data.  It contains ConsoleInfo, so the channel can work
 * with the appropriate console window, and a type value to distinguish
 * the stdout channel from the stderr channel.







|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 * console.  A refCount permits the struct to be shared as instance data
 * by commands and by channels.
 */

typedef struct ConsoleInfo {
    Tcl_Interp *consoleInterp;	/* Interpreter displaying the console. */
    Tcl_Interp *interp;		/* Interpreter controlled by console. */
    int refCount;
} ConsoleInfo;

/*
 * Each console channel holds an instance of the ChannelData struct as
 * its instance data.  It contains ConsoleInfo, so the channel can work
 * with the appropriate console window, and a type value to distinguish
 * the stdout channel from the stderr channel.
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * This structure describes the channel type structure for file based IO:
 */

static const Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */
    TCL_CHANNEL_VERSION_5,	/* v5 channel */
    (Tcl_DriverCloseProc *)ConsoleClose,		/* Close proc. */
    ConsoleInput,		/* Input proc. */
    ConsoleOutput,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    ConsoleWatch,		/* Watch for events on console. */
    ConsoleHandle,		/* Get a handle from the device. */







|







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*
 * This structure describes the channel type structure for file based IO:
 */

static const Tcl_ChannelType consoleChannelType = {
    "console",			/* Type name. */
    TCL_CHANNEL_VERSION_5,	/* v5 channel */
    ConsoleClose,		/* Close proc. */
    ConsoleInput,		/* Input proc. */
    ConsoleOutput,		/* Output proc. */
    NULL,			/* Seek proc. */
    NULL,			/* Set option proc. */
    NULL,			/* Get option proc. */
    ConsoleWatch,		/* Watch for events on console. */
    ConsoleHandle,		/* Get a handle from the device. */
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
    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.







|







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.
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
    if (mainWindow) {
	Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
		ConsoleEventProc, info);
	info->refCount++;
    }

    Tcl_Preserve(consoleInterp);
    result = Tcl_EvalEx(consoleInterp, "source $tk_library/console.tcl",
	    -1, TCL_EVAL_GLOBAL);
    if (result == TCL_ERROR) {
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
    }
    Tcl_Release(consoleInterp);







|







439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
    if (mainWindow) {
	Tk_CreateEventHandler(mainWindow, StructureNotifyMask,
		ConsoleEventProc, info);
	info->refCount++;
    }

    Tcl_Preserve(consoleInterp);
    result = Tcl_EvalEx(consoleInterp, "source -encoding utf-8 $tk_library/console.tcl",
	    -1, TCL_EVAL_GLOBAL);
    if (result == TCL_ERROR) {
	Tcl_SetReturnOptions(interp,
		Tcl_GetReturnOptions(consoleInterp, result));
	Tcl_SetObjResult(interp, Tcl_GetObjResult(consoleInterp));
    }
    Tcl_Release(consoleInterp);
Changes to generic/tkCursor.c.
10
11
12
13
14
15
16




17
18
19
20
21
22
23
 *
 * 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.
 */







>
>
>
>







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * A TkCursor structure exists for each cursor that is currently active. Each
 * structure is indexed with two hash tables defined below. One of the tables
 * is cursorIdTable, and the other is either cursorNameTable or
 * cursorDataTable, each of which are stored in the TkDisplay structure for
 * the current thread.
 */
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
    TkCursor *cursorPtr;
    TkDisplay *dispPtr;

    dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
    printid:
	sprintf(dispPtr->cursorString, "cursor id 0x%" TCL_Z_MODIFIER "x", (size_t)cursor);
	return dispPtr->cursorString;
    }
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, cursor);
    if (idHashPtr == NULL) {
	goto printid;
    }
    cursorPtr = (TkCursor *)Tcl_GetHashValue(idHashPtr);
    if (cursorPtr->otherTable != &dispPtr->cursorNameTable) {
	goto printid;
    }







|


|







425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
    TkCursor *cursorPtr;
    TkDisplay *dispPtr;

    dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
    printid:
	snprintf(dispPtr->cursorString, sizeof(dispPtr->cursorString), "cursor id 0x%" TCL_Z_MODIFIER "x", (size_t)cursor);
	return dispPtr->cursorString;
    }
    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
    if (idHashPtr == NULL) {
	goto printid;
    }
    cursorPtr = (TkCursor *)Tcl_GetHashValue(idHashPtr);
    if (cursorPtr->otherTable != &dispPtr->cursorNameTable) {
	goto printid;
    }
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
	Tcl_Panic("Tk_FreeCursor called before Tk_GetCursor");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, cursor);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeCursor received unknown cursor argument");
    }
    FreeCursor((TkCursor *)Tcl_GetHashValue(idHashPtr));
}

/*







|







517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
    Tcl_HashEntry *idHashPtr;
    TkDisplay *dispPtr = TkGetDisplay(display);

    if (!dispPtr->cursorInit) {
	Tcl_Panic("Tk_FreeCursor called before Tk_GetCursor");
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->cursorIdTable, (char *) cursor);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeCursor received unknown cursor argument");
    }
    FreeCursor((TkCursor *)Tcl_GetHashValue(idHashPtr));
}

/*
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
	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:
 */







|

|













862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
	cursorPtr = (TkCursor *)Tcl_GetHashValue(hashPtr);
	if (cursorPtr == NULL) {
	    Tcl_Panic("TkDebugCursor found empty hash table entry");
	}
	for ( ; (cursorPtr != NULL); cursorPtr = cursorPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(cursorPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(cursorPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
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 (c) 2018 Gregor Cramer.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/*
 * Note that this file will not be included in header files, it is the purpose
Changes to generic/tkDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
 * 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

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif

#if !defined(BUILD_tk)
# define TK_DEPRECATED(msg) EXTERN TCL_DEPRECATED_API(msg)
#elif defined(TK_NO_DEPRECATED)
# define TK_DEPRECATED(msg) MODULE_SCOPE
#else
# define TK_DEPRECATED(msg) EXTERN
#endif

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tk.decls script.
 */

/* !BEGIN!: Do not edit below this line. */





|













<
<
<
<
<
<
<
<







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








20
21
22
23
24
25
26
/*
 * tkDecls.h --
 *
 *	Declarations of functions in the platform independent public Tcl API.
 *
 * Copyright (c) 1998-1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKDECLS
#define _TKDECLS

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif









/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tk.decls script.
 */

/* !BEGIN!: Do not edit below this line. */
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
/* 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,







|







91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/* 17 */
EXTERN void		Tk_CanvasSetStippleOrigin(Tk_Canvas canvas, GC gc);
/* 18 */
EXTERN int		Tk_CanvasTagsParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);
/* 19 */
EXTERN CONST86 char *	Tk_CanvasTagsPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 20 */
EXTERN Tk_Window	Tk_CanvasTkwin(Tk_Canvas canvas);
/* 21 */
EXTERN void		Tk_CanvasWindowCoords(Tk_Canvas canvas, double x,
				double y, short *screenXPtr,
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
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,







|







129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
EXTERN int		Tk_ConfigureValue(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				char *widgRec, const char *argvName,
				int flags);
/* 29 */
EXTERN int		Tk_ConfigureWidget(Tcl_Interp *interp,
				Tk_Window tkwin, const Tk_ConfigSpec *specs,
				int argc, CONST84 char **argv, char *widgRec,
				int flags);
/* 30 */
EXTERN void		Tk_ConfigureWindow(Tk_Window tkwin,
				unsigned int valueMask,
				XWindowChanges *valuePtr);
/* 31 */
EXTERN Tk_TextLayout	Tk_ComputeTextLayout(Tk_Font font, const char *str,
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
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,







|







211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
EXTERN void		Tk_DeleteImage(Tcl_Interp *interp, const char *name);
/* 53 */
EXTERN void		Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection,
				Atom target);
/* 54 */
EXTERN void		Tk_DestroyWindow(Tk_Window tkwin);
/* 55 */
EXTERN CONST84_RETURN char * Tk_DisplayName(Tk_Window tkwin);
/* 56 */
EXTERN int		Tk_DistanceToTextLayout(Tk_TextLayout layout, int x,
				int y);
/* 57 */
EXTERN void		Tk_Draw3DPolygon(Tk_Window tkwin, Drawable drawable,
				Tk_3DBorder border, XPoint *pointPtr,
				int numPoints, int borderWidth,
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
				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,







<
|
















|

|







277
278
279
280
281
282
283

284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
				char *widgRec, Display *display,
				int needFlags);
/* 75 */
EXTERN void		Tk_FreePixmap(Display *display, Pixmap pixmap);
/* 76 */
EXTERN void		Tk_FreeTextLayout(Tk_TextLayout textLayout);
/* 77 */

EXTERN void		Tk_FreeXId(Display *display, XID xid);
/* 78 */
EXTERN GC		Tk_GCForColor(XColor *colorPtr, Drawable drawable);
/* 79 */
EXTERN void		Tk_GeometryRequest(Tk_Window tkwin, int reqWidth,
				int reqHeight);
/* 80 */
EXTERN Tk_3DBorder	Tk_Get3DBorder(Tcl_Interp *interp, Tk_Window tkwin,
				Tk_Uid colorName);
/* 81 */
EXTERN void		Tk_GetAllBindings(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object);
/* 82 */
EXTERN int		Tk_GetAnchor(Tcl_Interp *interp, const char *str,
				Tk_Anchor *anchorPtr);
/* 83 */
EXTERN CONST84_RETURN char * Tk_GetAtomName(Tk_Window tkwin, Atom atom);
/* 84 */
EXTERN CONST84_RETURN char * Tk_GetBinding(Tcl_Interp *interp,
				Tk_BindingTable bindingTable,
				ClientData object, const char *eventStr);
/* 85 */
EXTERN Pixmap		Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str);
/* 86 */
EXTERN Pixmap		Tk_GetBitmapFromData(Tcl_Interp *interp,
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
				XGCValues *valuePtr);
/* 97 */
EXTERN Tk_Image		Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin,
				const char *name,
				Tk_ImageChangedProc *changeProc,
				ClientData clientData);
/* 98 */
EXTERN ClientData	Tk_GetImageModelData(Tcl_Interp *interp,
				const char *name,
				const Tk_ImageType **typePtrPtr);
/* 99 */
EXTERN Tk_ItemType *	Tk_GetItemTypes(void);
/* 100 */
EXTERN int		Tk_GetJoinStyle(Tcl_Interp *interp, const char *str,
				int *joinPtr);
/* 101 */
EXTERN int		Tk_GetJustify(Tcl_Interp *interp, const char *str,







|

|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
				XGCValues *valuePtr);
/* 97 */
EXTERN Tk_Image		Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin,
				const char *name,
				Tk_ImageChangedProc *changeProc,
				ClientData clientData);
/* 98 */
EXTERN ClientData	Tk_GetImageMasterData(Tcl_Interp *interp,
				const char *name,
				CONST86 Tk_ImageType **typePtrPtr);
/* 99 */
EXTERN Tk_ItemType *	Tk_GetItemTypes(void);
/* 100 */
EXTERN int		Tk_GetJoinStyle(Tcl_Interp *interp, const char *str,
				int *joinPtr);
/* 101 */
EXTERN int		Tk_GetJustify(Tcl_Interp *interp, const char *str,
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
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,







|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
EXTERN int		Tk_GetRelief(Tcl_Interp *interp, const char *name,
				int *reliefPtr);
/* 107 */
EXTERN void		Tk_GetRootCoords(Tk_Window tkwin, int *xPtr,
				int *yPtr);
/* 108 */
EXTERN int		Tk_GetScrollInfo(Tcl_Interp *interp, int argc,
				CONST84 char **argv, double *dblPtr,
				int *intPtr);
/* 109 */
EXTERN int		Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin,
				const char *str, double *doublePtr);
/* 110 */
EXTERN int		Tk_GetSelection(Tcl_Interp *interp, Tk_Window tkwin,
				Atom selection, Atom target,
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
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 */







|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
EXTERN int		Tk_Grab(Tcl_Interp *interp, Tk_Window tkwin,
				int grabGlobal);
/* 115 */
EXTERN void		Tk_HandleEvent(XEvent *eventPtr);
/* 116 */
EXTERN Tk_Window	Tk_IdToWindow(Display *display, Window window);
/* 117 */
EXTERN void		Tk_ImageChanged(Tk_ImageMaster model, int x, int y,
				int width, int height, int imageWidth,
				int imageHeight);
/* 118 */
EXTERN int		Tk_Init(Tcl_Interp *interp);
/* 119 */
EXTERN Atom		Tk_InternAtom(Tk_Window tkwin, const char *name);
/* 120 */
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
EXTERN void		Tk_MoveResizeWindow(Tk_Window tkwin, int x, int y,
				int width, int height);
/* 128 */
EXTERN void		Tk_MoveWindow(Tk_Window tkwin, int x, int y);
/* 129 */
EXTERN void		Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y);
/* 130 */
EXTERN const char *	Tk_NameOf3DBorder(Tk_3DBorder border);
/* 131 */
EXTERN const char *	Tk_NameOfAnchor(Tk_Anchor anchor);
/* 132 */
EXTERN const char *	Tk_NameOfBitmap(Display *display, Pixmap bitmap);
/* 133 */
EXTERN const char *	Tk_NameOfCapStyle(int cap);
/* 134 */
EXTERN const char *	Tk_NameOfColor(XColor *colorPtr);
/* 135 */
EXTERN const char *	Tk_NameOfCursor(Display *display, Tk_Cursor cursor);

/* 136 */
EXTERN const char *	Tk_NameOfFont(Tk_Font font);
/* 137 */
EXTERN const char *	Tk_NameOfImage(Tk_ImageModel model);
/* 138 */
EXTERN const char *	Tk_NameOfJoinStyle(int join);
/* 139 */
EXTERN const char *	Tk_NameOfJustify(Tk_Justify justify);
/* 140 */
EXTERN const char *	Tk_NameOfRelief(int relief);
/* 141 */
EXTERN Tk_Window	Tk_NameToWindow(Tcl_Interp *interp,
				const char *pathName, Tk_Window tkwin);
/* 142 */
EXTERN void		Tk_OwnSelection(Tk_Window tkwin, Atom selection,
				Tk_LostSelProc *proc, ClientData clientData);
/* 143 */
EXTERN int		Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin,
				int *argcPtr, const char **argv,
				const Tk_ArgvInfo *argTable, int flags);
/* 144 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height);
/* 145 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoPutZoomedBlock_NoComposite(
				Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int zoomX, int zoomY,
				int subsampleX, int subsampleY);
/* 146 */
EXTERN int		Tk_PhotoGetImage(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr);
/* 147 */
EXTERN void		Tk_PhotoBlank(Tk_PhotoHandle handle);
/* 148 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoExpand_Panic(Tk_PhotoHandle handle,
				int width, int height);
/* 149 */
EXTERN void		Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr,
				int *heightPtr);
/* 150 */
TK_DEPRECATED("function signature changed")
void			Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle,
				int width, int height);
/* 151 */
EXTERN int		Tk_PointToChar(Tk_TextLayout layout, int x, int y);
/* 152 */
EXTERN int		Tk_PostscriptFontName(Tk_Font tkfont,
				Tcl_DString *dsPtr);
/* 153 */







|

|

|

|

|

|
>

|

|

|

|

|








|


<
|



<
|










<
|





<
|







434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473

474
475
476
477

478
479
480
481
482
483
484
485
486
487
488

489
490
491
492
493
494

495
496
497
498
499
500
501
502
EXTERN void		Tk_MoveResizeWindow(Tk_Window tkwin, int x, int y,
				int width, int height);
/* 128 */
EXTERN void		Tk_MoveWindow(Tk_Window tkwin, int x, int y);
/* 129 */
EXTERN void		Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y);
/* 130 */
EXTERN CONST84_RETURN char * Tk_NameOf3DBorder(Tk_3DBorder border);
/* 131 */
EXTERN CONST84_RETURN char * Tk_NameOfAnchor(Tk_Anchor anchor);
/* 132 */
EXTERN CONST84_RETURN char * Tk_NameOfBitmap(Display *display, Pixmap bitmap);
/* 133 */
EXTERN CONST84_RETURN char * Tk_NameOfCapStyle(int cap);
/* 134 */
EXTERN CONST84_RETURN char * Tk_NameOfColor(XColor *colorPtr);
/* 135 */
EXTERN CONST84_RETURN char * Tk_NameOfCursor(Display *display,
				Tk_Cursor cursor);
/* 136 */
EXTERN CONST84_RETURN char * Tk_NameOfFont(Tk_Font font);
/* 137 */
EXTERN CONST84_RETURN char * Tk_NameOfImage(Tk_ImageMaster model);
/* 138 */
EXTERN CONST84_RETURN char * Tk_NameOfJoinStyle(int join);
/* 139 */
EXTERN CONST84_RETURN char * Tk_NameOfJustify(Tk_Justify justify);
/* 140 */
EXTERN CONST84_RETURN char * Tk_NameOfRelief(int relief);
/* 141 */
EXTERN Tk_Window	Tk_NameToWindow(Tcl_Interp *interp,
				const char *pathName, Tk_Window tkwin);
/* 142 */
EXTERN void		Tk_OwnSelection(Tk_Window tkwin, Atom selection,
				Tk_LostSelProc *proc, ClientData clientData);
/* 143 */
EXTERN int		Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin,
				int *argcPtr, CONST84 char **argv,
				const Tk_ArgvInfo *argTable, int flags);
/* 144 */

EXTERN void		Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height);
/* 145 */

EXTERN void		Tk_PhotoPutZoomedBlock_NoComposite(
				Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int zoomX, int zoomY,
				int subsampleX, int subsampleY);
/* 146 */
EXTERN int		Tk_PhotoGetImage(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr);
/* 147 */
EXTERN void		Tk_PhotoBlank(Tk_PhotoHandle handle);
/* 148 */

EXTERN void		Tk_PhotoExpand_Panic(Tk_PhotoHandle handle,
				int width, int height);
/* 149 */
EXTERN void		Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr,
				int *heightPtr);
/* 150 */

EXTERN void		Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle,
				int width, int height);
/* 151 */
EXTERN int		Tk_PointToChar(Tk_TextLayout layout, int x, int y);
/* 152 */
EXTERN int		Tk_PostscriptFontName(Tk_Font tkfont,
				Tcl_DString *dsPtr);
/* 153 */
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
				Tcl_Obj *objPtr);
/* 193 */
EXTERN void		Tk_FreeBitmapFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);
/* 194 */
EXTERN void		Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 195 */
EXTERN void		Tk_FreeConfigOptions(void *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);
/* 196 */
EXTERN void		Tk_FreeSavedOptions(Tk_SavedOptions *savePtr);
/* 197 */
EXTERN void		Tk_FreeCursorFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);
/* 198 */







|







616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
				Tcl_Obj *objPtr);
/* 193 */
EXTERN void		Tk_FreeBitmapFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);
/* 194 */
EXTERN void		Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 195 */
EXTERN void		Tk_FreeConfigOptions(char *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);
/* 196 */
EXTERN void		Tk_FreeSavedOptions(Tk_SavedOptions *savePtr);
/* 197 */
EXTERN void		Tk_FreeCursorFromObj(Tk_Window tkwin,
				Tcl_Obj *objPtr);
/* 198 */
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
/* 201 */
EXTERN Pixmap		Tk_GetBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 202 */
EXTERN XColor *		Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 203 */
EXTERN Tk_Cursor	Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 204 */
EXTERN Tcl_Obj *	Tk_GetOptionInfo(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionTable, Tcl_Obj *namePtr,
				Tk_Window tkwin);
/* 205 */
EXTERN Tcl_Obj *	Tk_GetOptionValue(Tcl_Interp *interp,
				void *recordPtr, Tk_OptionTable optionTable,
				Tcl_Obj *namePtr, Tk_Window tkwin);
/* 206 */
EXTERN int		Tk_GetJustifyFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, Tk_Justify *justifyPtr);
/* 207 */
EXTERN int		Tk_GetMMFromObj(Tcl_Interp *interp, Tk_Window tkwin,
				Tcl_Obj *objPtr, double *doublePtr);
/* 208 */
EXTERN int		Tk_GetPixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				int *intPtr);
/* 209 */
EXTERN int		Tk_GetReliefFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, int *resultPtr);
/* 210 */
EXTERN int		Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[], double *dblPtr,
				int *intPtr);
/* 211 */
EXTERN int		Tk_InitOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);
/* 212 */
EXTERN void		Tk_MainEx(int argc, char **argv,
				Tcl_AppInitProc *appInitProc,
				Tcl_Interp *interp);
/* 213 */
EXTERN void		Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);
/* 214 */
EXTERN int		Tk_SetOptions(Tcl_Interp *interp, void *recordPtr,
				Tk_OptionTable optionTable, int objc,
				Tcl_Obj *const objv[], Tk_Window tkwin,
				Tk_SavedOptions *savePtr, int *maskPtr);
/* 215 */
EXTERN void		Tk_InitConsoleChannels(Tcl_Interp *interp);
/* 216 */
EXTERN int		Tk_CreateConsoleWindow(Tcl_Interp *interp);







|




|



















|








|







638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
/* 201 */
EXTERN Pixmap		Tk_GetBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 202 */
EXTERN XColor *		Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 203 */
EXTERN Tk_Cursor	Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr);
/* 204 */
EXTERN Tcl_Obj *	Tk_GetOptionInfo(Tcl_Interp *interp, char *recordPtr,
				Tk_OptionTable optionTable, Tcl_Obj *namePtr,
				Tk_Window tkwin);
/* 205 */
EXTERN Tcl_Obj *	Tk_GetOptionValue(Tcl_Interp *interp,
				char *recordPtr, Tk_OptionTable optionTable,
				Tcl_Obj *namePtr, Tk_Window tkwin);
/* 206 */
EXTERN int		Tk_GetJustifyFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, Tk_Justify *justifyPtr);
/* 207 */
EXTERN int		Tk_GetMMFromObj(Tcl_Interp *interp, Tk_Window tkwin,
				Tcl_Obj *objPtr, double *doublePtr);
/* 208 */
EXTERN int		Tk_GetPixelsFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				int *intPtr);
/* 209 */
EXTERN int		Tk_GetReliefFromObj(Tcl_Interp *interp,
				Tcl_Obj *objPtr, int *resultPtr);
/* 210 */
EXTERN int		Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc,
				Tcl_Obj *const objv[], double *dblPtr,
				int *intPtr);
/* 211 */
EXTERN int		Tk_InitOptions(Tcl_Interp *interp, char *recordPtr,
				Tk_OptionTable optionToken, Tk_Window tkwin);
/* 212 */
EXTERN void		Tk_MainEx(int argc, char **argv,
				Tcl_AppInitProc *appInitProc,
				Tcl_Interp *interp);
/* 213 */
EXTERN void		Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr);
/* 214 */
EXTERN int		Tk_SetOptions(Tcl_Interp *interp, char *recordPtr,
				Tk_OptionTable optionTable, int objc,
				Tcl_Obj *const objv[], Tk_Window tkwin,
				Tk_SavedOptions *savePtr, int *maskPtr);
/* 215 */
EXTERN void		Tk_InitConsoleChannels(Tcl_Interp *interp);
/* 216 */
EXTERN int		Tk_CreateConsoleWindow(Tcl_Interp *interp);
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
/* 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 */







<
|



<
|







772
773
774
775
776
777
778

779
780
781
782

783
784
785
786
787
788
789
790
/* 244 */
EXTERN void		Tk_SetMinimumRequestSize(Tk_Window tkwin,
				int minWidth, int minHeight);
/* 245 */
EXTERN void		Tk_SetCaretPos(Tk_Window tkwin, int x, int y,
				int height);
/* 246 */

EXTERN void		Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int compRule);
/* 247 */

EXTERN void		Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle,
				Tk_PhotoImageBlock *blockPtr, int x, int y,
				int width, int height, int zoomX, int zoomY,
				int subsampleX, int subsampleY, int compRule);
/* 248 */
EXTERN int		Tk_CollapseMotionEvents(Display *display,
				int collapse);
/* 249 */
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
/* 259 */
EXTERN void		Tk_FreeStyleFromObj(Tcl_Obj *objPtr);
/* 260 */
EXTERN Tk_StyledElement	 Tk_GetStyledElement(Tk_Style style, int elementId,
				Tk_OptionTable optionTable);
/* 261 */
EXTERN void		Tk_GetElementSize(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, int width, int height,
				int inner, int *widthPtr, int *heightPtr);
/* 262 */
EXTERN void		Tk_GetElementBox(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, int x, int y, int width,
				int height, int inner, int *xPtr, int *yPtr,
				int *widthPtr, int *heightPtr);
/* 263 */
EXTERN int		Tk_GetElementBorderWidth(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin);
/* 264 */
EXTERN void		Tk_DrawElement(Tk_Style style,
				Tk_StyledElement element, void *recordPtr,
				Tk_Window tkwin, Drawable d, int x, int y,
				int width, int height, int state);
/* 265 */
EXTERN int		Tk_PhotoExpand(Tcl_Interp *interp,
				Tk_PhotoHandle handle, int width, int height);
/* 266 */
EXTERN int		Tk_PhotoPutBlock(Tcl_Interp *interp,







|




|





|



|







814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
/* 259 */
EXTERN void		Tk_FreeStyleFromObj(Tcl_Obj *objPtr);
/* 260 */
EXTERN Tk_StyledElement	 Tk_GetStyledElement(Tk_Style style, int elementId,
				Tk_OptionTable optionTable);
/* 261 */
EXTERN void		Tk_GetElementSize(Tk_Style style,
				Tk_StyledElement element, char *recordPtr,
				Tk_Window tkwin, int width, int height,
				int inner, int *widthPtr, int *heightPtr);
/* 262 */
EXTERN void		Tk_GetElementBox(Tk_Style style,
				Tk_StyledElement element, char *recordPtr,
				Tk_Window tkwin, int x, int y, int width,
				int height, int inner, int *xPtr, int *yPtr,
				int *widthPtr, int *heightPtr);
/* 263 */
EXTERN int		Tk_GetElementBorderWidth(Tk_Style style,
				Tk_StyledElement element, char *recordPtr,
				Tk_Window tkwin);
/* 264 */
EXTERN void		Tk_DrawElement(Tk_Style style,
				Tk_StyledElement element, char *recordPtr,
				Tk_Window tkwin, Drawable d, int x, int y,
				int width, int height, int state);
/* 265 */
EXTERN int		Tk_PhotoExpand(Tcl_Interp *interp,
				Tk_PhotoHandle handle, int width, int height);
/* 266 */
EXTERN int		Tk_PhotoPutBlock(Tcl_Interp *interp,
874
875
876
877
878
879
880
881
882
883
884
885


886
887
888
889
890
891
892
893



894
895
896
897
898
899
900
901
902
/* 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;







|
<
|
<
|
>
>
|
|
|
|
|
|
|
|
>
>
>
|
|







860
861
862
863
864
865
866
867

868

869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
/* 271 */
EXTERN Tcl_Interp *	Tk_Interp(Tk_Window tkwin);
/* 272 */
EXTERN void		Tk_CreateOldImageType(const Tk_ImageType *typePtr);
/* 273 */
EXTERN void		Tk_CreateOldPhotoImageFormat(
				const Tk_PhotoImageFormat *formatPtr);
/* Slot 274 is reserved */

/* Slot 275 is reserved */

/* Slot 276 is reserved */
/* Slot 277 is reserved */
/* Slot 278 is reserved */
/* Slot 279 is reserved */
/* Slot 280 is reserved */
/* Slot 281 is reserved */
/* Slot 282 is reserved */
/* Slot 283 is reserved */
/* Slot 284 is reserved */
/* Slot 285 is reserved */
/* Slot 286 is reserved */
/* Slot 287 is reserved */
/* Slot 288 is reserved */
/* Slot 289 is reserved */
/* 290 */
EXTERN void		TkUnusedStubEntry(void);

typedef struct {
    const struct TkPlatStubs *tkPlatStubs;
    const struct TkIntStubs *tkIntStubs;
    const struct TkIntPlatStubs *tkIntPlatStubs;
    const struct TkIntXlibStubs *tkIntXlibStubs;
} TkStubHooks;
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
    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 */







|









|







909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
    int (*tk_CanvasPsColor) (Tcl_Interp *interp, Tk_Canvas canvas, XColor *colorPtr); /* 12 */
    int (*tk_CanvasPsFont) (Tcl_Interp *interp, Tk_Canvas canvas, Tk_Font font); /* 13 */
    void (*tk_CanvasPsPath) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints); /* 14 */
    int (*tk_CanvasPsStipple) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap); /* 15 */
    double (*tk_CanvasPsY) (Tk_Canvas canvas, double y); /* 16 */
    void (*tk_CanvasSetStippleOrigin) (Tk_Canvas canvas, GC gc); /* 17 */
    int (*tk_CanvasTagsParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 18 */
    CONST86 char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */
    Tk_Window (*tk_CanvasTkwin) (Tk_Canvas canvas); /* 20 */
    void (*tk_CanvasWindowCoords) (Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); /* 21 */
    void (*tk_ChangeWindowAttributes) (Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); /* 22 */
    int (*tk_CharBbox) (Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 23 */
    void (*tk_ClearSelection) (Tk_Window tkwin, Atom selection); /* 24 */
    int (*tk_ClipboardAppend) (Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, const char *buffer); /* 25 */
    int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */
    int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 27 */
    int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 28 */
    int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags); /* 29 */
    void (*tk_ConfigureWindow) (Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); /* 30 */
    Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, const char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */
    Tk_Window (*tk_CoordsToWindow) (int rootX, int rootY, Tk_Window tkwin); /* 32 */
    unsigned long (*tk_CreateBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr, const char *script, int append); /* 33 */
    Tk_BindingTable (*tk_CreateBindingTable) (Tcl_Interp *interp); /* 34 */
    Tk_ErrorHandler (*tk_CreateErrorHandler) (Display *display, int errNum, int request, int minorCode, Tk_ErrorProc *errorProc, ClientData clientData); /* 35 */
    void (*tk_CreateEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 36 */
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
    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 */







|







945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
    void (*tk_DeleteBindingTable) (Tk_BindingTable bindingTable); /* 48 */
    void (*tk_DeleteErrorHandler) (Tk_ErrorHandler handler); /* 49 */
    void (*tk_DeleteEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 50 */
    void (*tk_DeleteGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 51 */
    void (*tk_DeleteImage) (Tcl_Interp *interp, const char *name); /* 52 */
    void (*tk_DeleteSelHandler) (Tk_Window tkwin, Atom selection, Atom target); /* 53 */
    void (*tk_DestroyWindow) (Tk_Window tkwin); /* 54 */
    CONST84_RETURN char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */
    int (*tk_DistanceToTextLayout) (Tk_TextLayout layout, int x, int y); /* 56 */
    void (*tk_Draw3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 57 */
    void (*tk_Draw3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 58 */
    void (*tk_DrawChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, int x, int y); /* 59 */
    void (*tk_DrawFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable); /* 60 */
    void (*tk_DrawTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, int firstChar, int lastChar); /* 61 */
    void (*tk_Fill3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 62 */
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
    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 */







|





|
|













|









|








|












|
|
|
|
|
|
|
|
|
|
|


|
|
|


|

|







967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
    void (*tk_FreeCursor) (Display *display, Tk_Cursor cursor); /* 70 */
    void (*tk_FreeFont) (Tk_Font f); /* 71 */
    void (*tk_FreeGC) (Display *display, GC gc); /* 72 */
    void (*tk_FreeImage) (Tk_Image image); /* 73 */
    void (*tk_FreeOptions) (const Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */
    void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */
    void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */
    void (*tk_FreeXId) (Display *display, XID xid); /* 77 */
    GC (*tk_GCForColor) (XColor *colorPtr, Drawable drawable); /* 78 */
    void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */
    Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */
    void (*tk_GetAllBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object); /* 81 */
    int (*tk_GetAnchor) (Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); /* 82 */
    CONST84_RETURN char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */
    CONST84_RETURN char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 84 */
    Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 85 */
    Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, const 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_GetImageMasterData) (Tcl_Interp *interp, const char *name, CONST86 Tk_ImageType **typePtrPtr); /* 98 */
    Tk_ItemType * (*tk_GetItemTypes) (void); /* 99 */
    int (*tk_GetJoinStyle) (Tcl_Interp *interp, const char *str, int *joinPtr); /* 100 */
    int (*tk_GetJustify) (Tcl_Interp *interp, const char *str, Tk_Justify *justifyPtr); /* 101 */
    int (*tk_GetNumMainWindows) (void); /* 102 */
    Tk_Uid (*tk_GetOption) (Tk_Window tkwin, const char *name, const char *className); /* 103 */
    int (*tk_GetPixels) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *intPtr); /* 104 */
    Pixmap (*tk_GetPixmap) (Display *display, Drawable d, int width, int height, int depth); /* 105 */
    int (*tk_GetRelief) (Tcl_Interp *interp, const char *name, int *reliefPtr); /* 106 */
    void (*tk_GetRootCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 107 */
    int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, CONST84 char **argv, double *dblPtr, int *intPtr); /* 108 */
    int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr); /* 109 */
    int (*tk_GetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 110 */
    Tk_Uid (*tk_GetUid) (const char *str); /* 111 */
    Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */
    void (*tk_GetVRootGeometry) (Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 113 */
    int (*tk_Grab) (Tcl_Interp *interp, Tk_Window tkwin, int grabGlobal); /* 114 */
    void (*tk_HandleEvent) (XEvent *eventPtr); /* 115 */
    Tk_Window (*tk_IdToWindow) (Display *display, Window window); /* 116 */
    void (*tk_ImageChanged) (Tk_ImageMaster 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 */
    CONST84_RETURN char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */
    CONST84_RETURN char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */
    CONST84_RETURN char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */
    CONST84_RETURN char * (*tk_NameOfCapStyle) (int cap); /* 133 */
    CONST84_RETURN char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */
    CONST84_RETURN char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */
    CONST84_RETURN char * (*tk_NameOfFont) (Tk_Font font); /* 136 */
    CONST84_RETURN char * (*tk_NameOfImage) (Tk_ImageMaster model); /* 137 */
    CONST84_RETURN char * (*tk_NameOfJoinStyle) (int join); /* 138 */
    CONST84_RETURN char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */
    CONST84_RETURN char * (*tk_NameOfRelief) (int relief); /* 140 */
    Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */
    void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */
    int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */
    void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */
    void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */
    int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */
    void (*tk_PhotoBlank) (Tk_PhotoHandle handle); /* 147 */
    void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */
    void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */
    void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */
    int (*tk_PointToChar) (Tk_TextLayout layout, int x, int y); /* 151 */
    int (*tk_PostscriptFontName) (Tk_Font tkfont, Tcl_DString *dsPtr); /* 152 */
    void (*tk_PreserveColormap) (Display *display, Colormap colormap); /* 153 */
    void (*tk_QueueWindowEvent) (XEvent *eventPtr, Tcl_QueuePosition position); /* 154 */
    void (*tk_RedrawImage) (Tk_Image image, int imageX, int imageY, int width, int height, Drawable drawable, int drawableX, int drawableY); /* 155 */
    void (*tk_ResizeWindow) (Tk_Window tkwin, int width, int height); /* 156 */
    int (*tk_RestackWindow) (Tk_Window tkwin, int aboveBelow, Tk_Window other); /* 157 */
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
    Tk_Cursor (*tk_AllocCursorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 188 */
    Tk_Font (*tk_AllocFontFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 189 */
    Tk_OptionTable (*tk_CreateOptionTable) (Tcl_Interp *interp, const Tk_OptionSpec *templatePtr); /* 190 */
    void (*tk_DeleteOptionTable) (Tk_OptionTable optionTable); /* 191 */
    void (*tk_Free3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 192 */
    void (*tk_FreeBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 193 */
    void (*tk_FreeColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 194 */
    void (*tk_FreeConfigOptions) (void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 195 */
    void (*tk_FreeSavedOptions) (Tk_SavedOptions *savePtr); /* 196 */
    void (*tk_FreeCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 197 */
    void (*tk_FreeFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 198 */
    Tk_3DBorder (*tk_Get3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 199 */
    int (*tk_GetAnchorFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Anchor *anchorPtr); /* 200 */
    Pixmap (*tk_GetBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 201 */
    XColor * (*tk_GetColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 202 */
    Tk_Cursor (*tk_GetCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */
    Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
    Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
    int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
    int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
    int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
    int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
    int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */
    int (*tk_InitOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
    TCL_DEPRECATED_API("Don't use this function in a stub-enabled extension") void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */
    void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
    int (*tk_SetOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
    void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
    int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */
    void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */
    void (*reserved218)(void);
    void (*reserved219)(void);
    int (*tk_GetDash) (Tcl_Interp *interp, const char *value, Tk_Dash *dash); /* 220 */
    void (*tk_CreateOutline) (Tk_Outline *outline); /* 221 */







|








|
|





|
|

|







1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
    Tk_Cursor (*tk_AllocCursorFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 188 */
    Tk_Font (*tk_AllocFontFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr); /* 189 */
    Tk_OptionTable (*tk_CreateOptionTable) (Tcl_Interp *interp, const Tk_OptionSpec *templatePtr); /* 190 */
    void (*tk_DeleteOptionTable) (Tk_OptionTable optionTable); /* 191 */
    void (*tk_Free3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 192 */
    void (*tk_FreeBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 193 */
    void (*tk_FreeColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 194 */
    void (*tk_FreeConfigOptions) (char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 195 */
    void (*tk_FreeSavedOptions) (Tk_SavedOptions *savePtr); /* 196 */
    void (*tk_FreeCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 197 */
    void (*tk_FreeFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 198 */
    Tk_3DBorder (*tk_Get3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 199 */
    int (*tk_GetAnchorFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Anchor *anchorPtr); /* 200 */
    Pixmap (*tk_GetBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 201 */
    XColor * (*tk_GetColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 202 */
    Tk_Cursor (*tk_GetCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */
    Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */
    Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */
    int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */
    int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */
    int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */
    int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */
    int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */
    int (*tk_InitOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */
    void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */
    void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */
    int (*tk_SetOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */
    void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */
    int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */
    void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */
    void (*reserved218)(void);
    void (*reserved219)(void);
    int (*tk_GetDash) (Tcl_Interp *interp, const char *value, Tk_Dash *dash); /* 220 */
    void (*tk_CreateOutline) (Tk_Outline *outline); /* 221 */
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186











1187
1188
1189
1190
1191
1192
1193
1194
    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







|
|













|
|
|
|









|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
|







1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
    void (*tk_CreateClientMessageHandler) (Tk_ClientMessageProc *proc); /* 239 */
    void (*tk_DeleteClientMessageHandler) (Tk_ClientMessageProc *proc); /* 240 */
    Tk_Window (*tk_CreateAnonymousWindow) (Tcl_Interp *interp, Tk_Window parent, const char *screenName); /* 241 */
    void (*tk_SetClassProcs) (Tk_Window tkwin, const Tk_ClassProcs *procs, ClientData instanceData); /* 242 */
    void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */
    void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */
    void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */
    void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */
    void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */
    int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */
    Tk_StyleEngine (*tk_RegisterStyleEngine) (const char *name, Tk_StyleEngine parent); /* 249 */
    Tk_StyleEngine (*tk_GetStyleEngine) (const char *name); /* 250 */
    int (*tk_RegisterStyledElement) (Tk_StyleEngine engine, Tk_ElementSpec *templatePtr); /* 251 */
    int (*tk_GetElementId) (const char *name); /* 252 */
    Tk_Style (*tk_CreateStyle) (const char *name, Tk_StyleEngine engine, ClientData clientData); /* 253 */
    Tk_Style (*tk_GetStyle) (Tcl_Interp *interp, const char *name); /* 254 */
    void (*tk_FreeStyle) (Tk_Style style); /* 255 */
    const char * (*tk_NameOfStyle) (Tk_Style style); /* 256 */
    Tk_Style (*tk_AllocStyleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 257 */
    Tk_Style (*tk_GetStyleFromObj) (Tcl_Obj *objPtr); /* 258 */
    void (*tk_FreeStyleFromObj) (Tcl_Obj *objPtr); /* 259 */
    Tk_StyledElement (*tk_GetStyledElement) (Tk_Style style, int elementId, Tk_OptionTable optionTable); /* 260 */
    void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */
    void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */
    int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin); /* 263 */
    void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */
    int (*tk_PhotoExpand) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 265 */
    int (*tk_PhotoPutBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 266 */
    int (*tk_PhotoPutZoomedBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 267 */
    int (*tk_PhotoSetSize) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 268 */
    long (*tk_GetUserInactiveTime) (Display *dpy); /* 269 */
    void (*tk_ResetUserInactiveTime) (Display *dpy); /* 270 */
    Tcl_Interp * (*tk_Interp) (Tk_Window tkwin); /* 271 */
    void (*tk_CreateOldImageType) (const Tk_ImageType *typePtr); /* 272 */
    void (*tk_CreateOldPhotoImageFormat) (const Tk_PhotoImageFormat *formatPtr); /* 273 */
    void (*reserved274)(void);
    void (*reserved275)(void);
    void (*reserved276)(void);
    void (*reserved277)(void);
    void (*reserved278)(void);
    void (*reserved279)(void);
    void (*reserved280)(void);
    void (*reserved281)(void);
    void (*reserved282)(void);
    void (*reserved283)(void);
    void (*reserved284)(void);
    void (*reserved285)(void);
    void (*reserved286)(void);
    void (*reserved287)(void);
    void (*reserved288)(void);
    void (*reserved289)(void);
    void (*tkUnusedStubEntry) (void); /* 290 */
} TkStubs;

extern const TkStubs *tkStubsPtr;

#ifdef __cplusplus
}
#endif
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
	(tkStubsPtr->tk_GetFontFromObj) /* 94 */
#define Tk_GetFontMetrics \
	(tkStubsPtr->tk_GetFontMetrics) /* 95 */
#define Tk_GetGC \
	(tkStubsPtr->tk_GetGC) /* 96 */
#define Tk_GetImage \
	(tkStubsPtr->tk_GetImage) /* 97 */
#define Tk_GetImageModelData \
	(tkStubsPtr->tk_GetImageModelData) /* 98 */
#define Tk_GetItemTypes \
	(tkStubsPtr->tk_GetItemTypes) /* 99 */
#define Tk_GetJoinStyle \
	(tkStubsPtr->tk_GetJoinStyle) /* 100 */
#define Tk_GetJustify \
	(tkStubsPtr->tk_GetJustify) /* 101 */
#define Tk_GetNumMainWindows \







|
|







1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
	(tkStubsPtr->tk_GetFontFromObj) /* 94 */
#define Tk_GetFontMetrics \
	(tkStubsPtr->tk_GetFontMetrics) /* 95 */
#define Tk_GetGC \
	(tkStubsPtr->tk_GetGC) /* 96 */
#define Tk_GetImage \
	(tkStubsPtr->tk_GetImage) /* 97 */
#define Tk_GetImageMasterData \
	(tkStubsPtr->tk_GetImageMasterData) /* 98 */
#define Tk_GetItemTypes \
	(tkStubsPtr->tk_GetItemTypes) /* 99 */
#define Tk_GetJoinStyle \
	(tkStubsPtr->tk_GetJoinStyle) /* 100 */
#define Tk_GetJustify \
	(tkStubsPtr->tk_GetJustify) /* 101 */
#define Tk_GetNumMainWindows \
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757






1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798


1799
	(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 */







|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
|
|










<
<
<
<
<
<
<
|






|
|
<
<
<
<
<
<
<
<
<




>
>

1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775







1776
1777
1778
1779
1780
1781
1782
1783
1784









1785
1786
1787
1788
1789
1790
1791
	(tkStubsPtr->tk_ResetUserInactiveTime) /* 270 */
#define Tk_Interp \
	(tkStubsPtr->tk_Interp) /* 271 */
#define Tk_CreateOldImageType \
	(tkStubsPtr->tk_CreateOldImageType) /* 272 */
#define Tk_CreateOldPhotoImageFormat \
	(tkStubsPtr->tk_CreateOldPhotoImageFormat) /* 273 */
/* Slot 274 is reserved */
/* Slot 275 is reserved */
/* Slot 276 is reserved */
/* Slot 277 is reserved */
/* Slot 278 is reserved */
/* Slot 279 is reserved */
/* Slot 280 is reserved */
/* Slot 281 is reserved */
/* Slot 282 is reserved */
/* Slot 283 is reserved */
/* Slot 284 is reserved */
/* Slot 285 is reserved */
/* Slot 286 is reserved */
/* Slot 287 is reserved */
/* Slot 288 is reserved */
/* Slot 289 is reserved */
#define TkUnusedStubEntry \
	(tkStubsPtr->tkUnusedStubEntry) /* 290 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

/* Functions that don't belong in the stub table */
#undef Tk_MainEx
#undef Tk_Init
#undef Tk_SafeInit
#undef Tk_CreateConsoleWindow







#define Tk_GetImageModelData Tk_GetImageMasterData

#if defined(_WIN32) && defined(UNICODE)
#   define Tk_MainEx Tk_MainExW
    EXTERN void Tk_MainExW(int argc, wchar_t **argv,
	    Tcl_AppInitProc *appInitProc, Tcl_Interp *interp);
#endif
#undef Tk_FreeStyleFromObj
#define Tk_FreeStyleFromObj(objPtr) ((void)(objPtr))










#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkUnusedStubEntry

#endif /* _TKDECLS */
Changes to generic/tkEntry.c.
15
16
17
18
19
20
21




22
23
24
25
26
27
28
 * 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
#define YPAD 1







>
>
>
>







15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkEntry.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following macro defines how many extra pixels to leave on each side of
 * the text in the entry.
 */

#define XPAD 1
#define YPAD 1
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174

/*
 * Information used for Entry objv parsing.
 */

static const Tk_OptionSpec entryOptSpec[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_ENTRY_BG_COLOR, TCL_INDEX_NONE, offsetof(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, TCL_INDEX_NONE, offsetof(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, TCL_INDEX_NONE, offsetof(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
        offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, selBorderWidth),
	0, DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Entry, selFgColorPtr),
	TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-show", "show", "Show",
	DEF_ENTRY_SHOW, TCL_INDEX_NONE, offsetof(Entry, showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, TCL_INDEX_NONE, offsetof(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Entry, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_ENTRY_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Entry, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	DEF_ENTRY_VALIDATE, TCL_INDEX_NONE, offsetof(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, TCL_INDEX_NONE, offsetof(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * Information used for Spinbox objv parsing.
 */

#define DEF_SPINBOX_REPEAT_DELAY	"400"







|


|

|

|

|


|
|
|

|
|

|
|

|

|

|


|

|

|
|

|

|
|
|

|


|

|

|


|

|
<
<
<
<
<
<

|
|
|

|

|


|
|


|


|


|


|


|


|


|

|

|

|

|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124






125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172

/*
 * Information used for Entry objv parsing.
 */

static const Tk_OptionSpec entryOptSpec[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
	Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
	Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
	Tk_Offset(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	-1, Tk_Offset(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, -1, Tk_Offset(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1,
	Tk_Offset(Entry, insertBorderWidth), 0,
	DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, -1, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0},






    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
	Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
	Tk_Offset(Entry, selBorderWidth),
	0, DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
	TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-show", "show", "Show",
	DEF_ENTRY_SHOW, -1, Tk_Offset(Entry, showChar),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, -1, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * Information used for Spinbox objv parsing.
 */

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

#define DEF_SPINBOX_VALUES		""
#define DEF_SPINBOX_WRAP		"0"

static const Tk_OptionSpec sbOptSpec[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background",
	DEF_BUTTON_ACTIVE_BG_COLOR, TCL_INDEX_NONE, offsetof(Spinbox, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_ENTRY_BG_COLOR, TCL_INDEX_NONE, offsetof(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-buttonbackground", "buttonBackground", "Background",
	DEF_BUTTON_BG_COLOR, TCL_INDEX_NONE, offsetof(Spinbox, buttonBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_CURSOR, "-buttoncursor", "buttonCursor", "Cursor",
	DEF_BUTTON_CURSOR, TCL_INDEX_NONE, offsetof(Spinbox, bCursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-buttondownrelief", "buttonDownRelief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(Spinbox, bdRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-buttonuprelief", "buttonUpRelief", "Relief",
	DEF_BUTTON_RELIEF, TCL_INDEX_NONE, offsetof(Spinbox, buRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_SPINBOX_CMD, TCL_INDEX_NONE, offsetof(Spinbox, command),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, TCL_INDEX_NONE, offsetof(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, disabledBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, TCL_INDEX_NONE,
	offsetof(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, TCL_INDEX_NONE,
	offsetof(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, TCL_INDEX_NONE, offsetof(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, TCL_INDEX_NONE, offsetof(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_STRING, "-format", "format", "Format",
	DEF_SPINBOX_FORMAT, TCL_INDEX_NONE, offsetof(Spinbox, reqFormat),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From",
	DEF_SPINBOX_FROM, TCL_INDEX_NONE, offsetof(Spinbox, fromValue), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	TCL_INDEX_NONE, offsetof(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	DEF_SPINBOX_INCREMENT, TCL_INDEX_NONE, offsetof(Spinbox, increment), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, TCL_INDEX_NONE, offsetof(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, insertBorderWidth), 0,
	(ClientData) DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, TCL_INDEX_NONE, offsetof(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, TCL_INDEX_NONE, offsetof(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, TCL_INDEX_NONE, offsetof(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, TCL_INDEX_NONE, offsetof(Entry, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder",
	DEF_ENTRY_PLACEHOLDER, TCL_INDEX_NONE, offsetof(Entry, placeholderString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground",
        "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, TCL_INDEX_NONE,
        offsetof(Entry, placeholderColorPtr), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, TCL_INDEX_NONE, offsetof(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	(ClientData) DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SPINBOX_REPEAT_DELAY, TCL_INDEX_NONE, offsetof(Spinbox, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SPINBOX_REPEAT_INTERVAL, TCL_INDEX_NONE, offsetof(Spinbox, repeatInterval),
	0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, TCL_INDEX_NONE,
	offsetof(Entry, selBorderWidth),
	0, DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Entry, selFgColorPtr),
	TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, TCL_INDEX_NONE, offsetof(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Entry, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_ENTRY_TEXT_VARIABLE, TCL_INDEX_NONE, offsetof(Entry, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	DEF_SPINBOX_TO, TCL_INDEX_NONE, offsetof(Spinbox, toValue), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	DEF_ENTRY_VALIDATE, TCL_INDEX_NONE, offsetof(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, TCL_INDEX_NONE, offsetof(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-values", "values", "Values",
	DEF_SPINBOX_VALUES, TCL_INDEX_NONE, offsetof(Spinbox, valueStr),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, TCL_INDEX_NONE, offsetof(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
	DEF_SPINBOX_WRAP, TCL_INDEX_NONE, offsetof(Spinbox, wrap), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * The following tables define the entry widget commands (and sub-commands)
 * and map the indexes into the string tables into enumerated types used to
 * dispatch the entry widget command.
 */







|


|


|

|

|

|


|


|

|

|


|


|
|
|

|
|

|
|

|

|

|

|


|


|

|

|
|

|

|

|
|
|

|


|

|

|


|

|
<
<
<
<
<
<

|

|
|
|

|


|


|


|
|


|


|


|


|


|

|


|

|


|

|

|

|

|







180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264






265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#define DEF_SPINBOX_FORMAT		""

#define DEF_SPINBOX_VALUES		""
#define DEF_SPINBOX_WRAP		"0"

static const Tk_OptionSpec sbOptSpec[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Background",
	DEF_BUTTON_ACTIVE_BG_COLOR, -1, Tk_Offset(Spinbox, activeBorder),
	0, DEF_BUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_ENTRY_BG_COLOR, -1, Tk_Offset(Entry, normalBorder),
	0, DEF_ENTRY_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_ENTRY_BORDER_WIDTH, -1, Tk_Offset(Entry, borderWidth), 0, 0, 0},
    {TK_OPTION_BORDER, "-buttonbackground", "buttonBackground", "Background",
	DEF_BUTTON_BG_COLOR, -1, Tk_Offset(Spinbox, buttonBorder),
	0, DEF_BUTTON_BG_MONO, 0},
    {TK_OPTION_CURSOR, "-buttoncursor", "buttonCursor", "Cursor",
	DEF_BUTTON_CURSOR, -1, Tk_Offset(Spinbox, bCursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-buttondownrelief", "buttonDownRelief", "Relief",
	DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, bdRelief), 0, 0, 0},
    {TK_OPTION_RELIEF, "-buttonuprelief", "buttonUpRelief", "Relief",
	DEF_BUTTON_RELIEF, -1, Tk_Offset(Spinbox, buRelief), 0, 0, 0},
    {TK_OPTION_STRING, "-command", "command", "Command",
	DEF_SPINBOX_CMD, -1, Tk_Offset(Spinbox, command),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_ENTRY_CURSOR, -1, Tk_Offset(Entry, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BORDER, "-disabledbackground", "disabledBackground",
	"DisabledBackground", DEF_ENTRY_DISABLED_BG_COLOR, -1,
	Tk_Offset(Entry, disabledBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_DISABLED_BG_MONO, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_ENTRY_DISABLED_FG, -1,
	Tk_Offset(Entry, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	"ExportSelection", DEF_ENTRY_EXPORT_SELECTION, -1,
	Tk_Offset(Entry, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_ENTRY_FONT, -1, Tk_Offset(Entry, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_ENTRY_FG, -1, Tk_Offset(Entry, fgColorPtr), 0, 0, 0},
    {TK_OPTION_STRING, "-format", "format", "Format",
	DEF_SPINBOX_FORMAT, -1, Tk_Offset(Spinbox, reqFormat),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-from", "from", "From",
	DEF_SPINBOX_FROM, -1, Tk_Offset(Spinbox, fromValue), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_ENTRY_HIGHLIGHT_BG,
	-1, Tk_Offset(Entry, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_ENTRY_HIGHLIGHT, -1, Tk_Offset(Entry, highlightColorPtr), 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_ENTRY_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Entry, highlightWidth), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-increment", "increment", "Increment",
	DEF_SPINBOX_INCREMENT, -1, Tk_Offset(Spinbox, increment), 0, 0, 0},
    {TK_OPTION_BORDER, "-insertbackground", "insertBackground", "Foreground",
	DEF_ENTRY_INSERT_BG, -1, Tk_Offset(Entry, insertBorder), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertborderwidth", "insertBorderWidth",
	"BorderWidth", DEF_ENTRY_INSERT_BD_COLOR, -1,
	Tk_Offset(Entry, insertBorderWidth), 0,
	DEF_ENTRY_INSERT_BD_MONO, 0},
    {TK_OPTION_INT, "-insertofftime", "insertOffTime", "OffTime",
	DEF_ENTRY_INSERT_OFF_TIME, -1, Tk_Offset(Entry, insertOffTime),
	0, 0, 0},
    {TK_OPTION_INT, "-insertontime", "insertOnTime", "OnTime",
	DEF_ENTRY_INSERT_ON_TIME, -1, Tk_Offset(Entry, insertOnTime), 0, 0, 0},
    {TK_OPTION_PIXELS, "-insertwidth", "insertWidth", "InsertWidth",
	DEF_ENTRY_INSERT_WIDTH, -1, Tk_Offset(Entry, insertWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-invalidcommand", "invalidCommand", "InvalidCommand",
	DEF_ENTRY_INVALIDCMD, -1, Tk_Offset(Entry, invalidCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL,
	NULL, 0, -1, 0, "-invalidcommand", 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0},






    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground",
	"ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1,
	Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK,
	DEF_ENTRY_READONLY_BG_MONO, 0},
    {TK_OPTION_INT, "-repeatdelay", "repeatDelay", "RepeatDelay",
	DEF_SPINBOX_REPEAT_DELAY, -1, Tk_Offset(Spinbox, repeatDelay),
	0, 0, 0},
    {TK_OPTION_INT, "-repeatinterval", "repeatInterval", "RepeatInterval",
	DEF_SPINBOX_REPEAT_INTERVAL, -1, Tk_Offset(Spinbox, repeatInterval),
	0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	DEF_ENTRY_SELECT_COLOR, -1, Tk_Offset(Entry, selBorder),
	0, DEF_ENTRY_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	"BorderWidth", DEF_ENTRY_SELECT_BD_COLOR, -1,
	Tk_Offset(Entry, selBorderWidth),
	0, DEF_ENTRY_SELECT_BD_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	DEF_ENTRY_SELECT_FG_COLOR, -1, Tk_Offset(Entry, selFgColorPtr),
	TK_OPTION_NULL_OK, DEF_ENTRY_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_ENTRY_STATE, -1, Tk_Offset(Entry, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_ENTRY_TAKE_FOCUS, -1, Tk_Offset(Entry, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_ENTRY_TEXT_VARIABLE, -1, Tk_Offset(Entry, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-to", "to", "To",
	DEF_SPINBOX_TO, -1, Tk_Offset(Spinbox, toValue), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-validate", "validate", "Validate",
	DEF_ENTRY_VALIDATE, -1, Tk_Offset(Entry, validate),
	0, validateStrings, 0},
    {TK_OPTION_STRING, "-validatecommand", "validateCommand","ValidateCommand",
	NULL, -1, Tk_Offset(Entry, validateCmd), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-values", "values", "Values",
	DEF_SPINBOX_VALUES, -1, Tk_Offset(Spinbox, valueStr),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-vcmd", NULL, NULL,
	NULL, 0, -1, 0, "-validatecommand", 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	DEF_ENTRY_WIDTH, -1, Tk_Offset(Entry, prefWidth), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-wrap", "wrap", "Wrap",
	DEF_SPINBOX_WRAP, -1, Tk_Offset(Spinbox, wrap), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	DEF_ENTRY_SCROLL_COMMAND, -1, Tk_Offset(Entry, scrollCmd),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * The following tables define the entry widget commands (and sub-commands)
 * and map the indexes into the string tables into enumerated types used to
 * dispatch the entry widget command.
 */
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

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








|
|
|
|
|

|


|
|
|



|
|





|

|





|


|

|
|





|







391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447

/*
 * Forward declarations for functions defined later in this file:
 */

static int		ConfigureEntry(Tcl_Interp *interp, Entry *entryPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		DeleteChars(Entry *entryPtr, int index, int count);
static Tcl_FreeProc	DestroyEntry;
static void		DisplayEntry(void *clientData);
static void		EntryBlinkProc(void *clientData);
static void		EntryCmdDeletedProc(void *clientData);
static void		EntryComputeGeometry(Entry *entryPtr);
static void		EntryEventProc(void *clientData,
			    XEvent *eventPtr);
static void		EntryFocusProc(Entry *entryPtr, int gotFocus);
static int		EntryFetchSelection(void *clientData, int offset,
			    char *buffer, int maxBytes);
static void		EntryLostSelection(void *clientData);
static void		EventuallyRedraw(Entry *entryPtr);
static void		EntryScanTo(Entry *entryPtr, int y);
static void		EntrySetValue(Entry *entryPtr, const char *value);
static void		EntrySelectTo(Entry *entryPtr, int index);
static char *		EntryTextVarProc(void *clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static void		EntryUpdateScrollbar(Entry *entryPtr);
static int		EntryValidate(Entry *entryPtr, char *cmd);
static int		EntryValidateChange(Entry *entryPtr, const char *change,
			    const char *newStr, int index, int type);
static void		ExpandPercents(Entry *entryPtr, const char *before,
			    const char *change, const char *newStr, int index,
			    int type, Tcl_DString *dsPtr);
static int		EntryValueChanged(Entry *entryPtr,
			    const char *newValue);
static void		EntryVisibleRange(Entry *entryPtr,
			    double *firstPtr, double *lastPtr);
static int		EntryWidgetObjCmd(void *clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		EntryWorldChanged(void *instanceData);
static int		GetEntryIndex(Tcl_Interp *interp, Entry *entryPtr,
			    Tcl_Obj *indexObj, int *indexPtr);
static int		InsertChars(Entry *entryPtr, int index, const char *string);

/*
 * These forward declarations are the spinbox specific ones:
 */

static int		SpinboxWidgetObjCmd(void *clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static int		GetSpinboxElement(Spinbox *sbPtr, int x, int y);
static int		SpinboxInvoke(Tcl_Interp *interp, Spinbox *sbPtr,
			    int element);
static int		ComputeFormat(Spinbox *sbPtr);

480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
 *	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),







|








<







472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487

488
489
490
491
492
493
494
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_EntryObjCmd(
    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),
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
	    Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd, entryPtr,
	    EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_ENTRY;
    tmp				= (char *)ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= TCL_INDEX_NONE;
    entryPtr->selectLast	= TCL_INDEX_NONE;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;
    entryPtr->inset		= XPAD;
    entryPtr->textGC		= NULL;
    entryPtr->selTextGC		= NULL;
    entryPtr->highlightGC	= NULL;
    entryPtr->avgWidth		= 1;
    entryPtr->validate		= VALIDATE_NONE;

    entryPtr->placeholderGC	= NULL;

    /*
     * Keep a hold of the associated tkwin until we destroy the entry,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Entry");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, entryPtr, XA_STRING);

    if ((Tk_InitOptions(interp, entryPtr, optionTable, tkwin)
	    != TCL_OK) ||
	    (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EntryWidgetObjCmd --







|
|














<
<















|






|







521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543


544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
	    Tk_PathName(entryPtr->tkwin), EntryWidgetObjCmd, entryPtr,
	    EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_ENTRY;
    tmp				= (char *)ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= -1;
    entryPtr->selectLast	= -1;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;
    entryPtr->inset		= XPAD;
    entryPtr->textGC		= NULL;
    entryPtr->selTextGC		= NULL;
    entryPtr->highlightGC	= NULL;
    entryPtr->avgWidth		= 1;
    entryPtr->validate		= VALIDATE_NONE;



    /*
     * Keep a hold of the associated tkwin until we destroy the entry,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Entry");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, entryPtr, XA_STRING);

    if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin)
	    != TCL_OK) ||
	    (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * EntryWidgetObjCmd --
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;







|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
 *	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
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum entryCmd) cmdIndex) {
    case COMMAND_BBOX: {
	TkSizeT index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index + 1 > 1)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
	bbox[0] = Tcl_NewWideIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewWideIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewWideIntObj(width);
	bbox[3] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox));
	break;
    }

    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, entryPtr,
		entryPtr->optionTable, objv[2], entryPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, entryPtr,
		    entryPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL,
		    entryPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DELETE: {
	TkSizeT first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else if (GetEntryIndex(interp, entryPtr, objv[3],
		&last) != TCL_OK) {
	    goto error;
	}
	if ((last + 1 >= first + 1 ) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case COMMAND_GET:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, TCL_INDEX_NONE));
	break;

    case COMMAND_ICURSOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pos");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&entryPtr->insertPos) != TCL_OK) {
	    goto error;
	}
	EventuallyRedraw(entryPtr);
	break;

    case COMMAND_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	break;
    }

    case COMMAND_INSERT: {
	TkSizeT index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],







|











|



|
|
|
|










|









|













|
















|













|















|









|




|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum entryCmd) cmdIndex) {
    case COMMAND_BBOX: {
	int index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index > 0)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
	bbox[0] = Tcl_NewIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewIntObj(width);
	bbox[3] = Tcl_NewIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox));
	break;
    }

    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
		entryPtr->optionTable, objv[2], entryPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
		    entryPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL,
		    entryPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case COMMAND_DELETE: {
	int first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else if (GetEntryIndex(interp, entryPtr, objv[3],
		&last) != TCL_OK) {
	    goto error;
	}
	if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }

    case COMMAND_GET:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewStringObj(entryPtr->string, -1));
	break;

    case COMMAND_ICURSOR:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "pos");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&entryPtr->insertPos) != TCL_OK) {
	    goto error;
	}
	EventuallyRedraw(entryPtr);
	break;

    case COMMAND_INDEX: {
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	break;
    }

    case COMMAND_INSERT: {
	int index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
		    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
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case COMMAND_SELECTION: {
	int index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		TkSizeT half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1 ) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1 ) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}
	    }
	    EntrySelectTo(entryPtr, index);
	    break;

	case SELECTION_CLEAR:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
		EventuallyRedraw(entryPtr);
	    }
	    goto done;

	case SELECTION_FROM:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");







|
|



|

|
















|
|
|







817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst >= 0) {
		int half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index < half1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index > half2) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}
	    }
	    EntrySelectTo(entryPtr, index);
	    break;

	case SELECTION_CLEAR:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    if (entryPtr->selectFirst >= 0) {
		entryPtr->selectFirst = -1;
		entryPtr->selectLast = -1;
		EventuallyRedraw(entryPtr);
	    }
	    goto done;

	case SELECTION_FROM:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909

	case SELECTION_PRESENT:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp,
		    Tcl_NewWideIntObj(entryPtr->selectFirst != TCL_INDEX_NONE));
	    goto done;

	case SELECTION_RANGE:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "start end");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[4],
		    &index2) != TCL_OK) {
		goto error;
	    }
	    if (index + 1 >= index2 + 1 ) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && (entryPtr->exportSelection)
		    && (!Tcl_IsSafe(entryPtr->interp))) {







|















|
|
|







866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898

	case SELECTION_PRESENT:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(entryPtr->selectFirst >= 0));
	    goto done;

	case SELECTION_RANGE:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "start end");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr, objv[4],
		    &index2) != TCL_OK) {
		goto error;
	    }
	    if (index >= index2) {
		entryPtr->selectFirst = -1;
		entryPtr->selectLast = -1;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && (entryPtr->exportSelection)
		    && (!Tcl_IsSafe(entryPtr->interp))) {
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
	    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);







|







933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
	    entryPtr->validate = selIndex;
	}
	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case COMMAND_XVIEW: {
	int index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992


993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
	} 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;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;







<
<

















>
>


|


|







956
957
958
959
960
961
962


963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
	} else {
	    double fraction;
	    int count;

	    index = entryPtr->leftIndex;
	    switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
		    &count)) {


	    case TK_SCROLL_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 (index < 0) {
	    index = 0;
	}
	entryPtr->leftIndex = index;
	entryPtr->flags |= UPDATE_SCROLLBAR;
	EntryComputeGeometry(entryPtr);
	EventuallyRedraw(entryPtr);
	break;
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
 *	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.
     */







|







1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
 *	Everything associated with the entry is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyEntry(
    char *memPtr)		/* Info about entry widget. */
{
    Entry *entryPtr = (Entry *)memPtr;

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeOptions handle all the standard option-related stuff.
     */
1119
1120
1121
1122
1123
1124
1125

1126
1127
1128
1129
1130
1131
1132
    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)) {







>







1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
    char *oldFormat = NULL;
    int error;
    int oldExport = 0;
    int valuesChanged = 0;
    double oldFrom = 0.0;
    double oldTo = 0.0;
    int code;
    size_t formatSpace = TCL_DOUBLE_SPACE;

    /*
     * Eliminate any existing trace on a variable monitored by the entry.
     */

    if ((entryPtr->textVarName != NULL)
	    && (entryPtr->flags & ENTRY_VAR_TRACED)) {
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, entryPtr,
		    entryPtr->optionTable, objc, objv,
		    entryPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|







1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) entryPtr,
		    entryPtr->optionTable, objc, objv,
		    entryPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
1191
1192
1193
1194
1195
1196
1197
1198

1199
1200
1201
1202
1203
1204

1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
	}
	if (entryPtr->insertBorderWidth > entryPtr->insertWidth/2) {
	    entryPtr->insertBorderWidth = entryPtr->insertWidth/2;
	}

	if (entryPtr->type == TK_SPINBOX) {
	    if (sbPtr->fromValue > sbPtr->toValue) {
                /*

                 * Swap -from and -to values.
                 */

                double tmpFromTo = sbPtr->fromValue;

                sbPtr->fromValue = sbPtr->toValue;

                sbPtr->toValue = tmpFromTo;
            }

	    if (sbPtr->reqFormat && (oldFormat != sbPtr->reqFormat)) {
		/*
		 * Make sure that the given format is somewhat correct, and
		 * calculate the minimum space we'll need for the values as
		 * strings.
		 */

		int min, max;
		size_t formatLen, formatSpace = TCL_DOUBLE_SPACE;
		char fbuf[4], *fmt = sbPtr->reqFormat;

		formatLen = strlen(fmt);
		if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) {
		badFormatOpt:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad spinbox format specifier \"%s\"",







<
>
|
<
|
<
|
<
>
|
|









|







1181
1182
1183
1184
1185
1186
1187

1188
1189

1190

1191

1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
	}
	if (entryPtr->insertBorderWidth > entryPtr->insertWidth/2) {
	    entryPtr->insertBorderWidth = entryPtr->insertWidth/2;
	}

	if (entryPtr->type == TK_SPINBOX) {
	    if (sbPtr->fromValue > sbPtr->toValue) {

		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-to value must be greater than -from value",

			-1));

		Tcl_SetErrorCode(interp, "TK", "SPINBOX", "RANGE_SANITY",

			NULL);
		continue;
	    }

	    if (sbPtr->reqFormat && (oldFormat != sbPtr->reqFormat)) {
		/*
		 * Make sure that the given format is somewhat correct, and
		 * calculate the minimum space we'll need for the values as
		 * strings.
		 */

		int min, max;
		size_t formatLen;
		char fbuf[4], *fmt = sbPtr->reqFormat;

		formatLen = strlen(fmt);
		if ((fmt[0] != '%') || (fmt[formatLen-1] != 'f')) {
		badFormatOpt:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "bad spinbox format specifier \"%s\"",
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
		    Tcl_DecrRefCount(sbPtr->listObj);
		}
		sbPtr->listObj = NULL;
		if (sbPtr->valueStr != NULL) {
		    Tcl_Obj *newObjPtr;
		    int nelems;

		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, TCL_INDEX_NONE);
		    if (Tcl_ListObjLength(interp, newObjPtr, &nelems)
			    != TCL_OK) {
			valuesChanged = -1;
			continue;
		    }
		    sbPtr->listObj = newObjPtr;
		    Tcl_IncrRefCount(sbPtr->listObj);







|







1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
		    Tcl_DecrRefCount(sbPtr->listObj);
		}
		sbPtr->listObj = NULL;
		if (sbPtr->valueStr != NULL) {
		    Tcl_Obj *newObjPtr;
		    int nelems;

		    newObjPtr = Tcl_NewStringObj(sbPtr->valueStr, -1);
		    if (Tcl_ListObjLength(interp, newObjPtr, &nelems)
			    != TCL_OK) {
			valuesChanged = -1;
			continue;
		    }
		    sbPtr->listObj = newObjPtr;
		    Tcl_IncrRefCount(sbPtr->listObj);
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308

	/*
	 * Claim the selection if we've suddenly started exporting it.
	 */

	if (entryPtr->exportSelection && (!oldExport)
		&& (!Tcl_IsSafe(entryPtr->interp))
		&& (entryPtr->selectFirst != TCL_INDEX_NONE)
		&& !(entryPtr->flags & GOT_SELECTION)) {
	    Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		    entryPtr);
	    entryPtr->flags |= GOT_SELECTION;
	}

	/*







|







1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296

	/*
	 * Claim the selection if we've suddenly started exporting it.
	 */

	if (entryPtr->exportSelection && (!oldExport)
		&& (!Tcl_IsSafe(entryPtr->interp))
		&& (entryPtr->selectFirst != -1)
		&& !(entryPtr->flags & GOT_SELECTION)) {
	    Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		    entryPtr);
	    entryPtr->flags |= GOT_SELECTION;
	}

	/*
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
		/* 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);







|







1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
		/* Scan failure */
		dvalue = sbPtr->fromValue;
	    } else if (dvalue > sbPtr->toValue) {
		dvalue = sbPtr->toValue;
	    } else if (dvalue < sbPtr->fromValue) {
		dvalue = sbPtr->fromValue;
	    }
	    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;







|







1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
 *	Entry will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
EntryWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    unsigned long mask;
    Tk_3DBorder border;
    XColor *colorPtr;
    Entry *entryPtr = (Entry *)instanceData;
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
    mask = GCForeground | GCFont | GCGraphicsExposures;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    entryPtr->textGC = gc;

    if (entryPtr->placeholderColorPtr != NULL) {
	gcValues.foreground = entryPtr->placeholderColorPtr->pixel;
    }
    mask = GCForeground | GCFont | GCGraphicsExposures;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->placeholderGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->placeholderGC);
    }
    entryPtr->placeholderGC = gc;

    if (entryPtr->selFgColorPtr != NULL) {
	gcValues.foreground = entryPtr->selFgColorPtr->pixel;
    } else {
        gcValues.foreground = colorPtr->pixel;
    }
    gcValues.font = Tk_FontId(entryPtr->tkfont);
    mask = GCForeground | GCFont;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
    }







<
<
<
<
<
<
<
<
<
<


<
<







1491
1492
1493
1494
1495
1496
1497










1498
1499


1500
1501
1502
1503
1504
1505
1506
    mask = GCForeground | GCFont | GCGraphicsExposures;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->textGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->textGC);
    }
    entryPtr->textGC = gc;











    if (entryPtr->selFgColorPtr != NULL) {
	gcValues.foreground = entryPtr->selFgColorPtr->pixel;


    }
    gcValues.font = Tk_FontId(entryPtr->tkfont);
    mask = GCForeground | GCFont;
    gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues);
    if (entryPtr->selTextGC != NULL) {
	Tk_FreeGC(entryPtr->display, entryPtr->selTextGC);
    }
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 --







|
|
|

<
<
<
<







1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542




1543
1544
1545
1546
1547
1548
1549
 *	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 */

/*
 *--------------------------------------------------------------
 *







|
|

<
<
<







1559
1560
1561
1562
1563
1564
1565
1566
1567
1568



1569
1570
1571
1572
1573
1574
1575
 *	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;







|







1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
 *	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;
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
    xBound = Tk_Width(tkwin) - entryPtr->inset - entryPtr->xWidth;
    baseY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2;

    /*
     * Hide the selection whenever we don't have the focus, unless we
     * always want to show selection.
     */
    if (Tk_AlwaysShowSelection(entryPtr->tkwin)) {
	showSelection = 1;
    } else {
	showSelection = (entryPtr->flags & GOT_FOCUS);
    }

    /*
     * Draw the background in three layers. From bottom to top the layers are:







|







1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
    xBound = Tk_Width(tkwin) - entryPtr->inset - entryPtr->xWidth;
    baseY = (Tk_Height(tkwin) + fm.ascent - fm.descent) / 2;

    /*
     * Hide the selection whenever we don't have the focus, unless we
     * always want to show selection.
     */
    if (TkpAlwaysShowSelection(entryPtr->tkwin)) {
	showSelection = 1;
    } else {
	showSelection = (entryPtr->flags & GOT_FOCUS);
    }

    /*
     * Draw the background in three layers. From bottom to top the layers are:
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
    } 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;
	}







|







1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
    } else {
	border = entryPtr->normalBorder;
    }
    Tk_Fill3DRectangle(tkwin, pixmap, border,
	    0, 0, Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selectLast > entryPtr->leftIndex)) {
	if (entryPtr->selectFirst <= entryPtr->leftIndex) {
	    selStartX = entryPtr->leftX;
	} else {
	    Tk_CharBbox(entryPtr->textLayout, entryPtr->selectFirst,
		    &selStartX, NULL, NULL, NULL);
	    selStartX += entryPtr->layoutX;
	}
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
    if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) {
	Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL,
		NULL, NULL);
	cursorX += entryPtr->layoutX;
	cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2;
	Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
		fm.ascent + fm.descent);
	if ((entryPtr->insertPos + 1 >= entryPtr->leftIndex + 1) && cursorX < xBound) {
	    if (entryPtr->flags & CURSOR_ON) {
		Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->insertBorder,
			cursorX, baseY - fm.ascent, entryPtr->insertWidth,
			fm.ascent + fm.descent, entryPtr->insertBorderWidth,
			TK_RELIEF_RAISED);
	    } else if (entryPtr->insertBorder == entryPtr->selBorder) {
		Tk_Fill3DRectangle(tkwin, pixmap, border, cursorX,
			baseY - fm.ascent, entryPtr->insertWidth,
			fm.ascent + fm.descent, 0, TK_RELIEF_FLAT);
	    }
	}
    }

    if ((entryPtr->numChars == 0) && (entryPtr->placeholderChars != 0)) {

        /*
         * Draw the placeholder text.
         */

        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->placeholderGC,
	    entryPtr->placeholderLayout, entryPtr->placeholderX, entryPtr->layoutY,
	    entryPtr->placeholderLeftIndex, entryPtr->placeholderChars);

    } else {

        if (showSelection && (entryPtr->state != STATE_DISABLED)
	        && (entryPtr->selTextGC != entryPtr->textGC)
	        && (entryPtr->selectFirst + 1 < entryPtr->selectLast + 1)) {

	    /*
	     * Draw the selected and unselected portions separately.
	     */

	    TkSizeT selFirst;

	    if (entryPtr->selectFirst + 1 < entryPtr->leftIndex + 1) {
	        selFirst = entryPtr->leftIndex;
	    } else {
	        selFirst = entryPtr->selectFirst;
	    }
	    if (entryPtr->leftIndex < selFirst) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		        entryPtr->leftIndex, selFirst);
	    }
	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->selTextGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    selFirst, entryPtr->selectLast);
	    if (entryPtr->selectLast < entryPtr->numChars) {
	        Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		        entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		        entryPtr->selectLast, entryPtr->numChars);
	    }
        } else {

            /*
             * Draw the entire visible text
             */

	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    entryPtr->leftIndex, entryPtr->numChars);
        }
    }

    if (entryPtr->type == TK_SPINBOX) {
	int startx, height, inset, pad, tHeight, xWidth;
	Spinbox *sbPtr = (Spinbox *) entryPtr;

	/*







|













<
<
<
<
<
<
<
<
<
<
<
<
|
|
|

|
|
|

|

|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|

|
|
|

|
|
|
<







1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737












1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774

1775
1776
1777
1778
1779
1780
1781
    if ((entryPtr->state == STATE_NORMAL) && (entryPtr->flags & GOT_FOCUS)) {
	Tk_CharBbox(entryPtr->textLayout, entryPtr->insertPos, &cursorX, NULL,
		NULL, NULL);
	cursorX += entryPtr->layoutX;
	cursorX -= (entryPtr->insertWidth == 1) ? 1 : (entryPtr->insertWidth)/2;
	Tk_SetCaretPos(entryPtr->tkwin, cursorX, baseY - fm.ascent,
		fm.ascent + fm.descent);
	if (entryPtr->insertPos >= entryPtr->leftIndex && cursorX < xBound) {
	    if (entryPtr->flags & CURSOR_ON) {
		Tk_Fill3DRectangle(tkwin, pixmap, entryPtr->insertBorder,
			cursorX, baseY - fm.ascent, entryPtr->insertWidth,
			fm.ascent + fm.descent, entryPtr->insertBorderWidth,
			TK_RELIEF_RAISED);
	    } else if (entryPtr->insertBorder == entryPtr->selBorder) {
		Tk_Fill3DRectangle(tkwin, pixmap, border, cursorX,
			baseY - fm.ascent, entryPtr->insertWidth,
			fm.ascent + fm.descent, 0, TK_RELIEF_FLAT);
	    }
	}
    }













    if (showSelection && (entryPtr->state != STATE_DISABLED)
	    && (entryPtr->selTextGC != entryPtr->textGC)
	    && (entryPtr->selectFirst < entryPtr->selectLast)) {

	/*
	 * Draw the selected and unselected portions separately.
	 */

	int 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,
		    entryPtr->leftIndex, selFirst);
	}
	Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->selTextGC,
		entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		selFirst, entryPtr->selectLast);
	if (entryPtr->selectLast < entryPtr->numChars) {
	    Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		    entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		    entryPtr->selectLast, entryPtr->numChars);
	}
    } else {

        /*
         * Draw the entire visible text
         */

	Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC,
		entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY,
		entryPtr->leftIndex, entryPtr->numChars);

    }

    if (entryPtr->type == TK_SPINBOX) {
	int startx, height, inset, pad, tHeight, xWidth;
	Spinbox *sbPtr = (Spinbox *) entryPtr;

	/*
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
 */

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;







|







1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
 */

static void
EntryComputeGeometry(
    Entry *entryPtr)		/* Widget record for entry. */
{
    int totalLength, overflow, rightX;
    int maxOffScreen;
    int height, width, i;
    Tk_FontMetrics fm;
    char *p;

    if (entryPtr->displayString != entryPtr->string) {
	ckfree((char *)entryPtr->displayString);
	entryPtr->displayString = entryPtr->string;
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
	TkUtfToUniChar(entryPtr->showChar, &ch);
	size = TkUniCharToUtf(ch, buf);

	entryPtr->numDisplayBytes = entryPtr->numChars * size;
	p = (char *)ckalloc(entryPtr->numDisplayBytes + 1);
	entryPtr->displayString = p;

	for (i = entryPtr->numChars; i-- > 0; ) {
	    memcpy(p, buf, size);
	    p += size;
	}
	*p = '\0';
    }

    /* Recompute layout of placeholder text.
     * Only the placeholderX and placeholderLeftIndex value is needed.
     * We use the same font so we can use the layoutY value from below.
     */

    Tk_FreeTextLayout(entryPtr->placeholderLayout);
    if (entryPtr->placeholderString) {
        entryPtr->placeholderChars = strlen(entryPtr->placeholderString);
        entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	        entryPtr->placeholderString, entryPtr->placeholderChars, 0,
	        entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, NULL);
	overflow = totalLength -
	        (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth);
	if (overflow <= 0) {
	    entryPtr->placeholderLeftIndex = 0;
	    if (entryPtr->justify == TK_JUSTIFY_LEFT) {
		entryPtr->placeholderX = entryPtr->inset;
	    } else if (entryPtr->justify == TK_JUSTIFY_RIGHT) {
		entryPtr->placeholderX = Tk_Width(entryPtr->tkwin) - entryPtr->inset
		        - entryPtr->xWidth - totalLength;
	    } else {
		entryPtr->placeholderX = (Tk_Width(entryPtr->tkwin)
		        - entryPtr->xWidth - totalLength)/2;
	    }
    	} else {

	    /*
	     * The whole string can't fit in the window. Compute the maximum
	     * number of characters that may be off-screen to the left without
	     * leaving empty space on the right of the window, then don't let
	     * placeholderLeftIndex be any greater than that.
	     */

	    maxOffScreen = Tk_PointToChar(entryPtr->placeholderLayout, overflow, 0);
	    Tk_CharBbox(entryPtr->placeholderLayout, maxOffScreen,
		&rightX, NULL, NULL, NULL);
	    if (rightX < overflow) {
		maxOffScreen++;
	    }
	    entryPtr->placeholderLeftIndex = maxOffScreen;
	    Tk_CharBbox(entryPtr->placeholderLayout, entryPtr->placeholderLeftIndex, &rightX,
		NULL, NULL, NULL);
	    entryPtr->placeholderX = entryPtr->inset -rightX;
        }
    } else {
        entryPtr->placeholderChars = 0;
        entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	        entryPtr->placeholderString, 0, 0,
	        entryPtr->justify, TK_IGNORE_NEWLINES, NULL, NULL);
	entryPtr->placeholderX = entryPtr->inset;
    }

    Tk_FreeTextLayout(entryPtr->textLayout);
    entryPtr->textLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	    entryPtr->displayString, entryPtr->numChars, 0,
	    entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, &height);

    entryPtr->layoutY = (Tk_Height(entryPtr->tkwin) - height) / 2;








|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973




















































1974
1975
1976
1977
1978
1979
1980
	TkUtfToUniChar(entryPtr->showChar, &ch);
	size = TkUniCharToUtf(ch, buf);

	entryPtr->numDisplayBytes = entryPtr->numChars * size;
	p = (char *)ckalloc(entryPtr->numDisplayBytes + 1);
	entryPtr->displayString = p;

	for (i = entryPtr->numChars; --i >= 0; ) {
	    memcpy(p, buf, size);
	    p += size;
	}
	*p = '\0';
    }





















































    Tk_FreeTextLayout(entryPtr->textLayout);
    entryPtr->textLayout = Tk_ComputeTextLayout(entryPtr->tkfont,
	    entryPtr->displayString, entryPtr->numChars, 0,
	    entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, &height);

    entryPtr->layoutY = (Tk_Height(entryPtr->tkwin) - height) / 2;

2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119

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







|







2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023

	maxOffScreen = Tk_PointToChar(entryPtr->textLayout, overflow, 0);
	Tk_CharBbox(entryPtr->textLayout, maxOffScreen,
		&rightX, NULL, NULL, NULL);
	if (rightX < overflow) {
	    maxOffScreen++;
	}
	if (entryPtr->leftIndex > maxOffScreen) {
	    entryPtr->leftIndex = maxOffScreen;
	}
	Tk_CharBbox(entryPtr->textLayout, entryPtr->leftIndex, &rightX,
		NULL, NULL, NULL);
	entryPtr->leftX = entryPtr->inset;
	entryPtr->layoutX = entryPtr->leftX - rightX;
    }
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164

2165

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

static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    TkSizeT index,			/* Add the new elements before this character
				 * index. */
    const char *value)		/* New characters to add (NULL-terminated
				 * string). */
{

    size_t byteIndex, byteCount, newByteCount, oldChars, charsAdded;

    const char *string;
    char *newStr;

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = strlen(value);
    if (byteCount == 0) {
	return TCL_OK;
    }

    newByteCount = entryPtr->numBytes + byteCount + 1;
    newStr = (char *)ckalloc(newByteCount);







|




>
|
>




|







2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
 *
 *----------------------------------------------------------------------
 */

static int
InsertChars(
    Entry *entryPtr,		/* Entry that is to get the new elements. */
    int index,			/* Add the new elements before this character
				 * index. */
    const char *value)		/* New characters to add (NULL-terminated
				 * string). */
{
    ptrdiff_t byteIndex;
    size_t byteCount, newByteCount;
    int oldChars, charsAdded;
    const char *string;
    char *newStr;

    string = entryPtr->string;
    byteIndex = TkUtfAtIndex(string, index) - string;
    byteCount = strlen(value);
    if (byteCount == 0) {
	return TCL_OK;
    }

    newByteCount = entryPtr->numBytes + byteCount + 1;
    newStr = (char *)ckalloc(newByteCount);
2187
2188
2189
2190
2191
2192
2193


2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
	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;
    entryPtr->numBytes += byteCount;

    if (entryPtr->displayString == string) {
	entryPtr->displayString = newStr;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * Inserting characters invalidates all indexes into the string. Touch up
     * the indexes so that they still refer to the same characters (at new
     * positions). When updating the selection end-points, don't include the
     * new text in the selection unless it was completely surrounded by the
     * selection.
     */

    if (entryPtr->selectFirst + 1 >= index + 1) {
	entryPtr->selectFirst += charsAdded;
    }
    if (entryPtr->selectLast + 1 > index + 1) {
	entryPtr->selectLast += charsAdded;
    }
    if ((entryPtr->selectAnchor + 1 > index + 1) || (entryPtr->selectFirst + 1 >= index + 1)) {
	entryPtr->selectAnchor += charsAdded;
    }
    if (entryPtr->leftIndex + 1 > index + 1) {
	entryPtr->leftIndex += charsAdded;
    }
    if (entryPtr->insertPos + 1 >= index + 1) {
	entryPtr->insertPos += charsAdded;
    }
    return EntryValueChanged(entryPtr, NULL);
}

/*
 *----------------------------------------------------------------------







>
>









|
















|


|


|


|


|







2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
	return TCL_OK;
    }

    ckfree((char *)string);
    entryPtr->string = newStr;

    /*
     * ??? Is this construction still needed with Tcl_NumUtfChars ???
     *
     * The following construction is used because inserting improperly formed
     * UTF-8 sequences between other improperly formed UTF-8 sequences could
     * result in actually forming valid UTF-8 sequences; the number of
     * characters added may not be Tcl_NumUtfChars(string, -1), because of
     * context. The actual number of characters added is how many characters
     * are in the string now minus the number that used to be there.
     */

    oldChars = entryPtr->numChars;
    entryPtr->numChars = Tcl_NumUtfChars(newStr, -1);
    charsAdded = entryPtr->numChars - oldChars;
    entryPtr->numBytes += byteCount;

    if (entryPtr->displayString == string) {
	entryPtr->displayString = newStr;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    /*
     * Inserting characters invalidates all indexes into the string. Touch up
     * the indexes so that they still refer to the same characters (at new
     * positions). When updating the selection end-points, don't include the
     * new text in the selection unless it was completely surrounded by the
     * selection.
     */

    if (entryPtr->selectFirst >= index) {
	entryPtr->selectFirst += charsAdded;
    }
    if (entryPtr->selectLast > index) {
	entryPtr->selectLast += charsAdded;
    }
    if ((entryPtr->selectAnchor > index) || (entryPtr->selectFirst >= index)) {
	entryPtr->selectAnchor += charsAdded;
    }
    if (entryPtr->leftIndex > index) {
	entryPtr->leftIndex += charsAdded;
    }
    if (entryPtr->insertPos >= index) {
	entryPtr->insertPos += charsAdded;
    }
    return EntryValueChanged(entryPtr, NULL);
}

/*
 *----------------------------------------------------------------------
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
 *
 *----------------------------------------------------------------------
 */

static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    TkSizeT index,			/* Index of first character to delete. */
    TkSizeT count)			/* How many characters to delete. */
{
    int byteIndex, byteCount, newByteCount;
    const char *string;
    char *newStr, *toDelete;

    if (index + count + 1 > entryPtr->numChars + 1) {
	count = entryPtr->numChars - index;
    }
    if ((int)count <= 0) {
	return TCL_OK;
    }

    string = entryPtr->string;
    byteIndex = Tcl_UtfAtIndex(string, index) - string;
    byteCount = Tcl_UtfAtIndex(string + byteIndex, count) - (string+byteIndex);

    newByteCount = entryPtr->numBytes + 1 - byteCount;
    newStr = (char *)ckalloc(newByteCount);
    memcpy(newStr, string, (size_t) byteIndex);
    strcpy(newStr + byteIndex, string + byteIndex + byteCount);

    toDelete = (char *)ckalloc(byteCount + 1);







|
|





|


|




|
|







2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
 *
 *----------------------------------------------------------------------
 */

static int
DeleteChars(
    Entry *entryPtr,		/* Entry widget to modify. */
    int index,			/* Index of first character to delete. */
    int count)			/* How many characters to delete. */
{
    int byteIndex, byteCount, newByteCount;
    const char *string;
    char *newStr, *toDelete;

    if (index + count > entryPtr->numChars) {
	count = entryPtr->numChars - index;
    }
    if (count <= 0) {
	return TCL_OK;
    }

    string = entryPtr->string;
    byteIndex = TkUtfAtIndex(string, index) - string;
    byteCount = TkUtfAtIndex(string + byteIndex, count) - (string+byteIndex);

    newByteCount = entryPtr->numBytes + 1 - byteCount;
    newStr = (char *)ckalloc(newByteCount);
    memcpy(newStr, string, (size_t) byteIndex);
    strcpy(newStr + byteIndex, string + byteIndex + byteCount);

    toDelete = (char *)ckalloc(byteCount + 1);
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352

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







|
|





|
|





|
|
|

|
|





|
|





|
|







2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260

    /*
     * Deleting characters results in the remaining characters being
     * renumbered. Update the various indexes into the string to reflect this
     * change.
     */

    if (entryPtr->selectFirst >= index) {
	if (entryPtr->selectFirst >= index + count) {
	    entryPtr->selectFirst -= count;
	} else {
	    entryPtr->selectFirst = index;
	}
    }
    if (entryPtr->selectLast >= index) {
	if (entryPtr->selectLast >= index + count) {
	    entryPtr->selectLast -= count;
	} else {
	    entryPtr->selectLast = index;
	}
    }
    if (entryPtr->selectLast <= entryPtr->selectFirst) {
	entryPtr->selectFirst = -1;
	entryPtr->selectLast = -1;
    }
    if (entryPtr->selectAnchor >= index) {
	if (entryPtr->selectAnchor >= index + count) {
	    entryPtr->selectAnchor -= count;
	} else {
	    entryPtr->selectAnchor = index;
	}
    }
    if (entryPtr->leftIndex > index) {
	if (entryPtr->leftIndex >= index + count) {
	    entryPtr->leftIndex -= count;
	} else {
	    entryPtr->leftIndex = index;
	}
    }
    if (entryPtr->insertPos >= index) {
	if (entryPtr->insertPos >= index + count) {
	    entryPtr->insertPos -= count;
	} else {
	    entryPtr->insertPos = index;
	}
    }
    return EntryValueChanged(entryPtr, NULL);
}
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
    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);
}







|
|
|
|
|



|
|





|







2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
    entryPtr->numChars = Tcl_NumUtfChars(value, valueLen);

    if (entryPtr->displayString == oldSource) {
	entryPtr->displayString = entryPtr->string;
	entryPtr->numDisplayBytes = entryPtr->numBytes;
    }

    if (entryPtr->selectFirst >= 0) {
	if (entryPtr->selectFirst >= entryPtr->numChars) {
	    entryPtr->selectFirst = -1;
	    entryPtr->selectLast = -1;
	} else if (entryPtr->selectLast > entryPtr->numChars) {
	    entryPtr->selectLast = entryPtr->numChars;
	}
    }
    if (entryPtr->leftIndex >= entryPtr->numChars) {
	if (entryPtr->numChars > 0) {
	    entryPtr->leftIndex = entryPtr->numChars - 1;
	} else {
	    entryPtr->leftIndex = 0;
	}
    }
    if (entryPtr->insertPos > entryPtr->numChars) {
	entryPtr->insertPos = entryPtr->numChars;
    }

    entryPtr->flags |= UPDATE_SCROLLBAR;
    EntryComputeGeometry(entryPtr);
    EventuallyRedraw(entryPtr);
}
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;







|







2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
EntryEventProc(
    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);







|







2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
    case DestroyNotify:
	if (!(entryPtr->flags & ENTRY_DELETED)) {
	    entryPtr->flags |= (ENTRY_DELETED | VALIDATE_ABORT);
	    Tcl_DeleteCommandFromToken(entryPtr->interp, entryPtr->widgetCmd);
	    if (entryPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayEntry, clientData);
	    }
	    Tcl_EventuallyFree(clientData, 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







|







2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
 *	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);







|

<
|
|
<
<
<
<
<
<
<
<
<
<
<








>
>
>
>
>
>







|







2579
2580
2581
2582
2583
2584
2585
2586
2587

2588
2589











2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618

static int
GetEntryIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Entry *entryPtr,		/* Entry for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,	/* Specifies character in entryPtr. */
    int *indexPtr)		/* Where to store converted character index */
{

    const char *string = Tcl_GetString(indexObj);
    size_t length = indexObj->length;












    switch (string[0]) {
    case 'a':
	if (strncmp(string, "anchor", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->selectAnchor;
	break;
    case 'e':
	if (strncmp(string, "end", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->numChars;
	break;
    case 'i':
	if (strncmp(string, "insert", length) != 0) {
	    goto badIndex;
	}
	*indexPtr = entryPtr->insertPos;
	break;
    case 's':
	if (entryPtr->selectFirst < 0) {
	    Tcl_ResetResult(interp);
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "selection isn't in widget %s",
		    Tk_PathName(entryPtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK",
		    (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX",
		    "NO_SELECTION", NULL);
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761











2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
	/*
	 * Special trick: if the x-position was off-screen to the right, round
	 * the index up to refer to the character just after the last visible
	 * one on the screen. This is needed to enable the last character to
	 * be selected, for example.
	 */

	if (roundUp && (*indexPtr + 1 < entryPtr->numChars + 1)) {
	    *indexPtr += 1;
	}
	break;
    }
    default:











	  badIndex:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad %s index \"%s\"",
		    (entryPtr->type == TK_ENTRY) ? "entry" : "spinbox", string));
	    Tcl_SetErrorCode(interp, "TK",
		    (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX",
		    "BAD_INDEX", NULL);
	    return TCL_ERROR;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * EntryScanTo --
 *







|





>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
<
<







2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681


2682
2683
2684
2685
2686
2687
2688
	/*
	 * Special trick: if the x-position was off-screen to the right, round
	 * the index up to refer to the character just after the last visible
	 * one on the screen. This is needed to enable the last character to
	 * be selected, for example.
	 */

	if (roundUp && (*indexPtr < entryPtr->numChars)) {
	    *indexPtr += 1;
	}
	break;
    }
    default:
	if (Tcl_GetIntFromObj(NULL, indexObj, indexPtr) != TCL_OK) {
	    goto badIndex;
	}
	if (*indexPtr < 0){
	    *indexPtr = 0;
	} else if (*indexPtr > entryPtr->numChars) {
	    *indexPtr = entryPtr->numChars;
	}
    }
    return TCL_OK;

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad %s index \"%s\"",
	    (entryPtr->type == TK_ENTRY) ? "entry" : "spinbox", string));
    Tcl_SetErrorCode(interp, "TK",
	    (entryPtr->type == TK_ENTRY) ? "ENTRY" : "SPINBOX",
	    "BAD_INDEX", NULL);
    return TCL_ERROR;


}

/*
 *----------------------------------------------------------------------
 *
 * EntryScanTo --
 *
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
 */

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;







|














|



|







2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
 */

static void
EntryScanTo(
    Entry *entryPtr,		/* Information about widget. */
    int x)			/* X-coordinate to use for scan operation. */
{
    int newLeftIndex;

    /*
     * Compute new leftIndex for entry by amplifying the difference between
     * the current position and the place where the scan started (the "mark"
     * position). If we run off the left or right side of the entry, then
     * reset the mark point so that the current position continues to
     * correspond to the edge of the window. This means that the picture will
     * start dragging as soon as the mouse reverses direction (without this
     * reset, might have to slide mouse a long ways back before the picture
     * starts moving again).
     */

    newLeftIndex = entryPtr->scanMarkIndex
	    - (10 * (x - entryPtr->scanMarkX)) / entryPtr->avgWidth;
    if (newLeftIndex >= entryPtr->numChars) {
	newLeftIndex = entryPtr->scanMarkIndex = entryPtr->numChars - 1;
	entryPtr->scanMarkX = x;
    }
    if (newLeftIndex < 0) {
	newLeftIndex = entryPtr->scanMarkIndex = 0;
	entryPtr->scanMarkX = x;
    }

    if (newLeftIndex != entryPtr->leftIndex) {
	entryPtr->leftIndex = newLeftIndex;
	entryPtr->flags |= UPDATE_SCROLLBAR;
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
 *
 *----------------------------------------------------------------------
 */

static void
EntrySelectTo(
    Entry *entryPtr,		/* Information about widget. */
    TkSizeT index)			/* Character index of element that is to
				 * become the "other" end of the selection. */
{
    TkSizeT newFirst, newLast;

    /*
     * Grab the selection if we don't own it already.
     */

    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
		entryPtr);
	entryPtr->flags |= GOT_SELECTION;
    }

    /*
     * Pick new starting and ending points for the selection.
     */

    if (entryPtr->selectAnchor + 1 > entryPtr->numChars + 1) {
	entryPtr->selectAnchor = entryPtr->numChars;
    }
    if (entryPtr->selectAnchor + 1 <= index + 1) {
	newFirst = entryPtr->selectAnchor;
	newLast = index;
    } else {
	newFirst = index;
	newLast = entryPtr->selectAnchor;
	if (newLast == TCL_INDEX_NONE) {
	    newFirst = newLast = TCL_INDEX_NONE;
	}
    }
    if ((entryPtr->selectFirst == newFirst)
	    && (entryPtr->selectLast == newLast)) {
	return;
    }
    entryPtr->selectFirst = newFirst;







|


|
















|


|





|
|







2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
 *
 *----------------------------------------------------------------------
 */

static void
EntrySelectTo(
    Entry *entryPtr,		/* Information about widget. */
    int index)			/* Character index of element that is to
				 * become the "other" end of the selection. */
{
    int newFirst, newLast;

    /*
     * Grab the selection if we don't own it already.
     */

    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)
	    && (!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 = -1;
	}
    }
    if ((entryPtr->selectFirst == newFirst)
	    && (entryPtr->selectLast == newLast)) {
	return;
    }
    entryPtr->selectFirst = newFirst;
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941



2942
2943
2944
2945
2946
2947
2948
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static TkSizeT
EntryFetchSelection(
    ClientData clientData,	/* Information about entry widget. */
    TkSizeT offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    TkSizeT maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NUL character. */
{
    Entry *entryPtr = (Entry *)clientData;
    TkSizeT byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if ((entryPtr->selectFirst == TCL_INDEX_NONE) || (!entryPtr->exportSelection)
	    || Tcl_IsSafe(entryPtr->interp)) {
	return -1;
    }
    string = entryPtr->displayString;
    selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst);
    selEnd = Tcl_UtfAtIndex(selStart,
	    entryPtr->selectLast - entryPtr->selectFirst);
    if (selEnd <= selStart + offset) {
	return 0;
    }
    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;



    }
    memcpy(buffer, selStart + offset, byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*







|

|
|


|



|



|




|
|

<
<
<



>
>
>







2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846



2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
EntryFetchSelection(
    void *clientData,	/* Information about entry widget. */
    int offset,			/* Byte offset within selection of first
				 * character to be returned. */
    char *buffer,		/* Location in which to place selection. */
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NUL character. */
{
    Entry *entryPtr = (Entry *)clientData;
    int byteCount;
    const char *string;
    const char *selStart, *selEnd;

    if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection)
	    || Tcl_IsSafe(entryPtr->interp)) {
	return -1;
    }
    string = entryPtr->displayString;
    selStart = TkUtfAtIndex(string, entryPtr->selectFirst);
    selEnd = TkUtfAtIndex(selStart,
	    entryPtr->selectLast - entryPtr->selectFirst);



    byteCount = selEnd - selStart - offset;
    if (byteCount > maxBytes) {
	byteCount = maxBytes;
    }
    if (byteCount <= 0) {
	return 0;
    }
    memcpy(buffer, selStart + offset, byteCount);
    buffer[byteCount] = '\0';
    return byteCount;
}

/*
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
 *	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
     * next time the focus enters the window. On Unix, we need to clear the
     * selection since it is always visible.
     * This is controlled by ::tk::AlwaysShowSelection.
     */

    if (Tk_AlwaysShowSelection(entryPtr->tkwin)
	    && (entryPtr->selectFirst != TCL_INDEX_NONE) && entryPtr->exportSelection
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	entryPtr->selectFirst = TCL_INDEX_NONE;
	entryPtr->selectLast = TCL_INDEX_NONE;
	EventuallyRedraw(entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *







|












|
|

|
|







2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
 *	not containing a selection.
 *
 *----------------------------------------------------------------------
 */

static void
EntryLostSelection(
    void *clientData)	/* Information about entry widget. */
{
    Entry *entryPtr = (Entry *)clientData;

    entryPtr->flags &= ~GOT_SELECTION;

    /*
     * On Windows and Mac systems, we want to remember the selection for the
     * next time the focus enters the window. On Unix, we need to clear the
     * selection since it is always visible.
     * This is controlled by ::tk::AlwaysShowSelection.
     */

    if (TkpAlwaysShowSelection(entryPtr->tkwin)
	    && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection
	    && (!Tcl_IsSafe(entryPtr->interp))) {
	entryPtr->selectFirst = -1;
	entryPtr->selectLast = -1;
	EventuallyRedraw(entryPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
    if (entryPtr->numChars == 0) {
	*firstPtr = 0.0;
	*lastPtr = 1.0;
    } else {
	charsInWindow = Tk_PointToChar(entryPtr->textLayout,
		Tk_Width(entryPtr->tkwin) - entryPtr->inset
		- entryPtr->xWidth - entryPtr->layoutX - 1, 0);
	if (charsInWindow < (int)entryPtr->numChars) {
	    charsInWindow++;
	}
	charsInWindow -= entryPtr->leftIndex;
	if (charsInWindow == 0) {
	    charsInWindow = 1;
	}








|







2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
    if (entryPtr->numChars == 0) {
	*firstPtr = 0.0;
	*lastPtr = 1.0;
    } else {
	charsInWindow = Tk_PointToChar(entryPtr->textLayout,
		Tk_Width(entryPtr->tkwin) - entryPtr->inset
		- entryPtr->xWidth - entryPtr->layoutX - 1, 0);
	if (charsInWindow < entryPtr->numChars) {
	    charsInWindow++;
	}
	charsInWindow -= entryPtr->leftIndex;
	if (charsInWindow == 0) {
	    charsInWindow = 1;
	}

3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130

    interp = entryPtr->interp;
    Tcl_Preserve(interp);
    EntryVisibleRange(entryPtr, &first, &last);
    Tcl_PrintDouble(NULL, first, firstStr);
    Tcl_PrintDouble(NULL, last, lastStr);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, entryPtr->scrollCmd, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, firstStr, TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, " ", TCL_INDEX_NONE);
    Tcl_DStringAppend(&buf, lastStr, TCL_INDEX_NONE);
    code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), TCL_INDEX_NONE, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (code != TCL_OK) {
	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		"\n    (horizontal scrolling command executed by %s)",
		Tk_PathName(entryPtr->tkwin)));
	Tcl_BackgroundException(interp, code);
    }







|
|
|
|
|
|







3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041

    interp = entryPtr->interp;
    Tcl_Preserve(interp);
    EntryVisibleRange(entryPtr, &first, &last);
    Tcl_PrintDouble(NULL, first, firstStr);
    Tcl_PrintDouble(NULL, last, lastStr);
    Tcl_DStringInit(&buf);
    Tcl_DStringAppend(&buf, entryPtr->scrollCmd, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, firstStr, -1);
    Tcl_DStringAppend(&buf, " ", -1);
    Tcl_DStringAppend(&buf, lastStr, -1);
    code = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, TCL_EVAL_GLOBAL);
    Tcl_DStringFree(&buf);
    if (code != TCL_OK) {
	Tcl_AppendObjToErrorInfo(interp, Tcl_ObjPrintf(
		"\n    (horizontal scrolling command executed by %s)",
		Tk_PathName(entryPtr->tkwin)));
	Tcl_BackgroundException(interp, code);
    }
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
 *	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;







|







3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
 *	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;
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







|

|
|




<
<















|






|







3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163


3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
 *	The text displayed in the entry will change to match the variable.
 *
 *--------------------------------------------------------------
 */

static char *
EntryTextVarProc(
    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 == (void *)entryPtr) {
                    break;
                }
            } while (probe);
            if (probe) {
                /*
                 * We were able to fetch the unset trace for our
                 * textVarName, which means it is not unset and not
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
3349
3350
     Entry *entryPtr,	/* Entry that needs validation. */
     char *cmd)	/* Validation command (NULL-terminated
				 * string). */
{
    Tcl_Interp *interp = entryPtr->interp;
    int code, isOK;

    code = Tcl_EvalEx(interp, cmd, TCL_INDEX_NONE, TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);

    /*
     * We accept TCL_OK and TCL_RETURN as valid return codes from the command
     * callback.
     */

    if (code != TCL_OK && code != TCL_RETURN) {







|







3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
     Entry *entryPtr,	/* Entry that needs validation. */
     char *cmd)	/* Validation command (NULL-terminated
				 * string). */
{
    Tcl_Interp *interp = entryPtr->interp;
    int code, isOK;

    code = Tcl_EvalEx(interp, cmd, -1, TCL_EVAL_GLOBAL | TCL_EVAL_DIRECT);

    /*
     * We accept TCL_OK and TCL_RETURN as valid return codes from the command
     * callback.
     */

    if (code != TCL_OK && code != TCL_RETURN) {
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407

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;








|







3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316

static int
EntryValidateChange(
     Entry *entryPtr,	/* Entry that needs validation. */
     const char *change,	/* Characters to be added/deleted
				 * (NUL-terminated string). */
     const char *newValue,	/* Potential new value of entry string */
     int index,			/* index of insert/delete, -1 otherwise */
     int type)			/* forced, delete, insert, focusin or
				 * focusout */
{
    int code, varValidate = (entryPtr->flags & VALIDATE_VAR);
    char *p;
    Tcl_DString script;

3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
     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;







|







3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
     Entry *entryPtr,	/* Entry that needs validation. */
     const char *before,
				/* Command containing percent expressions to
				 * be replaced. */
     const char *change,	/* Characters to added/deleted (NUL-terminated
				 * string). */
     const char *newValue,	/* Potential new value of entry string */
     int index,			/* index of insert/delete */
     int type,			/* INSERT or DELETE */
     Tcl_DString *dsPtr)	/* Dynamic string in which to append new
				 * command. */
{
    int spaceNeeded, cvtFlags;	/* Used to substitute string as proper Tcl
				 * list element. */
    int number, length;
3624
3625
3626
3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
		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;







|



|







3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
		case VALIDATE_DELETE:
		    number = 0;
		    break;
		default:
		    number = -1;
		    break;
		}
		snprintf(numStorage, sizeof(numStorage), "%d", number);
		string = numStorage;
		break;
	    case 'i':		/* index of insert/delete */
		snprintf(numStorage, sizeof(numStorage), "%d", index);
		string = numStorage;
		break;
	    case 'P':		/* 'Peeked' new value of the string */
		string = newValue;
		break;
	    case 's':		/* Current string value of spinbox */
		string = entryPtr->string;
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
 *	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),







|









<







3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622

3623
3624
3625
3626
3627
3628
3629
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_SpinboxObjCmd(
    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),
3749
3750
3751
3752
3753
3754
3755
3756
3757
3758
3759
3760
3761
3762
3763
3764
	    Tk_PathName(entryPtr->tkwin), SpinboxWidgetObjCmd, sbPtr,
	    EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_SPINBOX;
    tmp				= (char *)ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= TCL_INDEX_NONE;
    entryPtr->selectLast	= TCL_INDEX_NONE;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;







|
|







3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
3668
3669
3670
3671
3672
	    Tk_PathName(entryPtr->tkwin), SpinboxWidgetObjCmd, sbPtr,
	    EntryCmdDeletedProc);
    entryPtr->optionTable	= optionTable;
    entryPtr->type		= TK_SPINBOX;
    tmp				= (char *)ckalloc(1);
    tmp[0]			= '\0';
    entryPtr->string		= tmp;
    entryPtr->selectFirst	= -1;
    entryPtr->selectLast	= -1;

    entryPtr->cursor		= NULL;
    entryPtr->exportSelection	= 1;
    entryPtr->justify		= TK_JUSTIFY_LEFT;
    entryPtr->relief		= TK_RELIEF_FLAT;
    entryPtr->state		= STATE_NORMAL;
    entryPtr->displayString	= entryPtr->string;
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
    sbPtr->fromValue		= 0.0;
    sbPtr->toValue		= 100.0;
    sbPtr->increment		= 1.0;
    sbPtr->formatBuf		= (char *)ckalloc(TCL_DOUBLE_SPACE);
    sbPtr->bdRelief		= TK_RELIEF_FLAT;
    sbPtr->buRelief		= TK_RELIEF_FLAT;

    entryPtr->placeholderGC	= NULL;

    /*
     * Keep a hold of the associated tkwin until we destroy the spinbox,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Spinbox");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, entryPtr, XA_STRING);

    if (Tk_InitOptions(interp, sbPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(entryPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(entryPtr->tkwin);
    return TCL_ERROR;
}








<
<















|








|







3685
3686
3687
3688
3689
3690
3691


3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
3722
3723
    sbPtr->fromValue		= 0.0;
    sbPtr->toValue		= 100.0;
    sbPtr->increment		= 1.0;
    sbPtr->formatBuf		= (char *)ckalloc(TCL_DOUBLE_SPACE);
    sbPtr->bdRelief		= TK_RELIEF_FLAT;
    sbPtr->buRelief		= TK_RELIEF_FLAT;



    /*
     * Keep a hold of the associated tkwin until we destroy the spinbox,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(entryPtr->tkwin);

    Tk_SetClass(entryPtr->tkwin, "Spinbox");
    Tk_SetClassProcs(entryPtr->tkwin, &entryClass, entryPtr);
    Tk_CreateEventHandler(entryPtr->tkwin,
	    PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask,
	    EntryEventProc, entryPtr);
    Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING,
	    EntryFetchSelection, entryPtr, XA_STRING);

    if (Tk_InitOptions(interp, (char *) sbPtr, optionTable, tkwin)
	    != TCL_OK) {
	Tk_DestroyWindow(entryPtr->tkwin);
	return TCL_ERROR;
    }
    if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) {
	goto error;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(entryPtr->tkwin));
    return TCL_OK;

  error:
    Tk_DestroyWindow(entryPtr->tkwin);
    return TCL_ERROR;
}

3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
 *	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;







|







3737
3738
3739
3740
3741
3742
3743
3744
3745
3746
3747
3748
3749
3750
3751
 *	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
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
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum sbCmd) cmdIndex) {
    case SB_CMD_BBOX: {
	TkSizeT index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index + 1 > 1)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
	bbox[0] = Tcl_NewWideIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewWideIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewWideIntObj(width);
	bbox[3] = Tcl_NewWideIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox));
	break;
    }

    case SB_CMD_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, entryPtr,
		entryPtr->optionTable, objv[2], entryPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case SB_CMD_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, entryPtr,
		    entryPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    entryPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case SB_CMD_DELETE: {
	TkSizeT first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else {
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &last) != TCL_OK) {
		goto error;
	    }
	}
	if ((last + 1 >= first + 1) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }







|











|



|
|
|
|










|









|












|


















|







3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
3810
3811
3812
3813
3814
3815
3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
3850
3851
3852
    if (result != TCL_OK) {
	return result;
    }

    Tcl_Preserve(entryPtr);
    switch ((enum sbCmd) cmdIndex) {
    case SB_CMD_BBOX: {
	int index;
	int x, y, width, height;
	Tcl_Obj *bbox[4];

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	if ((index == entryPtr->numChars) && (index > 0)) {
	    index--;
	}
	Tk_CharBbox(entryPtr->textLayout, index, &x, &y, &width, &height);
	bbox[0] = Tcl_NewIntObj(x + entryPtr->layoutX);
	bbox[1] = Tcl_NewIntObj(y + entryPtr->layoutY);
	bbox[2] = Tcl_NewIntObj(width);
	bbox[3] = Tcl_NewIntObj(height);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, bbox));
	break;
    }

    case SB_CMD_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, (char *) entryPtr,
		entryPtr->optionTable, objv[2], entryPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case SB_CMD_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr,
		    entryPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    entryPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    result = ConfigureEntry(interp, entryPtr, objc-2, objv+2);
	}
	break;

    case SB_CMD_DELETE: {
	int first, last;
	int code;

	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "firstIndex ?lastIndex?");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&first) != TCL_OK) {
	    goto error;
	}
	if (objc == 3) {
	    last = first + 1;
	} else {
	    if (GetEntryIndex(interp, entryPtr, objv[3],
		    &last) != TCL_OK) {
		goto error;
	    }
	}
	if ((last >= first) && (entryPtr->state == STATE_NORMAL)) {
	    code = DeleteChars(entryPtr, first, last - first);
            if (code != TCL_OK) {
                goto error;
            }
	}
	break;
    }
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
	    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],







|









|




|







3887
3888
3889
3890
3891
3892
3893
3894
3895
3896
3897
3898
3899
3900
3901
3902
3903
3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
	    Tcl_SetObjResult(interp,
		    Tcl_NewStringObj(selElementNames[elem], -1));
	}
	break;
    }

    case SB_CMD_INDEX: {
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
		&index) != TCL_OK) {
	    goto error;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	break;
    }

    case SB_CMD_INSERT: {
	int index;
	int code;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index text");
	    goto error;
	}
	if (GetEntryIndex(interp, entryPtr, objv[2],
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case SB_CMD_SELECTION: {
	TkSizeT index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*







|







3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
		    minorCmd, NULL);
	    goto error;
	}
	break;
    }

    case SB_CMD_SELECTION: {
	int index, index2;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option ?index?");
	    goto error;
	}

	/*
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		TkSizeT half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index + 1 < half1 + 1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index + 1 > half2 + 1) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}
	    }
	    EntrySelectTo(entryPtr, index);
	    break;

	case SB_SEL_CLEAR:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    if (entryPtr->selectFirst != TCL_INDEX_NONE) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
		EventuallyRedraw(entryPtr);
	    }
	    goto done;

	case SB_SEL_FROM:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");







|
|



|

|
















|
|
|







4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
		Tcl_WrongNumArgs(interp, 3, objv, "index");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (entryPtr->selectFirst >= 0) {
		int half1, half2;

		half1 = (entryPtr->selectFirst + entryPtr->selectLast)/2;
		half2 = (entryPtr->selectFirst + entryPtr->selectLast + 1)/2;
		if (index < half1) {
		    entryPtr->selectAnchor = entryPtr->selectLast;
		} else if (index > half2) {
		    entryPtr->selectAnchor = entryPtr->selectFirst;
		} else {
		    /*
		     * We're at about the halfway point in the selection; just
		     * keep the existing anchor.
		     */
		}
	    }
	    EntrySelectTo(entryPtr, index);
	    break;

	case SB_SEL_CLEAR:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    if (entryPtr->selectFirst >= 0) {
		entryPtr->selectFirst = -1;
		entryPtr->selectLast = -1;
		EventuallyRedraw(entryPtr);
	    }
	    goto done;

	case SB_SEL_FROM:
	    if (objc != 4) {
		Tcl_WrongNumArgs(interp, 3, objv, "index");
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

	case SB_SEL_PRESENT:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    entryPtr->selectFirst != TCL_INDEX_NONE));
	    goto done;

	case SB_SEL_RANGE:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "start end");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[4],& index2) != TCL_OK) {
		goto error;
	    }
	    if (index + 1 >= index2 + 1) {
		entryPtr->selectFirst = TCL_INDEX_NONE;
		entryPtr->selectLast = TCL_INDEX_NONE;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && entryPtr->exportSelection
		    && (!Tcl_IsSafe(entryPtr->interp))) {







|















|
|
|







4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090

	case SB_SEL_PRESENT:
	    if (objc != 3) {
		Tcl_WrongNumArgs(interp, 3, objv, NULL);
		goto error;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    entryPtr->selectFirst >= 0));
	    goto done;

	case SB_SEL_RANGE:
	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "start end");
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[3], &index) != TCL_OK) {
		goto error;
	    }
	    if (GetEntryIndex(interp, entryPtr,
		    objv[4],& index2) != TCL_OK) {
		goto error;
	    }
	    if (index >= index2) {
		entryPtr->selectFirst = -1;
		entryPtr->selectLast = -1;
	    } else {
		entryPtr->selectFirst = index;
		entryPtr->selectLast = index2;
	    }
	    if (!(entryPtr->flags & GOT_SELECTION)
		    && entryPtr->exportSelection
		    && (!Tcl_IsSafe(entryPtr->interp))) {
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
	}

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







|







4165
4166
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177
4178
4179
	}

	Tcl_SetObjResult(interp, Tcl_NewBooleanObj(code == TCL_OK));
	break;
    }

    case SB_CMD_XVIEW: {
	int index;

	if (objc == 2) {
	    double first, last;
	    Tcl_Obj *span[2];

	    EntryVisibleRange(entryPtr, &first, &last);
	    span[0] = Tcl_NewDoubleObj(first);
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308


4309
4310
4311
4312
4313
4314
4315
4316
4317
4318
4319
4320
4321
	} 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;







<
<

|
















>
>


|


|







4188
4189
4190
4191
4192
4193
4194


4195
4196
4197
4198
4199
4200
4201
4202
4203
4204
4205
4206
4207
4208
4209
4210
4211
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222
4223
4224
4225
4226
4227
	} else {
	    double fraction;
	    int count;

	    index = entryPtr->leftIndex;
	    switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction,
		    &count)) {


	    case TK_SCROLL_MOVETO:
		index = (int) ((fraction * entryPtr->numChars) + 0.5);
		break;
	    case TK_SCROLL_PAGES: {
		int charsPerPage;

		charsPerPage = ((Tk_Width(entryPtr->tkwin)
			- 2 * entryPtr->inset - entryPtr->xWidth)
			/ entryPtr->avgWidth) - 2;
		if (charsPerPage < 1) {
		    charsPerPage = 1;
		}
		index += count * charsPerPage;
		break;
	    }
	    case TK_SCROLL_UNITS:
		index += count;
		break;
	    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;
4423
4424
4425
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436
4437
4438
4439
4440
4441
4442
4443
		/*
		 * 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;
		    }
		}







|





|







4329
4330
4331
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342
4343
4344
4345
4346
4347
4348
4349
		/*
		 * Somehow the string changed from what we expected, so let's
		 * do a search on the list to see if the current value is
		 * there. If not, move to the first element of the list.
		 */

		int i, listc;
		int elemLen, length = entryPtr->numChars;
		const char *bytes;
		Tcl_Obj **listv;

		Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv);
		for (i = 0; i < listc; i++) {
		    bytes = 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
		     * 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;
    }








|







4408
4409
4410
4411
4412
4413
4414
4415
4416
4417
4418
4419
4420
4421
4422
		     * greater than the toValue, because the user may have
		     * manipulated the value by hand.
		     */

		    dvalue = sbPtr->toValue;
		}
	    }
	    snprintf(sbPtr->formatBuf, TCL_DOUBLE_SPACE, sbPtr->valueFormat, dvalue);
	    code = EntryValueChanged(entryPtr, sbPtr->formatBuf);
	}
    }
    if (code != TCL_OK) {
        return TCL_ERROR;
    }

4619
4620
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
    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:
 */







|

|












4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546
    if (afterDecimal > 0) {
	fDigits++;		/* Decimal point. */
    }
    if (mostSigDigit < 0) {
	fDigits++;		/* Zero to left of decimal point. */
    }
    if (fDigits <= eDigits) {
	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.
41
42
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. */
    int insertPos;		/* Character index before which next typed
				 * character will be inserted. */

    /*
     * Information about what's selected, if any.
     */

    int selectFirst;		/* Character index of first selected character
				 * (-1 means nothing selected. */
    int selectLast;		/* Character index just after last selected
				 * character (-1 means nothing selected. */
    int selectAnchor;		/* Fixed end of selection (i.e. "select to"
				 * operation will use this as one end of the
				 * selection). */

    /*
     * Information for scanning:
     */

124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
				 * scrollbar(s). Malloc'ed. NULL means no
				 * command to issue. */
    char *showChar;		/* Value of -show option. If non-NULL, first
				 * character is used for displaying all
				 * characters in entry. Malloc'ed. This is
				 * only used by the Entry widget. */

    /*
     * Fields used in displaying help text if entry value is empty
     */

    Tk_TextLayout placeholderLayout;/* Cached placeholder text layout information. */
    char *placeholderString;	/* String value of placeholder. */
    TkSizeT placeholderChars;	/* Number of chars in placeholder. */
    XColor *placeholderColorPtr;/* Color value of placeholder foreground. */
    GC placeholderGC;		/* For drawing placeholder text. */
    int placeholderX;		/* Origin for layout. */
    int placeholderLeftIndex;	/* Character index of left-most character
				 * visible in window. */

    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    const char *displayString;	/* String to use when displaying. This may be
				 * a pointer to string, or a pointer to
				 * malloced memory with the same character
				 * length as string but whose characters are
				 * all equal to showChar. */
    TkSizeT numBytes;		/* Length of string in bytes. */
    TkSizeT numChars;		/* Length of string in characters. Both string
				 * and displayString have the same character
				 * length, but may have different byte lengths
				 * due to being made from different UTF-8
				 * characters. */
    TkSizeT numDisplayBytes;	/* Length of displayString in bytes. */
    int inset;			/* Number of pixels on the left and right
				 * sides that are taken up by XPAD,
				 * borderWidth (if any), and highlightWidth
				 * (if any). */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int layoutX, layoutY;	/* Origin for layout. */
    int leftX;			/* X position at which character at leftIndex
				 * is drawn (varies depending on justify). */
    TkSizeT leftIndex;		/* Character index of left-most character
				 * visible in window. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
    GC textGC;			/* For drawing normal text. */
    GC selTextGC;		/* For drawing selected text. */
    GC highlightGC;		/* For drawing traversal highlight. */







<
<
<
<
<
<
<
<
<
<
<
<
<










|
|




|








|







124
125
126
127
128
129
130













131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
				 * scrollbar(s). Malloc'ed. NULL means no
				 * command to issue. */
    char *showChar;		/* Value of -show option. If non-NULL, first
				 * character is used for displaying all
				 * characters in entry. Malloc'ed. This is
				 * only used by the Entry widget. */














    /*
     * Fields whose values are derived from the current values of the
     * configuration settings above.
     */

    const char *displayString;	/* String to use when displaying. This may be
				 * a pointer to string, or a pointer to
				 * malloced memory with the same character
				 * length as string but whose characters are
				 * all equal to showChar. */
    int numBytes;		/* Length of string in bytes. */
    int numChars;		/* Length of string in characters. Both string
				 * and displayString have the same character
				 * length, but may have different byte lengths
				 * due to being made from different UTF-8
				 * characters. */
    int numDisplayBytes;	/* Length of displayString in bytes. */
    int inset;			/* Number of pixels on the left and right
				 * sides that are taken up by XPAD,
				 * borderWidth (if any), and highlightWidth
				 * (if any). */
    Tk_TextLayout textLayout;	/* Cached text layout information. */
    int layoutX, layoutY;	/* Origin for layout. */
    int leftX;			/* X position at which character at leftIndex
				 * is drawn (varies depending on justify). */
    int leftIndex;		/* Character index of left-most character
				 * visible in window. */
    Tcl_TimerToken insertBlinkHandler;
				/* Timer handler used to blink cursor on and
				 * off. */
    GC textGC;			/* For drawing normal text. */
    GC selTextGC;		/* For drawing selected text. */
    GC highlightGC;		/* For drawing traversal highlight. */
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 */







|

|

|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
    double fromValue;		/* Value corresponding to left/top of dial */
    double toValue;		/* Value corresponding to right/bottom of
				 * dial */
    double increment;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    char *formatBuf;		/* string into which to format value.
				 * Malloc'ed. */
    char *reqFormat;		/* 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 */
Changes to generic/tkError.c.
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.
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    /*
     * Create the handler record.
     */

    errorPtr = (TkErrorHandler *)ckalloc(sizeof(TkErrorHandler));
    errorPtr->dispPtr = dispPtr;
    errorPtr->firstRequest = NextRequest(display);
    errorPtr->lastRequest = (unsigned) -1;
    errorPtr->error = error;
    errorPtr->request = request;
    errorPtr->minorCode = minorCode;
    errorPtr->errorProc = errorProc;
    errorPtr->clientData = clientData;
    errorPtr->nextPtr = dispPtr->errorPtr;
    dispPtr->errorPtr = errorPtr;







|







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    /*
     * Create the handler record.
     */

    errorPtr = (TkErrorHandler *)ckalloc(sizeof(TkErrorHandler));
    errorPtr->dispPtr = dispPtr;
    errorPtr->firstRequest = NextRequest(display);
    errorPtr->lastRequest = (unsigned long) -1;
    errorPtr->error = error;
    errorPtr->request = request;
    errorPtr->minorCode = minorCode;
    errorPtr->errorProc = errorProc;
    errorPtr->clientData = clientData;
    errorPtr->nextPtr = dispPtr->errorPtr;
    dispPtr->errorPtr = errorPtr;
148
149
150
151
152
153
154





155
156
157
158
159
160
161
				 * return value from Tk_CreateErrorHandler. */
{
    TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
    TkDisplay *dispPtr = errorPtr->dispPtr;

    errorPtr->lastRequest = NextRequest(dispPtr->display) - 1;






    /*
     * Every once-in-a-while, cleanup handlers that are no longer active. We
     * probably won't be able to free the handler that was just deleted (need
     * to wait for any outstanding requests to be processed by server), but
     * there may be previously-deleted handlers that are now ready for garbage
     * collection. To reduce the cost of the cleanup, let a few dead handlers
     * pile up, then clean them all at once. This adds a bit of overhead to







>
>
>
>
>







148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
				 * return value from Tk_CreateErrorHandler. */
{
    TkErrorHandler *errorPtr = (TkErrorHandler *) handler;
    TkDisplay *dispPtr = errorPtr->dispPtr;

    errorPtr->lastRequest = NextRequest(dispPtr->display) - 1;

    /*
     * Ensure that no user callback for this handler is invoked any further.
     */
    errorPtr->errorProc = NULL;

    /*
     * Every once-in-a-while, cleanup handlers that are no longer active. We
     * probably won't be able to free the handler that was just deleted (need
     * to wait for any outstanding requests to be processed by server), but
     * there may be previously-deleted handlers that are now ready for garbage
     * collection. To reduce the cost of the cleanup, let a few dead handlers
     * pile up, then clean them all at once. This adds a bit of overhead to
Changes to generic/tkEvent.c.
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#elif defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#else
#include "tkUnixInt.h"
#endif

/*
 * There's a potential problem if a handler is deleted while it's current
 * (i.e. its function is executing), since Tk_HandleEvent will need to read
 * the handler's "nextPtr" field when the function returns. To handle this
 * problem, structures of the type below indicate the next handler to be
 * processed for any (recursively nested) dispatches in progress. The
 * nextHandler fields get updated if the handlers pointed to are deleted.







<
<
<
<
<
<
<
<







11
12
13
14
15
16
17








18
19
20
21
22
23
24
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"









/*
 * There's a potential problem if a handler is deleted while it's current
 * (i.e. its function is executing), since Tk_HandleEvent will need to read
 * the handler's "nextPtr" field when the function returns. To handle this
 * problem, structures of the type below indicate the next handler to be
 * processed for any (recursively nested) dispatches in progress. The
 * nextHandler fields get updated if the handlers pointed to are deleted.
209
210
211
212
213
214
215

216

217
218
219
220
221
222
223
static int		InvokeMouseHandlers(TkWindow *winPtr,
			    unsigned long mask, XEvent *eventPtr);
static Window		ParentXId(Display *display, Window w);
static int		RefreshKeyboardMappingIfNeeded(XEvent *eventPtr);
static int		TkXErrorHandler(ClientData clientData,
			    XErrorEvent *errEventPtr);
static int		WindowEventProc(Tcl_Event *evPtr, int flags);

static void		CreateXIC(TkWindow *winPtr);


/*
 *----------------------------------------------------------------------
 *
 * InvokeFocusHandlers --
 *
 *	Call focus-related code to look at FocusIn, FocusOut, Enter, and Leave







>

>







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
static int		InvokeMouseHandlers(TkWindow *winPtr,
			    unsigned long mask, XEvent *eventPtr);
static Window		ParentXId(Display *display, Window w);
static int		RefreshKeyboardMappingIfNeeded(XEvent *eventPtr);
static int		TkXErrorHandler(ClientData clientData,
			    XErrorEvent *errEventPtr);
static int		WindowEventProc(Tcl_Event *evPtr, int flags);
#ifdef TK_USE_INPUT_METHODS
static void		CreateXIC(TkWindow *winPtr);
#endif /* TK_USE_INPUT_METHODS */

/*
 *----------------------------------------------------------------------
 *
 * InvokeFocusHandlers --
 *
 *	Call focus-related code to look at FocusIn, FocusOut, Enter, and Leave
317
318
319
320
321
322
323

324
325
326
327
328
329
330
 *
 *	Create the X input context for our winPtr.
 *	XIM is only ever enabled on Unix.
 *
 *----------------------------------------------------------------------
 */


static void
CreateXIC(
    TkWindow *winPtr)
{
    TkDisplay *dispPtr = winPtr->dispPtr;
    long im_event_mask = 0L;
    const char *preedit_attname = NULL;







>







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
 *
 *	Create the X input context for our winPtr.
 *	XIM is only ever enabled on Unix.
 *
 *----------------------------------------------------------------------
 */

#ifdef TK_USE_INPUT_METHODS
static void
CreateXIC(
    TkWindow *winPtr)
{
    TkDisplay *dispPtr = winPtr->dispPtr;
    long im_event_mask = 0L;
    const char *preedit_attname = NULL;
363
364
365
366
367
368
369

370
371
372
373
374
375
376
     */
    XGetICValues(winPtr->inputContext, XNFilterEvents, &im_event_mask, NULL);
    if ((winPtr->atts.event_mask & im_event_mask) != im_event_mask) {
	winPtr->atts.event_mask |= im_event_mask;
	XSelectInput(winPtr->display, winPtr->window, winPtr->atts.event_mask);
    }
}


/*
 *----------------------------------------------------------------------
 *
 * GetTkWindowFromXEvent --
 *
 *	Attempt to find which TkWindow is associated with an event. If it







>







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
     */
    XGetICValues(winPtr->inputContext, XNFilterEvents, &im_event_mask, NULL);
    if ((winPtr->atts.event_mask & im_event_mask) != im_event_mask) {
	winPtr->atts.event_mask |= im_event_mask;
	XSelectInput(winPtr->display, winPtr->window, winPtr->atts.event_mask);
    }
}
#endif

/*
 *----------------------------------------------------------------------
 *
 * GetTkWindowFromXEvent --
 *
 *	Attempt to find which TkWindow is associated with an event. If it
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_GetButtonMask --
 *
 *	Return the proper Button${n}Mask for the button. Don't care about
 *	Button4 - Button7, because those are not actually buttons: Those
 *	are used for the horizontal or vertical mouse wheels. Button4Mask
 *	and higher is actually used for Button 8 and higher.
 *
 * Results:
 *	A button mask.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static const unsigned buttonMasks[] = {
    0, Button1Mask, Button2Mask, Button3Mask, 0, 0, 0, 0, Button4Mask, \
	    Button5Mask, Button6Mask, Button7Mask, Button8Mask, Button9Mask
};

unsigned
Tk_GetButtonMask(
    unsigned button)
{
    return (button > Button9) ? 0 : buttonMasks[button];
}

/*
 *----------------------------------------------------------------------
 *
 * InvokeClientMessageHandlers --
 *







|

|
<
<
<











|
<



|


|







505
506
507
508
509
510
511
512
513
514



515
516
517
518
519
520
521
522
523
524
525
526

527
528
529
530
531
532
533
534
535
536
537
538
539
540
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetButtonMask --
 *
 *	Return the proper Button${n}Mask for the button.



 *
 * Results:
 *	A button mask.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static const unsigned buttonMasks[] = {
    0, Button1Mask, Button2Mask, Button3Mask, Button4Mask, Button5Mask

};

unsigned
TkGetButtonMask(
    unsigned button)
{
    return (button > Button5) ? 0 : buttonMasks[button];
}

/*
 *----------------------------------------------------------------------
 *
 * InvokeClientMessageHandlers --
 *
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkEventInit --
 *
 *	This functions initializes all the event module structures used by the
 *	current thread. It must be called before any other function in this
 *	file is called.
 *
 * Results:
 *	None.
 *
 * Side Effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

void
TkEventInit(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->handlersActive	= 0;
    tsdPtr->pendingPtr		= NULL;
    tsdPtr->genericList		= NULL;
    tsdPtr->lastGenericPtr	= NULL;
    tsdPtr->cmList		= NULL;
    tsdPtr->lastCmPtr		= NULL;
    tsdPtr->restrictProc	= NULL;
    tsdPtr->restrictArg		= NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkXErrorHandler --
 *
 *	TkXErrorHandler is an error handler, to be installed via
 *	Tk_CreateErrorHandler, that will set a flag if an X error occurred.
 *
 * Results:
 *	Always returns 0, indicating that the X error was handled.







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







980
981
982
983
984
985
986


































987
988
989
990
991
992
993
	}
    }
}

/*
 *----------------------------------------------------------------------
 *


































 * TkXErrorHandler --
 *
 *	TkXErrorHandler is an error handler, to be installed via
 *	Tk_CreateErrorHandler, that will set a flag if an X error occurred.
 *
 * Results:
 *	Always returns 0, indicating that the X error was handled.
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
    TkWindow *winPtr;
    unsigned long mask;
    InProgress ip;
    Tcl_Interp *interp = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


#if !defined(_WIN32) && !defined(MAC_OSX_TK)
    if ((eventPtr->xbutton.button >= Button4) && (eventPtr->xbutton.button < Button8)) {
	if (eventPtr->type == ButtonRelease) {
	    return;
	} else if (eventPtr->type == ButtonPress) {
	    int but = eventPtr->xbutton.button;
	    eventPtr->type = MouseWheelEvent;
	    eventPtr->xany.send_event = -1;
	    eventPtr->xkey.keycode = (but & 1) ? -120 : 120;
	    if (but > Button5) {
		eventPtr->xkey.state ^= ShiftMask;
	    }
	}
    }
#endif

    /*
     * If the generic handler processed this event we are done and can return.
     */








<
|
<
<
<
|
|
<
|
<
<
|
<
<







1094
1095
1096
1097
1098
1099
1100

1101



1102
1103

1104


1105


1106
1107
1108
1109
1110
1111
1112
    TkWindow *winPtr;
    unsigned long mask;
    InProgress ip;
    Tcl_Interp *interp = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


#if !defined(MAC_OSX_TK) && !defined(_WIN32)



    if (((eventPtr->type == ButtonPress) || (eventPtr->type == ButtonRelease))
	    && ((eventPtr->xbutton.button - 6) < 2)) {

	eventPtr->xbutton.button -= 2;


	eventPtr->xbutton.state ^= ShiftMask;


    }
#endif

    /*
     * If the generic handler processed this event we are done and can return.
     */

1219
1220
1221
1222
1223
1224
1225

1226
1227
1228
1229
1230
1231
1232
    /*
     * Create the input context for the window if it hasn't already been done
     * (XFilterEvent needs this context). When the event is a FocusIn event,
     * set the input context focus to the receiving window. This code is only
     * ever active for X11.
     */


    /*
     * If the XIC has been invalidated, it must be recreated.
     */
    if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) {
	winPtr->flags &= ~TK_CHECKED_IC;
	winPtr->inputContext = NULL;
    }







>







1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
    /*
     * Create the input context for the window if it hasn't already been done
     * (XFilterEvent needs this context). When the event is a FocusIn event,
     * set the input context focus to the receiving window. This code is only
     * ever active for X11.
     */

#ifdef TK_USE_INPUT_METHODS
    /*
     * If the XIC has been invalidated, it must be recreated.
     */
    if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) {
	winPtr->flags &= ~TK_CHECKED_IC;
	winPtr->inputContext = NULL;
    }
1240
1241
1242
1243
1244
1245
1246

1247
1248
1249
1250
1251
1252
1253
	}
	if ((eventPtr->type == FocusIn) &&
		(winPtr->dispPtr->inputMethod != NULL) &&
		(winPtr->inputContext != NULL)) {
	    XSetICFocus(winPtr->inputContext);
	}
    }


    /*
     * For events where it hasn't already been done, update the current time
     * in the display.
     */

    if (eventPtr->type == PropertyNotify) {







>







1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
	}
	if ((eventPtr->type == FocusIn) &&
		(winPtr->dispPtr->inputMethod != NULL) &&
		(winPtr->inputContext != NULL)) {
	    XSetICFocus(winPtr->inputContext);
	}
    }
#endif /*TK_USE_INPUT_METHODS*/

    /*
     * For events where it hasn't already been done, update the current time
     * in the display.
     */

    if (eventPtr->type == PropertyNotify) {
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017

/*
 *----------------------------------------------------------------------
 *
 * 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.







|







1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968

/*
 *----------------------------------------------------------------------
 *
 * TkFinalize --
 *
 *	Runs our private exit handlers and removes itself from Tcl. This is
 *	beneficial should we want to protect from dangling pointers should the
 *	Tk shared library be unloaded prior to Tcl which can happen on windows
 *	should the process be forcefully exiting from an exception handler.
 *
 * Results:
 *	None.
 *
 * Side effects.
Changes to generic/tkFileFilter.c.
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
	/*
	 * 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++) {
	    int len;
	    const char *strType = Tcl_GetStringFromObj(ostypeList[i], &len);

	    /*
	     * If len is < 4, it is definitely an error. If equal or longer,
	     * we need to use the macRoman encoding to determine the correct
	     * length (assuming there may be non-ascii characters, e.g.,
	     * embedded nulls or accented characters in the string, the
	     * macRoman length will be different).
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
	}
    }

    /*
     * Add the clause into the list of clauses
     */

    clausePtr = (FileFilterClause *)ckalloc(sizeof(FileFilterClause));
    clausePtr->patterns = NULL;
    clausePtr->patternsTail = NULL;
    clausePtr->macTypes = NULL;
    clausePtr->macTypesTail = NULL;

    if (filterPtr->clauses == NULL) {
	filterPtr->clauses = filterPtr->clausesTail = clausePtr;
    } else {
	filterPtr->clausesTail->next = clausePtr;
	filterPtr->clausesTail = clausePtr;
    }
    clausePtr->next = NULL;

    if (globCount > 0 && globList != NULL) {
	for (i=0; i<globCount; i++) {
	    GlobPattern *globPtr = (GlobPattern *)ckalloc(sizeof(GlobPattern));
	    TkSizeT len;
	    const char *str = TkGetStringFromObj(globList[i], &len);

	    len = (len + 1) * sizeof(char);
	    if (str[0] && str[0] != '*') {
		/*
		 * Prepend a "*" to patterns that do not have a leading "*"
		 */

		globPtr->pattern = (char *)ckalloc(len + 1);
		globPtr->pattern[0] = '*';
		strcpy(globPtr->pattern+1, str);
	    } else if (isWindows) {
		if (strcmp(str, "*") == 0) {
		    globPtr->pattern = (char *)ckalloc(4);
		    strcpy(globPtr->pattern, "*.*");
		} else if (strcmp(str, "") == 0) {
		    /*
		     * An empty string means "match all files with no
		     * extensions"
		     * TODO: "*." actually matches with all files on Win95
		     */

		    globPtr->pattern = (char *)ckalloc(3);
		    strcpy(globPtr->pattern, "*.");
		} else {
		    globPtr->pattern = (char *)ckalloc(len);
		    strcpy(globPtr->pattern, str);
		}
	    } else {
		globPtr->pattern = (char *)ckalloc(len);
		strcpy(globPtr->pattern, str);
	    }

	    /*
	     * Add the glob pattern into the list of patterns.
	     */








|















|
|
|







|




|








|


|



|







301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
	}
    }

    /*
     * Add the clause into the list of clauses
     */

    clausePtr = ckalloc(sizeof(FileFilterClause));
    clausePtr->patterns = NULL;
    clausePtr->patternsTail = NULL;
    clausePtr->macTypes = NULL;
    clausePtr->macTypesTail = NULL;

    if (filterPtr->clauses == NULL) {
	filterPtr->clauses = filterPtr->clausesTail = clausePtr;
    } else {
	filterPtr->clausesTail->next = clausePtr;
	filterPtr->clausesTail = clausePtr;
    }
    clausePtr->next = NULL;

    if (globCount > 0 && globList != NULL) {
	for (i=0; i<globCount; i++) {
	    GlobPattern *globPtr = ckalloc(sizeof(GlobPattern));
	    int len;
	    const char *str = Tcl_GetStringFromObj(globList[i], &len);

	    len = (len + 1) * sizeof(char);
	    if (str[0] && str[0] != '*') {
		/*
		 * Prepend a "*" to patterns that do not have a leading "*"
		 */

		globPtr->pattern = ckalloc(len + 1);
		globPtr->pattern[0] = '*';
		strcpy(globPtr->pattern+1, str);
	    } else if (isWindows) {
		if (strcmp(str, "*") == 0) {
		    globPtr->pattern = ckalloc(4);
		    strcpy(globPtr->pattern, "*.*");
		} else if (strcmp(str, "") == 0) {
		    /*
		     * An empty string means "match all files with no
		     * extensions"
		     * TODO: "*." actually matches with all files on Win95
		     */

		    globPtr->pattern = ckalloc(3);
		    strcpy(globPtr->pattern, "*.");
		} else {
		    globPtr->pattern = ckalloc(len);
		    strcpy(globPtr->pattern, str);
		}
	    } else {
		globPtr->pattern = ckalloc(len);
		strcpy(globPtr->pattern, str);
	    }

	    /*
	     * Add the glob pattern into the list of patterns.
	     */

371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
    }
    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
	     */








|
|
|







371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
    }
    if (ostypeList != NULL && ostypeCount > 0) {
	if (macRoman == NULL) {
	    macRoman = Tcl_GetEncoding(NULL, "macRoman");
	}
	for (i=0; i<ostypeCount; i++) {
	    Tcl_DString osTypeDS;
	    int len;
	    MacFileType *mfPtr = ckalloc(sizeof(MacFileType));
	    const char *strType = Tcl_GetStringFromObj(ostypeList[i], &len);
	    char *string;

	    /*
	     * Convert utf to macRoman, since MacOS types are defined to be 4
	     * macRoman characters long
	     */

441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

    for (; filterPtr; filterPtr=filterPtr->next) {
	if (strcmp(filterPtr->name, name) == 0) {
	    return filterPtr;
	}
    }

    filterPtr = (FileFilter *)ckalloc(sizeof(FileFilter));
    filterPtr->clauses = NULL;
    filterPtr->clausesTail = NULL;
    len = strlen(name) + 1;
    filterPtr->name = (char *)ckalloc(len);
    memcpy(filterPtr->name, name, len);

    if (flistPtr->filters == NULL) {
	flistPtr->filters = flistPtr->filtersTail = filterPtr;
    } else {
	flistPtr->filtersTail->next = filterPtr;
	flistPtr->filtersTail = filterPtr;







|



|







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459

    for (; filterPtr; filterPtr=filterPtr->next) {
	if (strcmp(filterPtr->name, name) == 0) {
	    return filterPtr;
	}
    }

    filterPtr = ckalloc(sizeof(FileFilter));
    filterPtr->clauses = NULL;
    filterPtr->clausesTail = NULL;
    len = strlen(name) + 1;
    filterPtr->name = ckalloc(len);
    memcpy(filterPtr->name, name, len);

    if (flistPtr->filters == NULL) {
	flistPtr->filters = flistPtr->filtersTail = filterPtr;
    } else {
	flistPtr->filtersTail->next = filterPtr;
	flistPtr->filtersTail = filterPtr;
Changes to generic/tkFileFilter.h.
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK_FILE_FILTER
#define _TK_FILE_FILTER

#ifdef __cplusplus
extern "C" {
#endif

#define OSType long

typedef struct GlobPattern {
    struct GlobPattern *next;	/* Chains to the next glob pattern in a glob
				 * pattern list */
    char *pattern;		/* String value of the pattern, such as
				 * "*.txt" or "*.*" */







<
<
<
<







9
10
11
12
13
14
15




16
17
18
19
20
21
22
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TK_FILE_FILTER
#define _TK_FILE_FILTER





#define OSType long

typedef struct GlobPattern {
    struct GlobPattern *next;	/* Chains to the next glob pattern in a glob
				 * pattern list */
    char *pattern;		/* String value of the pattern, such as
				 * "*.txt" or "*.*" */
75
76
77
78
79
80
81
82
83
84
85
86

MODULE_SCOPE void	TkFreeFileFilters(FileFilterList *flistPtr);
MODULE_SCOPE void	TkInitFileFilters(FileFilterList *flistPtr);
MODULE_SCOPE int	TkGetFileFilters(Tcl_Interp *interp,
    			    FileFilterList *flistPtr, Tcl_Obj *valuePtr,
			    int isWindows);

#ifdef __cplusplus
}
#endif

#endif	/* _TK_FILE_FILTER */







<
<
<
<

71
72
73
74
75
76
77




78

MODULE_SCOPE void	TkFreeFileFilters(FileFilterList *flistPtr);
MODULE_SCOPE void	TkInitFileFilters(FileFilterList *flistPtr);
MODULE_SCOPE int	TkGetFileFilters(Tcl_Interp *interp,
    			    FileFilterList *flistPtr, Tcl_Obj *valuePtr,
			    int isWindows);





#endif	/* _TK_FILE_FILTER */
Changes to generic/tkFocus.c.
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,
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
     * If invoked with no arguments, just return the current focus window.
     */

    if (objc == 1) {
	Tk_Window focusWin = (Tk_Window) TkGetFocusWin(winPtr);

	if (focusWin != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj(focusWin));
	}
	return TCL_OK;
    }

    /*
     * If invoked with a single argument beginning with "." then focus on that
     * window.







|







124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
     * If invoked with no arguments, just return the current focus window.
     */

    if (objc == 1) {
	Tk_Window focusWin = (Tk_Window) TkGetFocusWin(winPtr);

	if (focusWin != NULL) {
	    Tcl_SetObjResult(interp, TkNewWindowObj(focusWin));
	}
	return TCL_OK;
    }

    /*
     * If invoked with a single argument beginning with "." then focus on that
     * window.
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
	windowName = Tcl_GetString(objv[2]);
	newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin);
	if (newPtr == NULL) {
	    return TCL_ERROR;
	}
	newPtr = TkGetFocusWin(newPtr);
	if (newPtr != NULL) {
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) newPtr));
	}
	break;
    case 1:			/* -force */
	windowName = Tcl_GetString(objv[2]);

	/*
	 * The empty string case exists for backwards compatibility.







|







175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
	windowName = Tcl_GetString(objv[2]);
	newPtr = (TkWindow *) Tk_NameToWindow(interp, windowName, tkwin);
	if (newPtr == NULL) {
	    return TCL_ERROR;
	}
	newPtr = TkGetFocusWin(newPtr);
	if (newPtr != NULL) {
	    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) newPtr));
	}
	break;
    case 1:			/* -force */
	windowName = Tcl_GetString(objv[2]);

	/*
	 * The empty string case exists for backwards compatibility.
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
		topLevelPtr = topLevelPtr->parentPtr) {
	    if (!(topLevelPtr->flags & TK_TOP_HIERARCHY)) {
		continue;
	    }
	    for (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
		    tlFocusPtr = tlFocusPtr->nextPtr) {
		if (tlFocusPtr->topLevelPtr == topLevelPtr) {
		    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window)
			    tlFocusPtr->focusWinPtr));
		    return TCL_OK;
		}
	    }
	    Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window) topLevelPtr));
	    return TCL_OK;
	}
	break;
    default:
	Tcl_Panic("bad const entries to focusOptions in focus command");
    }
    return TCL_OK;







|




|







208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
		topLevelPtr = topLevelPtr->parentPtr) {
	    if (!(topLevelPtr->flags & TK_TOP_HIERARCHY)) {
		continue;
	    }
	    for (tlFocusPtr = newPtr->mainPtr->tlFocusPtr; tlFocusPtr != NULL;
		    tlFocusPtr = tlFocusPtr->nextPtr) {
		if (tlFocusPtr->topLevelPtr == topLevelPtr) {
		    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window)
			    tlFocusPtr->focusWinPtr));
		    return TCL_OK;
		}
	    }
	    Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window) topLevelPtr));
	    return TCL_OK;
	}
	break;
    default:
	Tcl_Panic("bad const entries to focusOptions in focus command");
    }
    return TCL_OK;
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
	 * 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.
13
14
15
16
17
18
19




20
21
22
23
24
25
26

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

typedef struct TkFontInfo {







>
>
>
>







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

#include "tkInt.h"
#include "tkFont.h"
#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"    /* Defines TK_DRAW_IN_CONTEXT */
#endif

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following structure is used to keep track of all the fonts that exist
 * in the current application. It must be stored in the TkMainInfo for the
 * application.
 */

typedef struct TkFontInfo {
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
/*
 * The following data structure is used to keep track of the font attributes
 * for each named font that has been defined. The named font is only deleted
 * when the last reference to it goes away.
 */

typedef struct NamedFont {
    size_t refCount;		/* Number of users of named font. */
    int deletePending;		/* Non-zero if font should be deleted when
				 * last reference goes away. */
    TkFontAttributes fa;	/* Desired attributes for named font. */
} NamedFont;

/*
 * The following two structures are used to keep track of string measurement







|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
/*
 * The following data structure is used to keep track of the font attributes
 * for each named font that has been defined. The named font is only deleted
 * when the last reference to it goes away.
 */

typedef struct NamedFont {
    int refCount;		/* Number of users of named font. */
    int deletePending;		/* Non-zero if font should be deleted when
				 * last reference goes away. */
    TkFontAttributes fa;	/* Desired attributes for named font. */
} NamedFont;

/*
 * The following two structures are used to keep track of string measurement
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
 */

const Tcl_ObjType tkFontObjType = {
    "font",			/* name */
    FreeFontObjProc,		/* freeIntRepProc */
    DupFontObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * TkFontPkgInit --
 *







|







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

const Tcl_ObjType tkFontObjType = {
    "font",			/* name */
    FreeFontObjProc,		/* freeIntRepProc */
    DupFontObjProc,		/* dupIntRepProc */
    NULL,			/* updateStringProc */
    SetFontFromAny		/* setFromAnyProc */
};

/*
 *---------------------------------------------------------------------------
 *
 * 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







>

>




>

>







416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
void
TkFontPkgFree(
    TkMainInfo *mainPtr)	/* The application being deleted. */
{
    TkFontInfo *fiPtr = mainPtr->fontInfoPtr;
    Tcl_HashEntry *hPtr, *searchPtr;
    Tcl_HashSearch search;
#ifdef PURIFY
    int fontsLeft = 0;
#endif

    for (searchPtr = Tcl_FirstHashEntry(&fiPtr->fontCache, &search);
	    searchPtr != NULL;
	    searchPtr = Tcl_NextHashEntry(&search)) {
#ifdef PURIFY
	fontsLeft++;
#endif
#ifdef DEBUG_FONTS
	fprintf(stderr, "Font %s still in cache.\n",
		(char *) Tcl_GetHashKey(&fiPtr->fontCache, searchPtr));
#endif
    }

#ifdef PURIFY
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
	    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++;







|







522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
	    return TCL_ERROR;
	}

	/*
	 * Next parameter may be an option.
	 */

	n = 3 + skip;
	optPtr = NULL;
	charPtr = NULL;
	if (n < objc) {
	    s = Tcl_GetString(objv[n]);
	    if (s[0] == '-' && s[1] != '-') {
		optPtr = objv[n];
		n++;
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578

	/*
	 * If there were fewer than 3 args, or args remain, that's an error.
	 */

	if (objc < 3 || n < objc) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? ?-option? ?--? ?char?");
	    return TCL_ERROR;
	}

	/*
	 * The 'charPtr' arg must be a single Unicode.
	 */

	if (charPtr != NULL) {
	    const char *string = Tcl_GetString(charPtr);
	    size_t len = TkUtfToUniChar(string, &uniChar);

	    if (len != (size_t)charPtr->length) {
		resultPtr = Tcl_NewStringObj(
			"expected a single character but got \"", -1);
		Tcl_AppendLimitedToObj(resultPtr, string,
			-1, 40, "...");
		Tcl_AppendToObj(resultPtr, "\"", -1);
		Tcl_SetObjResult(interp, resultPtr);
		Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL);







|









|

|







560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586

	/*
	 * If there were fewer than 3 args, or args remain, that's an error.
	 */

	if (objc < 3 || n < objc) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? ?option? ?--? ?char?");
	    return TCL_ERROR;
	}

	/*
	 * The 'charPtr' arg must be a single Unicode.
	 */

	if (charPtr != NULL) {
	    const char *string = Tcl_GetString(charPtr);
	    int len = TkUtfToUniChar(string, &uniChar);

	    if (len != charPtr->length) {
		resultPtr = Tcl_NewStringObj(
			"expected a single character but got \"", -1);
		Tcl_AppendLimitedToObj(resultPtr, string,
			-1, 40, "...");
		Tcl_AppendToObj(resultPtr, "\"", -1);
		Tcl_SetObjResult(interp, resultPtr);
		Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL);
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
	}
	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;







|







664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
	}
	if (name == NULL) {
	    /*
	     * No font name specified. Generate one of the form "fontX".
	     */

	    for (i = 1; ; i++) {
		snprintf(buf, sizeof(buf), "font%d", i);
		namedHashPtr = Tcl_FindHashEntry(&fiPtr->namedTable, buf);
		if (namedHashPtr == NULL) {
		    break;
		}
	    }
	    name = buf;
	    skip = 2;
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
    }
    case FONT_FAMILIES: {
	int skip = TkGetDisplayOf(interp, objc - 2, objv + 2, &tkwin);

	if (skip < 0) {
	    return TCL_ERROR;
	}
	if (objc - skip != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-displayof window?");
	    return TCL_ERROR;
	}
	TkpGetFontFamilies(interp, tkwin);
	break;
    }
    case FONT_MEASURE: {
	const char *string;
	Tk_Font tkfont;
	TkSizeT length = 0;
	int skip = 0;

	if (objc > 4) {
	    skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	    if (skip < 0) {
		return TCL_ERROR;
	    }
	}
	if (objc - skip != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? text");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;
	}
	string = TkGetStringFromObj(objv[3 + skip], &length);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		Tk_TextWidth(tkfont, string, length)));
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_METRICS: {
	Tk_Font tkfont;
	int skip, i;
	const TkFontMetrics *fmPtr;
	static const char *const switches[] = {
	    "-ascent", "-descent", "-linespace", "-fixed", NULL
	};

	skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if ((objc < 3) || ((objc - skip) > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "font ?-displayof window? ?-option?");
	    return TCL_ERROR;
	}
	tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]);
	if (tkfont == NULL) {
	    return TCL_ERROR;
	}
	objc -= skip;







|









|








|








|
|
















|

|







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
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;
	int length = 0;
	int skip = 0;

	if (objc > 4) {
	    skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	    if (skip < 0) {
		return TCL_ERROR;
	    }
	}
	if (objc != 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_NewIntObj(
		Tk_TextWidth(tkfont, string, length)));
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_METRICS: {
	Tk_Font tkfont;
	int skip, i;
	const TkFontMetrics *fmPtr;
	static const char *const switches[] = {
	    "-ascent", "-descent", "-linespace", "-fixed", NULL
	};

	skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin);
	if (skip < 0) {
	    return TCL_ERROR;
	}
	if ((objc < 3) || (objc > 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;
	}
	objc -= skip;
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
	    i = 0;		/* Needed only to prevent compiler warning. */
	    switch (index) {
	    case 0: i = fmPtr->ascent;			break;
	    case 1: i = fmPtr->descent;			break;
	    case 2: i = fmPtr->ascent + fmPtr->descent;	break;
	    case 3: i = fmPtr->fixed;			break;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(i));
	}
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *namedHashPtr;







|







785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
	    i = 0;		/* Needed only to prevent compiler warning. */
	    switch (index) {
	    case 0: i = fmPtr->ascent;			break;
	    case 1: i = fmPtr->descent;			break;
	    case 2: i = fmPtr->ascent + fmPtr->descent;	break;
	    case 3: i = fmPtr->fixed;			break;
	    }
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(i));
	}
	Tk_FreeFont(tkfont);
	break;
    }
    case FONT_NAMES: {
	Tcl_HashSearch search;
	Tcl_HashEntry *namedHashPtr;
894
895
896
897
898
899
900

901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927







928
929
930
931
932
933
934

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







>










|




|
|
|
|





|
|

>
>
>
>
>
>
>







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950

static void
RecomputeWidgets(
    TkWindow *winPtr)		/* Window to which command is sent. */
{
    Tk_ClassWorldChangedProc *proc =
	    Tk_GetClassProc(winPtr->classProcsPtr, worldChangedProc);
    TkWindow *tkwinPtr;

    if (proc != NULL) {
	proc(winPtr->instanceData);
    }

    /*
     * Notify all the descendants of this window that the world has changed.
     *
     * This could be done recursively or iteratively. The recursive version is
     * easier to implement and understand, and typically, windows with a -font
     * option will be leaf nodes in the widget 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.
    */
    TkSendVirtualEvent((Tk_Window)winPtr, "TkWorldChanged",
		       Tcl_NewStringObj("FontChanged",-1));
}

/*
 *---------------------------------------------------------------------------
 *
 * TkCreateNamedFont --
 *
1723
1724
1725
1726
1727
1728
1729

1730
1731
1732
1733
1734



1735
1736
1737
1738
1739
1740
1741
	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;
    }







>
|
|
|
|
|
>
>
>







1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
	upper = 1;
	for (; *src != '\0'; ) {
	    while (isspace(UCHAR(*src))) { /* INTL: ISO space */
		src++;
		upper = 1;
	    }
	    src += TkUtfToUniChar(src, &ch);
	    if (ch <= 0xffff) {
		if (upper) {
		    ch = Tcl_UniCharToUpper(ch);
		    upper = 0;
		} else {
		    ch = Tcl_UniCharToLower(ch);
		}
	    } else {
		upper = 0;
	    }
	    dest += TkUniCharToUtf(ch, dest);
	}
	*dest = '\0';
	Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr));
	family = Tcl_DStringValue(dsPtr) + len;
    }
1965
1966
1967
1968
1969
1970
1971

1972
1973
1974
1975
1976
1977
1978
1979
				 * 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);







>
|







1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
				 * newline characters should not cause a line
				 * break. */
    int *widthPtr,		/* Filled with width of string. */
    int *heightPtr)		/* Filled with height of string. */
{
    TkFont *fontPtr = (TkFont *) tkfont;
    const char *start, *endp, *special;
    int n;
    int y, bytesThisChunk, maxChunks, curLine, layoutHeight;
    int baseline, height, curX, newX, maxWidth, *lineLengths;
    TextLayout *layoutPtr;
    LayoutChunk *chunkPtr;
    const TkFontMetrics *fmPtr;
    Tcl_DString lineBuffer;

    Tcl_DStringInit(&lineBuffer);
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;

    layoutPtr = (TextLayout *)ckalloc(offsetof(TextLayout, chunks)
	    + maxChunks * sizeof(LayoutChunk));
    layoutPtr->tkfont = tkfont;
    layoutPtr->string = string;
    layoutPtr->numChunks = 0;

    baseline = fmPtr->ascent;
    maxWidth = 0;

    /*
     * Divide the string up into simple strings and measure each string.
     */

    curX = 0;

    endp = Tcl_UtfAtIndex(string, numChars);
    special = string;

    flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES;
    flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE;
    for (start = string; start < endp; ) {
	if (start >= special) {
	    /*







|














|







2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
    }
    if (wrapLength == 0) {
	wrapLength = -1;
    }

    maxChunks = 1;

    layoutPtr = (TextLayout *)ckalloc(Tk_Offset(TextLayout, chunks)
	    + maxChunks * sizeof(LayoutChunk));
    layoutPtr->tkfont = tkfont;
    layoutPtr->string = string;
    layoutPtr->numChunks = 0;

    baseline = fmPtr->ascent;
    maxWidth = 0;

    /*
     * Divide the string up into simple strings and measure each string.
     */

    curX = 0;

    endp = TkUtfAtIndex(string, numChars);
    special = string;

    flags &= TK_IGNORE_TABS | TK_IGNORE_NEWLINES;
    flags |= TK_WHOLE_WORDS | TK_AT_LEAST_ONE;
    for (start = string; start < endp; ) {
	if (start >= special) {
	    /*
2300
2301
2302
2303
2304
2305
2306

2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
				 * means to draw all characters. */
{
#if 0
    /* Use TkDrawAngledTextLayout() implementation - testing purposes at this point */
    TkDrawAngledTextLayout(display, drawable, gc, layout, x, y, 0.0, firstChar, lastChar);
#else
    TextLayout *layoutPtr = (TextLayout *) layout;

    int i, numDisplayChars, drawX;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;

    if (layoutPtr == NULL) {
	return;
    }

    if (lastChar < 0) {
	lastChar = 100000000;
    }
    chunkPtr = layoutPtr->chunks;
    for (i = 0; i < layoutPtr->numChunks; i++) {
	numDisplayChars = chunkPtr->numDisplayChars;
	if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) {
	    if (firstChar <= 0) {
		drawX = 0;
		firstChar = 0;
		firstByte = chunkPtr->start;
	    } else {
		firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar);
		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    TkpDrawCharsInContext(display, drawable, gc, layoutPtr->tkfont,
		    chunkPtr->start, chunkPtr->numBytes,
		    firstByte - chunkPtr->start, lastByte - firstByte,
		    x+chunkPtr->x, y+chunkPtr->y);
#else /* !TK_DRAW_IN_CONTEXT */
	    Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, firstByte,







>
|



















|






|







2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
				 * means to draw all characters. */
{
#if 0
    /* Use TkDrawAngledTextLayout() implementation - testing purposes at this point */
    TkDrawAngledTextLayout(display, drawable, gc, layout, x, y, 0.0, firstChar, lastChar);
#else
    TextLayout *layoutPtr = (TextLayout *) layout;
    int i, drawX;
    int numDisplayChars;
    const char *firstByte, *lastByte;
    LayoutChunk *chunkPtr;

    if (layoutPtr == NULL) {
	return;
    }

    if (lastChar < 0) {
	lastChar = 100000000;
    }
    chunkPtr = layoutPtr->chunks;
    for (i = 0; i < layoutPtr->numChunks; i++) {
	numDisplayChars = chunkPtr->numDisplayChars;
	if ((numDisplayChars > 0) && (firstChar < numDisplayChars)) {
	    if (firstChar <= 0) {
		drawX = 0;
		firstChar = 0;
		firstByte = chunkPtr->start;
	    } else {
		firstByte = TkUtfAtIndex(chunkPtr->start, firstChar);
		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = TkUtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    TkpDrawCharsInContext(display, drawable, gc, layoutPtr->tkfont,
		    chunkPtr->start, chunkPtr->numBytes,
		    firstByte - chunkPtr->start, lastByte - firstByte,
		    x+chunkPtr->x, y+chunkPtr->y);
#else /* !TK_DRAW_IN_CONTEXT */
	    Tk_DrawChars(display, drawable, gc, layoutPtr->tkfont, firstByte,
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
	    double dx, dy;

	    if (firstChar <= 0) {
		drawX = 0;
		firstChar = 0;
		firstByte = chunkPtr->start;
	    } else {
		firstByte = Tcl_UtfAtIndex(chunkPtr->start, firstChar);
		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = Tcl_UtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    dx = cosA * (chunkPtr->x) + sinA * (chunkPtr->y);
	    dy = -sinA * (chunkPtr->x) + cosA * (chunkPtr->y);
	    if (angle == 0.0) {
		TkpDrawCharsInContext(display, drawable, gc,
			layoutPtr->tkfont, chunkPtr->start, chunkPtr->numBytes,
			firstByte - chunkPtr->start, lastByte - firstByte,







|






|







2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
	    double dx, dy;

	    if (firstChar <= 0) {
		drawX = 0;
		firstChar = 0;
		firstByte = chunkPtr->start;
	    } else {
		firstByte = TkUtfAtIndex(chunkPtr->start, firstChar);
		Tk_MeasureChars(layoutPtr->tkfont, chunkPtr->start,
			firstByte - chunkPtr->start, -1, 0, &drawX);
	    }
	    if (lastChar < numDisplayChars) {
		numDisplayChars = lastChar;
	    }
	    lastByte = TkUtfAtIndex(chunkPtr->start, numDisplayChars);
#ifdef TK_DRAW_IN_CONTEXT
	    dx = cosA * (chunkPtr->x) + sinA * (chunkPtr->y);
	    dy = -sinA * (chunkPtr->x) + cosA * (chunkPtr->y);
	    if (angle == 0.0) {
		TkpDrawCharsInContext(display, drawable, gc,
			layoutPtr->tkfont, chunkPtr->start, chunkPtr->numBytes,
			firstByte - chunkPtr->start, lastByte - firstByte,
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749

2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
				 * non-NULL. */
    int *widthPtr, int *heightPtr)
				/* Filled with the width and height of the
				 * bounding box for the character specified by
				 * index, if non-NULL. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int i, x = 0, w;
    Tk_Font tkfont;
    TkFont *fontPtr;
    const char *end;

    if (index < 0) {
	return 0;
    }


    tkfont = layoutPtr->tkfont;
    fontPtr = (TkFont *) tkfont;

    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (chunkPtr->numDisplayChars < 0) {
	    if (index == 0) {
		x = chunkPtr->x;
		w = chunkPtr->totalWidth;
		goto check;
	    }
	} else if (index < chunkPtr->numChars) {
	    end = Tcl_UtfAtIndex(chunkPtr->start, index);
	    if (xPtr != NULL) {
		Tk_MeasureChars(tkfont, chunkPtr->start,
			end - chunkPtr->start, -1, 0, &x);
		x += chunkPtr->x;
	    }
	    if (widthPtr != NULL) {
		int ch;







|









>











|







2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
				 * non-NULL. */
    int *widthPtr, int *heightPtr)
				/* Filled with the width and height of the
				 * bounding box for the character specified by
				 * index, if non-NULL. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr;
    int i, x = 0, w;
    Tk_Font tkfont;
    TkFont *fontPtr;
    const char *end;

    if (index < 0) {
	return 0;
    }

    chunkPtr = layoutPtr->chunks;
    tkfont = layoutPtr->tkfont;
    fontPtr = (TkFont *) tkfont;

    for (i = 0; i < layoutPtr->numChunks; i++) {
	if (chunkPtr->numDisplayChars < 0) {
	    if (index == 0) {
		x = chunkPtr->x;
		w = chunkPtr->totalWidth;
		goto check;
	    }
	} else if (index < chunkPtr->numChars) {
	    end = TkUtfAtIndex(chunkPtr->start, index);
	    if (xPtr != NULL) {
		Tk_MeasureChars(tkfont, chunkPtr->start,
			end - chunkPtr->start, -1, 0, &x);
		x += chunkPtr->x;
	    }
	    if (widthPtr != NULL) {
		int ch;
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
    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) {







|







3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
    Tk_TextLayout layout)	/* The layout to be rendered. */
{
    TextLayout *layoutPtr = (TextLayout *) layout;
    LayoutChunk *chunkPtr = layoutPtr->chunks;
    int baseline = chunkPtr->y;
    Tcl_Obj *psObj = Tcl_NewObj();
    int i, j;
    int len;
    const char *p, *glyphname;
    char uindex[5], c, *ps;
    int ch;

    Tcl_AppendToObj(psObj, "[(", -1);
    for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) {
	if (baseline != chunkPtr->y) {
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
	     * 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;







|







3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347
3348
	     * Eventually this should be revised to handle more sophsticiated
	     * international postscript fonts.
	     */

	    p += TkUtfToUniChar(p, &ch);
	    if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) {
		/*
		 * Tricky point: the "03" is necessary in the 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
	     * 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 {







|


|







3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
	     * This character doesn't belong to the ASCII character set, so we
	     * use the full glyph name.
	     */

	    if (ch > 0xffff) {
		goto noMapping;
	    }
	    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 {
3402
3403
3404
3405
3406
3407
3408

3409
3410
3411
3412
3413
3414
3415
3416
    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,







>
|







3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437
3438
3439
3440
    TCL_UNUSED(Tk_Window),	/* For display on which font will be used. */
    int objc,			/* Number of elements in argv. */
    Tcl_Obj *const objv[],	/* Command line options. */
    TkFontAttributes *faPtr)	/* Font attributes structure whose fields are
				 * to be modified. Structure must already be
				 * properly initialized. */
{
    int i;
    int n, index;
    Tcl_Obj *optionPtr, *valuePtr;
    const char *value;

    for (i = 0; i < objc; i += 2) {
	optionPtr = objv[i];

	if (Tcl_GetIndexFromObj(interp, optionPtr, fontOpt, "option", 1,
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
	case FONT_FAMILY:
	    str = faPtr->family;
	    valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1));
	    break;

	case FONT_SIZE:
	    if (faPtr->size >= 0.0) {
		valuePtr = Tcl_NewWideIntObj((Tcl_WideInt)(faPtr->size + 0.5));
	    } else {
		valuePtr = Tcl_NewWideIntObj(-(Tcl_WideInt)(-faPtr->size + 0.5));
	    }
	    break;

	case FONT_WEIGHT:
	    str = TkFindStateString(weightMap, faPtr->weight);
	    valuePtr = Tcl_NewStringObj(str, -1);
	    break;







|

|







3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
	case FONT_FAMILY:
	    str = faPtr->family;
	    valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1));
	    break;

	case FONT_SIZE:
	    if (faPtr->size >= 0.0) {
		valuePtr = Tcl_NewIntObj((int)(faPtr->size + 0.5));
	    } else {
		valuePtr = Tcl_NewIntObj(-(int)(-faPtr->size + 0.5));
	    }
	    break;

	case FONT_WEIGHT:
	    str = TkFindStateString(weightMap, faPtr->weight);
	    valuePtr = Tcl_NewStringObj(str, -1);
	    break;
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
3628
3629
3630
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj(fontOpt[i], -1));
	Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}

/*
 *---------------------------------------------------------------------------
 *
 * Tk_FontGetDescription --
 *
 *	Return information about the font description as a Tcl list. One
 *	possible result is "{{DejaVu Sans} -16 bold underline}".
 *
 * Results:
 *	The list of descriptions.
 *
 * Side effects:
 *	None.
 *
 *---------------------------------------------------------------------------
 */

Tcl_Obj *
Tk_FontGetDescription(
    Tk_Font tkfont)		/* Font whose description is desired. */
{
    const TkFontAttributes *faPtr = GetFontAttributes(tkfont);
    Tcl_Obj *resultPtr = Tcl_NewObj();
    const char *str;

    str = faPtr->family;
    Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, str ? -1 : 0));
    if (faPtr->size >= 0.0) {
    	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewWideIntObj((int)(faPtr->size + 0.5)));
    } else {
    	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewWideIntObj(-(int)(-faPtr->size + 0.5)));
    }
    if (faPtr->weight != TK_FW_NORMAL) {
	str = TkFindStateString(weightMap, faPtr->weight);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    if (faPtr->slant != TK_FS_ROMAN) {
	str = TkFindStateString(slantMap, faPtr->slant);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    if (faPtr->underline) {
	str = TkFindStateString(underlineMap, faPtr->underline);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    if (faPtr->overstrike) {
	str = TkFindStateString(overstrikeMap, faPtr->overstrike);
	Tcl_ListObjAppendElement(NULL, resultPtr, Tcl_NewStringObj(str, -1));
    }
    return resultPtr;
}

/*
 *---------------------------------------------------------------------------
 *
 * ParseFontNameObj --
 *
 *	Converts a object into a set of font attributes that can be used to







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







3590
3591
3592
3593
3594
3595
3596



















































3597
3598
3599
3600
3601
3602
3603
	Tcl_ListObjAppendElement(NULL, resultPtr,
		Tcl_NewStringObj(fontOpt[i], -1));
	Tcl_ListObjAppendElement(NULL, resultPtr, valuePtr);
    }
    Tcl_SetObjResult(interp, resultPtr);
    return TCL_OK;
}




















































/*
 *---------------------------------------------------------------------------
 *
 * ParseFontNameObj --
 *
 *	Converts a object into a set of font attributes that can be used to
3654
3655
3656
3657
3658
3659
3660

3661
3662
3663
3664
3665
3666
3667
3668
    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 == '-') {







>
|







3627
3628
3629
3630
3631
3632
3633
3634
3635
3636
3637
3638
3639
3640
3641
3642
    Tcl_Obj *objPtr,		/* Parseable font description object. */
    TkFontAttributes *faPtr)	/* Filled with attributes parsed from font
				 * name. Any attributes that were not
				 * specified in font name are filled with
				 * default values. */
{
    const char *dash;
    int result, n;
    int objc, i;
    Tcl_Obj **objv;
    const char *string;

    TkInitFontAttributes(faPtr);

    string = Tcl_GetString(objPtr);
    if (*string == '-') {
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
    int maxChunks, numChars;
    size_t s;

    layoutPtr = *layoutPtrPtr;
    maxChunks = *maxPtr;
    if (layoutPtr->numChunks == maxChunks) {
	maxChunks *= 2;
	s = offsetof(TextLayout, chunks) + (maxChunks * sizeof(LayoutChunk));
	layoutPtr = (TextLayout *)ckrealloc(layoutPtr, s);

	*layoutPtrPtr = layoutPtr;
	*maxPtr = maxChunks;
    }
    numChars = Tcl_NumUtfChars(start, numBytes);
    chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks];







|







3795
3796
3797
3798
3799
3800
3801
3802
3803
3804
3805
3806
3807
3808
3809
    int maxChunks, numChars;
    size_t s;

    layoutPtr = *layoutPtrPtr;
    maxChunks = *maxPtr;
    if (layoutPtr->numChunks == maxChunks) {
	maxChunks *= 2;
	s = Tk_Offset(TextLayout, chunks) + (maxChunks * sizeof(LayoutChunk));
	layoutPtr = (TextLayout *)ckrealloc(layoutPtr, s);

	*layoutPtrPtr = layoutPtr;
	*maxPtr = maxChunks;
    }
    numChars = Tcl_NumUtfChars(start, numBytes);
    chunkPtr = &layoutPtr->chunks[layoutPtr->numChunks];
4275
4276
4277
4278
4279
4280
4281
4282
4283
4284
4285
4286
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297
4298
4299
4300
4301
4302
4303
4304
4305
4306
4307
4308
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugFont(
    Tk_Window tkwin,		/* The window in which the font will be used
				 * (not currently used). */
    const char *name)		/* Name of the desired color. */
{
    TkFont *fontPtr;
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr, *objPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(
	    &((TkWindow *) tkwin)->mainPtr->fontInfoPtr->fontCache, name);
    if (hashPtr != NULL) {
	fontPtr = (TkFont *)Tcl_GetHashValue(hashPtr);
	if (fontPtr == NULL) {
	    Tcl_Panic("TkDebugFont found empty hash table entry");
	}
	for ( ; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(fontPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewWideIntObj(fontPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*







|
















|

|







4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277
4278
4279
4280
4281
4282
 *----------------------------------------------------------------------
 */

Tcl_Obj *
TkDebugFont(
    Tk_Window tkwin,		/* The window in which the font will be used
				 * (not currently used). */
    const char *name)		/* Name of the desired font. */
{
    TkFont *fontPtr;
    Tcl_HashEntry *hashPtr;
    Tcl_Obj *resultPtr, *objPtr;

    resultPtr = Tcl_NewObj();
    hashPtr = Tcl_FindHashEntry(
	    &((TkWindow *) tkwin)->mainPtr->fontInfoPtr->fontCache, name);
    if (hashPtr != NULL) {
	fontPtr = (TkFont *)Tcl_GetHashValue(hashPtr);
	if (fontPtr == NULL) {
	    Tcl_Panic("TkDebugFont found empty hash table entry");
	}
	for ( ; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) {
	    objPtr = Tcl_NewObj();
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(fontPtr->resourceRefCount));
	    Tcl_ListObjAppendElement(NULL, objPtr,
		    Tcl_NewIntObj(fontPtr->objRefCount));
	    Tcl_ListObjAppendElement(NULL, resultPtr, objPtr);
	}
    }
    return resultPtr;
}

/*
Changes to generic/tkFont.h.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKFONT
#define _TKFONT

#ifdef __cplusplus
extern "C" {
#endif

/*
 * The following structure keeps track of the attributes of a font. It can be
 * used to keep track of either the desired attributes or the actual
 * attributes gotten when the font was instantiated.
 */

struct TkFontAttributes {







<
<
<
<







10
11
12
13
14
15
16




17
18
19
20
21
22
23
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKFONT
#define _TKFONT





/*
 * The following structure keeps track of the attributes of a font. It can be
 * used to keep track of either the desired attributes or the actual
 * attributes gotten when the font was instantiated.
 */

struct TkFontAttributes {
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
 */

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







|









|







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
 */

typedef struct TkFont {
    /*
     * Fields used and maintained exclusively by generic code.
     */

    int resourceRefCount;	/* Number of active uses of this font (each
				 * active use corresponds to a call to
				 * Tk_AllocFontFromTable or Tk_GetFont). If
				 * this count is 0, then this TkFont structure
				 * is no longer valid and it isn't present in
				 * a hash table: it is being kept around only
				 * because there are objects referring to it.
				 * The structure is freed when
				 * resourceRefCount and objRefCount are both
				 * 0. */
    int objRefCount;		/* The number of Tcl objects that reference
				 * this structure. */
    Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure,
				 * used when deleting it. */
    Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that
				 * corresponds to the named font that the
				 * tkfont was based on, or NULL if the tkfont
				 * was not based on a named font. */
221
222
223
224
225
226
227
228
229
230
231
232
MODULE_SCOPE void	TkpFontPkgInit(TkMainInfo *mainPtr);
MODULE_SCOPE TkFont *	TkpGetFontFromAttributes(TkFont *tkFontPtr,
			    Tk_Window tkwin, const TkFontAttributes *faPtr);
MODULE_SCOPE void	TkpGetFontFamilies(Tcl_Interp *interp,
			    Tk_Window tkwin);
MODULE_SCOPE TkFont *	TkpGetNativeFont(Tk_Window tkwin, const char *name);

#ifdef __cplusplus
}
#endif

#endif	/* _TKFONT */







<
<
<
<

217
218
219
220
221
222
223




224
MODULE_SCOPE void	TkpFontPkgInit(TkMainInfo *mainPtr);
MODULE_SCOPE TkFont *	TkpGetFontFromAttributes(TkFont *tkFontPtr,
			    Tk_Window tkwin, const TkFontAttributes *faPtr);
MODULE_SCOPE void	TkpGetFontFamilies(Tcl_Interp *interp,
			    Tk_Window tkwin);
MODULE_SCOPE TkFont *	TkpGetNativeFont(Tk_Window tkwin, const char *name);





#endif	/* _TKFONT */
Changes to generic/tkFrame.c.
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
				 * pixels of extra space to leave on left and
				 * right of child area. */
    int padX;			/* Integer value corresponding to padXPtr. */
    Tcl_Obj *padYPtr;		/* Value of -padx option: specifies how many
				 * pixels of extra space to leave above and
				 * below child area. */
    int padY;			/* Integer value corresponding to padYPtr. */
    Tcl_Obj *bgimgPtr;		/* Value of -backgroundimage option: specifies
				 * image to display on window's background, or
				 * NULL if none. */
    Tk_Image bgimg;		/* Derived from bgimgPtr by calling
				 * Tk_GetImage, or NULL if bgimgPtr is
				 * NULL. */
    int tile;			/* Whether to tile the bgimg. */
#ifndef TK_NO_DOUBLE_BUFFERING
    GC copyGC;			/* GC for copying when double-buffering. */
#endif /* TK_NO_DOUBLE_BUFFERING */
} Frame;

/*
 * A data structure of the following type is kept for each labelframe widget
 * managed by this file:
 */








<
<
<
<
<
<
<
<
<
<







90
91
92
93
94
95
96










97
98
99
100
101
102
103
				 * pixels of extra space to leave on left and
				 * right of child area. */
    int padX;			/* Integer value corresponding to padXPtr. */
    Tcl_Obj *padYPtr;		/* Value of -padx option: specifies how many
				 * pixels of extra space to leave above and
				 * below child area. */
    int padY;			/* Integer value corresponding to padYPtr. */










} Frame;

/*
 * A data structure of the following type is kept for each labelframe widget
 * managed by this file:
 */

180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
/*
 * Information used for parsing configuration options. There are one common
 * table used by all and one table for each widget class.
 */

static const Tk_OptionSpec commonOptSpec[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_FRAME_BG_COLOR, TCL_INDEX_NONE, offsetof(Frame, border),
	TK_OPTION_NULL_OK, DEF_FRAME_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_STRING, "-colormap", "colormap", "Colormap",
	DEF_FRAME_COLORMAP, TCL_INDEX_NONE, offsetof(Frame, colormapName),
	TK_OPTION_NULL_OK, 0, 0},
    /*
     * Having -container is useless in a labelframe since a container has
     * no border. It should be deprecated.
     */
    {TK_OPTION_BOOLEAN, "-container", "container", "Container",
	DEF_FRAME_CONTAINER, TCL_INDEX_NONE, offsetof(Frame, isContainer), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_FRAME_CURSOR, TCL_INDEX_NONE, offsetof(Frame, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_FRAME_HEIGHT, TCL_INDEX_NONE, offsetof(Frame, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, TCL_INDEX_NONE,
	offsetof(Frame, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_FRAME_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Frame, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	offsetof(Frame, highlightWidth), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_FRAME_PADX, offsetof(Frame, padXPtr),
	offsetof(Frame, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_FRAME_PADY, offsetof(Frame, padYPtr),
	offsetof(Frame, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_FRAME_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Frame, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-visual", "visual", "Visual",
	DEF_FRAME_VISUAL, TCL_INDEX_NONE, offsetof(Frame, visualName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_FRAME_WIDTH, TCL_INDEX_NONE, offsetof(Frame, width), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec frameOptSpec[] = {
    {TK_OPTION_STRING, "-backgroundimage", "backgroundImage", "BackgroundImage",
	DEF_FRAME_BG_IMAGE, offsetof(Frame, bgimgPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bgimg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-backgroundimage", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_FRAME_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_FRAME_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_FRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
    {TK_OPTION_BOOLEAN, "-tile", "tile", "Tile",
	DEF_FRAME_BG_TILE, TCL_INDEX_NONE, offsetof(Frame, tile), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

static const Tk_OptionSpec toplevelOptSpec[] = {
    {TK_OPTION_STRING, "-backgroundimage", "backgroundImage", "BackgroundImage",
	DEF_FRAME_BG_IMAGE, offsetof(Frame, bgimgPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bgimg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-backgroundimage", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_FRAME_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_TOPLEVEL_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_TOPLEVEL_MENU, TCL_INDEX_NONE, offsetof(Frame, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_FRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-screen", "screen", "Screen",
	DEF_TOPLEVEL_SCREEN, TCL_INDEX_NONE, offsetof(Frame, screenName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-tile", "tile", "Tile",
	DEF_FRAME_BG_TILE, TCL_INDEX_NONE, offsetof(Frame, tile), 0, 0, 0},
    {TK_OPTION_STRING, "-use", "use", "Use",
	DEF_TOPLEVEL_USE, TCL_INDEX_NONE, offsetof(Frame, useThis),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

static const Tk_OptionSpec labelframeOptSpec[] = {
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_LABELFRAME_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Frame, borderWidth),
	0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_LABELFRAME_CLASS, TCL_INDEX_NONE, offsetof(Frame, className), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_LABELFRAME_FONT, TCL_INDEX_NONE, offsetof(Labelframe, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_LABELFRAME_FG, TCL_INDEX_NONE, offsetof(Labelframe, textColorPtr), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor",
	DEF_LABELFRAME_LABELANCHOR, TCL_INDEX_NONE, offsetof(Labelframe, labelAnchor),
	0, labelAnchorStrings, 0},
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget",
	NULL, TCL_INDEX_NONE, offsetof(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABELFRAME_RELIEF, TCL_INDEX_NONE, offsetof(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_LABELFRAME_TEXT, offsetof(Labelframe, textPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

/*
 * Class names for widgets, indexed by FrameType.







|


|

|






|

|


|

|
|

|


|
|

|
|

|
|

|


|


|




<
<
<

|
<
<

|

|

|
<
<





<
<
<

|
<
<

|

|

|


|

|

<
<

|







|

|


|

|

|

|

|


|

|

|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221



222
223


224
225
226
227
228
229


230
231
232
233
234



235
236


237
238
239
240
241
242
243
244
245
246
247
248


249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
/*
 * Information used for parsing configuration options. There are one common
 * table used by all and one table for each widget class.
 */

static const Tk_OptionSpec commonOptSpec[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_FRAME_BG_COLOR, -1, Tk_Offset(Frame, border),
	TK_OPTION_NULL_OK, DEF_FRAME_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_STRING, "-colormap", "colormap", "Colormap",
	DEF_FRAME_COLORMAP, -1, Tk_Offset(Frame, colormapName),
	TK_OPTION_NULL_OK, 0, 0},
    /*
     * Having -container is useless in a labelframe since a container has
     * no border. It should be deprecated.
     */
    {TK_OPTION_BOOLEAN, "-container", "container", "Container",
	DEF_FRAME_CONTAINER, -1, Tk_Offset(Frame, isContainer), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_FRAME_CURSOR, -1, Tk_Offset(Frame, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_FRAME_HEIGHT, -1, Tk_Offset(Frame, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_FRAME_HIGHLIGHT_BG, -1,
	Tk_Offset(Frame, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_FRAME_HIGHLIGHT, -1, Tk_Offset(Frame, highlightColorPtr),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_FRAME_HIGHLIGHT_WIDTH, -1,
	Tk_Offset(Frame, highlightWidth), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_FRAME_PADX, Tk_Offset(Frame, padXPtr),
	Tk_Offset(Frame, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_FRAME_PADY, Tk_Offset(Frame, padYPtr),
	Tk_Offset(Frame, padY), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_FRAME_TAKE_FOCUS, -1, Tk_Offset(Frame, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-visual", "visual", "Visual",
	DEF_FRAME_VISUAL, -1, Tk_Offset(Frame, visualName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_FRAME_WIDTH, -1, Tk_Offset(Frame, width), 0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec frameOptSpec[] = {



    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},


    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_FRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},


    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

static const Tk_OptionSpec toplevelOptSpec[] = {



    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},


    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_FRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_TOPLEVEL_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_TOPLEVEL_MENU, -1, Tk_Offset(Frame, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_FRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-screen", "screen", "Screen",
	DEF_TOPLEVEL_SCREEN, -1, Tk_Offset(Frame, screenName),
	TK_OPTION_NULL_OK, 0, 0},


    {TK_OPTION_STRING, "-use", "use", "Use",
	DEF_TOPLEVEL_USE, -1, Tk_Offset(Frame, useThis),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

static const Tk_OptionSpec labelframeOptSpec[] = {
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_LABELFRAME_BORDER_WIDTH, -1, Tk_Offset(Frame, borderWidth),
	0, 0, 0},
    {TK_OPTION_STRING, "-class", "class", "Class",
	DEF_LABELFRAME_CLASS, -1, Tk_Offset(Frame, className), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_LABELFRAME_FONT, -1, Tk_Offset(Labelframe, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_LABELFRAME_FG, -1, Tk_Offset(Labelframe, textColorPtr), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-labelanchor", "labelAnchor", "LabelAnchor",
	DEF_LABELFRAME_LABELANCHOR, -1, Tk_Offset(Labelframe, labelAnchor),
	0, labelAnchorStrings, 0},
    {TK_OPTION_WINDOW, "-labelwidget", "labelWidget", "LabelWidget",
	NULL, -1, Tk_Offset(Labelframe, labelWin), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_LABELFRAME_RELIEF, -1, Tk_Offset(Frame, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_LABELFRAME_TEXT, Tk_Offset(Labelframe, textPtr), -1,
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, 0, 0, commonOptSpec, 0}
};

/*
 * Class names for widgets, indexed by FrameType.
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
/*
 * 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 = {







|
|

|

|
<
<
<
<
<
<
|
|

|

|

|

|


|
|







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






314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
/*
 * Forward declarations for functions defined later in this file:
 */

static void		ComputeFrameGeometry(Frame *framePtr);
static int		ConfigureFrame(Tcl_Interp *interp, Frame *framePtr,
			    int objc, Tcl_Obj *const objv[]);
static int		CreateFrame(void *clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[],
			    enum FrameType type, const char *appName);
static Tcl_FreeProc	DestroyFrame;
static void		DestroyFramePartly(Frame *framePtr);
static void		DisplayFrame(void *clientData);






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 int		FrameWidgetObjCmd(void *clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
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
 *	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);
}








|









|









|







366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
 *	call CreateFrame to do all of the real work.
 *
 *--------------------------------------------------------------
 */

int
Tk_FrameObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return CreateFrame(clientData, interp, objc, objv, TYPE_FRAME, NULL);
}

int
Tk_ToplevelObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return CreateFrame(clientData, interp, objc, objv, TYPE_TOPLEVEL, NULL);
}

int
Tk_LabelframeObjCmd(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    return CreateFrame(clientData, interp, objc, objv, TYPE_LABELFRAME, NULL);
}

445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
 *	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.







|







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
TkCreateFrame(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int argc,			/* Number of arguments. */
    const char *const *argv,	/* Argument strings. */
    int toplevel,		/* Non-zero means create a toplevel window,
				 * zero means create a frame. */
    const char *appName)	/* Should only be non-NULL if there is no main
				 * window associated with the interpreter.
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
    }
    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







|







445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
    }
    ckfree(objv);
    return result;
}

int
TkListCreateFrame(
    void *clientData,	/* Either NULL or pointer to option table. */
    Tcl_Interp *interp,		/* Current interpreter. */
    Tcl_Obj *listObj,		/* List of arguments. */
    int toplevel,		/* Non-zero means create a toplevel window,
				 * zero means create a frame. */
    Tcl_Obj *nameObj)		/* Should only be non-NULL if there is no main
				 * window associated with the interpreter.
				 * Gives the base name to use for the new
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
    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;
    }

    /*







|
















|



<







468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

496
497
498
499
500
501
502
    return CreateFrame(clientData, interp, objc, objv,
	    toplevel ? TYPE_TOPLEVEL : TYPE_FRAME,
	    nameObj ? Tcl_GetString(nameObj) : NULL);
}

static int
CreateFrame(
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects. */
    enum FrameType type,	/* What widget type to create. */
    const char *appName)	/* Should only be non-NULL if there are no
				 * Main window associated with the
				 * interpreter. Gives the base name to use for
				 * the new application. */
{
    Tk_Window tkwin;
    Frame *framePtr;
    Tk_OptionTable optionTable;
    Tk_Window newWin;
    const char *className, *screenName, *visualName, *colormapName;
    const char *arg, *useOption;
    int i, depth;
    int 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)







|







512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
     * be processed specially, before the window is configured using the usual
     * Tk mechanisms.
     */

    className = colormapName = screenName = visualName = useOption = NULL;
    colormap = None;
    for (i = 2; i < objc; i += 2) {
	arg = Tcl_GetStringFromObj(objv[i], &length);
	if (length < 2) {
	    continue;
	}
	if ((arg[1] == 'c') && (length >= 3)
		&& (strncmp(arg, "-class", length) == 0)) {
	    className = Tcl_GetString(objv[i+1]);
	} else if ((arg[1] == 'c') && (length >= 3)
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
    Tk_SetClassProcs(newWin, &frameClass, framePtr);

    mask = ExposureMask | StructureNotifyMask | FocusChangeMask;
    if (type == TYPE_TOPLEVEL) {
	mask |= ActivateMask;
    }
    Tk_CreateEventHandler(newWin, mask, FrameEventProc, framePtr);
    if ((Tk_InitOptions(interp, framePtr, optionTable, newWin)
	    != TCL_OK) ||
	    (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) {
	goto error;
    }
    if (framePtr->isContainer) {
	if (framePtr->useThis != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "windows cannot have both the -use and the -container"
		    " option set", -1));
	    Tcl_SetErrorCode(interp, "TK", "FRAME", "CONTAINMENT", NULL);
	    goto error;
	}
	TkpMakeContainer(framePtr->tkwin);
    }
    if (type == TYPE_TOPLEVEL) {
	Tcl_DoWhenIdle(MapFrame, framePtr);
    }
    Tcl_SetObjResult(interp, Tk_NewWindowObj(newWin));
    return TCL_OK;

  error:
    if (newWin != NULL) {
	Tk_DestroyWindow(newWin);
    }
    return TCL_ERROR;







|

















|







679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
    Tk_SetClassProcs(newWin, &frameClass, framePtr);

    mask = ExposureMask | StructureNotifyMask | FocusChangeMask;
    if (type == TYPE_TOPLEVEL) {
	mask |= ActivateMask;
    }
    Tk_CreateEventHandler(newWin, mask, FrameEventProc, framePtr);
    if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, newWin)
	    != TCL_OK) ||
	    (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) {
	goto error;
    }
    if (framePtr->isContainer) {
	if (framePtr->useThis != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "windows cannot have both the -use and the -container"
		    " option set", -1));
	    Tcl_SetErrorCode(interp, "TK", "FRAME", "CONTAINMENT", NULL);
	    goto error;
	}
	TkpMakeContainer(framePtr->tkwin);
    }
    if (type == TYPE_TOPLEVEL) {
	Tcl_DoWhenIdle(MapFrame, framePtr);
    }
    Tcl_SetObjResult(interp, TkNewWindowObj(newWin));
    return TCL_OK;

  error:
    if (newWin != NULL) {
	Tk_DestroyWindow(newWin);
    }
    return TCL_ERROR;
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
 *	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,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(framePtr);
    switch ((enum options) index) {
    case FRAME_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	objPtr = Tk_GetOptionValue(interp, framePtr,
		framePtr->optionTable, objv[2], framePtr->tkwin);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;
    case FRAME_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, framePtr,
		    framePtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    framePtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    /*
	     * Don't allow the options -class, -colormap, -container, -screen,
	     * -use, or -visual to be changed.
	     */

	    for (i = 2; i < objc; i++) {
		const char *arg = TkGetStringFromObj(objv[i], &length);

		if (length < 2) {
		    continue;
		}
		c = arg[1];
		if (((c == 'c') && (length >= 2)
			&& (strncmp(arg, "-class", length) == 0))
		    || ((c == 'c') && (length >= 3)
			&& (strncmp(arg, "-colormap", length) == 0))
		    || ((c == 'c') && (length >= 3)
			&& (strncmp(arg, "-container", length) == 0))
		    || ((c == 's') && (framePtr->type == TYPE_TOPLEVEL)
			&& (strncmp(arg, "-screen", length) == 0))
		    || ((c == 'u') && (framePtr->type == TYPE_TOPLEVEL)
			&& (strncmp(arg, "-use", length) == 0))
		    || ((c == 'v')
			&& (strncmp(arg, "-visual", length) == 0))) {

#ifdef SUPPORT_CONFIG_EMBEDDED
		    if (c == 'u') {
			const char *string = Tcl_GetString(objv[i+1]);

			if (TkpUseWindow(interp, framePtr->tkwin,
				string) != TCL_OK) {
			    result = TCL_ERROR;
			    goto done;







|













|


















|









|














|


















|







727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

static int
FrameWidgetObjCmd(
    void *clientData,	/* Information about frame widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    static const char *const frameOptions[] = {
	"cget", "configure", NULL
    };
    enum options {
	FRAME_CGET, FRAME_CONFIGURE
    };
    Frame *framePtr = (Frame *)clientData;
    int result = TCL_OK, index;
    int c, i;
    int length;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (Tcl_GetIndexFromObjStruct(interp, objv[1], frameOptions,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(framePtr);
    switch ((enum options) index) {
    case FRAME_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    goto done;
	}
	objPtr = Tk_GetOptionValue(interp, (char *) framePtr,
		framePtr->optionTable, objv[2], framePtr->tkwin);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;
    case FRAME_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) framePtr,
		    framePtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    framePtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		goto done;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
	    /*
	     * Don't allow the options -class, -colormap, -container, -screen,
	     * -use, or -visual to be changed.
	     */

	    for (i = 2; i < objc; i++) {
		const char *arg = 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 (TkpUseWindow(interp, framePtr->tkwin,
				string) != TCL_OK) {
			    result = TCL_ERROR;
			    goto done;
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
 *	Everything associated with the frame is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyFrame(
    void *memPtr)		/* Info about frame widget. */
{
    Frame *framePtr = (Frame *)memPtr;
    Labelframe *labelframePtr = (Labelframe *)memPtr;

    if (framePtr->type == TYPE_LABELFRAME) {
	Tk_FreeTextLayout(labelframePtr->textLayout);
	if (labelframePtr->textGC != NULL) {
	    Tk_FreeGC(framePtr->display, labelframePtr->textGC);
	}
    }
#ifndef TK_NO_DOUBLE_BUFFERING
    if (framePtr->copyGC != NULL) {
	Tk_FreeGC(framePtr->display, framePtr->copyGC);
    }
#endif /* TK_NO_DOUBLE_BUFFERING */
    if (framePtr->colormap != None) {
	Tk_FreeColormap(framePtr->display, framePtr->colormap);
    }
    if (framePtr->bgimg) {
	Tk_FreeImage(framePtr->bgimg);
    }
    ckfree(framePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyFramePartly --







|










<
<
<
<
<



<
<
<







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872





873
874
875



876
877
878
879
880
881
882
 *	Everything associated with the frame is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyFrame(
    char *memPtr)		/* Info about frame widget. */
{
    Frame *framePtr = (Frame *)memPtr;
    Labelframe *labelframePtr = (Labelframe *)memPtr;

    if (framePtr->type == TYPE_LABELFRAME) {
	Tk_FreeTextLayout(labelframePtr->textLayout);
	if (labelframePtr->textGC != NULL) {
	    Tk_FreeGC(framePtr->display, labelframePtr->textGC);
	}
    }





    if (framePtr->colormap != None) {
	Tk_FreeColormap(framePtr->display, framePtr->colormap);
    }



    ckfree(framePtr);
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyFramePartly --
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
    int objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    Tk_SavedOptions savedOptions;
    char *oldMenuName;
    Tk_Window oldWindow = NULL;
    Labelframe *labelframePtr = (Labelframe *) framePtr;
    Tk_Image image = NULL;

    /*
     * Need the old menubar name for the menu code to delete it.
     */

    if (framePtr->menuName == NULL) {
    	oldMenuName = NULL;
    } else {
    	oldMenuName = (char *)ckalloc(strlen(framePtr->menuName) + 1);
    	strcpy(oldMenuName, framePtr->menuName);
    }

    if (framePtr->type == TYPE_LABELFRAME) {
	oldWindow = labelframePtr->labelWin;
    }
    if (Tk_SetOptions(interp, framePtr,
	    framePtr->optionTable, objc, objv,
	    framePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
	if (oldMenuName != NULL) {
	    ckfree(oldMenuName);
	}
	return TCL_ERROR;
    }

    if (framePtr->bgimgPtr) {
	image = Tk_GetImage(interp, framePtr->tkwin,
		Tcl_GetString(framePtr->bgimgPtr), FrameBgImageProc, framePtr);
	if (image == NULL) {
	    Tk_RestoreSavedOptions(&savedOptions);
	    return TCL_ERROR;
	}
    }
    if (framePtr->bgimg) {
	Tk_FreeImage(framePtr->bgimg);
    }
    framePtr->bgimg = image;

    Tk_FreeSavedOptions(&savedOptions);

    /*
     * A few of the options require additional processing.
     */

    if ((((oldMenuName == NULL) && (framePtr->menuName != NULL))







<















|







<
<
<
<
<
<
<
<
<
<
<
<
<
<







943
944
945
946
947
948
949

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972














973
974
975
976
977
978
979
    int objc,			/* Number of valid entries in objv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    Tk_SavedOptions savedOptions;
    char *oldMenuName;
    Tk_Window oldWindow = NULL;
    Labelframe *labelframePtr = (Labelframe *) framePtr;


    /*
     * Need the old menubar name for the menu code to delete it.
     */

    if (framePtr->menuName == NULL) {
    	oldMenuName = NULL;
    } else {
    	oldMenuName = (char *)ckalloc(strlen(framePtr->menuName) + 1);
    	strcpy(oldMenuName, framePtr->menuName);
    }

    if (framePtr->type == TYPE_LABELFRAME) {
	oldWindow = labelframePtr->labelWin;
    }
    if (Tk_SetOptions(interp, (char *) framePtr,
	    framePtr->optionTable, objc, objv,
	    framePtr->tkwin, &savedOptions, NULL) != TCL_OK) {
	if (oldMenuName != NULL) {
	    ckfree(oldMenuName);
	}
	return TCL_ERROR;
    }














    Tk_FreeSavedOptions(&savedOptions);

    /*
     * A few of the options require additional processing.
     */

    if ((((oldMenuName == NULL) && (framePtr->menuName != NULL))
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
 *	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;
    int bWidthLeft, bWidthRight, bWidthTop, bWidthBottom;
    const char *labelText;

    anyTextLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->textPtr != NULL) &&
	    (labelframePtr->labelWin == NULL);
    anyWindowLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->labelWin != NULL);

#ifndef TK_NO_DOUBLE_BUFFERING
    gcValues.graphics_exposures = False;
    gc = Tk_GetGC(tkwin, GCGraphicsExposures, &gcValues);
    if (framePtr->copyGC != NULL) {
	Tk_FreeGC(framePtr->display, framePtr->copyGC);
    }
    framePtr->copyGC = gc;
#endif /* TK_NO_DOUBLE_BUFFERING */

    if (framePtr->type == TYPE_LABELFRAME) {
	/*
	 * The textGC is needed even in the labelWin case, so it's always
	 * created for a labelframe.
	 */

	gcValues.font = Tk_FontId(labelframePtr->tkfont);







|
















<
<
<
<
<
<
<
<
<







1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113









1114
1115
1116
1117
1118
1119
1120
 *	Frame will be relayed out and redisplayed.
 *
 *---------------------------------------------------------------------------
 */

static void
FrameWorldChanged(
    void *instanceData)	/* Information about widget. */
{
    Frame *framePtr = (Frame *)instanceData;
    Labelframe *labelframePtr = (Labelframe *)instanceData;
    Tk_Window tkwin = framePtr->tkwin;
    XGCValues gcValues;
    GC gc;
    int anyTextLabel, anyWindowLabel;
    int bWidthLeft, bWidthRight, bWidthTop, bWidthBottom;
    const char *labelText;

    anyTextLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->textPtr != NULL) &&
	    (labelframePtr->labelWin == NULL);
    anyWindowLabel = (framePtr->type == TYPE_LABELFRAME) &&
	    (labelframePtr->labelWin != NULL);










    if (framePtr->type == TYPE_LABELFRAME) {
	/*
	 * The textGC is needed even in the labelWin case, so it's always
	 * created for a labelframe.
	 */

	gcValues.font = Tk_FontId(labelframePtr->tkfont);
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
 *	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;
    }

    /*







|





|







1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
 *	Commands are output to X to display the frame in its current mode.
 *
 *----------------------------------------------------------------------
 */

static void
DisplayFrame(
    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;
    }

    /*
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555














1556
1557
1558
1559
1560
1561
1562
     * If -background is set to "", no interior is drawn.
     */

    if (framePtr->border == NULL) {
	return;
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * In order to avoid screen flashes, this function redraws the frame into
     * off-screen memory, then copies it back on-screen in a single operation.
     * This means there's no point in time where the on-screen image has been
     * cleared.
     */

    pixmap = Tk_GetPixmap(framePtr->display, Tk_WindowId(tkwin),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
    pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */

    if (framePtr->type != TYPE_LABELFRAME) {
	/*
	 * Pass to platform specific draw function. In general, it just draws
	 * a simple rectangle, but it may "theme" the background.
	 */

    noLabel:
	TkpDrawFrameEx(tkwin, pixmap, framePtr->border, hlWidth,
		framePtr->borderWidth, framePtr->relief);
	if (framePtr->bgimg) {
	    DrawFrameBackground(tkwin, pixmap, hlWidth, framePtr->borderWidth,
		    framePtr->bgimg, framePtr->tile);
	}
    } else {
	Labelframe *labelframePtr = (Labelframe *) framePtr;

	if ((labelframePtr->textPtr == NULL) &&
		(labelframePtr->labelWin == NULL)) {
	    goto noLabel;
	}















	/*
	 * Clear the pixmap.
	 */

	Tk_Fill3DRectangle(tkwin, pixmap, framePtr->border, 0, 0,
		Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);








<
<
<
<
<
<
<
<
<
<
<
<
<
<







|

<
<
<
<








>
>
>
>
>
>
>
>
>
>
>
>
>
>







1451
1452
1453
1454
1455
1456
1457














1458
1459
1460
1461
1462
1463
1464
1465
1466




1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
     * If -background is set to "", no interior is drawn.
     */

    if (framePtr->border == NULL) {
	return;
    }















    if (framePtr->type != TYPE_LABELFRAME) {
	/*
	 * Pass to platform specific draw function. In general, it just draws
	 * a simple rectangle, but it may "theme" the background.
	 */

    noLabel:
	TkpDrawFrame(tkwin, framePtr->border, hlWidth,
		framePtr->borderWidth, framePtr->relief);




    } else {
	Labelframe *labelframePtr = (Labelframe *) framePtr;

	if ((labelframePtr->textPtr == NULL) &&
		(labelframePtr->labelWin == NULL)) {
	    goto noLabel;
	}

#ifndef TK_NO_DOUBLE_BUFFERING
	/*
	 * In order to avoid screen flashes, this function redraws the frame
	 * into off-screen memory, then copies it back on-screen in a single
	 * operation. This means there's no point in time where the on-screen
	 * image has been cleared.
	 */

	pixmap = Tk_GetPixmap(framePtr->display, Tk_WindowId(tkwin),
		Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
	pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */

	/*
	 * Clear the pixmap.
	 */

	Tk_Fill3DRectangle(tkwin, pixmap, framePtr->border, 0, 0,
		Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

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








<
<
|
|
<
>







|

<







1549
1550
1551
1552
1553
1554
1555


1556
1557

1558
1559
1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
	     * Draw label. If there is not room for the entire label, use
	     * clipping to get a nice appearance.
	     */

	    if ((labelframePtr->labelBox.width < labelframePtr->labelReqWidth)
		    || (labelframePtr->labelBox.height <
			    labelframePtr->labelReqHeight)) {


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

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
	    } else {
		Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin,
			labelframePtr->labelBox.x, labelframePtr->labelBox.y,
			labelframePtr->labelBox.width,
			labelframePtr->labelBox.height);
	    }
	}
    }

#ifndef TK_NO_DOUBLE_BUFFERING
    /*
     * Everything's been redisplayed; now copy the pixmap onto the screen and
     * free up the pixmap.
     */

    XCopyArea(framePtr->display, pixmap, Tk_WindowId(tkwin),
	    framePtr->copyGC, hlWidth, hlWidth,
	    (unsigned) (Tk_Width(tkwin) - 2 * hlWidth),
	    (unsigned) (Tk_Height(tkwin) - 2 * hlWidth),
	    hlWidth, hlWidth);
    Tk_FreePixmap(framePtr->display, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
}

/*
 *----------------------------------------------------------------------
 *
 * TkpDrawFrame --
 *
 *	This procedure draws the rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

void
TkpDrawFrame(
    Tk_Window tkwin,
    Tk_3DBorder border,
    int highlightWidth,
    int borderWidth,
    int relief)
{
    /*
     * Legacy shim to allow for external callers. Internal ones use
     * non-exposed TkpDrawFrameEx directly so they can use double-buffering.
     */

    TkpDrawFrameEx(tkwin, Tk_WindowId(tkwin), border,
	    highlightWidth, borderWidth, relief);
}

/*
 *--------------------------------------------------------------
 *
 * FrameEventProc --
 *







|
<

|
|
|
|

|
|
|
|
|
|

|
|
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







1590
1591
1592
1593
1594
1595
1596
1597

1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612































1613
1614
1615
1616
1617
1618
1619
	    } else {
		Tk_MaintainGeometry(labelframePtr->labelWin, framePtr->tkwin,
			labelframePtr->labelBox.x, labelframePtr->labelBox.y,
			labelframePtr->labelBox.width,
			labelframePtr->labelBox.height);
	    }
	}


#ifndef TK_NO_DOUBLE_BUFFERING
	/*
	 * Everything's been redisplayed; now copy the pixmap onto the screen
	 * and free up the pixmap.
	 */

	XCopyArea(framePtr->display, pixmap, Tk_WindowId(tkwin),
		labelframePtr->textGC, hlWidth, hlWidth,
		(unsigned) (Tk_Width(tkwin) - 2 * hlWidth),
		(unsigned) (Tk_Height(tkwin) - 2 * hlWidth),
		hlWidth, hlWidth);
	Tk_FreePixmap(framePtr->display, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
    }
































}

/*
 *--------------------------------------------------------------
 *
 * FrameEventProc --
 *
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
 *	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) {







|







1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
 *	When it gets exposed, it is redisplayed.
 *
 *--------------------------------------------------------------
 */

static void
FrameEventProc(
    void *clientData,	/* Information about window. */
    XEvent *eventPtr)	/* Information about event. */
{
    Frame *framePtr = (Frame *)clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
	    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;
	    }
	}







|







1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
	    framePtr->tkwin = NULL;
	    Tcl_DeleteCommandFromToken(framePtr->interp, framePtr->widgetCmd);
	}
	if (framePtr->flags & REDRAW_PENDING) {
	    Tcl_CancelIdleCall(DisplayFrame, framePtr);
	}
	Tcl_CancelIdleCall(MapFrame, framePtr);
	Tcl_EventuallyFree(framePtr, DestroyFrame);
    } else if (eventPtr->type == FocusIn) {
	if (eventPtr->xfocus.detail != NotifyInferior) {
	    framePtr->flags |= GOT_FOCUS;
	    if (framePtr->highlightWidth > 0) {
		goto redraw;
	    }
	}
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
 *	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);







|







1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
 *	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) {
	TkSetWindowMenuBar(framePtr->interp, framePtr->tkwin,
		framePtr->menuName, NULL);
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







|







1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
 *	The frame given by the clientData argument is mapped.
 *
 *----------------------------------------------------------------------
 */

static void
MapFrame(
    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







|







1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
 *	The window is disassociated from the frame when it is deleted.
 *
 *--------------------------------------------------------------
 */

static void
FrameStructureProc(
    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);
}

/*
 *--------------------------------------------------------------
 *







|
|


<







1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908

1909
1910
1911
1912
1913
1914
1915
 *	on the options specified for the frame.
 *
 *--------------------------------------------------------------
 */

static void
FrameRequestProc(
    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) {







|

|



<







1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937

1938
1939
1940
1941
1942
1943
1944
 *	Forgets all frame-related information about the content window.
 *
 *--------------------------------------------------------------
 */

static void
FrameLostContentProc(
    void *clientData,	/* Frame structure for content 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) {
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
    }
    framePtr = (Frame *)cmdInfo.objClientData;
    if (framePtr->type != TYPE_TOPLEVEL) {
	return NULL;
    }
    return framePtr->tkwin;
}

/*
 *----------------------------------------------------------------------
 *
 * FrameBgImageProc --
 *
 *	This function is invoked by the image code whenever the manager for an
 *	image does something that affects the size or contents of an image
 *	displayed on a frame's background.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Arranges for the button to get redisplayed.
 *
 *----------------------------------------------------------------------
 */

static void
FrameBgImageProc(
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (might be
				 * <= 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    Frame *framePtr = (Frame *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;


    /*
     * Changing the background image never alters the dimensions of the frame.
     */

    if (framePtr->tkwin && Tk_IsMapped(framePtr->tkwin) &&
	    !(framePtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayFrame, framePtr);
	framePtr->flags |= REDRAW_PENDING;
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DrawFrameBackground --
 *
 *	This function draws the background image of a rectangular frame area.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws inside the tkwin area.
 *
 *----------------------------------------------------------------------
 */

static void
DrawFrameBackground(
    Tk_Window tkwin,
    Pixmap pixmap,
    int highlightWidth,
    int borderWidth,
    Tk_Image bgimg,
    int bgtile)
{
    int width, height;			/* Area to paint on. */
    int imageWidth, imageHeight;	/* Dimensions of image. */
    const int bw = highlightWidth + borderWidth;

    Tk_SizeOfImage(bgimg, &imageWidth, &imageHeight);
    width = Tk_Width(tkwin) - 2*bw;
    height = Tk_Height(tkwin) - 2*bw;

    if (bgtile) {
	/*
	 * Draw the image tiled in the widget (inside the border).
	 */

	int x, y;

	for (x = bw; x - bw < width; x += imageWidth) {
	    int w = imageWidth;
	    if (x - bw + imageWidth > width) {
		w = (width + bw) - x;
	    }
	    for (y = bw; y < height + bw; y += imageHeight) {
		int h = imageHeight;
		if (y - bw + imageHeight > height) {
		    h = (height + bw) - y;
		}
		Tk_RedrawImage(bgimg, 0, 0, w, h, pixmap, x, y);
	    }
	}
    } else {
	/*
	 * Draw the image centred in the widget (inside the border).
	 */

	int x, y, xOff, yOff, w, h;

	if (width > imageWidth) {
	    x = 0;
	    xOff = (Tk_Width(tkwin) - imageWidth) / 2;
	    w = imageWidth;
	} else {
	    x = (imageWidth - width) / 2;
	    xOff = bw;
	    w = width;
	}
	if (height > imageHeight) {
	    y = 0;
	    yOff = (Tk_Height(tkwin) - imageHeight) / 2;
	    h = imageHeight;
	} else {
	    y = (imageHeight - height) / 2;
	    yOff = bw;
	    h = height;
	}
	Tk_RedrawImage(bgimg, x, y, w, h, pixmap, xOff, yOff);
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */









<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






2023
2024
2025
2026
2027
2028
2029
2030
2031

































































































































2032
2033
2034
2035
2036
2037
    }
    framePtr = (Frame *)cmdInfo.objClientData;
    if (framePtr->type != TYPE_TOPLEVEL) {
	return NULL;
    }
    return framePtr->tkwin;
}

/*

































































































































 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkGC.c.
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * values in the graphics context and the other based on the display and GC
 * identifier.
 */

typedef struct {
    GC gc;			/* Graphics context. */
    Display *display;		/* Display to which gc belongs. */
    size_t refCount;		/* Number of active uses of gc. */
    Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting
				 * this structure). */
} TkGC;

typedef struct {
    XGCValues values;		/* Desired values for GC. */
    Display *display;		/* Display for which GC is valid. */







|







19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 * values in the graphics context and the other based on the display and GC
 * identifier.
 */

typedef struct {
    GC gc;			/* Graphics context. */
    Display *display;		/* Display to which gc belongs. */
    int refCount;		/* Number of active uses of gc. */
    Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting
				 * this structure). */
} TkGC;

typedef struct {
    XGCValues values;		/* Desired values for GC. */
    Display *display;		/* Display for which GC is valid. */
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
	 * This may still get called by other things shutting down, but the
	 * GCs should no longer be in use.
	 */

	return;
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, gc);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeGC received unknown gc argument");
    }
    gcPtr = (TkGC *)Tcl_GetHashValue(idHashPtr);
    if (gcPtr->refCount-- <= 1) {
	XFreeGC(gcPtr->display, gcPtr->gc);
	Tcl_DeleteHashEntry(gcPtr->valueHashPtr);







|







303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
	 * This may still get called by other things shutting down, but the
	 * GCs should no longer be in use.
	 */

	return;
    }

    idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, (char *) gc);
    if (idHashPtr == NULL) {
	Tcl_Panic("Tk_FreeGC received unknown gc argument");
    }
    gcPtr = (TkGC *)Tcl_GetHashValue(idHashPtr);
    if (gcPtr->refCount-- <= 1) {
	XFreeGC(gcPtr->display, gcPtr->gc);
	Tcl_DeleteHashEntry(gcPtr->valueHashPtr);
Changes to generic/tkGeometry.c.
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 *	None.
 *
 * Side effects:
 *	Proc becomes the new geometry manager for tkwin, replacing any
 *	previous geometry manager. The geometry manager will be notified (by
 *	calling procedures in *mgrPtr) when interesting things happen in the
 *	future. If there was an existing geometry manager for tkwin different
 *	from the new one, it is notified by calling its lostContentProc.
 *
 *--------------------------------------------------------------
 */

void
Tk_ManageGeometry(
    Tk_Window tkwin,		/* Window whose geometry is to be managed by
				 * proc. */
    const Tk_GeomMgr *mgrPtr,	/* Static structure describing the geometry
				 * manager. This structure must never go
				 * away. */
    ClientData clientData)	/* Arbitrary one-word argument to pass to
				 * geometry manager procedures. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if ((winPtr->geomMgrPtr != NULL) && (mgrPtr != NULL)
	    && ((winPtr->geomMgrPtr != mgrPtr)
		|| (winPtr->geomData != clientData))
	    && (winPtr->geomMgrPtr->lostContentProc != NULL)) {
	winPtr->geomMgrPtr->lostContentProc(winPtr->geomData, tkwin);
    }

    winPtr->geomMgrPtr = mgrPtr;
    winPtr->geomData = clientData;
}

/*







|



















|
|







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
 *	None.
 *
 * Side effects:
 *	Proc becomes the new geometry manager for tkwin, replacing any
 *	previous geometry manager. The geometry manager will be notified (by
 *	calling procedures in *mgrPtr) when interesting things happen in the
 *	future. If there was an existing geometry manager for tkwin different
 *	from the new one, it is notified by calling its lostSlaveProc.
 *
 *--------------------------------------------------------------
 */

void
Tk_ManageGeometry(
    Tk_Window tkwin,		/* Window whose geometry is to be managed by
				 * proc. */
    const Tk_GeomMgr *mgrPtr,	/* Static structure describing the geometry
				 * manager. This structure must never go
				 * away. */
    ClientData clientData)	/* Arbitrary one-word argument to pass to
				 * geometry manager procedures. */
{
    TkWindow *winPtr = (TkWindow *) tkwin;

    if ((winPtr->geomMgrPtr != NULL) && (mgrPtr != NULL)
	    && ((winPtr->geomMgrPtr != mgrPtr)
		|| (winPtr->geomData != clientData))
	    && (winPtr->geomMgrPtr->lostSlaveProc != NULL)) {
	winPtr->geomMgrPtr->lostSlaveProc(winPtr->geomData, tkwin);
    }

    winPtr->geomMgrPtr = mgrPtr;
    winPtr->geomData = clientData;
}

/*
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
    if (winPtr->geomMgrName != NULL &&
	    strcmp(winPtr->geomMgrName, name) == 0) {
	return TCL_OK;
    }
    if (winPtr->geomMgrName != NULL) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cannot use geometry manager %s inside %s because"
		    " %s is already managing it's content windows",
		    name, Tk_PathName(tkwin), winPtr->geomMgrName));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "FIGHT", NULL);
	}
	return TCL_ERROR;
    }

    winPtr->geomMgrName = (char *)ckalloc(strlen(name) + 1);







|
|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
    if (winPtr->geomMgrName != NULL &&
	    strcmp(winPtr->geomMgrName, name) == 0) {
	return TCL_OK;
    }
    if (winPtr->geomMgrName != NULL) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "cannot use geometry manager %s inside %s which already"
		    " has slaves managed by %s",
		    name, Tk_PathName(tkwin), winPtr->geomMgrName));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "FIGHT", NULL);
	}
	return TCL_ERROR;
    }

    winPtr->geomMgrName = (char *)ckalloc(strlen(name) + 1);
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
 *	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.
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";
}

/*
 *----------------------------------------------------------------------
 *







>







467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
    Tk_Justify justify)		/* Justification style for which identifying
				 * string is desired. */
{
    switch (justify) {
    case TK_JUSTIFY_LEFT: return "left";
    case TK_JUSTIFY_RIGHT: return "right";
    case TK_JUSTIFY_CENTER: return "center";
    default: break;
    }
    return "unknown justification style";
}

/*
 *----------------------------------------------------------------------
 *
690
691
692
693
694
695
696





697
698
699
700
701
702
703
				 * 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++;
    }







>
>
>
>
>







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
				 * units. */
    const char *string,		/* String describing a number of pixels. */
    double *doublePtr)		/* Place to store converted result. */
{
    char *end;
    double d;

    if (!tkwin) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad screen"));
	Tcl_SetErrorCode(interp, "TK", "VALUE", "FRACTIONAL_PIXELS", NULL);
	return TCL_ERROR;
    }
    d = strtod((char *) string, &end);
    if (end == string) {
	goto error;
    }
    while ((*end != '\0') && isspace(UCHAR(*end))) {
	end++;
    }
Changes to generic/tkGrab.c.
12
13
14
15
16
17
18


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

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







>
>








|







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

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#elif !defined(MAC_OSX_TK)
#include "tkUnixInt.h"
#else
#include "tkMacOSXInt.h"
#endif

/*
 * The grab state machine has four states: ungrabbed, button pressed, grabbed,
 * and button pressed while grabbed. In addition, there are three pieces of
 * grab state information: the current grab window, the current restrict
 * window, and whether the mouse is captured.
 *
 * The current grab window specifies the point in the Tk window hierarchy
 * above which pointer events will not be reported. Any window within the
 * subtree below the grab window will continue to receive events as normal.
 * Events outside of the grab tree will be reported to the grab window.
 *
 * If the current restrict window is set, then all pointer events will be
 * reported only to the restrict window. The restrict window is normally set
 * during an automatic button grab.
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
    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 {







|







176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    int globalGrab;
    Tk_Window tkwin;
    TkDisplay *dispPtr;
    const char *arg;
    int index;
    int len;
    static const char *const optionStrings[] = {
	"current", "release", "set", "status", NULL
    };
    static const char *const flagStrings[] = {
	"-global", NULL
    };
    enum options {
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
	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);
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    (Tk_Window)clientData);
	    if (tkwin == NULL) {
		return TCL_ERROR;
	    }
	    dispPtr = ((TkWindow *) tkwin)->dispPtr;
	    if (dispPtr->eventualGrabWinPtr != NULL) {
		Tcl_SetObjResult(interp, Tk_NewWindowObj((Tk_Window)
			dispPtr->eventualGrabWinPtr));
	    }
	} else {
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
		    dispPtr = dispPtr->nextPtr) {
		if (dispPtr->eventualGrabWinPtr != NULL) {
		    Tcl_ListObjAppendElement(NULL, resultObj, Tk_NewWindowObj(
			    (Tk_Window) dispPtr->eventualGrabWinPtr));
		}
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	return TCL_OK;








|








|







268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    (Tk_Window)clientData);
	    if (tkwin == NULL) {
		return TCL_ERROR;
	    }
	    dispPtr = ((TkWindow *) tkwin)->dispPtr;
	    if (dispPtr->eventualGrabWinPtr != NULL) {
		Tcl_SetObjResult(interp, TkNewWindowObj((Tk_Window)
			dispPtr->eventualGrabWinPtr));
	    }
	} else {
	    Tcl_Obj *resultObj = Tcl_NewObj();

	    for (dispPtr = TkGetDisplayList(); dispPtr != NULL;
		    dispPtr = dispPtr->nextPtr) {
		if (dispPtr->eventualGrabWinPtr != NULL) {
		    Tcl_ListObjAppendElement(NULL, resultObj, TkNewWindowObj(
			    (Tk_Window) dispPtr->eventualGrabWinPtr));
		}
	    }
	    Tcl_SetObjResult(interp, resultObj);
	}
	return TCL_OK;

662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
 *----------------------------------------------------------------------
 *
 * TkPointerEvent --
 *
 *	This function is called for each pointer-related event, before the
 *	event has been processed. It does various things to make grabs work
 *	correctly.
 *	Also, this function takes care of warping the mouse pointer with
 *	respect to a given window, both when there is a grab in effect and
 *	when there is none.
 *
 * Results:
 *	If the return value is 1 it means the event should be processed (event
 *	handlers should be invoked). If the return value is 0 it means the
 *	event should be ignored in order to make grabs work correctly. In some
 *	cases this function modifies the event.
 *
 * Side effects:
 *	Grab state information may be updated. New events may also be pushed
 *	back onto the event queue to replace or augment the one passed in
 *	here.
 *	The mouse pointer may be moved.
 *
 *----------------------------------------------------------------------
 */

int
TkPointerEvent(
    XEvent *eventPtr,	/* Pointer to the event. */







<
<
<











<







664
665
666
667
668
669
670



671
672
673
674
675
676
677
678
679
680
681

682
683
684
685
686
687
688
 *----------------------------------------------------------------------
 *
 * TkPointerEvent --
 *
 *	This function is called for each pointer-related event, before the
 *	event has been processed. It does various things to make grabs work
 *	correctly.



 *
 * Results:
 *	If the return value is 1 it means the event should be processed (event
 *	handlers should be invoked). If the return value is 0 it means the
 *	event should be ignored in order to make grabs work correctly. In some
 *	cases this function modifies the event.
 *
 * Side effects:
 *	Grab state information may be updated. New events may also be pushed
 *	back onto the event queue to replace or augment the one passed in
 *	here.

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

int
TkPointerEvent(
    XEvent *eventPtr,	/* Pointer to the event. */
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
		    && (winPtr != dispPtr->buttonWinPtr)) {
		return 0;
	    }
	}
	return 1;
    }

    if ((eventPtr->type == MotionNotify) && !appGrabbed) {

        /*
         * Warp the mouse pointer with respect to window dispPtr->warpWindow
         * if such a window was set in HandleEventGenerate.
         */

        TkDoWarpWrtWin(dispPtr);
    }

    if (!appGrabbed) {
	return 1;
    }

    /*
     * From this point on, there is a grab in effect.
     */

    if (eventPtr->type == MotionNotify) {
	/*
	 * When grabs are active, X reports motion events relative to the
	 * window under the pointer. Instead, it should report the events
	 * relative to the window the button went down in, if there is a
	 * button down. Otherwise, if the pointer window is outside the
	 * subtree of the grab window, the events should be reported relative







<
<
<
<
<
<
<
<
<
<




<
<
<
<







771
772
773
774
775
776
777










778
779
780
781




782
783
784
785
786
787
788
		    && (winPtr != dispPtr->buttonWinPtr)) {
		return 0;
	    }
	}
	return 1;
    }











    if (!appGrabbed) {
	return 1;
    }





    if (eventPtr->type == MotionNotify) {
	/*
	 * When grabs are active, X reports motion events relative to the
	 * window under the pointer. Instead, it should report the events
	 * relative to the window the button went down in, if there is a
	 * button down. Otherwise, if the pointer window is outside the
	 * subtree of the grab window, the events should be reported relative
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
	    winPtr2 = dispPtr->grabWinPtr;
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;
	}

        /*
         * Warp the mouse pointer with respect to window dispPtr->warpWindow
         * if such a window was set in HandleEventGenerate.
         */

        TkDoWarpWrtWin(dispPtr);
	return 1;
    }

    /*
     * Process ButtonPress and ButtonRelease events:
     * 1. Keep track of whether a button is down and what window it went down
     *    in.







<
<
<
<
<
<
<







797
798
799
800
801
802
803







804
805
806
807
808
809
810
	    winPtr2 = dispPtr->grabWinPtr;
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;
	}







	return 1;
    }

    /*
     * Process ButtonPress and ButtonRelease events:
     * 1. Keep track of whether a button is down and what window it went down
     *    in.
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
		}
		dispPtr->buttonWinPtr = winPtr;
		return 1;
	    }
	} else {
	    if (eventPtr->xbutton.button != AnyButton &&
		    ((eventPtr->xbutton.state & ALL_BUTTONS)
		    == Tk_GetButtonMask(eventPtr->xbutton.button))) {
		ReleaseButtonGrab(dispPtr);			/* Note 4. */
	    }
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;						/* Note 3. */







|







869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
		}
		dispPtr->buttonWinPtr = winPtr;
		return 1;
	    }
	} else {
	    if (eventPtr->xbutton.button != AnyButton &&
		    ((eventPtr->xbutton.state & ALL_BUTTONS)
		    == TkGetButtonMask(eventPtr->xbutton.button))) {
		ReleaseButtonGrab(dispPtr);			/* Note 4. */
	    }
	}
	if (winPtr2 != winPtr) {
	    TkChangeEventWindow(eventPtr, winPtr2);
	    Tk_QueueWindowEvent(eventPtr, TCL_QUEUE_HEAD);
	    return 0;						/* Note 3. */
Changes to generic/tkGrid.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * 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 (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
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,







|







258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
static int		AdjustOffsets(int width, int elements,
			    SlotInfo *slotPtr);
static void		ArrangeGrid(ClientData clientData);
static int		CheckSlotData(Gridder *containerPtr, int slot,
			    int slotType, int checkOnly);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static Tcl_FreeProc	DestroyGrid;
static Gridder *	GetGrid(Tk_Window tkwin);
static int		GridAnchorCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridBboxCommand(Tk_Window tkwin, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		GridForgetRemoveCommand(Tk_Window tkwin,
			    Tcl_Interp *interp, int objc,
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
			    int objc, Tcl_Obj *const objv[]);
static void		GridStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		GridLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		GridReqProc(ClientData clientData, Tk_Window tkwin);
static void		InitContainerData(Gridder *containerPtr);
static Tcl_Obj *	NewPairObj(Tcl_WideInt, Tcl_WideInt);
static Tcl_Obj *	NewQuadObj(Tcl_WideInt, Tcl_WideInt, Tcl_WideInt, Tcl_WideInt);
static int		ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
			    int maxOffset);
static void		SetGridSize(Gridder *gridPtr);
static int		SetContentColumn(Tcl_Interp *interp, Gridder *contentPtr,
			    int column, int numCols);
static int		SetContentRow(Tcl_Interp *interp, Gridder *contentPtr,
			    int row, int numRows);
static Tcl_Obj *	StickyToObj(int flags);
static int		StringToSticky(const char *string);
static void		Unlink(Gridder *gridPtr);

static const Tk_GeomMgr gridMgrType = {
    "grid",			/* name */
    GridReqProc,		/* requestProc */
    GridLostContentProc,		/* lostContentProc */
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GridCmd --
 *







|
|














|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
			    int objc, Tcl_Obj *const objv[]);
static void		GridStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		GridLostContentProc(ClientData clientData,
			    Tk_Window tkwin);
static void		GridReqProc(ClientData clientData, Tk_Window tkwin);
static void		InitContainerData(Gridder *containerPtr);
static Tcl_Obj *	NewPairObj(int, int);
static Tcl_Obj *	NewQuadObj(int, int, int, int);
static int		ResolveConstraints(Gridder *gridPtr, int rowOrColumn,
			    int maxOffset);
static void		SetGridSize(Gridder *gridPtr);
static int		SetContentColumn(Tcl_Interp *interp, Gridder *contentPtr,
			    int column, int numCols);
static int		SetContentRow(Tcl_Interp *interp, Gridder *contentPtr,
			    int row, int numRows);
static Tcl_Obj *	StickyToObj(int flags);
static int		StringToSticky(const char *string);
static void		Unlink(Gridder *gridPtr);

static const Tk_GeomMgr gridMgrType = {
    "grid",			/* name */
    GridReqProc,		/* requestProc */
    GridLostContentProc,		/* lostSlaveProc */
};

/*
 *----------------------------------------------------------------------
 *
 * Tk_GridCmd --
 *
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"anchor", "bbox", "columnconfigure", "configure",
	"content", "forget", "info", "location", "propagate",
	"remove", "rowconfigure", "size", "slaves", NULL
    };
    static const char *const optionStringsNoDep[] = {
	"anchor", "bbox", "columnconfigure", "configure",
	"content", "forget", "info", "location", "propagate",
	"remove", "rowconfigure", "size", NULL
    };
    enum options {
	GRID_ANCHOR, GRID_BBOX, GRID_COLUMNCONFIGURE, GRID_CONFIGURE,
	GRID_CONTENT, GRID_FORGET, GRID_INFO, GRID_LOCATION, GRID_PROPAGATE,
	GRID_REMOVE, GRID_ROWCONFIGURE, GRID_SIZE, GRID_SLAVES
    };
    int index;

    if (objc >= 2) {
	const char *argv1 = Tcl_GetString(objv[1]);

	if ((argv1[0] == '.') || (argv1[0] == REL_SKIP) ||
    		(argv1[0] == REL_VERT)) {
	    return ConfigureContent(interp, tkwin, objc-1, objv+1);
	}
    }
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(NULL, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case GRID_ANCHOR:
	return GridAnchorCommand(tkwin, interp, objc, objv);
    case GRID_BBOX:







<
<
<
<
<




















<
<
<
<
<
<
<
<
|
|







337
338
339
340
341
342
343





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








364
365
366
367
368
369
370
371
372
{
    Tk_Window tkwin = (Tk_Window)clientData;
    static const char *const optionStrings[] = {
	"anchor", "bbox", "columnconfigure", "configure",
	"content", "forget", "info", "location", "propagate",
	"remove", "rowconfigure", "size", "slaves", NULL
    };





    enum options {
	GRID_ANCHOR, GRID_BBOX, GRID_COLUMNCONFIGURE, GRID_CONFIGURE,
	GRID_CONTENT, GRID_FORGET, GRID_INFO, GRID_LOCATION, GRID_PROPAGATE,
	GRID_REMOVE, GRID_ROWCONFIGURE, GRID_SIZE, GRID_SLAVES
    };
    int index;

    if (objc >= 2) {
	const char *argv1 = Tcl_GetString(objv[1]);

	if ((argv1[0] == '.') || (argv1[0] == REL_SKIP) ||
    		(argv1[0] == REL_VERT)) {
	    return ConfigureContent(interp, tkwin, objc-1, objv+1);
	}
    }
    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option arg ?arg ...?");
	return TCL_ERROR;
    }









    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case GRID_ANCHOR:
	return GridAnchorCommand(tkwin, interp, objc, objv);
    case GRID_BBOX:
454
455
456
457
458
459
460
461


462
463
464
465
466
467
468
	Tcl_WrongNumArgs(interp, 2, objv, "window ?anchor?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);



    if (objc == 3) {
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		Tk_NameOfAnchor(gridPtr?gridPtr->anchor:GRID_DEFAULT_ANCHOR),
		-1));
	return TCL_OK;







|
>
>







441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
	Tcl_WrongNumArgs(interp, 2, objv, "window ?anchor?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }

    if (objc == 3) {
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		Tk_NameOfAnchor(gridPtr?gridPtr->anchor:GRID_DEFAULT_ANCHOR),
		-1));
	return TCL_OK;
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534


535
536
537
538
539
540
541
    int row, column;		/* origin for bounding box */
    int row2, column2;		/* end of bounding box */
    int endX, endY;		/* last column/row in the layout */
    int x=0, y=0;		/* starting pixels for this bounding box */
    int width, height;		/* size of the bounding box */

    if (objc!=3 && objc != 5 && objc != 7) {
	Tcl_WrongNumArgs(interp, 2, objv, "window ?column row ?column row??");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);



    if (objc >= 5) {
	if (Tcl_GetIntFromObj(interp, objv[3], &column) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[4], &row) != TCL_OK) {
	    return TCL_ERROR;







|






|
>
>







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
    int row, column;		/* origin for bounding box */
    int row2, column2;		/* end of bounding box */
    int endX, endY;		/* last column/row in the layout */
    int x=0, y=0;		/* starting pixels for this bounding box */
    int width, height;		/* size of the bounding box */

    if (objc!=3 && objc != 5 && objc != 7) {
	Tcl_WrongNumArgs(interp, 2, objv, "master ?column row ?column row??");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }

    if (objc >= 5) {
	if (Tcl_GetIntFromObj(interp, objv[3], &column) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[4], &row) != TCL_OK) {
	    return TCL_ERROR;
651
652
653
654
655
656
657
658


659
660
661
662
663
664
665
    char c = string[0];

    for (i = 2; i < objc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
	    return TCL_ERROR;
	}

	contentPtr = GetGrid(content);


	if (contentPtr->containerPtr != NULL) {
	    /*
	     * For "forget", reset all the settings to their defaults
	     */

	    if (c == 'f') {
		contentPtr->column = -1;







|
>
>







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
    char c = string[0];

    for (i = 2; i < objc; i++) {
	if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
	    return TCL_ERROR;
	}

	if (!(contentPtr = GetGrid(content))) {
	    continue;
	}
	if (contentPtr->containerPtr != NULL) {
	    /*
	     * For "forget", reset all the settings to their defaults
	     */

	    if (c == 'f') {
		contentPtr->column = -1;
741
742
743
744
745
746
747
748


749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
    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);







|
>
>







|

|

|

|

|







734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }
    if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	return TCL_ERROR;
    }
    if (!(contentPtr = GetGrid(content))) {
	return TCL_OK;
    }
    if (contentPtr->containerPtr == NULL) {
	Tcl_ResetResult(interp);
	return TCL_OK;
    }

    infoObj = Tcl_NewObj();
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
	    TkNewWindowObj(contentPtr->containerPtr->tkwin));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-column", -1),
	    Tcl_NewIntObj(contentPtr->column));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-row", -1),
	    Tcl_NewIntObj(contentPtr->row));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-columnspan", -1),
	    Tcl_NewIntObj(contentPtr->numCols));
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-rowspan", -1),
	    Tcl_NewIntObj(contentPtr->numRows));
    TkAppendPadAmount(infoObj, "-ipadx", contentPtr->iPadX/2, contentPtr->iPadX);
    TkAppendPadAmount(infoObj, "-ipady", contentPtr->iPadY/2, contentPtr->iPadY);
    TkAppendPadAmount(infoObj, "-padx", contentPtr->padLeft, contentPtr->padX);
    TkAppendPadAmount(infoObj, "-pady", contentPtr->padTop, contentPtr->padY);
    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-sticky", -1),
	    StickyToObj(contentPtr->sticky));
    Tcl_SetObjResult(interp, infoObj);
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823


824
825
826
827
828
829
830
    GridContainer *gridPtr;	/* Pointer to grid data. */
    SlotInfo *slotPtr;
    int x, y;			/* Offset in pixels, from edge of container. */
    int i, j;			/* Corresponding column and row indeces. */
    int endX, endY;		/* End of grid. */

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "window x y");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

    if (Tk_GetPixelsFromObj(interp, container, objv[3], &x) != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tk_GetPixelsFromObj(interp, container, objv[4], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    containerPtr = GetGrid(container);


    if (containerPtr->containerDataPtr == NULL) {
	Tcl_SetObjResult(interp, NewPairObj(-1, -1));
	return TCL_OK;
    }
    gridPtr = containerPtr->containerDataPtr;

    /*







|














|
>
>







796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
    GridContainer *gridPtr;	/* Pointer to grid data. */
    SlotInfo *slotPtr;
    int x, y;			/* Offset in pixels, from edge of container. */
    int i, j;			/* Corresponding column and row indeces. */
    int endX, endY;		/* End of grid. */

    if (objc != 5) {
	Tcl_WrongNumArgs(interp, 2, objv, "master x y");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

    if (Tk_GetPixelsFromObj(interp, container, objv[3], &x) != TCL_OK) {
	return TCL_ERROR;
    }
    if (Tk_GetPixelsFromObj(interp, container, objv[4], &y) != TCL_OK) {
	return TCL_ERROR;
    }

    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }
    if (containerPtr->containerDataPtr == NULL) {
	Tcl_SetObjResult(interp, NewPairObj(-1, -1));
	return TCL_OK;
    }
    gridPtr = containerPtr->containerDataPtr;

    /*
897
898
899
900
901
902
903
904


905
906
907
908
909
910
911
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);


    if (objc == 3) {
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	return TCL_ERROR;







|
>
>







894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
	Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }
    if (objc == 3) {
	Tcl_SetObjResult(interp,
		Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	return TCL_OK;
    }
    if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	return TCL_ERROR;
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
    enum options {
	ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT
    };
    int index;
    Tcl_Obj *listCopy;

    if (((objc % 2 != 0) && (objc > 6)) || (objc < 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "window index ?-option value ...?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }








|







993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
    enum options {
	ROWCOL_MINSIZE, ROWCOL_PAD, ROWCOL_UNIFORM, ROWCOL_WEIGHT
    };
    int index;
    Tcl_Obj *listCopy;

    if (((objc % 2 != 0) && (objc > 6)) || (objc < 4)) {
	Tcl_WrongNumArgs(interp, 2, objv, "master index ?-option value ...?");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }

1019
1020
1021
1022
1023
1024
1025
1026


1027
1028
1029
1030
1031
1032
1033
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("no %s indices specified",
		(slotType == COLUMN) ? "column" : "row"));
	Tcl_SetErrorCode(interp, "TK", "GRID", "NO_INDEX", NULL);
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    containerPtr = GetGrid(container);


    first = 0;
    last = 0;

    if ((objc == 4) || (objc == 5)) {
	if (lObjc != 1) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "must specify a single element on retrieval", -1));







|
>
>







1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
	Tcl_SetObjResult(interp, Tcl_ObjPrintf("no %s indices specified",
		(slotType == COLUMN) ? "column" : "row"));
	Tcl_SetErrorCode(interp, "TK", "GRID", "NO_INDEX", NULL);
	Tcl_DecrRefCount(listCopy);
	return TCL_ERROR;
    }

    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }
    first = 0;
    last = 0;

    if ((objc == 4) || (objc == 5)) {
	if (lObjc != 1) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "must specify a single element on retrieval", -1));
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
		pad     = slotPtr[slot].pad;
		weight  = slotPtr[slot].weight;
		uniform = slotPtr[slot].uniform;
	    }

	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-minsize", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(minsize));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-pad", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(pad));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-uniform", -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj(uniform == NULL ? "" : uniform, -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-weight", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewWideIntObj(weight));
	    Tcl_SetObjResult(interp, res);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_OK;
	}

	/*
	 * If only one option is given, with no value, the current value is
	 * returned.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[4], optionStrings,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}
	if (index == ROWCOL_MINSIZE) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].minSize : 0));
	} else if (index == ROWCOL_WEIGHT) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].weight : 0));
	} else if (index == ROWCOL_UNIFORM) {
	    Tk_Uid value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    (value == NULL) ? "" : value, -1));
	} else if (index == ROWCOL_PAD) {
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].pad : 0));
	}
	Tcl_DecrRefCount(listCopy);
	return TCL_OK;
    }

    for (j = 0; j < lObjc; j++) {







|


|






|
















|


|







|







1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
		pad     = slotPtr[slot].pad;
		weight  = slotPtr[slot].weight;
		uniform = slotPtr[slot].uniform;
	    }

	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-minsize", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(minsize));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-pad", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(pad));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-uniform", -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj(uniform == NULL ? "" : uniform, -1));
	    Tcl_ListObjAppendElement(interp, res,
		    Tcl_NewStringObj("-weight", -1));
	    Tcl_ListObjAppendElement(interp, res, Tcl_NewIntObj(weight));
	    Tcl_SetObjResult(interp, res);
	    Tcl_DecrRefCount(listCopy);
	    return TCL_OK;
	}

	/*
	 * If only one option is given, with no value, the current value is
	 * returned.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[4], optionStrings,
		sizeof(char *), "option", 0, &index) != TCL_OK) {
	    Tcl_DecrRefCount(listCopy);
	    return TCL_ERROR;
	}
	if (index == ROWCOL_MINSIZE) {
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].minSize : 0));
	} else if (index == ROWCOL_WEIGHT) {
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].weight : 0));
	} else if (index == ROWCOL_UNIFORM) {
	    Tk_Uid value = (ok == TCL_OK) ? slotPtr[slot].uniform : "";

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    (value == NULL) ? "" : value, -1));
	} else if (index == ROWCOL_PAD) {
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(
		    (ok == TCL_OK) ? slotPtr[slot].pad : 0));
	}
	Tcl_DecrRefCount(listCopy);
	return TCL_OK;
    }

    for (j = 0; j < lObjc; j++) {
1135
1136
1137
1138
1139
1140
1141
1142


1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
	    allContent = 1;
	} else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &content)
		== TCL_OK) {
	    /*
	     * Is it gridded in this container?
	     */

	    contentPtr = GetGrid(content);


	    if (contentPtr->containerPtr != containerPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"the window \"%s\" is not managed by \"%s\"",
			Tcl_GetString(lObjv[j]), Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "GRID", "NOT_MANAGED", NULL);
		Tcl_DecrRefCount(listCopy);
		return TCL_ERROR;
	    }
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "illegal index \"%s\"", Tcl_GetString(lObjv[j])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID_INDEX", NULL);







|
>
>




|







1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
	    allContent = 1;
	} else if (TkGetWindowFromObj(NULL, tkwin, lObjv[j], &content)
		== TCL_OK) {
	    /*
	     * Is it gridded in this container?
	     */

	    if (!(contentPtr = GetGrid(content))) {
		continue;
	    }
	    if (contentPtr->containerPtr != containerPtr) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"the window \"%s\" is not managed by \"%s\"",
			Tcl_GetString(lObjv[j]), Tcl_GetString(objv[2])));
		Tcl_SetErrorCode(interp, "TK", "GRID", "NOT_MASTER", NULL);
		Tcl_DecrRefCount(listCopy);
		return TCL_ERROR;
	    }
	} else {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "illegal index \"%s\"", Tcl_GetString(lObjv[j])));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "GRID_INDEX", NULL);
1318
1319
1320
1321
1322
1323
1324
1325


1326
1327
1328
1329
1330
1331
1332
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);



    if (containerPtr->containerDataPtr != NULL) {
	SetGridSize(containerPtr);
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, NewPairObj(
		MAX(gridPtr->columnEnd, gridPtr->columnMax),
		MAX(gridPtr->rowEnd, gridPtr->rowMax)));







|
>
>







1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
	Tcl_WrongNumArgs(interp, 2, objv, "window");
	return TCL_ERROR;
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }

    if (containerPtr->containerDataPtr != NULL) {
	SetGridSize(containerPtr);
	gridPtr = containerPtr->containerDataPtr;
	Tcl_SetObjResult(interp, NewPairObj(
		MAX(gridPtr->columnEnd, gridPtr->columnMax),
		MAX(gridPtr->rowEnd, gridPtr->rowMax)));
1397
1398
1399
1400
1401
1402
1403
1404


1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
	    row = value;
	}
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    containerPtr = GetGrid(container);



    res = Tcl_NewListObj(0, NULL);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if ((column >= 0) && (contentPtr->column > column
		|| contentPtr->column+contentPtr->numCols-1 < column)) {
	    continue;
	}
	if ((row >= 0) && (contentPtr->row > row ||
		contentPtr->row+contentPtr->numRows-1 < row)) {
	    continue;
	}
	Tcl_ListObjAppendElement(interp,res, Tk_NewWindowObj(contentPtr->tkwin));
    }
    Tcl_SetObjResult(interp, res);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
>
>












|







1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
	    row = value;
	}
    }

    if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	return TCL_ERROR;
    }
    if (!(containerPtr = GetGrid(container))) {
	return TCL_OK;
    }

    res = Tcl_NewListObj(0, NULL);
    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
	    contentPtr = contentPtr->nextPtr) {
	if ((column >= 0) && (contentPtr->column > column
		|| contentPtr->column+contentPtr->numCols-1 < column)) {
	    continue;
	}
	if ((row >= 0) && (contentPtr->row > row ||
		contentPtr->row+contentPtr->numRows-1 < row)) {
	    continue;
	}
	Tcl_ListObjAppendElement(interp,res, TkNewWindowObj(contentPtr->tkwin));
    }
    Tcl_SetObjResult(interp, res);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
2413
2414
2415
2416
2417
2418
2419
2420

2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441




2442
2443
2444
2445
2446
2447
2448

/*
 *----------------------------------------------------------------------
 *
 * GetGrid --
 *
 *	This internal procedure is used to locate a Grid structure for a given
 *	window, creating one if one doesn't exist already.

 *
 * Results:
 *	The return value is a pointer to the Grid structure corresponding to
 *	tkwin.
 *
 * Side effects:
 *	A new grid structure may be created. If so, then a callback is set up
 *	to clean things up when the window is deleted.
 *
 *----------------------------------------------------------------------
 */

static Gridder *
GetGrid(
    Tk_Window tkwin)		/* Token for window for which grid structure
				 * is desired. */
{
    Gridder *gridPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;





    if (!dispPtr->gridInit) {
	Tcl_InitHashTable(&dispPtr->gridHashTable, TCL_ONE_WORD_KEYS);
	dispPtr->gridInit = 1;
    }

    /*







|
>



|

















>
>
>
>







2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460

/*
 *----------------------------------------------------------------------
 *
 * GetGrid --
 *
 *	This internal procedure is used to locate a Grid structure for a given
 *	window, creating one if one doesn't exist already, except if the window
 *	is already dead.
 *
 * Results:
 *	The return value is a pointer to the Grid structure corresponding to
 *	tkwin, or NULL when tkwin is already dead.
 *
 * Side effects:
 *	A new grid structure may be created. If so, then a callback is set up
 *	to clean things up when the window is deleted.
 *
 *----------------------------------------------------------------------
 */

static Gridder *
GetGrid(
    Tk_Window tkwin)		/* Token for window for which grid structure
				 * is desired. */
{
    Gridder *gridPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (((TkWindow *) tkwin)->flags & TK_ALREADY_DEAD) {
	return NULL;
    }

    if (!dispPtr->gridInit) {
	Tcl_InitHashTable(&dispPtr->gridHashTable, TCL_ONE_WORD_KEYS);
	dispPtr->gridInit = 1;
    }

    /*
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
    gridPtr->iPadY = 0;
    gridPtr->doubleBw = 2 * Tk_Changes(tkwin)->border_width;
    gridPtr->abortPtr = NULL;
    gridPtr->flags = 0;
    gridPtr->sticky = 0;
    gridPtr->size = 0;
    gridPtr->in = NULL;
    gridPtr->containerDataPtr = NULL;
    Tcl_SetHashValue(hPtr, gridPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    GridStructureProc, gridPtr);
    return gridPtr;
}

/*







<







2487
2488
2489
2490
2491
2492
2493

2494
2495
2496
2497
2498
2499
2500
    gridPtr->iPadY = 0;
    gridPtr->doubleBw = 2 * Tk_Changes(tkwin)->border_width;
    gridPtr->abortPtr = NULL;
    gridPtr->flags = 0;
    gridPtr->sticky = 0;
    gridPtr->size = 0;
    gridPtr->in = NULL;

    Tcl_SetHashValue(hPtr, gridPtr);
    Tk_CreateEventHandler(tkwin, StructureNotifyMask,
	    GridStructureProc, gridPtr);
    return gridPtr;
}

/*
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808

    SetGridSize(contentPtr->containerPtr);
    contentPtr->containerPtr = NULL;

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "grid");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * DestroyGrid --







<
<
<





<







2797
2798
2799
2800
2801
2802
2803



2804
2805
2806
2807
2808

2809
2810
2811
2812
2813
2814
2815

    SetGridSize(contentPtr->containerPtr);
    contentPtr->containerPtr = NULL;

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.



     */

    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "grid");
	containerPtr->flags &= ~ALLOCED_CONTAINER;

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







|



>
>
>







2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
 *	Everything associated with the grid is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyGrid(
    char *memPtr)		/* Info about window that is now dead. */
{
    Gridder *gridPtr = (Gridder *)memPtr;

    if (gridPtr->flags & REQUESTED_RELAYOUT) {
	Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
    }
    if (gridPtr->containerDataPtr != NULL) {
	if (gridPtr->containerDataPtr->rowPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> rowPtr);
	}
	if (gridPtr->containerDataPtr->columnPtr != NULL) {
	    ckfree(gridPtr->containerDataPtr -> columnPtr);
	}
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
	    Tk_ManageGeometry(contentPtr->tkwin, NULL, NULL);
	    Tk_UnmapWindow(contentPtr->tkwin);
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
		gridPtr->tkwin));
	if (gridPtr->flags & REQUESTED_RELAYOUT) {
	    Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
	}
	gridPtr->tkwin = NULL;
	Tcl_EventuallyFree(gridPtr, (Tcl_FreeProc *)DestroyGrid);
    } else if (eventPtr->type == MapNotify) {
	if ((gridPtr->contentPtr != NULL)
		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
	    gridPtr->flags |= REQUESTED_RELAYOUT;
	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
	}
    } else if (eventPtr->type == UnmapNotify) {







|




|







2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
	    Tk_ManageGeometry(contentPtr->tkwin, NULL, NULL);
	    Tk_UnmapWindow(contentPtr->tkwin);
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
		(char *)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) {
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

    /*
     * Count the number of windows, or window short-cuts.
     */

    firstChar = 0;
    for (numWindows=0, i=0; i < objc; i++) {
	TkSizeT length;
	char prevChar = firstChar;

	string = TkGetStringFromObj(objv[i], &length);
    	firstChar = string[0];

	if (firstChar == '.') {
	    /*
	     * Check that windows are valid, and locate the first content's
	     * parent window (default for -in).
	     */

	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (containerPtr == NULL) {
		/*
		 * Is there any saved -in from a removed content?
		 * If there is, it becomes default for -in.
		 * If the stored container does not exist, just ignore it.
		 */

		contentPtr = GetGrid(content);


		if (contentPtr->in != NULL) {
		    if (TkGetWindowFromObj(interp, content, contentPtr->in, &parent)
			    == TCL_OK) {
			containerPtr = GetGrid(parent);


			InitContainerData(containerPtr);
		    }
		}
	    }
	    if (containerPtr == NULL) {
		parent = Tk_Parent(content);
		if (parent != NULL) {
		    containerPtr = GetGrid(parent);


		    InitContainerData(containerPtr);
		}
	    }
	    numWindows++;
	    continue;
    	}
	if (length > 1 && i == 0) {







|


|


















|
>
>



|
>
>







|
>
>







2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043

    /*
     * Count the number of windows, or window short-cuts.
     */

    firstChar = 0;
    for (numWindows=0, i=0; i < objc; i++) {
	int length;
	char prevChar = firstChar;

	string = Tcl_GetStringFromObj(objv[i], &length);
    	firstChar = string[0];

	if (firstChar == '.') {
	    /*
	     * Check that windows are valid, and locate the first content's
	     * parent window (default for -in).
	     */

	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (containerPtr == NULL) {
		/*
		 * Is there any saved -in from a removed content?
		 * If there is, it becomes default for -in.
		 * If the stored container does not exist, just ignore it.
		 */

		if (!(contentPtr = GetGrid(content))) {
		    continue;
		}
		if (contentPtr->in != NULL) {
		    if (TkGetWindowFromObj(interp, content, contentPtr->in, &parent)
			    == TCL_OK) {
			if (!(containerPtr = GetGrid(parent))) {
			    continue;
			}
			InitContainerData(containerPtr);
		    }
		}
	    }
	    if (containerPtr == NULL) {
		parent = Tk_Parent(content);
		if (parent != NULL) {
		    if (!(containerPtr = GetGrid(parent))) {
			continue;
		    }
		    InitContainerData(containerPtr);
		}
	    }
	    numWindows++;
	    continue;
    	}
	if (length > 1 && i == 0) {
3082
3083
3084
3085
3086
3087
3088
3089


3090
3091
3092
3093
3094
3095
3096
	    return TCL_ERROR;
	}
	if (index == CONF_IN) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) !=
		    TCL_OK) {
		return TCL_ERROR;
	    }
	    containerPtr = GetGrid(other);


	    InitContainerData(containerPtr);
	} else if (index == CONF_ROW) {
	    if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK
		    || tmp < 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad row value \"%s\": must be a non-negative integer",
			Tcl_GetString(objv[i+1])));







|
>
>







3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
	    return TCL_ERROR;
	}
	if (index == CONF_IN) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other) !=
		    TCL_OK) {
		return TCL_ERROR;
	    }
	    if (!(containerPtr = GetGrid(other))) {
		continue;
	    }
	    InitContainerData(containerPtr);
	} else if (index == CONF_ROW) {
	    if (Tcl_GetIntFromObj(interp, objv[i+1], &tmp) != TCL_OK
		    || tmp < 0) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"bad row value \"%s\": must be a non-negative integer",
			Tcl_GetString(objv[i+1])));
3159
3160
3161
3162
3163
3164
3165
3166


3167
3168
3169
3170
3171
3172
3173
	if (Tk_TopWinHierarchy(content)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't manage \"%s\": it's a top-level window",
		    Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}
	contentPtr = GetGrid(content);



	/*
	 * The following statement is taken from tkPack.c:
	 *
	 * "If the content isn't currently managed, reset all of its
	 * configuration information to default values (there could be old
	 * values left from a previous packer)."







|
>
>







3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
	if (Tk_TopWinHierarchy(content)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't manage \"%s\": it's a top-level window",
		    Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}
	if (!(contentPtr = GetGrid(content))) {
	    continue;
	}

	/*
	 * The following statement is taken from tkPack.c:
	 *
	 * "If the content isn't currently managed, reset all of its
	 * configuration information to default values (there could be old
	 * values left from a previous packer)."
3218
3219
3220
3221
3222
3223
3224
3225


3226
3227
3228
3229
3230
3231
3232
		if (other == content) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "window can't be managed in itself", -1));
		    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
		    return TCL_ERROR;
		}
		positionGiven = 1;
		containerPtr = GetGrid(other);


		InitContainerData(containerPtr);
		break;
	    case CONF_STICKY: {
		int sticky = StringToSticky(Tcl_GetString(objv[i+1]));

		if (sticky == -1) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(







|
>
>







3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
		if (other == content) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "window can't be managed in itself", -1));
		    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
		    return TCL_ERROR;
		}
		positionGiven = 1;
		if (!(containerPtr = GetGrid(other))) {
		    continue;
		}
		InitContainerData(containerPtr);
		break;
	    case CONF_STICKY: {
		int sticky = StringToSticky(Tcl_GetString(objv[i+1]));

		if (sticky == -1) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
3325
3326
3327
3328
3329
3330
3331
3332


3333
3334
3335
3336
3337
3338
3339
	 * Make sure we have a geometry container. We look at:
	 *  1)   the -in flag
	 *  2)   the parent of the first content.
	 */

	parent = Tk_Parent(content);
    	if (containerPtr == NULL) {
	    containerPtr = GetGrid(parent);


	    InitContainerData(containerPtr);
    	}

	if (contentPtr->containerPtr != NULL && contentPtr->containerPtr != containerPtr) {
            if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
                Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
            }







|
>
>







3347
3348
3349
3350
3351
3352
3353
3354
3355
3356
3357
3358
3359
3360
3361
3362
3363
	 * Make sure we have a geometry container. We look at:
	 *  1)   the -in flag
	 *  2)   the parent of the first content.
	 */

	parent = Tk_Parent(content);
    	if (containerPtr == NULL) {
	    if (!(containerPtr = GetGrid(parent))) {
		continue;
	    }
	    InitContainerData(containerPtr);
    	}

	if (contentPtr->containerPtr != NULL && contentPtr->containerPtr != containerPtr) {
            if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
                Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
            }
3357
3358
3359
3360
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387

	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't put \"%s\" inside \"%s\"", Tcl_GetString(objv[j]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put \"%s\" inside \"%s\": would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}
	if (containerPtr->tkwin != Tk_Parent(content)) {







|















|







3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411

	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't put %s inside %s", Tcl_GetString(objv[j]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put %s inside %s, would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		Unlink(contentPtr);
		return TCL_ERROR;
	    }
	}
	if (containerPtr->tkwin != Tk_Parent(content)) {
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.
	 */







|







3482
3483
3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
	}
	if (firstChar != REL_VERT) {
	    continue;
	}

	if (containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't use '^', cant find master", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Count the number of consecutive ^'s starting from this position.
	 */
3484
3485
3486
3487
3488
3489
3490
3491


3492
3493
3494
3495
3496
3497
3498
	 */

	if (lastWindow == NULL) {
	    lastRow = defaultRow - 1;
	    lastColumn = 0;
	} else {
	    other = Tk_NameToWindow(interp, lastWindow, tkwin);
	    otherPtr = GetGrid(other);


	    lastRow = otherPtr->row + otherPtr->numRows - 2;
	    lastColumn = otherPtr->column + otherPtr->numCols;
	}

	lastColumn += numSkip;

	match = 0;







|
>
>







3508
3509
3510
3511
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
	 */

	if (lastWindow == NULL) {
	    lastRow = defaultRow - 1;
	    lastColumn = 0;
	} else {
	    other = Tk_NameToWindow(interp, lastWindow, tkwin);
	    if (!(otherPtr = GetGrid(other))) {
		continue;
	    }
	    lastRow = otherPtr->row + otherPtr->numRows - 2;
	    lastColumn = otherPtr->column + otherPtr->numCols;
	}

	lastColumn += numSkip;

	match = 0;
3512
3513
3514
3515
3516
3517
3518
3519
3520
3521
3522
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find content to extend with \"^\"", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}
    }

    if (containerPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't determine container window", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    SetGridSize(containerPtr);

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if (containerPtr->contentPtr == NULL && containerPtr->flags & ALLOCED_CONTAINER) {
	TkFreeGeometryContainer(containerPtr->tkwin, "grid");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|







|








<
<
<





<







3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561



3562
3563
3564
3565
3566

3567
3568
3569
3570
3571
3572
3573
		    numSkip = 0;
		    break;
		}
	    }
	}
	if (!match) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't find slave to extend with \"^\"", -1));
	    Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	    return TCL_ERROR;
	}
    }

    if (containerPtr == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"can't determine master window", -1));
	Tcl_SetErrorCode(interp, "TK", "GRID", "SHORTCUT_USAGE", NULL);
	return TCL_ERROR;
    }
    SetGridSize(containerPtr);

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.



     */

    if (containerPtr->contentPtr == NULL && containerPtr->flags & ALLOCED_CONTAINER) {
	TkFreeGeometryContainer(containerPtr->tkwin, "grid");
	containerPtr->flags &= ~ALLOCED_CONTAINER;

    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
3662
3663
3664
3665
3666
3667
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewPairObj(
    Tcl_WideInt val1, Tcl_WideInt val2)
{
    Tcl_Obj *ary[2];

    ary[0] = Tcl_NewWideIntObj(val1);
    ary[1] = Tcl_NewWideIntObj(val2);
    return Tcl_NewListObj(2, ary);
}

/*
 *----------------------------------------------------------------------
 *
 * NewQuadObj --







|



|
|







3670
3671
3672
3673
3674
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewPairObj(
    int val1, int val2)
{
    Tcl_Obj *ary[2];

    ary[0] = Tcl_NewIntObj(val1);
    ary[1] = Tcl_NewIntObj(val2);
    return Tcl_NewListObj(2, ary);
}

/*
 *----------------------------------------------------------------------
 *
 * NewQuadObj --
3675
3676
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3689
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewQuadObj(
    Tcl_WideInt val1, Tcl_WideInt val2, Tcl_WideInt val3, Tcl_WideInt val4)
{
    Tcl_Obj *ary[4];

    ary[0] = Tcl_NewWideIntObj(val1);
    ary[1] = Tcl_NewWideIntObj(val2);
    ary[2] = Tcl_NewWideIntObj(val3);
    ary[3] = Tcl_NewWideIntObj(val4);
    return Tcl_NewListObj(4, ary);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|



|
|
|
|










3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
3709
3710
3711
3712
3713
3714
3715
3716
3717
3718
3719
3720
3721
 *	None.
 *
 *----------------------------------------------------------------------
 */

static Tcl_Obj *
NewQuadObj(
    int val1, int val2, int val3, int val4)
{
    Tcl_Obj *ary[4];

    ary[0] = Tcl_NewIntObj(val1);
    ary[1] = Tcl_NewIntObj(val2);
    ary[2] = Tcl_NewIntObj(val3);
    ary[3] = Tcl_NewIntObj(val4);
    return Tcl_NewListObj(4, ary);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkImage.c.
9
10
11
12
13
14
15




16
17
18
19
20
21
22
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"





/*
 * 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 {







>
>
>
>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Each call to Tk_GetImage returns a pointer to one of the following
 * structures, which is used as a token by clients (widgets) that display
 * images.
 */

typedef struct Image {
32
33
34
35
36
37
38


39
40
41
42
43
44
45
    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.







>
>







36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
    ClientData instanceData;	/* One word argument to pass to image manager
				 * when dealing with this image instance. */
    Tk_ImageChangedProc *changeProc;
				/* Code in widget to call when image changes
				 * in a way that affects redisplay. */
    ClientData widgetClientData;/* Argument to pass to changeProc. */
    struct Image *nextPtr;	/* Next in list of all image instances
				 * associated with the same name. */
    struct Image *prevPtr;	/* Previous in list of all image instances
				 * associated with the same name. */
} Image;

/*
 * For each image model there is one of the following structures, which
 * represents a name in the image table and all of the images instantiated
 * from it. Entries in mainPtr->imageTable point to these structures.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
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 --







|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
static Tcl_ThreadDataKey dataKey;

/*
 * Prototypes for local functions:
 */

static void		ImageTypeThreadExitProc(ClientData clientData);
static Tcl_FreeProc	DeleteImage;
static void		EventuallyDeleteImage(ImageModel *modelPtr,
			    int forgetImageHashNow);

/*
 *----------------------------------------------------------------------
 *
 * ImageTypeThreadExitProc --
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char idString[16 + TCL_INTEGER_SPACE];
    TkDisplay *dispPtr = winPtr->dispPtr;
    const char *arg, *name;
    Tcl_Obj *resultObj;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], imageOptions,







|







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
    Tcl_HashEntry *hPtr;
    Tcl_HashSearch search;
    char idString[16 + TCL_INTEGER_SPACE];
    TkDisplay *dispPtr = winPtr->dispPtr;
    const char *arg, *name;
    Tcl_Obj *resultObj;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?args?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], imageOptions,
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
	/*
	 * 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;







|







287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
	/*
	 * Figure out a name to use for the new image.
	 */

	if ((objc == 3) || (*(arg = Tcl_GetString(objv[3])) == '-')) {
	    do {
		dispPtr->imageId++;
		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
	    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;
	}







>
>
>
>
>
>
>
|
|
>
>







370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
	    args = (Tcl_Obj **)ckalloc((objc+1) * sizeof(Tcl_Obj *));
	    for (i = 0; i < objc; i++) {
		args[i] = (Tcl_Obj *) Tcl_GetString(objv[i]);
	    }
	    args[objc] = NULL;
	}
	Tcl_Preserve(modelPtr);
	if (oldimage) {
	    typedef int (OldCreateProc)(Tcl_Interp*, char*, int, char**,
		Tk_ImageType*, Tk_ImageModel, ClientData*);
	    i = ((OldCreateProc*)typePtr->createProc)(interp,
		(char*)name, objc, (char**)args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	} else {
	    i = typePtr->createProc(interp, name, objc, args, typePtr,
		(Tk_ImageModel)modelPtr, &modelPtr->modelData);
	}
	if (i != TCL_OK){
	    EventuallyDeleteImage(modelPtr, 0);
	    Tcl_Release(modelPtr);
	    if (oldimage) {
		ckfree(args);
	    }
	    return TCL_ERROR;
	}
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
	    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;
	}







|







413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
	    if (hPtr == NULL) {
		goto alreadyDeleted;
	    }
	    modelPtr = (ImageModel *)Tcl_GetHashValue(hPtr);
	    if (modelPtr->deleted) {
		goto alreadyDeleted;
	    }
	    DeleteImage((char *)modelPtr);
	}
	break;
    case IMAGE_NAMES:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    return TCL_ERROR;
	}
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495

	/*
	 * Now we read off the specific piece of data we were asked for.
	 */

	switch ((enum options) index) {
	case IMAGE_HEIGHT:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->height));
	    break;
	case IMAGE_INUSE:
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    modelPtr->typePtr && modelPtr->instancePtr));
	    break;
	case IMAGE_TYPE:
	    if (modelPtr->typePtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(modelPtr->typePtr->name, -1));
	    }
	    break;
	case IMAGE_WIDTH:
	    Tcl_SetObjResult(interp, Tcl_NewWideIntObj(modelPtr->width));
	    break;
	default:
	    Tcl_Panic("can't happen");
	}
	break;
    }
    return TCL_OK;







|












|







483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

	/*
	 * Now we read off the specific piece of data we were asked for.
	 */

	switch ((enum options) index) {
	case IMAGE_HEIGHT:
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(modelPtr->height));
	    break;
	case IMAGE_INUSE:
	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(
		    modelPtr->typePtr && modelPtr->instancePtr));
	    break;
	case IMAGE_TYPE:
	    if (modelPtr->typePtr != NULL) {
		Tcl_SetObjResult(interp,
			Tcl_NewStringObj(modelPtr->typePtr->name, -1));
	    }
	    break;
	case IMAGE_WIDTH:
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(modelPtr->width));
	    break;
	default:
	    Tcl_Panic("can't happen");
	}
	break;
    }
    return TCL_OK;
627
628
629
630
631
632
633




634
635
636
637
638
639
640
    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));







>
>
>
>







642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
    imagePtr->display = Tk_Display(tkwin);
    imagePtr->modelPtr = modelPtr;
    imagePtr->instanceData =
	    modelPtr->typePtr->getProc(tkwin, modelPtr->modelData);
    imagePtr->changeProc = changeProc;
    imagePtr->widgetClientData = clientData;
    imagePtr->nextPtr = modelPtr->instancePtr;
    if (imagePtr->nextPtr) {
	imagePtr->nextPtr->prevPtr = imagePtr;
    }
    imagePtr->prevPtr = NULL;
    modelPtr->instancePtr = imagePtr;
    return (Tk_Image) imagePtr;

  noSuchImage:
    if (interp) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"image \"%s\" doesn't exist", name));
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683


684
685

686
687
688
689
690
691
692
693
694
695
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.
     */







<









|
|
|
>
>

|
>
|

<







683
684
685
686
687
688
689

690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708

709
710
711
712
713
714
715
void
Tk_FreeImage(
    Tk_Image image)		/* Token for image that is no longer needed by
				 * a widget. */
{
    Image *imagePtr = (Image *) image;
    ImageModel *modelPtr = imagePtr->modelPtr;


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







|







947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
    if (winPtr == NULL) {
	return;
    }
    hPtr = Tcl_FindHashEntry(&winPtr->mainPtr->imageTable, name);
    if (hPtr == NULL) {
	return;
    }
    DeleteImage((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);







|



>







970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
 *	existing instances will not be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
DeleteImage(
    char *blockPtr)	/* Pointer to main data structure for image. */
{
    Image *imagePtr;
    Tk_ImageType *typePtr;
    ImageModel *modelPtr = (ImageModel *)blockPtr;

    typePtr = modelPtr->typePtr;
    modelPtr->typePtr = NULL;
    if (typePtr != NULL) {
	for (imagePtr = modelPtr->instancePtr; imagePtr != NULL;
		imagePtr = imagePtr->nextPtr) {
	    typePtr->freeProc(imagePtr->instanceData, imagePtr->display);
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
				 * to vanish. */
{
    if (forgetImageHashNow) {
	modelPtr->hPtr = NULL;
    }
    if (!modelPtr->deleted) {
	modelPtr->deleted = 1;
	Tcl_EventuallyFree(modelPtr, (Tcl_FreeProc *) DeleteImage);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --







|







1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
				 * to vanish. */
{
    if (forgetImageHashNow) {
	modelPtr->hPtr = NULL;
    }
    if (!modelPtr->deleted) {
	modelPtr->deleted = 1;
	Tcl_EventuallyFree(modelPtr, DeleteImage);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDeleteAllImages --
Changes to generic/tkImgBmap.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
 * 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"

/*
 * The following data structure represents the model for a bitmap
 * image:
 */

typedef struct {
    Tk_ImageModel tkModel;	/* Tk's token for image model. NULL means the
				 * image is being deleted. */
    Tcl_Interp *interp;		/* Interpreter for application that is using
				 * image. */
    Tcl_Command imageCmd;	/* Token for image command (used to delete it
				 * when the image goes away). NULL means the
				 * image command has already been deleted. */
    int width, height;		/* Dimensions of image. */
    char *data;			/* Data comprising bitmap (suitable for input
				 * to XCreateBitmapFromData). May be NULL if
				 * no data. Malloc'ed. */
    char *maskData;		/* Data for bitmap's mask (suitable for input
				 * to XCreateBitmapFromData). Malloc'ed. */
    Tk_Uid fgUid;		/* Value of -foreground option (malloc'ed). */
    Tk_Uid bgUid;		/* Value of -background option (malloc'ed). */
    char *fileString;		/* Value of -file option (malloc'ed). */
    char *dataString;		/* Value of -data option (malloc'ed). */
    char *maskFileString;	/* Value of -maskfile option (malloc'ed). */
    char *maskDataString;	/* Value of -maskdata option (malloc'ed). */
    struct BitmapInstance *instancePtr;
				/* First in list of all instances associated
				 * with this model. */
} BitmapModel;

/*
 * The following data structure represents all of the instances of an image
 * that lie within a particular window:
 */

typedef struct BitmapInstance {
    size_t refCount;		/* Number of instances that share this data
				 * structure. */
    BitmapModel *modelPtr;	/* Pointer to model for image. */
    Tk_Window tkwin;		/* Window in which the instances will be
				 * displayed. */
    XColor *fg;			/* Foreground color for displaying image. */
    XColor *bg;			/* Background color for displaying image. */
    Pixmap bitmap;		/* The bitmap to display. */







|












|













|
|















|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/*
 * tkImgBmap.c --
 *
 *	This procedure implements images of type "bitmap" for Tk.
 *
 * Copyright (c) 1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1999 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

/*
 * The following data structure represents the model for a bitmap
 * image:
 */

typedef struct BitmapModel {
    Tk_ImageModel tkModel;	/* Tk's token for image model. NULL means the
				 * image is being deleted. */
    Tcl_Interp *interp;		/* Interpreter for application that is using
				 * image. */
    Tcl_Command imageCmd;	/* Token for image command (used to delete it
				 * when the image goes away). NULL means the
				 * image command has already been deleted. */
    int width, height;		/* Dimensions of image. */
    char *data;			/* Data comprising bitmap (suitable for input
				 * to XCreateBitmapFromData). May be NULL if
				 * no data. Malloc'ed. */
    char *maskData;		/* Data for bitmap's mask (suitable for input
				 * to XCreateBitmapFromData). Malloc'ed. */
    Tk_Uid fgUid;		/* Value of -foreground option. */
    Tk_Uid bgUid;		/* Value of -background option. */
    char *fileString;		/* Value of -file option (malloc'ed). */
    char *dataString;		/* Value of -data option (malloc'ed). */
    char *maskFileString;	/* Value of -maskfile option (malloc'ed). */
    char *maskDataString;	/* Value of -maskdata option (malloc'ed). */
    struct BitmapInstance *instancePtr;
				/* First in list of all instances associated
				 * with this model. */
} BitmapModel;

/*
 * The following data structure represents all of the instances of an image
 * that lie within a particular window:
 */

typedef struct BitmapInstance {
    int refCount;		/* Number of instances that share this data
				 * structure. */
    BitmapModel *modelPtr;	/* Pointer to model for image. */
    Tk_Window tkwin;		/* Window in which the instances will be
				 * displayed. */
    XColor *fg;			/* Foreground color for displaying image. */
    XColor *bg;			/* Background color for displaying image. */
    Pixmap bitmap;		/* The bitmap to display. */
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

/*
 * 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, int 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 */
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

/*
 * Information used for parsing configuration specs:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_UID, "-background", NULL, NULL,
	"", offsetof(BitmapModel, bgUid), 0, NULL},
    {TK_CONFIG_STRING, "-data", NULL, NULL,
	NULL, offsetof(BitmapModel, dataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	NULL, offsetof(BitmapModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_UID, "-foreground", NULL, NULL,
	"#000000", offsetof(BitmapModel, fgUid), 0, NULL},
    {TK_CONFIG_STRING, "-maskdata", NULL, NULL,
	NULL, offsetof(BitmapModel, maskDataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-maskfile", NULL, NULL,
	NULL, offsetof(BitmapModel, maskFileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * The following data structure is used to describe the state of parsing a
 * bitmap file or string. It is used for communication between TkGetBitmapData
 * and NextBitmapWord.







|

|

|

|

|

|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

/*
 * Information used for parsing configuration specs:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_UID, "-background", NULL, NULL,
	"", Tk_Offset(BitmapModel, bgUid), 0, NULL},
    {TK_CONFIG_STRING, "-data", NULL, NULL,
	NULL, Tk_Offset(BitmapModel, dataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	NULL, Tk_Offset(BitmapModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_UID, "-foreground", NULL, NULL,
	"#000000", Tk_Offset(BitmapModel, fgUid), 0, NULL},
    {TK_CONFIG_STRING, "-maskdata", NULL, NULL,
	NULL, Tk_Offset(BitmapModel, maskDataString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-maskfile", NULL, NULL,
	NULL, Tk_Offset(BitmapModel, maskFileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * The following data structure is used to describe the state of parsing a
 * bitmap file or string. It is used for communication between TkGetBitmapData
 * and NextBitmapWord.
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
    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,
			    int objc, Tcl_Obj *const objv[], int flags);
static int		NextBitmapWord(ParseInfo *parseInfoPtr);

/*
 *----------------------------------------------------------------------
 *
 * ImgBmapCreate --
 *
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
 */

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. */
    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. */
    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;
}

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
    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) {







<

<
<
<
<
<

|
<


<







234
235
236
237
238
239
240

241





242
243

244
245

246
247
248
249
250
251
252
    int objc,			/* Number of entries in objv. */
    Tcl_Obj *const objv[],	/* Pairs of configuration options for image. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget, such
				 * as TK_CONFIG_ARGV_ONLY. */
{
    BitmapInstance *instancePtr;
    int maskWidth, maskHeight, dummy1, dummy2;







    if (Tk_ConfigureWidget(modelPtr->interp, Tk_MainWindow(modelPtr->interp),
	    configSpecs, objc, (const char **) objv, (char *) modelPtr, flags|TK_CONFIG_OBJS) != 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) {
496
497
498
499
500
501
502
503
504
505

506
507
508
509

510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
	if ((interp != NULL) && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get bitmap data from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    return NULL;
	}
	expandedFileName = Tcl_TranslateFileName(interp, fileName, &buffer);
	if (expandedFileName == NULL) {
	    return NULL;

	}
	pi.chan = Tcl_OpenFileChannel(interp, expandedFileName, "r", 0);
	Tcl_DStringFree(&buffer);
	if (pi.chan == NULL) {

	    if (interp != NULL) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"couldn't read bitmap file \"%s\": %s",
			fileName, Tcl_PosixError(interp)));
	    }
	    return NULL;
	}

	if (Tcl_SetChannelOption(interp, pi.chan, "-translation", "binary")
		!= TCL_OK) {
	    return NULL;
	}
	if (Tcl_SetChannelOption(interp, pi.chan, "-encoding", "binary")
		!= TCL_OK) {
	    return NULL;
	}
    } else {
	pi.chan = NULL;
    }

    /*







|

|
>




>











<
<
<
<







487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513




514
515
516
517
518
519
520
	if ((interp != NULL) && Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get bitmap data from a file in a safe interpreter",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "BITMAP_FILE", NULL);
	    return NULL;
	}
	expandedFileName = Tcl_TranslateFileName(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;
	}

	if (Tcl_SetChannelOption(interp, pi.chan, "-translation", "binary")
		!= TCL_OK) {




	    return NULL;
	}
    } else {
	pi.chan = NULL;
    }

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







|







736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
 *	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");







|



|


|







760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
    switch (index) {
    case 0: /* cget */
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	return Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		(char *)modelPtr, Tcl_GetString(objv[2]), 0);
    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");
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







|



|







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
 * Side effects:
 *	A data structure is set up for the instance (or, an existing instance
 *	is re-used for the new one).
 *
 *----------------------------------------------------------------------
 */

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







|







868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
 *	A portion of the image gets rendered in a pixmap or window.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDisplay(
    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) {







|







929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
 *	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 --







|

















|







991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgBmapDelete(
    void *modelData)	/* Pointer to BitmapModel structure for
				 * image. Must not have any more instances. */
{
    BitmapModel *modelPtr = (BitmapModel *)modelData;

    if (modelPtr->instancePtr != NULL) {
	Tcl_Panic("tried to delete bitmap image when instances still exist");
    }
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->data != NULL) {
	ckfree(modelPtr->data);
    }
    if (modelPtr->maskData != NULL) {
	ckfree(modelPtr->maskData);
    }
    Tk_FreeOptions(configSpecs, (char *)modelPtr, NULL, 0);
    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));







|







1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
 *	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;
    }
}

/*







<

|
<







1064
1065
1066
1067
1068
1069
1070

1071
1072

1073
1074
1075
1076
1077
1078
1079
 */

static int
GetByte(
    Tcl_Channel chan)	/* The channel we read from. */
{
    char buffer;


    if (Tcl_Read(chan, &buffer, 1) != 1) {

	return EOF;
    } else {
	return buffer;
    }
}

/*
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;







|







1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
 *	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;
Changes to generic/tkImgGIF.c.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 * state keeps track of which byte we are about to read, or EOF.
 */

typedef struct mFile {
    unsigned char *data;	/* mmencoded source string */
    int c;			/* bits left over from previous character */
    int state;			/* decoder state (0-4 or GIF_DONE) */
    size_t length;			/* Total amount of bytes in data */
} 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







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
 * state keeps track of which byte we are about to read, or EOF.
 */

typedef struct mFile {
    unsigned char *data;	/* mmencoded source string */
    int c;			/* bits left over from previous character */
    int state;			/* decoder state (0-4 or GIF_DONE) */
    int length;			/* Total amount of bytes in data */
} MFile;

/*
 * Non-ASCII encoding support:
 * Most data in a GIF image is binary and is treated as such. However, a few
 * key bits are stashed in ASCII. If we try to compare those pieces to the
 * char they represent, it will fail on any non-ASCII (eg, EBCDIC) system. To
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
} 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,







|
|







107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
} GIFImageConfig;

/*
 * Type of a function used to do the writing to a file or buffer when
 * serializing in the GIF format.
 */

typedef int (WriteBytesFunc) (void *clientData, const char *bytes,
			    int byteCount);

/*
 * The format record for the GIF file format:
 */

static int		FileMatchGIF(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *format, int *widthPtr, int *heightPtr,
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
			    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 */







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
			    Tcl_Obj *format, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
static int		FileWriteGIF(Tcl_Interp *interp, const char *filename,
			    Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr);
static int		StringWriteGIF(Tcl_Interp *interp, Tcl_Obj *format,
			    Tk_PhotoImageBlock *blockPtr);
static int		CommonWriteGIF(Tcl_Interp *interp, void *clientData,
			    WriteBytesFunc *writeProc, Tcl_Obj *format,
			    Tk_PhotoImageBlock *blockPtr);

Tk_PhotoImageFormat tkImgFmtGIF = {
    "gif",		/* name */
    FileMatchGIF,	/* fileMatchProc */
    StringMatchGIF,	/* stringMatchProc */
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
			    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))







|

|




|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
			    unsigned char cmap[MAXCOLORMAPSIZE][4], int srcX,
			    int srcY, int interlace, int transparent);

/*
 * these are for the BASE64 image reader code only
 */

static int		Fread(GIFImageConfig *gifConfPtr, unsigned char *dst,
			    size_t size, size_t count, Tcl_Channel chan);
static int		Mread(unsigned char *dst, size_t size, size_t count,
			    MFile *handle);
static int		Mgetc(MFile *handle);
static int		char64(int c);
static void		mInit(unsigned char *string, MFile *handle,
			    int length);

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







|







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







|







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, void *handle,
			    WriteBytesFunc *writeProc, ifunptr readValue,
			    GifWriterState *statePtr);
static int		IsNewColor(GifWriterState *statePtr,
			    int red, int green, int blue);
static void		SaveMap(GifWriterState *statePtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		ReadValue(GifWriterState *statePtr);
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
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);
}

/*
 *----------------------------------------------------------------------







|


<
<
<







347
348
349
350
351
352
353
354
355
356



357
358
359
360
361
362
363
FileMatchGIF(
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char *fileName,	/* The name of the image file. */
    Tcl_Obj *format,		/* User-specified format object, or NULL. */
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here if the file is a valid raw GIF file. */
    TCL_UNUSED(Tcl_Interp *))
{
    GIFImageConfig gifConf;




    memset(&gifConf, 0, sizeof(GIFImageConfig));
    return ReadGIFHeader(&gifConf, chan, widthPtr, heightPtr);
}

/*
 *----------------------------------------------------------------------
435
436
437
438
439
440
441
442

443
444
445
446
447
448
449
450
451
452
453
454
455
456
457

458
459
460
461
462
463

464
465
466
467
468
469
470
471







472
473
474
475
476
477
478
479
480

481
482
483
484
485
486
487
		sizeof(char *), "option name", 0, &optionIdx) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i == (argc-1)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no value given for \"%s\" option",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "OPT_VALUE", NULL);

	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[++i], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    /*
     * Read the GIF file header and check for some sanity.
     */

    if (!ReadGIFHeader(gifConfPtr, chan, &fileWidth, &fileHeight)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't read GIF header from file \"%s\"", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "HEADER", NULL);

	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"GIF image file \"%s\" has dimension(s) <= 0", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BOGUS_SIZE", NULL);

	return TCL_ERROR;
    }

    /*
     * Get the general colormap information.
     */

    if (Fread(gifConfPtr, buf, 1, 3, chan) != 3) {







	return TCL_OK;
    }
    bitPixel = 2 << (buf[0] & 0x07);

    if (BitSet(buf[0], LOCALCOLORMAP)) {	/* Global Colormap */
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP", NULL);

	    return TCL_ERROR;
	}
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
    }







|
>














|
>





|
>








>
>
>
>
>
>
>
|







|
>







432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
		sizeof(char *), "option name", 0, &optionIdx) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (i == (argc-1)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "no value given for \"%s\" option",
		    Tcl_GetString(objv[i])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "OPT_VALUE",
		    (char *) NULL);
	    return TCL_ERROR;
	}
	if (Tcl_GetIntFromObj(interp, objv[++i], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    }

    /*
     * Read the GIF file header and check for some sanity.
     */

    if (!ReadGIFHeader(gifConfPtr, chan, &fileWidth, &fileHeight)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't read GIF header from file \"%s\"", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "HEADER",
		(char *) NULL);
	return TCL_ERROR;
    }
    if ((fileWidth <= 0) || (fileHeight <= 0)) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"GIF image file \"%s\" has dimension(s) <= 0", fileName));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BOGUS_SIZE",
		(char *) NULL);
	return TCL_ERROR;
    }

    /*
     * Get the general colormap information.
     */

    if (Fread(gifConfPtr, buf, 1, 3, chan) != 3) {
	/*
	 * Bug [865af0148c]: 3 bytes should be there, but data ended before
	 */
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"GIF file truncated", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "TRUNCATED",
		(char *) NULL);
	return TCL_ERROR;
    }
    bitPixel = 2 << (buf[0] & 0x07);

    if (BitSet(buf[0], LOCALCOLORMAP)) {	/* Global Colormap */
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP",
		    (char *) NULL);
	    return TCL_ERROR;
	}
    }

    if ((srcX + width) > fileWidth) {
	width = fileWidth - srcX;
    }
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
	    /*
	     * Premature end of image.
	     */

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "premature end of image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "PREMATURE_END",
		    NULL);
	    goto error;
	}

	switch (buf[0]) {
	case GIF_TERMINATOR:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "no image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "NO_DATA", NULL);

	    goto error;

	case GIF_EXTENSION:
	    /*
	     * This is a GIF extension.
	     */

	    if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension function code in GIF image",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    if (DoExtension(gifConfPtr, chan, buf[0],
		    gifConfPtr->workingBuffer, &transparent) < 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension in GIF image", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			NULL);
		goto error;
	    }
	    continue;
	case GIF_START:
	    if (Fread(gifConfPtr, buf, 1, 9, chan) != 9) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't read left/top/width/height in GIF image",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "DIMENSIONS",
			NULL);
		goto error;
	    }
	    break;
	default:
	    /*
	     * Not a valid start character; ignore it.
	     */







|







|
>












|







|









|







520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
	    /*
	     * Premature end of image.
	     */

	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "premature end of image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "PREMATURE_END",
		    (char *) NULL);
	    goto error;
	}

	switch (buf[0]) {
	case GIF_TERMINATOR:
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "no image data for this index", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "NO_DATA",
		    (char *) NULL);
	    goto error;

	case GIF_EXTENSION:
	    /*
	     * This is a GIF extension.
	     */

	    if (Fread(gifConfPtr, buf, 1, 1, chan) != 1) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension function code in GIF image",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			(char *) NULL);
		goto error;
	    }
	    if (DoExtension(gifConfPtr, chan, buf[0],
		    gifConfPtr->workingBuffer, &transparent) < 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"error reading extension in GIF image", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "BAD_EXT",
			(char *) NULL);
		goto error;
	    }
	    continue;
	case GIF_START:
	    if (Fread(gifConfPtr, buf, 1, 9, chan) != 9) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"couldn't read left/top/width/height in GIF image",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "DIMENSIONS",
			(char *) NULL);
		goto error;
	    }
	    break;
	default:
	    /*
	     * Not a valid start character; ignore it.
	     */
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
	     */

	    if (BitSet(buf[8], LOCALCOLORMAP)) {
		if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "error reading color map", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF",
			    "COLOR_MAP", NULL);
		    goto error;
		}
	    }

	    /*
	     * If we've not yet allocated a trash buffer, do so now.
	     */







|







591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
	     */

	    if (BitSet(buf[8], LOCALCOLORMAP)) {
		if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "error reading color map", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF",
			    "COLOR_MAP", (char *) NULL);
		    goto error;
		}
	    }

	    /*
	     * If we've not yet allocated a trash buffer, do so now.
	     */
623
624
625
626
627
628
629







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644

645
646
647
648
649
650
651
	     * 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
     * in this frame, together with the size of this frame.







>
>
>
>
>
>
>














|
>







632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
	     * common case.
	     */

	    if (ReadImage(gifConfPtr, interp, trashBuffer, chan, imageWidth,
		    imageHeight, colorMap, 0, 0, 0, -1) != TCL_OK) {
		goto error;
	    }

	    /*
	     * This extension starts a new scope, so Graphic control Extension
	     * data should be cleared
	     */
	    transparent = -1;

	    continue;
	}
	break;
    }

    /*
     * Found the frame we want to read. Next, check for a local color map for
     * this frame.
     */

    if (BitSet(buf[8], LOCALCOLORMAP)) {
	if (!ReadColorMap(gifConfPtr, chan, bitPixel, colorMap)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "error reading color map", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLOR_MAP",
		    (char *) NULL);
	    goto error;
	}
    }

    /*
     * Extract the location within the overall visible image to put the data
     * in this frame, together with the size of this frame.
669
670
671
672
673
674
675

676
677
678
679
680
681
682
	srcY = 0;
    }
    if (height > imageHeight) {
	height = imageHeight;
    }

    if ((width > 0) && (height > 0)) {

	Tk_PhotoImageBlock block;

	/*
	 * Read the data and put it into the photo buffer for display by the
	 * general image machinery.
	 */








>







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
	srcY = 0;
    }
    if (height > imageHeight) {
	height = imageHeight;
    }

    if ((width > 0) && (height > 0)) {
	unsigned char* pixelPtr;
	Tk_PhotoImageBlock block;

	/*
	 * Read the data and put it into the photo buffer for display by the
	 * general image machinery.
	 */

691
692
693
694
695
696
697
698
699
700
701
702

703
704
705
706
707
708

709
710
711
712
713
714
715
716
717
718
719
720
721
	    goto error;
	}
	block.pitch = block.pixelSize * imageWidth;
	if (imageHeight > (int)(UINT_MAX/block.pitch)) {
	    goto error;
	}
	nBytes = block.pitch * imageHeight;
	block.pixelPtr = (unsigned char *)ckalloc(nBytes);
	if (block.pixelPtr) {
	    memset(block.pixelPtr, 0, nBytes);
	}


	if (ReadImage(gifConfPtr, interp, block.pixelPtr, chan, imageWidth,
		imageHeight, colorMap, srcX, srcY, BitSet(buf[8], INTERLACE),
		transparent) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    goto error;
	}

	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(block.pixelPtr);
	    goto error;
	}
	ckfree(block.pixelPtr);
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */








|
|
|


>



|


>


|


|







709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
	    goto error;
	}
	block.pitch = block.pixelSize * imageWidth;
	if (imageHeight > (int)(UINT_MAX/block.pitch)) {
	    goto error;
	}
	nBytes = block.pitch * imageHeight;
	pixelPtr = (unsigned char*)ckalloc(nBytes);
	if (pixelPtr) {
	    memset(pixelPtr, 0, nBytes);
	}

	block.pixelPtr = pixelPtr;
	if (ReadImage(gifConfPtr, interp, block.pixelPtr, chan, imageWidth,
		imageHeight, colorMap, srcX, srcY, BitSet(buf[8], INTERLACE),
		transparent) != TCL_OK) {
	    ckfree(pixelPtr);
	    goto error;
	}
	block.pixelPtr += srcX * block.pixelSize + srcY * block.pitch;
	if (Tk_PhotoPutBlock(interp, imageHandle, &block, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	    ckfree(pixelPtr);
	    goto error;
	}
	ckfree(pixelPtr);
    }

    /*
     * We've successfully read the GIF frame (or there was nothing to read,
     * which suits as well). We're done.
     */

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775

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;







|


|

<
<

|







773
774
775
776
777
778
779
780
781
782
783
784


785
786
787
788
789
790
791
792
793

static int
StringMatchGIF(
    Tcl_Obj *dataObj,		/* the object containing the image data */
    Tcl_Obj *format,		/* the image format object, or NULL */
    int *widthPtr,		/* where to put the string width */
    int *heightPtr,		/* where to put the string height */
    Tcl_Interp *interp)		/* not used */
{
    unsigned char *data, header[10];
    int got, length;
    MFile handle;



    data = Tcl_GetByteArrayFromObj(dataObj, &length);

    /*
     * Header is a minimum of 10 bytes.
     */

    if (length < 10) {
	return 0;
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
    Tcl_Obj *format,		/* format object, or NULL */
    Tk_PhotoHandle imageHandle,	/* the image to write this data into */
    int destX, int destY,	/* The rectangular region of the */
    int width, int height,	/* image to copy */
    int srcX, int srcY)
{
    MFile handle, *hdlPtr = &handle;
    TkSizeT length;
    const char *xferFormat;
    unsigned char *data = TkGetByteArrayFromObj(dataObj, &length);

    mInit(data, hdlPtr, length);

    /*
     * Check whether the data is Base64 encoded by doing a character-by-
     * charcter comparison with the binary-format headers; BASE64-encoded
     * never matches (matching the other way is harder because of potential







|

|







845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
    Tcl_Obj *format,		/* format object, or NULL */
    Tk_PhotoHandle imageHandle,	/* the image to write this data into */
    int destX, int destY,	/* The rectangular region of the */
    int width, int height,	/* image to copy */
    int srcX, int srcY)
{
    MFile handle, *hdlPtr = &handle;
    int length;
    const char *xferFormat;
    unsigned char *data = Tcl_GetByteArrayFromObj(dataObj, &length);

    mInit(data, hdlPtr, length);

    /*
     * Check whether the data is Base64 encoded by doing a character-by-
     * charcter comparison with the binary-format headers; BASE64-encoded
     * never matches (matching the other way is harder because of potential
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
    int number,
    unsigned char buffer[MAXCOLORMAPSIZE][4])
{
    int i;
    unsigned char rgb[3];

    for (i = 0; i < number; ++i) {
	if (((size_t)Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) + 1) < 2) {
	    return 0;
	}

	if (buffer) {
	    buffer[i][CM_RED] = rgb[0];
	    buffer[i][CM_GREEN] = rgb[1];
	    buffer[i][CM_BLUE] = rgb[2];







|







936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
    int number,
    unsigned char buffer[MAXCOLORMAPSIZE][4])
{
    int i;
    unsigned char rgb[3];

    for (i = 0; i < number; ++i) {
	if (Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) <= 0) {
	    return 0;
	}

	if (buffer) {
	    buffer[i][CM_RED] = rgb[0];
	    buffer[i][CM_GREEN] = rgb[1];
	    buffer[i][CM_BLUE] = rgb[2];
944
945
946
947
948
949
950





951
952
953
954
955
956
957
    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 {







>
>
>
>
>







962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
    unsigned char *buf,
    int *transparent)
{
    int count;

    switch (label) {
    case 0x01:			/* Plain Text Extension */
	/*
	 * This extension starts a new scope, so Graphic control Extension
	 * data should be cleared
	 */
	*transparent = -1;
	break;

    case 0xff:			/* Application Extension */
	break;

    case 0xfe:			/* Comment Extension */
	do {
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
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;
}

/*







|



|







1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
GetDataBlock(
    GIFImageConfig *gifConfPtr,
    Tcl_Channel chan,
    unsigned char *buf)
{
    unsigned char count;

    if (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
1074
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;
	cmap[transparent][CM_BLUE] = 0;







|
>














<
<





|







|
>







1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075


1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
ReadImage(
    GIFImageConfig *gifConfPtr,
    Tcl_Interp *interp,
    unsigned char *imagePtr,
    Tcl_Channel chan,
    int len, int rows,
    unsigned char cmap[MAXCOLORMAPSIZE][4],
    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", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "MALFORMED",
		(char *) NULL);
	return TCL_ERROR;
    }

    if (transparent != -1) {
	cmap[transparent][CM_RED] = 0;
	cmap[transparent][CM_GREEN] = 0;
	cmap[transparent][CM_BLUE] = 0;
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
		     */

		    *top++ = append[code];
		    code = prefix[code];
		}
		firstCode = append[code];

	        /*
	         * Push the head of the code onto the stack.
	         */

	        *top++ = firstCode;

                if (maxCode < (1 << MAX_LWZ_BITS)) {
		    /*
		     * If there's still room in our codes table, add a new entry.
		     * Otherwise don't, and keep using the current table.
                     * See DEFERRED CLEAR CODE IN LZW COMPRESSION in the GIF89a
                     * specification.
		     */

		    prefix[maxCode] = oldCode;
		    append[maxCode] = firstCode;
		    maxCode++;
                }

		/*
		 * maxCode tells us the maximum code value we can accept. If
		 * we see that we need more bits to represent it than we are
		 * requesting from the unpacker, we need to increase the
		 * number we ask for.
		 */







|
|
|

|

|



|
|





|







1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
		     */

		    *top++ = append[code];
		    code = prefix[code];
		}
		firstCode = append[code];

		/*
		 * Push the head of the code onto the stack.
		 */

		*top++ = firstCode;

		if (maxCode < (1 << MAX_LWZ_BITS)) {
		    /*
		     * If there's still room in our codes table, add a new entry.
		     * Otherwise don't, and keep using the current table.
		     * See DEFERRED CLEAR CODE IN LZW COMPRESSION in the GIF89a
		     * specification.
		     */

		    prefix[maxCode] = oldCode;
		    append[maxCode] = firstCode;
		    maxCode++;
		}

		/*
		 * maxCode tells us the maximum code value we can accept. If
		 * we see that we need more bits to represent it than we are
		 * requesting from the unpacker, we need to increase the
		 * number we ask for.
		 */
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
 *----------------------------------------------------------------------
 */

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







|







1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
 *----------------------------------------------------------------------
 */

static void
mInit(
    unsigned char *string,	/* string containing initial mmencoded data */
    MFile *handle,		/* mmdecode "file" handle */
    int length)			/* Number of bytes in string */
{
    handle->data = string;
    handle->state = 0;
    handle->c = 0;
    handle->length = length;
}

1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
 *
 * Side effects:
 *	The base64 handle will change state.
 *
 *----------------------------------------------------------------------
 */

static size_t
Mread(
    unsigned char *dst,		/* where to put the result */
    size_t chunkSize,		/* size of each transfer */
    size_t numChunks,		/* number of chunks */
    MFile *handle)		/* mmdecode "file" handle */
{
    int c;
    size_t i, count = chunkSize * numChunks;

    for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
	*dst++ = c;
    }
    return i;
}








|






|
|







1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
 *
 * Side effects:
 *	The base64 handle will change state.
 *
 *----------------------------------------------------------------------
 */

static int
Mread(
    unsigned char *dst,		/* where to put the result */
    size_t chunkSize,		/* size of each transfer */
    size_t numChunks,		/* number of chunks */
    MFile *handle)		/* mmdecode "file" handle */
{
    int i, c;
    int count = chunkSize * numChunks;

    for (i=0; i<count && (c=Mgetc(handle)) != GIF_DONE; i++) {
	*dst++ = c;
    }
    return i;
}

1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
 *	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;
    }








|













|
|







1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
 *	a base64 encoded string.
 *
 * Results: - same as POSIX fread() or Tcl Tcl_Read()
 *
 *----------------------------------------------------------------------
 */

static int
Fread(
    GIFImageConfig *gifConfPtr,
    unsigned char *dst,		/* where to put the result */
    size_t hunk, size_t count,	/* how many */
    Tcl_Channel chan)
{
    if (gifConfPtr->fromData == INLINE_DATA_BASE64) {
	return Mread(dst, hunk, count, (MFile *) chan);
    }

    if (gifConfPtr->fromData == INLINE_DATA_BINARY) {
	MFile *handle = (MFile *) chan;

	if ((handle->length <= 0) || ((size_t)handle->length < hunk * count)) {
	    return -1;
	}
	memcpy(dst, handle->data, hunk * count);
	handle->data += hunk * count;
	handle->length -= hunk * count;
	return hunk * count;
    }

1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
    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) {







|
|







1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
    Tcl_Channel chan = NULL;
    int result;

    chan = Tcl_OpenFileChannel(interp, (char *) filename, "w", 0644);
    if (!chan) {
	return TCL_ERROR;
    }
    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    result = CommonWriteGIF(interp, chan, WriteToChannel, format, blockPtr);

    if (Tcl_Close(interp, chan) == TCL_ERROR) {
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
    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;







|

|

|






|

|

|













|









<







1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744

1745
1746
1747
1748
1749
1750
1751
    if (result == TCL_OK) {
	Tcl_SetObjResult(interp, objPtr);
    }
    Tcl_DecrRefCount(objPtr);
    return result;
}

static int
WriteToChannel(
    void *clientData,
    const char *bytes,
    int byteCount)
{
    Tcl_Channel handle = (Tcl_Channel)clientData;

    return Tcl_Write(handle, bytes, byteCount);
}

static int
WriteToByteArray(
    void *clientData,
    const char *bytes,
    int byteCount)
{
    Tcl_Obj *objPtr = (Tcl_Obj *)clientData;
    Tcl_Obj *tmpObj = Tcl_NewByteArrayObj((unsigned char *) bytes, byteCount);

    Tcl_IncrRefCount(tmpObj);
    Tcl_AppendObjToObj(objPtr, tmpObj);
    Tcl_DecrRefCount(tmpObj);
    return byteCount;
}

static int
CommonWriteGIF(
    Tcl_Interp *interp,
    void *handle,
    WriteBytesFunc *writeProc,
    Tcl_Obj *format,
    Tk_PhotoImageBlock *blockPtr)
{
    GifWriterState state;
    int resolution;
    long width, height, x;
    unsigned char c;
    unsigned int top, left;


    top = 0;
    left = 0;

    memset(&state, 0, sizeof(state));

    state.pixelSize = blockPtr->pixelSize;
1750
1751
1752
1753
1754
1755
1756
1757

1758
1759
1760
1761
1762
1763
1764
    width = blockPtr->width;
    height = blockPtr->height;
    state.pixelOffset = blockPtr->pixelPtr + blockPtr->offset[0];
    state.pixelPitch = blockPtr->pitch;
    SaveMap(&state, blockPtr);
    if (state.num >= MAXCOLORMAPSIZE) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("too many colors", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLORFUL", NULL);

	return TCL_ERROR;
    }
    if (state.num<2) {
	state.num = 2;
    }
    c = LSB(width);
    writeProc(handle, (char *) &c, 1);







|
>







1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
    width = blockPtr->width;
    height = blockPtr->height;
    state.pixelOffset = blockPtr->pixelPtr + blockPtr->offset[0];
    state.pixelPitch = blockPtr->pitch;
    SaveMap(&state, blockPtr);
    if (state.num >= MAXCOLORMAPSIZE) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("too many colors", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "GIF", "COLORFUL",
		(char *) NULL);
	return TCL_ERROR;
    }
    if (state.num<2) {
	state.num = 2;
    }
    c = LSB(width);
    writeProc(handle, (char *) &c, 1);
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
 *              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;







|







1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
 *              James A. Woods          (decvax!ihnp4!ames!jaw)
 *              Joe Orost               (decvax!vax135!petsd!joe)
 */

static void
Compress(
    int initialBits,
    void *handle,
    WriteBytesFunc *writeProc,
    ifunptr readValue,
    GifWriterState *statePtr)
{
    long fcode, ent, disp, hSize, i = 0;
    int c, hshift;
    GIFState_t state;
Deleted generic/tkImgListFormat.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
/*
 * tkImgListFormat.c --
 *
 *      Implements the default image data format. I.e. the format used for
 *      [imageName data] and [imageName put] if no other format is specified.
 *
 *      The default format consits of a list of scan lines (rows) with each
 *      list element being itself a list of pixels (or columns). For details,
 *      see the manpage photo.n
 *
 *      This image format cannot read/write files, it is meant for string
 *      data only.
 *
 *
 * Copyright (c) 1994 The Australian National University.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 2002-2003 Donal K. Fellows
 * Copyright (c) 2003 ActiveState Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Authors:
 *      Paul Mackerras (paulus@cs.anu.edu.au),
 *              Department of Computer Science,
 *              Australian National University.
 *
 *      Simon Bachmann (simonbachmann@bluewin.ch)
 */


#include "tkImgPhoto.h"

/*
 * Message to generate when an attempt to allocate memory for an image fails.
 */

#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
        "not enough free memory for image buffer"


/*
 * Color name length limit: do not attempt to parse as color strings that are
 * longer than this limit
 */

#define TK_PHOTO_MAX_COLOR_CHARS 99

/*
 * Symbols for the different formats of a color string.
 */

enum ColorFormatType {
    COLORFORMAT_TKCOLOR,
    COLORFORMAT_EMPTYSTRING,
    COLORFORMAT_LIST,
    COLORFORMAT_RGB1,
    COLORFORMAT_RGB2,
    COLORFORMAT_RGBA1,
    COLORFORMAT_RGBA2
};

/*
 * Names for the color format types above.
 * Order must match the one in enum ColorFormatType
 */

static const char *const colorFormatNames[] = {
    "tkcolor",
    "emptystring",
    "list",
    "rgb-short",
    "rgb",
    "rgba-short",
    "rgba",
    NULL
};

/*
 * The following data structure is used to return information from
 * ParseFormatOptions:
 */

struct FormatOptions {
    int options;         /* Individual bits indicate which options were
                          * specified - see below. */
    Tcl_Obj *formatName; /* Name specified without an option. */
    enum ColorFormatType colorFormat;
                         /* The color format type given with the
                          * -colorformat option */
};

/*
 * Bit definitions for use with ParseFormatOptions: each bit is set in the
 * allowedOptions parameter on a call to ParseFormatOptions if that option
 * is allowed for the current photo image subcommand. On return, the bit is
 * set in the options field of the FormatOptions structure if that option
 * was specified.
 *
 * OPT_COLORFORMAT:         Set if -alpha option allowed/specified.
 */

#define OPT_COLORFORMAT     1

/*
 * List of format option names. The order here must match the order of
 * declarations of the FMT_OPT_* constants above.
 */

static const char *const formatOptionNames[] = {
    "-colorformat",
    NULL
};

/*
 * Forward declarations
 */

static int      ParseFormatOptions(Tcl_Interp *interp, int allowedOptions,
                    int objc, Tcl_Obj *const objv[], int *indexPtr,
                    struct FormatOptions *optPtr);
static Tcl_Obj  *GetBadOptMsg(const char *badValue, int allowedOpts);
static int      StringMatchDef(Tcl_Obj *data, Tcl_Obj *formatString,
                    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int      StringReadDef(Tcl_Interp *interp, Tcl_Obj *data,
                    Tcl_Obj *formatString, Tk_PhotoHandle imageHandle,
                    int destX, int destY, int width, int height,
                    int srcX, int srcY);
static int      StringWriteDef(Tcl_Interp *interp,
                    Tcl_Obj *formatString,
                    Tk_PhotoImageBlock *blockPtr);
static int      ParseColor(Tcl_Interp *interp, Tcl_Obj *specObj,
                    Display *display, Colormap colormap, unsigned char *redPtr,
                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsList(Tcl_Interp *interp, const char *colorString,
                    int colorStrLen, unsigned char *redPtr,
                    unsigned char *greenPtr, unsigned char *bluePtr,
                    unsigned char *alphaPtr);
static int      ParseColorAsHex(Tcl_Interp *interp, const char *colorString,
                    int colorStrLen, Display *display, Colormap colormap,
                    unsigned char *redPtr, unsigned char *greenPtr,
                    unsigned char *bluePtr, unsigned char *alphaPtr);
static int      ParseColorAsStandard(Tcl_Interp *interp,
                    const char *colorString, int colorStrLen,
                    Display *display, Colormap colormap,
                    unsigned char *redPtr, unsigned char *greenPtr,
                    unsigned char *bluePtr, unsigned char *alphaPtr);

/*
 * The format record for the default image handler
 */

Tk_PhotoImageFormat tkImgFmtDefault = {
    "default",      /* name */
    NULL,           /* fileMatchProc: format doesn't support file ops */
    StringMatchDef, /* stringMatchProc */
    NULL,           /* fileReadProc: format doesn't support file read */
    StringReadDef,  /* stringReadProc */
    NULL,           /* fileWriteProc: format doesn't support file write */
    StringWriteDef, /* stringWriteProc */
    NULL            /* nextPtr */
};

/*
 *----------------------------------------------------------------------
 *
 * ParseFormatOptions --
 *
 *      Parse the options passed to the image format handler.
 *
 * Results:
 *      On success, the structure pointed to by optPtr is filled with the
 *      values passed or with the defaults and TCL_OK returned.
 *      If an error occurs, leaves an error message in interp and returns
 *      TCL_ERROR.
 *
 * Side effects:
 *      The value in *indexPtr is updated to the index of the fist
 *      element in argv[] that does not look like an option/value, or to
 *      argc if parsing reached the end of argv[].
 *
 *----------------------------------------------------------------------
 */
static int
ParseFormatOptions(
    Tcl_Interp *interp,               /* For error messages */
    int allowedOptions,               /* Bitfield specifying which options are
                                       * to be considered allowed */
    int objc,                         /* Number of elements in argv[] */
    Tcl_Obj *const objv[],            /* The arguments to parse */
    int *indexPtr,                    /* Index giving the first element to
                                       * parse. The value is updated to the
                                       * index where parsing ended */
    struct FormatOptions *optPtr)     /* Parsed option values are written to
                                       * this struct */

{
    int index, optIndex, first;
    enum ColorFormatType typeIndex;
    const char *option;

    first = 1;

    /*
     * Fill in default values
     */
    optPtr->options = 0;
    optPtr->formatName = NULL;
    optPtr->colorFormat = COLORFORMAT_RGB2;
    for (index = *indexPtr; index < objc; *indexPtr = ++index) {
        int optionExists;

        /*
         * The first value can be the format handler's name. It goes to
         * optPtr->name.
         */
        option = Tcl_GetString(objv[index]);
        if (option[0] != '-') {
            if (first) {
                optPtr->formatName = objv[index];
                first = 0;
                continue;
            } else {
                break;
            }
        }
        first = 0;

        /*
         * Check if option is known and allowed
         */

        optionExists = 1;
        if (Tcl_GetIndexFromObj(NULL, objv[index], formatOptionNames,
                "format option", 0, &optIndex) != TCL_OK) {
            optionExists = 0;
        }
        if (!optionExists || !((1 << optIndex) & allowedOptions)) {
            Tcl_SetObjResult(interp, GetBadOptMsg(Tcl_GetString(objv[index]),
                    allowedOptions));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
            return TCL_ERROR;
        }

        /*
         * Option-specific checks
         */

        switch (1 << optIndex) {
        case OPT_COLORFORMAT:
            *indexPtr = ++index;
            if (index >= objc) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("the \"%s\" option "
                        "requires a value", Tcl_GetString(objv[index - 1])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "MISSING_VALUE", NULL);
                return TCL_ERROR;
            }
            if (Tcl_GetIndexFromObj(NULL, objv[index], colorFormatNames, "",
                    TCL_EXACT, (int *)&typeIndex) != TCL_OK
                    || (typeIndex != COLORFORMAT_LIST
                    && typeIndex != COLORFORMAT_RGB2
                    && typeIndex != COLORFORMAT_RGBA2) ) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad color format "
                        "\"%s\": must be rgb, rgba, or list",
                        Tcl_GetString(objv[index])));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "BAD_COLOR_FORMAT", NULL);
                return TCL_ERROR;
            }
            optPtr->colorFormat = typeIndex;
            break;
        default:
            Tcl_Panic("ParseFormatOptions: unexpected switch fallthrough");
        }

        /*
         * Add option to bitfield in optPtr
         */
        optPtr->options |= (1 << optIndex);
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 *  GetBadOptMsg --
 *
 *      Build a Tcl_Obj containing an error message in the form "bad option
 *      "xx": must be y, or z", based on the bits set in allowedOpts.
 *
 * Results:
 *      A Tcl Object containig the error message.
 *
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
static Tcl_Obj *
GetBadOptMsg(
    const char *badValue,   /* the erroneous option */
    int allowedOpts)        /* bitfield specifying the allowed options */
{
    int i, bit;
    Tcl_Obj *resObj = Tcl_ObjPrintf("bad format option \"%s\": ", badValue);

    if (allowedOpts == 0) {
        Tcl_AppendToObj(resObj, "no options allowed", -1);
    } else {
        Tcl_AppendToObj(resObj, "must be ", -1);
        bit = 1;
        for (i = 0; formatOptionNames[i] != NULL; i++) {
            if (allowedOpts & bit) {
                if (allowedOpts & (bit -1)) {
                    /*
                     * not the first option
                     */
                    if (allowedOpts & ~((bit << 1) - 1)) {
                        /*
                         * not the last option
                         */
                        Tcl_AppendToObj(resObj, ", ", -1);
                    } else {
                        Tcl_AppendToObj(resObj, ", or ", -1);
                    }
                }
                Tcl_AppendToObj(resObj, formatOptionNames[i], -1);
            }
            bit <<=1;
        }
    }
    return resObj;
}

/*
 *----------------------------------------------------------------------
 *
 * StringMatchDef --
 *
 *      Default string match function. Test if image data in string form
 *      appears to be in the default list-of-list-of-pixel-data format
 *      accepted by the "<img> put" command.
 *
 * Results:
 *      If thte data is in the default format, writes the size of the image
 *      to widthPtr and heightPtr and returns 1. Otherwise, leaves an error
 *      message in interp (if not NULL) and returns 0.
 *      Note that this function does not parse all data points. A return
 *      value of 1 does not guarantee that the data can be read without
 *      errors.
 *
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
static int
StringMatchDef(
    Tcl_Obj *data,          /* The data to check */
    Tcl_Obj *formatString,  /* Value of the -format option, not used here */
    int *widthPtr,          /* Width of image is written to this location */
    int *heightPtr,         /* Height of image is written to this location */
    Tcl_Interp *interp)     /* Error messages are left in this interpreter */
{
    int y, rowCount, colCount, curColCount;
    unsigned char dummy;
    Tcl_Obj **rowListPtr, *pixelData;
    (void)formatString;

    /*
     * See if data can be parsed as a list, if every element is itself a valid
     * list and all sublists have the same length.
     */

    if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)
            != TCL_OK) {
        return 0;
    }
    if (rowCount == 0) {
        /*
         * empty list is valid data
         */

        *widthPtr = 0;
        *heightPtr = 0;
        return 1;
    }
    colCount = -1;
    for (y = 0; y < rowCount; y++) {
        if (Tcl_ListObjLength(interp, rowListPtr[y], &curColCount) != TCL_OK) {
            return 0;
        }
        if (colCount < 0) {
            colCount = curColCount;
        } else if (curColCount != colCount) {
            if (interp != NULL) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid row # %d: "
                        "all rows must have the same number of elements", y));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "INVALID_DATA", NULL);
            }
            return 0;
        }
    }

    /*
     * Data in base64 encoding (or even binary data), might actually pass
     * these tests. To avoid parsing it as list of lists format, check one
     * pixel for validity.
     */
    if (Tcl_ListObjIndex(interp, rowListPtr[0], 0, &pixelData) != TCL_OK) {
        return 0;
    }
    if (Tcl_GetCharLength(pixelData) > TK_PHOTO_MAX_COLOR_CHARS) {
        return 0;
    }
    if (ParseColor(interp, pixelData, Tk_Display(Tk_MainWindow(interp)),
            Tk_Colormap(Tk_MainWindow(interp)), &dummy, &dummy, &dummy, &dummy)
            != TCL_OK) {
        return 0;
    }

    /*
     * Looks like we have valid data for this format.
     * We do not check any pixel values - that's the job of ImgStringRead()
     */

    *widthPtr = colCount;
    *heightPtr = rowCount;

    return 1;

}

/*
 *----------------------------------------------------------------------
 *
 * StringReadDef --
 *
 *      String read function for default format. (see manpage for details on
 *      the format).
 *
 * Results:
 *      A standard Tcl result.
 *
 * Side effects:
 *      If the data has valid format, write it to the image identified by
 *      imageHandle.
 *      If the image data cannot be parsed, an error message is left in
 *      interp.
 *
 *----------------------------------------------------------------------
*/

static int
StringReadDef(
    Tcl_Interp *interp,         /* leave error messages here */
    Tcl_Obj *data,              /* the data to parse */
    Tcl_Obj *formatString,      /* value of the -format option */
    Tk_PhotoHandle imageHandle, /* write data to this image */
    int destX, int destY,       /* start writing data at this point
                                 * in destination image*/
    int width, int height,      /* dimensions of area to write to */
    int srcX, int srcY)         /* start reading source data at these
                                 * coordinates */
{
    Tcl_Obj **rowListPtr, **colListPtr;
    Tcl_Obj **objv;
    int objc;
    unsigned char *curPixelPtr;
    int x, y, rowCount, colCount, curColCount;
    Tk_PhotoImageBlock srcBlock;
    Display *display;
    Colormap colormap;
    struct FormatOptions opts;
    int optIndex;

    /*
     * Parse format suboptions
     * We don't use any format suboptions, but we still need to provide useful
     * error messages if suboptions were specified.
     */

    memset(&opts, 0, sizeof(opts));
    if (formatString != NULL) {
        if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
                != TCL_OK) {
            return TCL_ERROR;
        }
        optIndex = 0;
        if (ParseFormatOptions(interp, 0, objc, objv, &optIndex, &opts)
                != TCL_OK) {
            return TCL_ERROR;
        }
        if (optIndex < objc) {
            Tcl_SetObjResult(interp,
                    GetBadOptMsg(Tcl_GetString(objv[optIndex]), 0));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
            return TCL_ERROR;
        }
    }

    /*
     * Check input data
     */

    if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr)
            != TCL_OK ) {
        return TCL_ERROR;
    }
    if ( rowCount > 0 && Tcl_ListObjLength(interp, rowListPtr[0], &colCount)
            != TCL_OK) {
        return TCL_ERROR;
    }
    if (width <= 0 || height <= 0 || rowCount == 0 || colCount == 0) {
        /*
         * No changes with zero sized input or zero sized output region
         */

        return TCL_OK;
    }
    if (srcX < 0 || srcY < 0 || srcX >= rowCount || srcY >= colCount) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf("source coordinates out of range"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", NULL);
        return TCL_ERROR;
    }

    /*
     * Memory allocation overflow protection.
     * May not be able to trigger/ demo / test this.
     */

    if (colCount > (int)(UINT_MAX / 4 / rowCount)) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                        "photo image dimensions exceed Tcl memory limits"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                "OVERFLOW", NULL);
        return TCL_OK;
    }

    /*
     * Read data and put it to imageHandle
     */

    srcBlock.width = colCount - srcX;
    srcBlock.height = rowCount - srcY;
    srcBlock.pixelSize = 4;
    srcBlock.pitch = srcBlock.width * 4;
    srcBlock.offset[0] = 0;
    srcBlock.offset[1] = 1;
    srcBlock.offset[2] = 2;
    srcBlock.offset[3] = 3;
    srcBlock.pixelPtr = (unsigned char *)attemptckalloc(srcBlock.pitch * srcBlock.height);
    if (srcBlock.pixelPtr == NULL) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf(TK_PHOTO_ALLOC_FAILURE_MESSAGE));
        Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
        return TCL_ERROR;
    }
    curPixelPtr = srcBlock.pixelPtr;
    display = Tk_Display(Tk_MainWindow(interp));
    colormap = Tk_Colormap(Tk_MainWindow(interp));
    for (y = srcY; y < rowCount; y++) {
        /*
         * We don't test the length of row, as that's been done in
         * ImgStringMatch()
         */

        if (Tcl_ListObjGetElements(interp, rowListPtr[y], &curColCount,
                &colListPtr) != TCL_OK) {
            goto errorExit;
        }
        for (x = srcX; x < colCount; x++) {
            if (ParseColor(interp, colListPtr[x], display, colormap,
                    curPixelPtr, curPixelPtr + 1, curPixelPtr + 2,
                    curPixelPtr + 3) != TCL_OK) {
                goto errorExit;
            }
            curPixelPtr += 4;
        }
    }

    /*
     * Write image data to destHandle
     */
    if (Tk_PhotoPutBlock(interp, imageHandle, &srcBlock, destX, destY,
            width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
        goto errorExit;
    }

    ckfree(srcBlock.pixelPtr);

    return TCL_OK;

  errorExit:
    ckfree(srcBlock.pixelPtr);

    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * StringWriteDef --
 *
 *      String write function for default image data format. See the user
 *      documentation for details.
 *
 * Results:
 *      The converted data is set as the result of interp. Returns a standard
 *      Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */

static int
StringWriteDef(
    Tcl_Interp *interp,                 /* For the result and errors */
    Tcl_Obj *formatString,              /* The value of the -format option */
    Tk_PhotoImageBlock *blockPtr)       /* The image data to convert */
{
    int greenOffset, blueOffset, alphaOffset, hasAlpha;
    Tcl_Obj *result, **objv = NULL;
    int objc, allowedOpts, optIndex;
    struct FormatOptions opts;

    /*
     * Parse format suboptions
     */
    if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv)
            != TCL_OK) {
        return TCL_ERROR;
    }
    allowedOpts = OPT_COLORFORMAT;
    optIndex = 0;
    if (ParseFormatOptions(interp, allowedOpts, objc, objv, &optIndex, &opts)
            != TCL_OK) {
        return TCL_ERROR;
    }
    if (optIndex < objc) {
        Tcl_SetObjResult(interp,
                GetBadOptMsg(Tcl_GetString(objv[optIndex]), allowedOpts));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL);
        return TCL_ERROR;
    }

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    /*
     * A negative alpha offset signals that the image is fully opaque.
     * That's not really documented anywhere, but it's the way it is!
     */

    if (blockPtr->offset[3] < 0) {
        hasAlpha = 0;
        alphaOffset = 0;
    } else {
        hasAlpha = 1;
        alphaOffset = blockPtr->offset[3] - blockPtr->offset[0];
    }

    if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
        int row, col;
        Tcl_DString data, line;
        char colorBuf[11];
        unsigned char *pixelPtr;
        unsigned char alphaVal = 255;

        Tcl_DStringInit(&data);
        for (row=0; row<blockPtr->height; row++) {
            pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0]
                    + row * blockPtr->pitch;
            Tcl_DStringInit(&line);
            for (col=0; col<blockPtr->width; col++) {
                if (hasAlpha) {
                    alphaVal = pixelPtr[alphaOffset];
                }

                /*
                 * We don't build lines as a list for #RGBA and #RGB. Since
                 * these color formats look like comments, the first element
                 * of the list would get quoted with an additional {} .
                 * While this is not a problem if the data is used as
                 * a list, it would cause problems if someone decides to parse
                 * it as a string (and it looks kinda strange)
                 */

                switch (opts.colorFormat) {
                case COLORFORMAT_RGB2:
                    sprintf(colorBuf, "#%02x%02x%02x ",  pixelPtr[0],
                            pixelPtr[greenOffset], pixelPtr[blueOffset]);
                    Tcl_DStringAppend(&line, colorBuf, -1);
                    break;
                case COLORFORMAT_RGBA2:
                    sprintf(colorBuf, "#%02x%02x%02x%02x ",
                            pixelPtr[0], pixelPtr[greenOffset],
                            pixelPtr[blueOffset], alphaVal);
                    Tcl_DStringAppend(&line, colorBuf, -1);
                    break;
                case COLORFORMAT_LIST:
                    Tcl_DStringStartSublist(&line);
                    sprintf(colorBuf, "%d", pixelPtr[0]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", pixelPtr[greenOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", pixelPtr[blueOffset]);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    sprintf(colorBuf, "%d", alphaVal);
                    Tcl_DStringAppendElement(&line, colorBuf);
                    Tcl_DStringEndSublist(&line);
                    break;
                default:
                    Tcl_Panic("unexpected switch fallthrough");
                }
                pixelPtr += blockPtr->pixelSize;
            }
            if (opts.colorFormat != COLORFORMAT_LIST) {
                /*
                 * For the #XXX formats, we need to remove the last
                 * whitespace.
                 */

                *(Tcl_DStringValue(&line) + Tcl_DStringLength(&line) - 1)
                        = '\0';
            }
            Tcl_DStringAppendElement(&data, Tcl_DStringValue(&line));
            Tcl_DStringFree(&line);
        }
        result = Tcl_NewStringObj(Tcl_DStringValue(&data), -1);
        Tcl_DStringFree(&data);
    } else {
        result = Tcl_NewObj();
    }

    Tcl_SetObjResult(interp, result);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseColor --
 *
 *      This function extracts color and alpha values from a string. It
 *      understands standard Tk color formats, alpha suffixes and the color
 *      formats specific to photo images, which include alpha data.
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      If the input cannot be parsed, leaves an error message in
 *      interp. Returns a standard Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColor(
    Tcl_Interp *interp,         /* error messages go there */
    Tcl_Obj *specObj,           /* the color data to parse */
    Display *display,           /* display of main window, needed to parse
                                 * standard Tk colors */
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    const char *specString;
    TkSizeT charCount;

    /*
     * Find out which color format we have
     */

    specString = TkGetStringFromObj(specObj, &charCount);

    if (charCount == 0) {
        /* Empty string */
        *redPtr = *greenPtr = *bluePtr = *alphaPtr = 0;
        return TCL_OK;
    }
    if (charCount > TK_PHOTO_MAX_COLOR_CHARS) {
        Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid color"));
        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                "INVALID_COLOR", NULL);
        return TCL_ERROR;
    }
    if (specString[0] == '#') {
        return ParseColorAsHex(interp, specString, charCount, display,
                colormap, redPtr, greenPtr, bluePtr, alphaPtr);
    }
    if (ParseColorAsList(interp, specString, charCount,
            redPtr, greenPtr, bluePtr, alphaPtr) == TCL_OK) {
        return TCL_OK;
    }

    /*
     * Parsing the color as standard Tk color always is the last option tried
     * because TkParseColor() is very slow with values it cannot parse.
     */

    Tcl_ResetResult(interp);
    return ParseColorAsStandard(interp, specString, charCount, display,
            colormap, redPtr, greenPtr, bluePtr, alphaPtr);

}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsList --
 *
 *      This function extracts color and alpha values from a list of 3 or 4
 *      integers (the list color format).
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:
 *      Does *not* leave error messages in interp. The reason is that
 *      it is not always possible to tell if the list format was even
 *      intended and thus it is hard to return meaningful messages.
 *      A general error message from the caller is probably the best
 *      alternative.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsList(
    Tcl_Interp *dummy,         /* not used */
    const char *colorString,    /* the color data to parse */
    int colorStrLen,            /* length of the color string */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    /*
     * This is kinda ugly. The code would be certainly nicer if it
     * used Tcl_ListObjGetElements() and Tcl_GetIntFromObj(). But with
     * strtol() it's *much* faster.
     */

    const char *curPos;
    int values[4];
    int i;
    (void)dummy;
    (void)colorStrLen;

    curPos = colorString;
    i = 0;

    /*
     * strtol can give false positives with a sequence of space chars.
     * To avoid that, avance the pointer to the next non-blank char.
     */

    while(isspace(UCHAR(*curPos))) {
        ++curPos;
    }
    while (i < 4 && *curPos != '\0') {
        values[i] = strtol(curPos, (char **)&curPos, 0);
        if (values[i] < 0 || values[i] > 255) {
            return TCL_ERROR;
        }
        while(isspace(UCHAR(*curPos))) {
            ++curPos;
        }
        ++i;
    }

    if (i < 3 || *curPos != '\0') {
        return TCL_ERROR;
    }
    if (i < 4) {
        values[3] = 255;
    }

    *redPtr = (unsigned char) values[0];
    *greenPtr = (unsigned char) values[1];
    *bluePtr = (unsigned char) values[2];
    *alphaPtr = (unsigned char) values[3];

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsHex --
 *
 *      This function extracts color and alpha values from a string
 *      starting with '#', followed by hex digits. It undestands both
 *      the #RGBA form and the #RBG (with optional suffix)
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsHex(
    Tcl_Interp *interp,         /* error messages are left here */
    const char *colorString,    /* the color data to parse */
    int colorStrLen,            /* length of the color string */
    Display *display,           /* display of main window */
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    int i;
    unsigned long int colorValue = 0;

    if (colorStrLen - 1 != 4 && colorStrLen - 1 != 8) {
        return ParseColorAsStandard(interp, colorString, colorStrLen,
                display, colormap, redPtr, greenPtr, bluePtr, alphaPtr);
    }
    for (i = 1; i < colorStrLen; i++) {
        if (!isxdigit(UCHAR(colorString[i]))) {
            /*
             * There still is a chance that this is a Tk color with
             * an alpha suffix
             */

            return ParseColorAsStandard(interp, colorString, colorStrLen,
                    display, colormap, redPtr, greenPtr, bluePtr, alphaPtr);
        }
    }

    colorValue = strtoul(colorString + 1, NULL, 16);
    switch (colorStrLen - 1) {
    case 4:
        /* #RGBA format */
        *redPtr = (unsigned char) ((colorValue >> 12) * 0x11);
        *greenPtr = (unsigned char) (((colorValue >> 8) & 0xf) * 0x11);
        *bluePtr = (unsigned char) (((colorValue >> 4) & 0xf) * 0x11);
        *alphaPtr = (unsigned char) ((colorValue & 0xf) * 0x11);
        return TCL_OK;
    case 8:
        /* #RRGGBBAA format */
        *redPtr = (unsigned char) (colorValue >> 24);
        *greenPtr = (unsigned char) ((colorValue >> 16) & 0xff);
        *bluePtr = (unsigned char) ((colorValue >> 8) & 0xff);
        *alphaPtr = (unsigned char) (colorValue & 0xff);
        return TCL_OK;
    default:
        Tcl_Panic("unexpected switch fallthrough");
    }

    /* Shouldn't get here */
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ParseColorAsStandard --
 *
 *      This function tries to split a color stirng in a color and a
 *      suffix part and to extract color and alpha values from them. The
 *      color part is treated as regular Tk color.
 *
 * Results:
 *      On success, writes red, green, blue and alpha values to the
 *      corresponding pointers. If the color spec contains no alpha
 *      information, 255 is taken as transparency value.
 *      Returns a standard Tcl result.
 *
 * Side effects:
 *      None.
 *
 *----------------------------------------------------------------------
 */
static int
ParseColorAsStandard(
    Tcl_Interp *interp,         /* error messages are left here */
    const char *specString,    /* the color data to parse */
    int specStrLen,            /* length of the color string */
    Display *display,           /* display of main window */
    Colormap colormap,          /* colormap of current display */
    unsigned char *redPtr,      /* the result is written to these pointers */
    unsigned char *greenPtr,
    unsigned char *bluePtr,
    unsigned char *alphaPtr)
{
    XColor parsedColor;
    const char *suffixString, *colorString;
    char colorBuffer[TK_PHOTO_MAX_COLOR_CHARS + 1];
    char *tmpString;
    double fracAlpha;
    unsigned int suffixAlpha;
    int i;

    /*
     * Split color data string in color and suffix parts
     */

    if ((suffixString = strrchr(specString, '@')) == NULL
            && ((suffixString = strrchr(specString, '#')) == NULL
                    || suffixString == specString)) {
        suffixString = specString + specStrLen;
        colorString = specString;
    } else {
        strncpy(colorBuffer, specString, suffixString - specString);
        colorBuffer[suffixString - specString] = '\0';
        colorString = (const char*)colorBuffer;
    }

    /*
     * Try to parse as standard Tk color.
     *
     * We don't use Tk_GetColor() et al. here, as those functions
     * migth return a color that does not exaxtly match the given name
     * if the colormap is full. Also, we don't really want the color to be
     * added to the colormap.
     */

    if ( ! TkParseColor(display, colormap, colorString, &parsedColor)) {
         Tcl_SetObjResult(interp, Tcl_ObjPrintf(
            "invalid color name \"%s\"", specString));
         Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                 "INVALID_COLOR", NULL);
         return TCL_ERROR;
    }

    /*
     * parse the Suffix
     */

    switch (suffixString[0]) {
    case '\0':
        suffixAlpha = 255;
        break;
    case '@':
        fracAlpha = strtod(suffixString + 1, &tmpString);
        if (*tmpString != '\0') {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha "
                    "suffix \"%s\": expected floating-point value",
                    suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID COLOR", NULL);
            return TCL_ERROR;
        }
        if (fracAlpha < 0 || fracAlpha > 1) {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha suffix"
                    " \"%s\": value must be in the range from 0 to 1",
                    suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID_COLOR", NULL);
            return TCL_ERROR;
        }
        suffixAlpha = (unsigned int) floor(fracAlpha * 255 + 0.5);
        break;
    case '#':
        if (strlen(suffixString + 1) < 1 || strlen(suffixString + 1)> 2) {
            Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                    "invalid alpha suffix \"%s\"", suffixString));
            Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                    "INVALID_COLOR", NULL);
            return TCL_ERROR;
        }
        for (i = 1; i <= (int)strlen(suffixString + 1); i++) {
            if ( ! isxdigit(UCHAR(suffixString[i]))) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf(
                        "invalid alpha suffix \"%s\": expected hex digit",
                        suffixString));
                Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
                        "INVALID_COLOR", NULL);
                return TCL_ERROR;
            }
        }
        if (strlen(suffixString + 1) == 1) {
            sscanf(suffixString, "#%1x", &suffixAlpha);
            suffixAlpha *= 0x11;
        } else {
            sscanf(suffixString, "#%2x", &suffixAlpha);
        }
        break;
    default:
        Tcl_Panic("unexpected switch fallthrough");
    }

    *redPtr = (unsigned char) (parsedColor.red >> 8);
    *greenPtr = (unsigned char) (parsedColor.green >> 8);
    *bluePtr = (unsigned char) (parsedColor.blue >> 8);
    *alphaPtr = (unsigned char) suffixAlpha;

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * TkDebugStringMatchDef --
 *
 *      Debugging function for StringMatchDef. Basically just an alias for
 *      that function, intended to expose it directly to tests, as
 *      StirngMatchDef cannot be sufficiently tested otherwise.
 *
 * Results:
 *      See StringMatchDef.
 *
 * Side effects:
 *      None
 *----------------------------------------------------------------------
 */
int
TkDebugPhotoStringMatchDef(
    Tcl_Interp *interp,     /* Error messages are left in this interpreter */
    Tcl_Obj *data,          /* The data to check */
    Tcl_Obj *formatString,  /* Value of the -format option, not used here */
    int *widthPtr,          /* Width of image is written to this location */
    int *heightPtr)         /* Height of image is written to this location */
{
    return StringMatchDef(data, formatString, widthPtr, heightPtr, interp);
}


/* Local Variables: */
/* mode: c */
/* fill-column: 78 */
/* c-basic-offset: 4 */
/* tab-width: 8 */
/* indent-tabs-mode: nil */
/* End: */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkImgPNG.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * 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.
 */








|
|







8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#define	PNG_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. */
    int strDataLen;		/* Length of source data. */
    unsigned char *base64Data;	/* base64 encoded string data. */
    unsigned char base64Bits;	/* Remaining bits from last base64 read. */
    unsigned char base64State;	/* Current state of base64 decoder. */
    double alpha;		/* Alpha from -format option. */

    /*
     * Image header information.
192
193
194
195
196
197
198
199

200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
static int		CheckColor(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	CheckCRC(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long calculated);
static void		CleanupPNGImage(PNGImage *pngPtr);
static int		DecodeLine(Tcl_Interp *interp, PNGImage *pngPtr);
static int		DecodePNG(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY);

static int		EncodePNG(Tcl_Interp *interp,
			    Tk_PhotoImageBlock *blockPtr, PNGImage *pngPtr);
static int		FileMatchPNG(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *fmtObj, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		FileReadPNG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *fmtObj,
			    Tk_PhotoHandle imageHandle, int destX, int destY,
			    int width, int height, int srcX, int srcY);
static int		FileWritePNG(Tcl_Interp *interp, const char *filename,
			    Tcl_Obj *fmtObj, Tk_PhotoImageBlock *blockPtr);
static int		InitPNGImage(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Channel chan, Tcl_Obj *objPtr, int dir);
static inline unsigned char Paeth(int a, int b, int c);
static int		ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    PNGImage *pngPtr);
static int		ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadData(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, size_t destSz,
			    unsigned long *crcPtr);
static int		ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr,
			    size_t *sizePtr, unsigned long *typePtr,
			    unsigned long *crcPtr);
static int		ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadIHDR(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	ReadInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long *resultPtr, unsigned long *crcPtr);
static int		ReadPLTE(Tcl_Interp *interp, PNGImage *pngPtr,







|
>

















|


|


|


|







192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
static int		CheckColor(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	CheckCRC(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long calculated);
static void		CleanupPNGImage(PNGImage *pngPtr);
static int		DecodeLine(Tcl_Interp *interp, PNGImage *pngPtr);
static int		DecodePNG(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Obj *fmtObj, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
static int		EncodePNG(Tcl_Interp *interp,
			    Tk_PhotoImageBlock *blockPtr, PNGImage *pngPtr);
static int		FileMatchPNG(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *fmtObj, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		FileReadPNG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *fmtObj,
			    Tk_PhotoHandle imageHandle, int destX, int destY,
			    int width, int height, int srcX, int srcY);
static int		FileWritePNG(Tcl_Interp *interp, const char *filename,
			    Tcl_Obj *fmtObj, Tk_PhotoImageBlock *blockPtr);
static int		InitPNGImage(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tcl_Channel chan, Tcl_Obj *objPtr, int dir);
static inline unsigned char Paeth(int a, int b, int c);
static int		ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    PNGImage *pngPtr);
static int		ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, int destSz,
			    unsigned long *crcPtr);
static int		ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, int destSz,
			    unsigned long *crcPtr);
static int		ReadData(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char *destPtr, int destSz,
			    unsigned long *crcPtr);
static int		ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr,
			    int *sizePtr, unsigned long *typePtr,
			    unsigned long *crcPtr);
static int		ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    int chunkSz, unsigned long crc);
static int		ReadIHDR(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	ReadInt32(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long *resultPtr, unsigned long *crcPtr);
static int		ReadPLTE(Tcl_Interp *interp, PNGImage *pngPtr,
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
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);







|

|







247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
static int		StringWritePNG(Tcl_Interp *interp, Tcl_Obj *fmtObj,
			    Tk_PhotoImageBlock *blockPtr);
static int		UnfilterLine(Tcl_Interp *interp, PNGImage *pngPtr);
static inline int	WriteByte(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned char c, unsigned long *crcPtr);
static inline int	WriteChunk(Tcl_Interp *interp, PNGImage *pngPtr,
			    unsigned long chunkType,
			    const unsigned char *dataPtr, int dataSize);
static int		WriteData(Tcl_Interp *interp, PNGImage *pngPtr,
			    const unsigned char *srcPtr, int srcSz,
			    unsigned long *crcPtr);
static int		WriteExtraChunks(Tcl_Interp *interp,
			    PNGImage *pngPtr);
static int		WriteIHDR(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
static int		WriteIDAT(Tcl_Interp *interp, PNGImage *pngPtr,
			    Tk_PhotoImageBlock *blockPtr);
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
     * 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));







|







316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
     * reading with ReadData().
     */

    if (objPtr) {
	Tcl_IncrRefCount(objPtr);
	pngPtr->objDataPtr = objPtr;
	pngPtr->strDataBuf =
		Tcl_GetByteArrayFromObj(objPtr, &pngPtr->strDataLen);
    }

    /*
     * Initialize the palette transparency table to fully opaque.
     */

    memset(pngPtr->palette, 255, sizeof(pngPtr->palette));
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
 */

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,







|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
 */

static int
ReadBase64(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    int destSz,
    unsigned long *crcPtr)
{
    static const unsigned char from64[] = {
	0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x80,
	0x83, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x3e,
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	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 */







|







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83,
	0x83, 0x83, 0x83
    };

    /*
     * Definitions for the base-64 decoder.
     */

#define PNG64_SPECIAL	0x80	/* Flag bit */
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
 */

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







|






|







|







552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
 */

static int
ReadByteArray(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    int 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", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL);
	return TCL_ERROR;
    }

    while (destSz) {
	int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	memcpy(destPtr, pngPtr->strDataBuf, blockSz);

	pngPtr->strDataBuf += blockSz;
	pngPtr->strDataLen -= blockSz;

	if (crcPtr) {
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
 */

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

	/*







|









|


|







610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
 */

static int
ReadData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned char *destPtr,
    int destSz,
    unsigned long *crcPtr)
{
    if (pngPtr->base64Data) {
	return ReadBase64(interp, pngPtr, destPtr, destSz, crcPtr);
    } else if (pngPtr->strDataBuf) {
	return ReadByteArray(interp, pngPtr, destPtr, destSz, crcPtr);
    }

    while (destSz) {
	int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ);

	blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz);
	if (blockSz == -1) {
	    /* TODO: failure info... */
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "channel read failed: %s", Tcl_PosixError(interp)));
	    return TCL_ERROR;
	}

	/*
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
{
    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;
}

/*
 *----------------------------------------------------------------------
 *







|







691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
{
    unsigned char p[4];

    if (ReadData(interp, pngPtr, p, 4, crcPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }

    *resultPtr = PNG_UINT32(p[0], p[1], p[2], p[3]);

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
 *----------------------------------------------------------------------
 */

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;








|







855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
 *----------------------------------------------------------------------
 */

static int
ReadChunkHeader(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    int *sizePtr,
    unsigned long *typePtr,
    unsigned long *crcPtr)
{
    unsigned long chunkType = 0;
    int chunkSz = 0;
    unsigned long crc = 0;

882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
	 * 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;







|







883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
	 * maximum size for Tcl_Read, Tcl_GetByteArrayFromObj, etc.
	 */

	if (ReadData(interp, pngPtr, pc, 4, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

	temp = PNG_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.







|







908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
	    return TCL_ERROR;
	}

	/*
	 * Convert it to a host-order integer for simple comparison.
	 */

	chunkType = PNG_UINT32(pc[0], pc[1], pc[2], pc[3]);

	/*
	 * Check to see if this is a known/supported chunk type. Note that the
	 * PNG specs require non-critical (i.e., ancillary) chunk types that
	 * are not recognized to be ignored, rather than be treated as an
	 * error. It does, however, recommend that an unknown critical chunk
	 * type be treated as a failure.
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986

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







|







973
974
975
976
977
978
979
980
981
982
983
984
985
986
987

	default:
	    /*
	     * Unknown chunk type. If it's critical, we can't continue.
	     */

	    if (!(chunkType & PNG_CF_ANCILLARY)) {
		if (chunkType & PNG_UINT32(128,128,128,128)) {
		    /*
		     * No nice ASCII conversion; shouldn't happen either, but
		     * we'll be doubly careful.
		     */

		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "encountered an unsupported critical chunk type",
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
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.
     */







|







1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
static int
ReadIHDR(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char sigBuf[PNG_SIG_SZ];
    unsigned long chunkType;
    int chunkSz;
    unsigned long crc;
    unsigned long width, height;
    int mismatch;

    /*
     * Read the appropriate number of bytes for the PNG signature.
     */
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
    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;
	}








|







1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
    mismatch = memcmp(sigBuf, pngSignature, PNG_SIG_SZ);

    /*
     * If reading from string, reset position and try base64 decode.
     */

    if (mismatch && pngPtr->strDataBuf) {
	pngPtr->strDataBuf = Tcl_GetByteArrayFromObj(pngPtr->objDataPtr,
		&pngPtr->strDataLen);
	pngPtr->base64Data = pngPtr->strDataBuf;

	if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) {
	    return TCL_ERROR;
	}

1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720

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








|

|







1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721

static int
UnfilterLine(
    Tcl_Interp *interp,
    PNGImage *pngPtr)
{
    unsigned char *thisLine =
	    Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, (int *)NULL);
    unsigned char *lastLine =
	    Tcl_GetByteArrayFromObj(pngPtr->lastLineObj, (int *)NULL);

#define	PNG_FILTER_NONE		0
#define	PNG_FILTER_SUB		1
#define	PNG_FILTER_UP		2
#define	PNG_FILTER_AVG		3
#define	PNG_FILTER_PAETH	4

1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
    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(







|







1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
    int haveBits = 0;		/* Number of bits remaining in current byte */
    unsigned char pixBits = 0;	/* Extracted bits for current channel */
    int shifts = 0;		/* Number of channels extracted from byte */
    int offset = 0;		/* Current offset into pixelPtr */
    int colStep = 1;		/* Column increment each pass */
    int pixStep = 0;		/* extra pixelPtr increment each pass */
    unsigned char lastPixel[6];
    unsigned char *p = Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, (int *)NULL);

    p++;
    if (UnfilterLine(interp, pngPtr) == TCL_ERROR) {
	return TCL_ERROR;
    }
    if (pngPtr->currentLine >= pngPtr->block.height) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
    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;







|







2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
    unsigned long crc)
{
    /*
     * Process IDAT contents until there is no more in this chunk.
     */

    while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) {
	int len1, len2;

	/*
	 * Read another block of input into the zlib stream if data remains.
	 */

	if (chunkSz) {
	    Tcl_Obj *inputObj = NULL;
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163

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







|




|

|







2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164

	/*
	 * Inflate, processing each output buffer's worth as a line of pixels,
	 * until we cannot fill the buffer any more.
	 */

    getNextLine:
	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 == pngPtr->phaseSize) {
	    if (pngPtr->phase > 7) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"extra data after final scan line of final phase",
			-1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA",
			NULL);
		return TCL_ERROR;
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
    PNGImage *pngPtr)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    static const char *const fmtOptions[] = {
	"-alpha", NULL
    };
    enum fmtOptionsEnum {
	OPT_ALPHA
    };

    /*
     * Extract elements of format specification as a list.
     */








|







2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
    PNGImage *pngPtr)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    static const char *const fmtOptions[] = {
	"-alpha", NULL
    };
    enum fmtOptions {
	OPT_ALPHA
    };

    /*
     * Extract elements of format specification as a list.
     */

2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
	    Tcl_WrongNumArgs(interp, 1, objv, "value");
	    return TCL_ERROR;
	}

	objc--;
	objv++;

	switch ((enum fmtOptionsEnum) optIndex) {
	case OPT_ALPHA:
	    if (Tcl_GetDoubleFromObj(interp, objv[0],
		    &pngPtr->alpha) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    if ((pngPtr->alpha < 0.0) || (pngPtr->alpha > 1.0)) {







|







2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
	    Tcl_WrongNumArgs(interp, 1, objv, "value");
	    return TCL_ERROR;
	}

	objc--;
	objv++;

	switch ((enum fmtOptions) optIndex) {
	case OPT_ALPHA:
	    if (Tcl_GetDoubleFromObj(interp, objv[0],
		    &pngPtr->alpha) == TCL_ERROR) {
		return TCL_ERROR;
	    }

	    if ((pngPtr->alpha < 0.0) || (pngPtr->alpha > 1.0)) {
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381




2382
2383
2384

2385
2386
2387
2388
2389
2390
2391
2392
 *	dimensions and contents may change.
 *
 *----------------------------------------------------------------------
 */

static int
DecodePNG(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tcl_Obj *fmtObj,
    Tk_PhotoHandle imageHandle,
    int destX,




    int destY)
{
    unsigned long chunkType;

    size_t chunkSz;
    unsigned long crc;

    /*
     * Parse the PNG signature and IHDR (header) chunk.
     */

    if (ReadIHDR(interp, pngPtr) == TCL_ERROR) {







|
|
|
|
|
>
>
>
>
|


>
|







2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
 *	dimensions and contents may change.
 *
 *----------------------------------------------------------------------
 */

static int
DecodePNG(
    Tcl_Interp *interp,		/* Interpreter to use for reporting errors. */
    PNGImage *pngPtr,		/* PNG image information record. */
    Tcl_Obj *fmtObj,		/* User-specified format object, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    unsigned long chunkType;
    int result;
    int chunkSz;
    unsigned long crc;

    /*
     * Parse the PNG signature and IHDR (header) chunk.
     */

    if (ReadIHDR(interp, pngPtr) == TCL_ERROR) {
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494

    /*
     * Expand the photo size (if not set by the user) to provide enough space
     * for the image being parsed. It does not matter if width or height wrap
     * to negative here: Tk will not shrink the image.
     */

    if (Tk_PhotoExpand(interp, imageHandle, destX + pngPtr->block.width,
	    destY + pngPtr->block.height) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * A scan line consists of one byte for a filter type, plus the number of
     * bits per color sample times the number of color samples per pixel.
     */







|
|







2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500

    /*
     * Expand the photo size (if not set by the user) to provide enough space
     * for the image being parsed. It does not matter if width or height wrap
     * to negative here: Tk will not shrink the image.
     */

    if (Tk_PhotoExpand(interp, imageHandle, destX + width,
	    destY + height) == TCL_ERROR) {
	return TCL_ERROR;
    }

    /*
     * A scan line consists of one byte for a filter type, plus the number of
     * bits per color sample times the number of color samples per pixel.
     */
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
    pngPtr->thisLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->thisLineObj);

    pngPtr->block.pixelPtr = (unsigned char *)attemptckalloc(pngPtr->blockLen);
    if (!pngPtr->block.pixelPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"memory allocation failed", -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	return TCL_ERROR;
    }

    /*
     * Determine size of the first phase if interlaced. Phase size should
     * always be <= line size, so probably not necessary to check for
     * arithmetic overflow here: should be covered by line size check.







|







2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
    pngPtr->thisLineObj = Tcl_NewObj();
    Tcl_IncrRefCount(pngPtr->thisLineObj);

    pngPtr->block.pixelPtr = (unsigned char *)attemptckalloc(pngPtr->blockLen);
    if (!pngPtr->block.pixelPtr) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		"memory allocation failed", -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	return TCL_ERROR;
    }

    /*
     * Determine size of the first phase if interlaced. Phase size should
     * always be <= line size, so probably not necessary to check for
     * arithmetic overflow here: should be covered by line size check.
2634
2635
2636
2637
2638
2639
2640

2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654

    ApplyAlpha(pngPtr);

    /*
     * Copy the decoded image block into the Tk photo image.
     */


    if (Tk_PhotoPutBlock(interp, imageHandle, &pngPtr->block, destX, destY,
	    pngPtr->block.width, pngPtr->block.height,
	    TK_PHOTO_COMPOSITE_SET) == TCL_ERROR) {
	return TCL_ERROR;
    }

    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * FileMatchPNG --
 *







>
|
<
|
|
|
<
|







2640
2641
2642
2643
2644
2645
2646
2647
2648

2649
2650
2651

2652
2653
2654
2655
2656
2657
2658
2659

    ApplyAlpha(pngPtr);

    /*
     * Copy the decoded image block into the Tk photo image.
     */

    pngPtr->block.pixelPtr += srcX * pngPtr->block.pixelSize + srcY * pngPtr->block.pitch;
    result = Tk_PhotoPutBlock(interp, imageHandle, &pngPtr->block, destX, destY,

	    width, height, TK_PHOTO_COMPOSITE_SET);
    pngPtr->block.pixelPtr -= srcX * pngPtr->block.pixelSize + srcY * pngPtr->block.pitch;


    return result;
}

/*
 *----------------------------------------------------------------------
 *
 * FileMatchPNG --
 *
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
    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;







<
<







2677
2678
2679
2680
2681
2682
2683


2684
2685
2686
2687
2688
2689
2690
    Tcl_Obj *fmtObj,
    int *widthPtr,
    int *heightPtr,
    Tcl_Interp *interp)
{
    PNGImage png;
    int match = 0;



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







|
|
|
|
|
|
|
|
|
|
|



<
<
<
<
<




|







2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732





2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
 *	image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
FileReadPNG(
    Tcl_Interp* interp,		/* Interpreter to use for reporting errors. */
    Tcl_Channel chan,		/* The image file, open for reading. */
    const char* fileName,	/* The name of the image file. */
    Tcl_Obj *fmtObj,		/* User-specified format object, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    PNGImage png;
    int result = TCL_ERROR;






    result = InitPNGImage(interp, &png, chan, NULL, TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY, width, height, srcX, srcY);
    }

    CleanupPNGImage(&png);
    return result;
}

/*
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
    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;
    }








<



|







2765
2766
2767
2768
2769
2770
2771

2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
    Tcl_Obj *fmtObj,
    int *widthPtr,
    int *heightPtr,
    Tcl_Interp *interp)
{
    PNGImage png;
    int match = 0;


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







|

|
|
|
|
|
|
|
|



<
<
<
<





|







2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819




2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
 *	New data is added to the image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
StringReadPNG(
    Tcl_Interp* interp,		/* Interpreter to use for reporting errors. */
    Tcl_Obj *pObjData,
    Tcl_Obj *fmtObj,		/* User-specified format object, or NULL. */
    Tk_PhotoHandle imageHandle,	/* The photo image to write into. */
    int destX, int destY,	/* Coordinates of top-left pixel in photo
				 * image to be written to. */
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    PNGImage png;
    int result = TCL_ERROR;





    result = InitPNGImage(interp, &png, NULL, pObjData,
	    TCL_ZLIB_STREAM_INFLATE);

    if (TCL_OK == result) {
	result = DecodePNG(interp, &png, fmtObj, imageHandle, destX, destY, width, height, srcX, srcY);
    }

    CleanupPNGImage(&png);
    return result;
}

/*
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
 */

static int
WriteData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    const unsigned char *srcPtr,
    size_t srcSz,
    unsigned long *crcPtr)
{
    if (!srcPtr || !srcSz) {
	return TCL_OK;
    }

    if (crcPtr) {
	*crcPtr = Tcl_ZlibCRC32(*crcPtr, srcPtr, srcSz);
    }

    /*
     * TODO: is Tcl_AppendObjToObj faster here? i.e., does Tcl join the
     * objects immediately or store them in a multi-object rep?
     */

    if (pngPtr->objDataPtr) {
	TkSizeT objSz;
	unsigned char *destPtr;

	TkGetByteArrayFromObj(pngPtr->objDataPtr, &objSz);

	if (objSz + srcSz > INT_MAX) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "image too large to store completely in byte array", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	    return TCL_ERROR;
	}

	destPtr = Tcl_SetByteArrayLength(pngPtr->objDataPtr, objSz + srcSz);

	if (!destPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "memory allocation failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    return TCL_ERROR;
	}

	memcpy(destPtr+objSz, srcPtr, srcSz);
    } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"write to channel failed: %s", Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    return TCL_OK;
}







|


|













|


|

|
















|







2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
 */

static int
WriteData(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    const unsigned char *srcPtr,
    int 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) {
	int objSz;
	unsigned char *destPtr;

	Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, &objSz);

	if (objSz > INT_MAX - srcSz) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "image too large to store completely in byte array", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL);
	    return TCL_ERROR;
	}

	destPtr = Tcl_SetByteArrayLength(pngPtr->objDataPtr, objSz + srcSz);

	if (!destPtr) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "memory allocation failed", -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
	    return TCL_ERROR;
	}

	memcpy(destPtr+objSz, srcPtr, srcSz);
    } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == -1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"write to channel failed: %s", Tcl_PosixError(interp)));
	return TCL_ERROR;
    }

    return TCL_OK;
}
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982

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







|







2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975

static inline int
WriteChunk(
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    unsigned long chunkType,
    const unsigned char *dataPtr,
    int dataSize)
{
    unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0);
    int result = TCL_OK;

    /*
     * Write the length field for the chunk.
     */
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
    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;







|







3135
3136
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
    Tcl_Interp *interp,
    PNGImage *pngPtr,
    Tk_PhotoImageBlock *blockPtr)
{
    int rowNum, flush = TCL_ZLIB_NO_FLUSH, result;
    Tcl_Obj *outputObj;
    unsigned char *outputBytes;
    int outputSize;

    /*
     * Filter and compress each row one at a time.
     */

    for (rowNum=0 ; rowNum < blockPtr->height ; rowNum++) {
	int colNum;
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248

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







|







3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241

    /*
     * Now get the compressed data and write it as one big IDAT chunk.
     */

    outputObj = Tcl_NewObj();
    (void) Tcl_ZlibStreamGet(pngPtr->stream, outputObj, -1);
    outputBytes = Tcl_GetByteArrayFromObj(outputObj, &outputSize);
    result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize);
    Tcl_DecrRefCount(outputObj);
    return result;
}

/*
 *----------------------------------------------------------------------
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
    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);







<







3460
3461
3462
3463
3464
3465
3466

3467
3468
3469
3470
3471
3472
3473
    const char *filename,
    Tcl_Obj *fmtObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    PNGImage png;
    int result = TCL_ERROR;


    /*
     * Open a Tcl file channel where the image data will be stored. Tk ought
     * to take care of this, and just provide a channel, but it doesn't.
     */

    chan = Tcl_OpenFileChannel(interp, filename, "w", 0644);
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
     */

    if (InitPNGImage(interp, &png, chan, NULL,
	    TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) {
	goto cleanup;
    }

    /*
     * Set the translation mode to binary so that CR and LF are not to the
     * platform's EOL sequence.
     */

    if (Tcl_SetChannelOption(interp, chan, "-translation",
	    "binary") != TCL_OK) {
	goto cleanup;
    }

    /*
     * Write the raw PNG data out to the file.
     */








<
<
<
<
<
|
|







3481
3482
3483
3484
3485
3486
3487





3488
3489
3490
3491
3492
3493
3494
3495
3496
     */

    if (InitPNGImage(interp, &png, chan, NULL,
	    TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) {
	goto cleanup;
    }






    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
	    != TCL_OK) {
	goto cleanup;
    }

    /*
     * Write the raw PNG data out to the file.
     */

3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
    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) {







<







3525
3526
3527
3528
3529
3530
3531

3532
3533
3534
3535
3536
3537
3538
    Tcl_Interp *interp,
    Tcl_Obj *fmtObj,
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Obj *resultObj = Tcl_NewObj();
    PNGImage png;
    int result = TCL_ERROR;


    /*
     * Initalize PNGImage instance for encoding.
     */

    if (InitPNGImage(interp, &png, NULL, resultObj,
	    TCL_ZLIB_STREAM_DEFLATE) == TCL_ERROR) {
Changes to generic/tkImgPPM.c.
12
13
14
15
16
17
18




19
20
21
22
23
24
25
 * Author: Paul Mackerras (paulus@cs.anu.edu.au),
 *	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 */








>
>
>
>







12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
 * Author: Paul Mackerras (paulus@cs.anu.edu.au),
 *	Department of Computer Science,
 *	Australian National University.
 */

#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The maximum amount of memory to allocate for data read from the file. If we
 * need more than this, we do it in pieces.
 */

#define MAX_MEMORY	10000		/* don't allocate > 10KB */

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    int fileWidth, fileHeight, maxIntensity;
    int nLines, h, type, bytesPerChannel = 1;
    size_t nBytes, count;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;

    type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't read raw PPM header from file \"%s\"", fileName));







|







142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
    int width, int height,	/* Dimensions of block of photo image to be
				 * written to. */
    int srcX, int srcY)		/* Coordinates of top-left pixel to be used in
				 * image being read. */
{
    int fileWidth, fileHeight, maxIntensity;
    int nLines, h, type, bytesPerChannel = 1;
    int nBytes, count;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;

    type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity);
    if (type == 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"couldn't read raw PPM header from file \"%s\"", fileName));
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
	    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,
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
FileWritePPM(
    Tcl_Interp *interp,
    const char *fileName,
    TCL_UNUSED(Tcl_Obj *),
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    int w, h, greenOffset, blueOffset;
    size_t nBytes;
    unsigned char *pixelPtr, *pixLinePtr;
    char header[16 + TCL_INTEGER_SPACE * 2];

    chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666);
    if (chan == NULL) {
	return TCL_ERROR;
    }

    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }

    sprintf(header, "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
    Tcl_Write(chan, header, -1);

    pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
	    && (blockPtr->pitch == (blockPtr->width * 3))) {
	nBytes = blockPtr->height * blockPtr->pitch;
	if ((size_t)Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {
	    goto writeerror;
	}
    } else {
	for (h = blockPtr->height; h > 0; h--) {
	    pixelPtr = pixLinePtr;
	    for (w = blockPtr->width; w > 0; w--) {
		if (Tcl_Write(chan,(char *)&pixelPtr[0], 1) == TCL_IO_FAILURE ||
			Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1) == TCL_IO_FAILURE ||
			Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) == TCL_IO_FAILURE) {
		    goto writeerror;
		}
		pixelPtr += blockPtr->pixelSize;
	    }
	    pixLinePtr += blockPtr->pitch;
	}
    }







|
<













<
<
<
<
|
<
|









|






|
|
|







286
287
288
289
290
291
292
293

294
295
296
297
298
299
300
301
302
303
304
305
306




307

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
FileWritePPM(
    Tcl_Interp *interp,
    const char *fileName,
    TCL_UNUSED(Tcl_Obj *),
    Tk_PhotoImageBlock *blockPtr)
{
    Tcl_Channel chan;
    int w, h, greenOffset, blueOffset, nBytes;

    unsigned char *pixelPtr, *pixLinePtr;
    char header[16 + TCL_INTEGER_SPACE * 2];

    chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666);
    if (chan == NULL) {
	return TCL_ERROR;
    }

    if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
	    != TCL_OK) {
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }






    snprintf(header, sizeof(header), "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);
    Tcl_Write(chan, header, -1);

    pixLinePtr = blockPtr->pixelPtr + blockPtr->offset[0];
    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3)
	    && (blockPtr->pitch == (blockPtr->width * 3))) {
	nBytes = blockPtr->height * blockPtr->pitch;
	if (Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) {
	    goto writeerror;
	}
    } else {
	for (h = blockPtr->height; h > 0; h--) {
	    pixelPtr = pixLinePtr;
	    for (w = blockPtr->width; w > 0; w--) {
		if (Tcl_Write(chan,(char *)&pixelPtr[0], 1) == -1 ||
			Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1) == -1 ||
			Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) == -1) {
		    goto writeerror;
		}
		pixelPtr += blockPtr->pixelSize;
	    }
	    pixLinePtr += blockPtr->pitch;
	}
    }
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);







|







372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
    Tk_PhotoImageBlock *blockPtr)
{
    int w, h, size, greenOffset, blueOffset;
    unsigned char *pixLinePtr, *byteArray;
    char header[16 + TCL_INTEGER_SPACE * 2];
    Tcl_Obj *byteArrayObj;

    snprintf(header, sizeof(header), "P6\n%d %d\n255\n", blockPtr->width, blockPtr->height);

    /*
     * Construct a byte array of the right size with the header and
     * get a pointer to the data part of it.
     */

    size = strlen(header);
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
	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,







|
|







598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
	if (maxIntensity < 0x00ff) {
	    for (p=pixelPtr,count=nBytes ; count>0 ; count--,p++,dataBuffer++) {
		*p = (((int) *dataBuffer) * 255)/maxIntensity;
	    }
	} else {
	    unsigned int value;

	    for (p = pixelPtr,count=nBytes; count > 1; count-=2, p += 2, 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) {







|


|







758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
				 * is stored here. */
    unsigned char **dataBufferPtr,
    int *dataSizePtr)
{
#define BUFFER_SIZE 1000
    char buffer[BUFFER_SIZE], c;
    int i, numFields, type = 0;
    int 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.
17
18
19
20
21
22
23




24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
 *	   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);

/*







>
>
>
>



|
<
<
<

<
<
<
<





|





|







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



32




33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
 *	   Department of Computer Science,
 *	   Australian National University.
 */

#include "tkImgPhoto.h"
#include "tkPort.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * Declaration for internal Xlib function used here:
 */




extern int		_XInitImageFuncPtrs(XImage *image);





/*
 * 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(pixel mask);
static void		GetColorTable(PhotoInstance *instancePtr);
static void		FreeColorTable(ColorTable *colorPtr, int force);
static void		AllocateColors(ColorTable *colorPtr);
static void		DisposeColorTable(ClientData clientData);
static int		ReclaimColors(ColorTableId *id, int numColors);

/*
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
 *----------------------------------------------------------------------
 */

void
TkImgPhotoConfigureInstance(
    PhotoInstance *instancePtr)	/* Instance to reconfigure. */
{
    PhotoModel *modelPtr = instancePtr->modelPtr;
    XImage *imagePtr;
    int bitsPerPixel;
    ColorTable *colorTablePtr;
    XRectangle validBox;

    /*
     * If the -palette configuration option has been set for the model, use







|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
 *----------------------------------------------------------------------
 */

void
TkImgPhotoConfigureInstance(
    PhotoInstance *instancePtr)	/* Instance to reconfigure. */
{
    PhotoModel *modelPtr = instancePtr->masterPtr;
    XImage *imagePtr;
    int bitsPerPixel;
    ColorTable *colorTablePtr;
    XRectangle validBox;

    /*
     * If the -palette configuration option has been set for the model, use
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
	    || (instancePtr->palette != colorTablePtr->id.palette)
	    || (instancePtr->gamma != colorTablePtr->id.gamma)) {
	/*
	 * Free up our old color table, and get a new one.
	 */

	if (colorTablePtr != NULL) {
	    colorTablePtr->liveRefCount--;
	    FreeColorTable(colorTablePtr, 0);
	}
	GetColorTable(instancePtr);

	/*
	 * Create a new XImage structure for sending data to the X server, if
	 * necessary.







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
	    || (instancePtr->palette != colorTablePtr->id.palette)
	    || (instancePtr->gamma != colorTablePtr->id.gamma)) {
	/*
	 * Free up our old color table, and get a new one.
	 */

	if (colorTablePtr != NULL) {
	    colorTablePtr->liveRefCount -= 1;
	    FreeColorTable(colorTablePtr, 0);
	}
	GetColorTable(instancePtr);

	/*
	 * Create a new XImage structure for sending data to the X server, if
	 * necessary.
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227



228
229
230
231
232
233
234
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] = {







|







>
>
>







210
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 = 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.







|
>
>
>
>







253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
     * colormap. If so then just re-use it.
     */

    colormap = Tk_Colormap(tkwin);
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	if ((colormap == instancePtr->colormap)
	    && (Tk_Display(tkwin) == instancePtr->display)
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
	    && (Tk_Visual(tkwin) == instancePtr->visualInfo.visual)
#endif
	    ) {
	    /*
	     * Re-use this instance.
	     */

	    if (instancePtr->refCount == 0) {
		/*
		 * We are resurrecting this instance.
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
    }

    /*
     * The image isn't already in use in a window with the same colormap. Make
     * a new instance of the image.
     */

    instancePtr = (PhotoInstance *)ckalloc(sizeof(PhotoInstance));
    instancePtr->modelPtr = modelPtr;
    instancePtr->display = Tk_Display(tkwin);
    instancePtr->colormap = Tk_Colormap(tkwin);
    Tk_PreserveColormap(instancePtr->display, instancePtr->colormap);
    instancePtr->refCount = 1;
    instancePtr->colorTablePtr = NULL;
    instancePtr->pixels = None;
    instancePtr->error = NULL;







|
|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
    }

    /*
     * The image isn't already in use in a window with the same colormap. Make
     * a new instance of the image.
     */

    instancePtr = ckalloc(sizeof(PhotoInstance));
    instancePtr->masterPtr = modelPtr;
    instancePtr->display = Tk_Display(tkwin);
    instancePtr->colormap = Tk_Colormap(tkwin);
    Tk_PreserveColormap(instancePtr->display, instancePtr->colormap);
    instancePtr->refCount = 1;
    instancePtr->colorTablePtr = NULL;
    instancePtr->pixels = None;
    instancePtr->error = NULL;
310
311
312
313
314
315
316




317
318
319
320
321
322
323








324
325
326
327
328
329
330
	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;







>
>
>
>







>
>
>
>
>
>
>
>







314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
	Tcl_Panic("TkImgPhotoGet couldn't find visual for window");
    }

    nRed = 2;
    nGreen = nBlue = 0;
    mono = 1;
    instancePtr->visualInfo = *visInfoPtr;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
    gcmask = 0;
    instancePtr->visualInfo.visual = Tk_Visual(tkwin);
#endif
    switch (visInfoPtr->c_class) {
    case DirectColor:
    case TrueColor:
	nRed = 1 << CountBits(visInfoPtr->red_mask);
	nGreen = 1 << CountBits(visInfoPtr->green_mask);
	nBlue = 1 << CountBits(visInfoPtr->blue_mask);
	mono = 0;
#if (!defined(_WIN32) && !defined(MAC_OSX_TK))
	if (visInfoPtr->depth > 24) {
	    gcValues.plane_mask = visInfoPtr->red_mask
		    | visInfoPtr->green_mask
		    | visInfoPtr->blue_mask;
	    gcmask = GCPlaneMask;
	}
#endif
	break;
    case PseudoColor:
    case StaticColor:
	if (visInfoPtr->depth > 15) {
	    nRed = 32;
	    nGreen = 32;
	    nBlue = 32;
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367

368



369

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
    case StaticGray:
	nRed = 1 << visInfoPtr->depth;
	break;
    }
    XFree((char *) visInfoPtr);

    if (mono) {
	sprintf(buf, "%d", nRed);
    } else {
	sprintf(buf, "%d/%d/%d", nRed, nGreen, nBlue);
    }
    instancePtr->defaultPalette = Tk_GetUid(buf);

    /*
     * Make a GC with background = black and foreground = white.
     */

    white = Tk_GetColor(modelPtr->interp, tkwin, "white");
    black = Tk_GetColor(modelPtr->interp, tkwin, "black");
    gcValues.foreground = (white != NULL)? white->pixel:
	    WhitePixelOfScreen(Tk_Screen(tkwin));
    gcValues.background = (black != NULL)? black->pixel:
	    BlackPixelOfScreen(Tk_Screen(tkwin));
    Tk_FreeColor(white);
    Tk_FreeColor(black);
    gcValues.graphics_exposures = False;

    instancePtr->gc = Tk_GetGC(tkwin,



	    GCForeground|GCBackground|GCGraphicsExposures, &gcValues);


    /*
     * Set configuration options and finish the initialization of the
     * instance. This will also dither the image if necessary.
     */

    TkImgPhotoConfigureInstance(instancePtr);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(modelPtr->tkModel, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
    }

    return instancePtr;
}

/*







|

|
















>

>
>
>
|
>













|







358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    case StaticGray:
	nRed = 1 << visInfoPtr->depth;
	break;
    }
    XFree((char *) visInfoPtr);

    if (mono) {
	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);

    /*
     * If this is the first instance, must set the size of the image.
     */

    if (instancePtr->nextPtr == NULL) {
	Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
		modelPtr->width, modelPtr->height);
    }

    return instancePtr;
}

/*
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
 *	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) | \







|







433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
 *	whereas RGB15 is the correct version and works for 15bpp+, but it
 *	slower, so it's only used for 15bpp+.
 *
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *----------------------------------------------------------------------
 */
#ifndef TK_CAN_RENDER_RGBA
#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
#define RGB(r, g, b)	((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
    int xOffset, int yOffset,	/* X & Y offset into image instance to
				 * draw. */
    int width, int height)	/* Width & height of image to draw. */
{
    int x, y, line;
    unsigned long pixel;
    unsigned char r, g, b, alpha, unalpha, *modelPtr;
    unsigned char *alphaAr = iPtr->modelPtr->pix32;

    /*
     * This blending is an integer version of the Source-Over compositing rule
     * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
     * 1984) that has been hard-coded (for speed) to work with targetting a
     * solid surface.
     *







|







459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
    int xOffset, int yOffset,	/* X & Y offset into image instance to
				 * draw. */
    int width, int height)	/* Width & height of image to draw. */
{
    int x, y, line;
    unsigned long pixel;
    unsigned char r, g, b, alpha, unalpha, *modelPtr;
    unsigned char *alphaAr = iPtr->masterPtr->pix32;

    /*
     * This blending is an integer version of the Source-Over compositing rule
     * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
     * 1984) that has been hard-coded (for speed) to work with targetting a
     * solid surface.
     *
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
    if (bgImg->depth < 24) {
	unsigned char red_mlen, green_mlen, blue_mlen;

	red_mlen = 8 - CountBits(red_mask >> red_shift);
	green_mlen = 8 - CountBits(green_mask >> green_shift);
	blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
	for (y = 0; y < height; y++) {
	    line = (y + yOffset) * iPtr->modelPtr->width;
	    for (x = 0; x < width; x++) {
		modelPtr = alphaAr + ((line + x + xOffset) * 4);
		alpha = modelPtr[3];

		/*
		 * Ignore pixels that are fully transparent
		 */







|







516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
    if (bgImg->depth < 24) {
	unsigned char red_mlen, green_mlen, blue_mlen;

	red_mlen = 8 - CountBits(red_mask >> red_shift);
	green_mlen = 8 - CountBits(green_mask >> green_shift);
	blue_mlen = 8 - CountBits(blue_mask >> blue_shift);
	for (y = 0; y < height; y++) {
	    line = (y + yOffset) * iPtr->masterPtr->width;
	    for (x = 0; x < width; x++) {
		modelPtr = alphaAr + ((line + x + xOffset) * 4);
		alpha = modelPtr[3];

		/*
		 * Ignore pixels that are fully transparent
		 */
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
	    }
	}
	return;
    }
#endif /* !_WIN32 */

    for (y = 0; y < height; y++) {
	line = (y + yOffset) * iPtr->modelPtr->width;
	for (x = 0; x < width; x++) {
	    modelPtr = alphaAr + ((line + x + xOffset) * 4);
	    alpha = modelPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */







|







559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
	    }
	}
	return;
    }
#endif /* !_WIN32 */

    for (y = 0; y < height; y++) {
	line = (y + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    modelPtr = alphaAr + ((line + x + xOffset) * 4);
	    alpha = modelPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
		}
		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.







|







599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
		}
		XPutPixel(bgImg, x, y, RGB(r, g, b));
	    }
	}
    }
#undef ALPHA_BLEND
}
#endif /* TK_CAN_RENDER_RGBA */

/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
638
639
640
641
642
643
644
645

646
647
648
649
650
651
652
653
654
655
    int imageX, int imageY,	/* Upper-left corner of region within image to
				 * draw. */
    int width, int height,	/* Dimensions of region within image to
				 * draw. */
    int drawableX,int drawableY)/* Coordinates within drawable that correspond
				 * to imageX and imageY. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
#ifndef TKPUTIMAGE_CAN_BLEND
    XVisualInfo visInfo = instancePtr->visualInfo;
#endif

    /*
     * If there's no pixmap, it means that an error occurred while creating
     * the image instance so it can't be displayed.
     */

    if (instancePtr->pixels == None) {
	return;
    }

#ifdef TKPUTIMAGE_CAN_BLEND

    /*
     * If TkPutImage can handle RGBA Ximages directly there is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     */

    unsigned char *rgbaPixels = instancePtr->modelPtr->pix32;
    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);

#else

    if ((instancePtr->modelPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.c_class == DirectColor || visInfo.c_class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

	/*
	 * Create an error handler to suppress the case where the input was







|
|












|
>

|



|




|




>


|







630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
    int imageX, int imageY,	/* Upper-left corner of region within image to
				 * draw. */
    int width, int height,	/* Dimensions of region within image to
				 * draw. */
    int drawableX,int drawableY)/* Coordinates within drawable that correspond
				 * to imageX and imageY. */
{
    PhotoInstance *instancePtr = 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->masterPtr->pix32;
    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkpPutRGBAImage(display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);

#else

    if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.c_class == DirectColor || visInfo.c_class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

	/*
	 * Create an error handler to suppress the case where the input was
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
	TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
		bgImg, 0, 0, drawableX, drawableY,
		(unsigned int) width, (unsigned int) height);
	XDestroyImage(bgImg);
	Tk_DeleteErrorHandler(handler);
    } else {
	/*
	 * modelPtr->region describes which parts of the image contain valid
	 * data. We set this region as the clip mask for the gc, setting its
	 * origin appropriately, and use it when drawing the image.
	 */

    fallBack:
	TkSetRegion(display, instancePtr->gc,
		instancePtr->modelPtr->validRegion);
	XSetClipOrigin(display, instancePtr->gc, drawableX - imageX,
		drawableY - imageY);
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);







|






|







705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
	TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
		bgImg, 0, 0, drawableX, drawableY,
		(unsigned int) width, (unsigned int) height);
	XDestroyImage(bgImg);
	Tk_DeleteErrorHandler(handler);
    } else {
	/*
	 * modelPtr->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->masterPtr->validRegion);
	XSetClipOrigin(display, instancePtr->gc, drawableX - imageX,
		drawableY - imageY);
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
void
TkImgPhotoFree(
    ClientData clientData,	/* Pointer to PhotoInstance structure for
				 * instance to be displayed. */
    Display *display)		/* Display containing window that used
				 * image. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    ColorTable *colorPtr;
    (void)display;

    if (instancePtr->refCount-- > 1) {
	return;
    }

    /*
     * There are no more uses of the image within this widget. Decrement the
     * count of live uses of its color table, so that its colors can be
     * reclaimed if necessary, and set up an idle call to free the instance
     * structure.
     */

    colorPtr = instancePtr->colorTablePtr;
    if (colorPtr != NULL) {
	colorPtr->liveRefCount--;
    }

    Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr);
}

/*
 *----------------------------------------------------------------------







|

<














|







750
751
752
753
754
755
756
757
758

759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
void
TkImgPhotoFree(
    ClientData clientData,	/* Pointer to PhotoInstance structure for
				 * instance to be displayed. */
    Display *display)		/* Display containing window that used
				 * image. */
{
    PhotoInstance *instancePtr = clientData;
    ColorTable *colorPtr;


    if (instancePtr->refCount-- > 1) {
	return;
    }

    /*
     * There are no more uses of the image within this widget. Decrement the
     * count of live uses of its color table, so that its colors can be
     * reclaimed if necessary, and set up an idle call to free the instance
     * structure.
     */

    colorPtr = instancePtr->colorTablePtr;
    if (colorPtr != NULL) {
	colorPtr->liveRefCount -= 1;
    }

    Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr);
}

/*
 *----------------------------------------------------------------------
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
{
    PhotoModel *modelPtr;
    schar *newError, *errSrcPtr, *errDestPtr;
    int h, offset;
    XRectangle validBox;
    Pixmap newPixmap;

    modelPtr = instancePtr->modelPtr;
    TkClipBox(modelPtr->validRegion, &validBox);

    if ((instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)
	    || (instancePtr->pixels == None)) {
	newPixmap = Tk_GetPixmap(instancePtr->display,
		RootWindow(instancePtr->display,







|







800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
{
    PhotoModel *modelPtr;
    schar *newError, *errSrcPtr, *errDestPtr;
    int h, offset;
    XRectangle validBox;
    Pixmap newPixmap;

    modelPtr = instancePtr->masterPtr;
    TkClipBox(modelPtr->validRegion, &validBox);

    if ((instancePtr->width != modelPtr->width)
	    || (instancePtr->height != modelPtr->height)
	    || (instancePtr->pixels == None)) {
	newPixmap = Tk_GetPixmap(instancePtr->display,
		RootWindow(instancePtr->display,
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
	if (modelPtr->height > 0 && modelPtr->width > 0) {
	    /*
	     * TODO: use attemptckalloc() here once there is a strategy that
	     * will allow us to recover from failure. Right now, there's no
	     * such possibility.
	     */

	    newError = (schar *)ckalloc(modelPtr->height * modelPtr->width
		    * 3 * sizeof(schar));

	    /*
	     * Zero the new array so that we don't get bogus error values
	     * propagating into areas we dither later.
	     */








|







850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
	if (modelPtr->height > 0 && modelPtr->width > 0) {
	    /*
	     * TODO: use attemptckalloc() here once there is a strategy that
	     * will allow us to recover from failure. Right now, there's no
	     * such possibility.
	     */

	    newError = ckalloc(modelPtr->height * modelPtr->width
		    * 3 * sizeof(schar));

	    /*
	     * Zero the new array so that we don't get bogus error values
	     * propagating into areas we dither later.
	     */

866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
	     * Copy the common area over to the new array and free the old
	     * array.
	     */

	    if (modelPtr->width == instancePtr->width) {
		offset = validBox.y * modelPtr->width * 3;
		memcpy(newError + offset, instancePtr->error + offset,
			(size_t) validBox.height
			* modelPtr->width * 3 * sizeof(schar));

	    } else if (validBox.width > 0 && validBox.height > 0) {
		errDestPtr = newError +
			(validBox.y * modelPtr->width + validBox.x) * 3;
		errSrcPtr = instancePtr->error +
			(validBox.y * instancePtr->width + validBox.x) * 3;








|
|







888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
	     * Copy the common area over to the new array and free the old
	     * array.
	     */

	    if (modelPtr->width == instancePtr->width) {
		offset = validBox.y * modelPtr->width * 3;
		memcpy(newError + offset, instancePtr->error + offset,
			(size_t) (validBox.height
			* modelPtr->width * 3 * sizeof(schar)));

	    } else if (validBox.width > 0 && validBox.height > 0) {
		errDestPtr = newError +
			(validBox.y * modelPtr->width + validBox.x) * 3;
		errSrcPtr = instancePtr->error +
			(validBox.y * instancePtr->width + validBox.x) * 3;

995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CountBits(
    unsigned mask)			/* Value to count the 1 bits in. */
{
    int n;

    for (n=0 ; mask!=0 ; mask&=mask-1) {
	n++;
    }
    return n;







|







1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
CountBits(
    pixel mask)			/* Value to count the 1 bits in. */
{
    int n;

    for (n=0 ; mask!=0 ; mask&=mask-1) {
	n++;
    }
    return n;
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
    entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew);

    if (!isNew) {
	/*
	 * Re-use the existing entry.
	 */

	colorPtr = (ColorTable *)Tcl_GetHashValue(entry);
    } else {
	/*
	 * No color table currently available; need to make one.
	 */

	colorPtr = (ColorTable *)ckalloc(sizeof(ColorTable));

	/*
	 * The following line of code should not normally be needed due to the
	 * assignment in the following line. However, it compensates for bugs
	 * in some compilers (HP, for example) where sizeof(ColorTable) is 24
	 * but the assignment only copies 20 bytes, leaving 4 bytes
	 * uninitialized; these cause problems when using the id for lookups







|





|







1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
    entry = Tcl_CreateHashEntry(&imgPhotoColorHash, (char *) &id, &isNew);

    if (!isNew) {
	/*
	 * Re-use the existing entry.
	 */

	colorPtr = Tcl_GetHashValue(entry);
    } else {
	/*
	 * No color table currently available; need to make one.
	 */

	colorPtr = ckalloc(sizeof(ColorTable));

	/*
	 * The following line of code should not normally be needed due to the
	 * assignment in the following line. However, it compensates for bugs
	 * in some compilers (HP, for example) where sizeof(ColorTable) is 24
	 * but the assignment only copies 20 bytes, leaving 4 bytes
	 * uninitialized; these cause problems when using the id for lookups
1127
1128
1129
1130
1131
1132
1133

1134
1135
1136
1137
1138
1139
1140
1141

static void
FreeColorTable(
    ColorTable *colorPtr,	/* Pointer to the color table which is no
				 * longer required by an instance. */
    int force)			/* Force free to happen immediately. */
{

    if (colorPtr->refCount-- > 1) {
	return;
    }

    if (force) {
	if (colorPtr->flags & DISPOSE_PENDING) {
	    Tcl_CancelIdleCall(DisposeColorTable, colorPtr);
	    colorPtr->flags &= ~DISPOSE_PENDING;







>
|







1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164

static void
FreeColorTable(
    ColorTable *colorPtr,	/* Pointer to the color table which is no
				 * longer required by an instance. */
    int force)			/* Force free to happen immediately. */
{
    colorPtr->refCount--;
    if (colorPtr->refCount > 0) {
	return;
    }

    if (force) {
	if (colorPtr->flags & DISPOSE_PENDING) {
	    Tcl_CancelIdleCall(DisposeColorTable, colorPtr);
	    colorPtr->flags &= ~DISPOSE_PENDING;
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
	     */

	    if (mono) {
		numColors = nGreen = nBlue = nRed;
	    } else {
		numColors = MAX(MAX(nRed, nGreen), nBlue);
	    }
	    colors = (XColor *)ckalloc(numColors * sizeof(XColor));

	    for (i = 0; i < numColors; ++i) {
		if (igam == 1.0) {
		    colors[i].red = CFRAC(i, nRed - 1);
		    colors[i].green = CFRAC(i, nGreen - 1);
		    colors[i].blue = CFRAC(i, nBlue - 1);
		} else {
		    colors[i].red = CGFRAC(i, nRed - 1, igam);
		    colors[i].green = CGFRAC(i, nGreen - 1, igam);
		    colors[i].blue = CGFRAC(i, nBlue - 1, igam);
		}
	    }
	} else {
	    /*
	     * PseudoColor, StaticColor, GrayScale or StaticGray visual: we
	     * have to allocate each color in the color cube separately.
	     */

	    numColors = (mono) ? nRed: (nRed * nGreen * nBlue);
	    colors = (XColor *)ckalloc(numColors * sizeof(XColor));

	    if (!mono) {
		/*
		 * Color display using a PseudoColor or StaticColor visual.
		 */

		i = 0;







|



















|







1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
	     */

	    if (mono) {
		numColors = nGreen = nBlue = nRed;
	    } else {
		numColors = MAX(MAX(nRed, nGreen), nBlue);
	    }
	    colors = ckalloc(numColors * sizeof(XColor));

	    for (i = 0; i < numColors; ++i) {
		if (igam == 1.0) {
		    colors[i].red = CFRAC(i, nRed - 1);
		    colors[i].green = CFRAC(i, nGreen - 1);
		    colors[i].blue = CFRAC(i, nBlue - 1);
		} else {
		    colors[i].red = CGFRAC(i, nRed - 1, igam);
		    colors[i].green = CGFRAC(i, nGreen - 1, igam);
		    colors[i].blue = CGFRAC(i, nBlue - 1, igam);
		}
	    }
	} else {
	    /*
	     * PseudoColor, StaticColor, GrayScale or StaticGray visual: we
	     * have to allocate each color in the color cube separately.
	     */

	    numColors = (mono) ? nRed: (nRed * nGreen * nBlue);
	    colors = ckalloc(numColors * sizeof(XColor));

	    if (!mono) {
		/*
		 * Color display using a PseudoColor or StaticColor visual.
		 */

		i = 0;
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
	    }
	}

	/*
	 * Now try to allocate the colors we've calculated.
	 */

	pixels = (unsigned long *)ckalloc(numColors * sizeof(unsigned long));
	for (i = 0; i < numColors; ++i) {
	    if (!XAllocColor(colorPtr->id.display, colorPtr->id.colormap,
		    &colors[i])) {
		/*
		 * Can't get all the colors we want in the default colormap;
		 * first try freeing colors from other unused color tables.
		 */







|







1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
	    }
	}

	/*
	 * Now try to allocate the colors we've calculated.
	 */

	pixels = ckalloc(numColors * sizeof(unsigned long));
	for (i = 0; i < numColors; ++i) {
	    if (!XAllocColor(colorPtr->id.display, colorPtr->id.colormap,
		    &colors[i])) {
		/*
		 * Can't get all the colors we want in the default colormap;
		 * first try freeing colors from other unused color tables.
		 */
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
 */

static void
DisposeColorTable(
    ClientData clientData)	/* Pointer to the ColorTable whose
				 * colors are to be released. */
{
    ColorTable *colorPtr = (ColorTable *)clientData;
    Tcl_HashEntry *entry;

    if (colorPtr->pixelMap != NULL) {
	if (colorPtr->numColors > 0) {
	    XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
		    colorPtr->pixelMap, colorPtr->numColors, 0);
	    Tk_FreeColormap(colorPtr->id.display, colorPtr->id.colormap);
	}
	ckfree(colorPtr->pixelMap);
    }

    entry = Tcl_FindHashEntry(&imgPhotoColorHash, &colorPtr->id);
    if (entry == NULL) {
	Tcl_Panic("DisposeColorTable couldn't find hash entry");
    }
    Tcl_DeleteHashEntry(entry);

    ckfree(colorPtr);
}







|











|







1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
 */

static void
DisposeColorTable(
    ClientData clientData)	/* Pointer to the ColorTable whose
				 * colors are to be released. */
{
    ColorTable *colorPtr = clientData;
    Tcl_HashEntry *entry;

    if (colorPtr->pixelMap != NULL) {
	if (colorPtr->numColors > 0) {
	    XFreeColors(colorPtr->id.display, colorPtr->id.colormap,
		    colorPtr->pixelMap, colorPtr->numColors, 0);
	    Tk_FreeColormap(colorPtr->id.display, colorPtr->id.colormap);
	}
	ckfree(colorPtr->pixelMap);
    }

    entry = Tcl_FindHashEntry(&imgPhotoColorHash, (char *) &colorPtr->id);
    if (entry == NULL) {
	Tcl_Panic("DisposeColorTable couldn't find hash entry");
    }
    Tcl_DeleteHashEntry(entry);

    ckfree(colorPtr);
}
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
    /*
     * First scan through the color hash table to get an upper bound on how
     * many colors we might be able to free.
     */

    entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
    while (entry != NULL) {
	colorPtr = (ColorTable *)Tcl_GetHashValue(entry);
	if ((colorPtr->id.display == id->display)
		&& (colorPtr->id.colormap == id->colormap)
		&& (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0)
		&& ((colorPtr->id.palette != id->palette)
			|| (colorPtr->id.gamma != id->gamma))) {
	    /*
	     * We could take this guy's colors off him.







|







1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
    /*
     * First scan through the color hash table to get an upper bound on how
     * many colors we might be able to free.
     */

    entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
    while (entry != NULL) {
	colorPtr = Tcl_GetHashValue(entry);
	if ((colorPtr->id.display == id->display)
		&& (colorPtr->id.colormap == id->colormap)
		&& (colorPtr->liveRefCount == 0 )&& (colorPtr->numColors != 0)
		&& ((colorPtr->id.palette != id->palette)
			|| (colorPtr->id.gamma != id->gamma))) {
	    /*
	     * We could take this guy's colors off him.
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551

    /*
     * Scan through a second time freeing colors.
     */

    entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
    while ((entry != NULL) && (numColors > 0)) {
	colorPtr = (ColorTable *)Tcl_GetHashValue(entry);
	if ((colorPtr->id.display == id->display)
		&& (colorPtr->id.colormap == id->colormap)
		&& (colorPtr->liveRefCount == 0) && (colorPtr->numColors != 0)
		&& ((colorPtr->id.palette != id->palette)
			|| (colorPtr->id.gamma != id->gamma))) {
	    /*
	     * Free the colors that this ColorTable has.







|







1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574

    /*
     * Scan through a second time freeing colors.
     */

    entry = Tcl_FirstHashEntry(&imgPhotoColorHash, &srch);
    while ((entry != NULL) && (numColors > 0)) {
	colorPtr = Tcl_GetHashValue(entry);
	if ((colorPtr->id.display == id->display)
		&& (colorPtr->id.colormap == id->colormap)
		&& (colorPtr->liveRefCount == 0) && (colorPtr->numColors != 0)
		&& ((colorPtr->id.palette != id->palette)
			|| (colorPtr->id.gamma != id->gamma))) {
	    /*
	     * Free the colors that this ColorTable has.
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
 */

void
TkImgDisposeInstance(
    ClientData clientData)	/* Pointer to the instance whose resources are
				 * to be released. */
{
    PhotoInstance *instancePtr = (PhotoInstance *)clientData;
    PhotoInstance *prevPtr;

    if (instancePtr->pixels != None) {
	Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
    }
    if (instancePtr->gc != NULL) {
	Tk_FreeGC(instancePtr->display, instancePtr->gc);
    }
    if (instancePtr->imagePtr != NULL) {
	XDestroyImage(instancePtr->imagePtr);
    }
    if (instancePtr->error != NULL) {
	ckfree(instancePtr->error);
    }
    if (instancePtr->colorTablePtr != NULL) {
	FreeColorTable(instancePtr->colorTablePtr, 1);
    }

    if (instancePtr->modelPtr->instancePtr == instancePtr) {
	instancePtr->modelPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->modelPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body. */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    Tk_FreeColormap(instancePtr->display, instancePtr->colormap);
    ckfree(instancePtr);







|


















|
|

|







1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
 */

void
TkImgDisposeInstance(
    ClientData clientData)	/* Pointer to the instance whose resources are
				 * to be released. */
{
    PhotoInstance *instancePtr = clientData;
    PhotoInstance *prevPtr;

    if (instancePtr->pixels != None) {
	Tk_FreePixmap(instancePtr->display, instancePtr->pixels);
    }
    if (instancePtr->gc != NULL) {
	Tk_FreeGC(instancePtr->display, instancePtr->gc);
    }
    if (instancePtr->imagePtr != NULL) {
	XDestroyImage(instancePtr->imagePtr);
    }
    if (instancePtr->error != NULL) {
	ckfree(instancePtr->error);
    }
    if (instancePtr->colorTablePtr != NULL) {
	FreeColorTable(instancePtr->colorTablePtr, 1);
    }

    if (instancePtr->masterPtr->instancePtr == instancePtr) {
	instancePtr->masterPtr->instancePtr = instancePtr->nextPtr;
    } else {
	for (prevPtr = instancePtr->masterPtr->instancePtr;
		prevPtr->nextPtr != instancePtr; prevPtr = prevPtr->nextPtr) {
	    /* Empty loop body. */
	}
	prevPtr->nextPtr = instancePtr->nextPtr;
    }
    Tk_FreeColormap(instancePtr->display, instancePtr->colormap);
    ckfree(instancePtr);
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
void
TkImgDitherInstance(
    PhotoInstance *instancePtr,	/* The instance to be updated. */
    int xStart, int yStart,	/* Coordinates of the top-left pixel in the
				 * block to be dithered. */
    int width, int height)	/* Dimensions of the block to be dithered. */
{
    PhotoModel *modelPtr = instancePtr->modelPtr;
    ColorTable *colorPtr = instancePtr->colorTablePtr;
    XImage *imagePtr;
    int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1;
    int bitsPerPixel, bytesPerLine, lineLength;
    unsigned char *srcLinePtr;
    schar *errLinePtr;
    unsigned firstBit, word, mask;

    /*
     * Turn dithering off in certain cases where it is not needed (TrueColor,
     * DirectColor with many colors).
     */

    if ((colorPtr->visualInfo.c_class == DirectColor)







|






|







1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
void
TkImgDitherInstance(
    PhotoInstance *instancePtr,	/* The instance to be updated. */
    int xStart, int yStart,	/* Coordinates of the top-left pixel in the
				 * block to be dithered. */
    int width, int height)	/* Dimensions of the block to be dithered. */
{
    PhotoModel *modelPtr = instancePtr->masterPtr;
    ColorTable *colorPtr = instancePtr->colorTablePtr;
    XImage *imagePtr;
    int nLines, bigEndian, i, c, x, y, xEnd, doDithering = 1;
    int bitsPerPixel, bytesPerLine, lineLength;
    unsigned char *srcLinePtr;
    schar *errLinePtr;
    pixel firstBit, word, mask;

    /*
     * Turn dithering off in certain cases where it is not needed (TrueColor,
     * DirectColor with many colors).
     */

    if ((colorPtr->visualInfo.c_class == DirectColor)
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
    imagePtr->bytes_per_line = bytesPerLine;

    /*
     * TODO: use attemptckalloc() here once we have some strategy for
     * recovering from the failure.
     */

    imagePtr->data = (char *)ckalloc(imagePtr->bytes_per_line * nLines);
    bigEndian = imagePtr->bitmap_bit_order == MSBFirst;
    firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1;

    lineLength = modelPtr->width * 3;
    srcLinePtr = modelPtr->pix32 + (yStart * modelPtr->width + xStart) * 4;
    errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3;
    xEnd = xStart + width;







|







1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
    imagePtr->bytes_per_line = bytesPerLine;

    /*
     * TODO: use attemptckalloc() here once we have some strategy for
     * recovering from the failure.
     */

    imagePtr->data = ckalloc(imagePtr->bytes_per_line * nLines);
    bigEndian = imagePtr->bitmap_bit_order == MSBFirst;
    firstBit = bigEndian? (1 << (imagePtr->bitmap_unit - 1)): 1;

    lineLength = modelPtr->width * 3;
    srcLinePtr = modelPtr->pix32 + (yStart * modelPtr->width + xStart) * 4;
    errLinePtr = instancePtr->error + yStart * lineLength + xStart * 3;
    xEnd = xStart + width;
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
	    nLines = height;
	}
	yEnd = yStart + nLines;
	for (y = yStart; y < yEnd; ++y) {
	    unsigned char *srcPtr = srcLinePtr;
	    schar *errPtr = errLinePtr;
	    unsigned char *destBytePtr = dstLinePtr;
	    unsigned *destLongPtr = (unsigned *) dstLinePtr;

	    if (colorPtr->flags & COLOR_WINDOW) {
		/*
		 * Color window. We dither the three components independently,
		 * using Floyd-Steinberg dithering, which propagates errors
		 * from the quantization of pixels to the pixels below and to
		 * the right.







|







1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
	    nLines = height;
	}
	yEnd = yStart + nLines;
	for (y = yStart; y < yEnd; ++y) {
	    unsigned char *srcPtr = srcLinePtr;
	    schar *errPtr = errLinePtr;
	    unsigned char *destBytePtr = dstLinePtr;
	    pixel *destLongPtr = (pixel *) dstLinePtr;

	    if (colorPtr->flags & COLOR_WINDOW) {
		/*
		 * Color window. We dither the three components independently,
		 * using Floyd-Steinberg dithering, which propagates errors
		 * from the quantization of pixels to the pixels below and to
		 * the right.
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
			 * image format is different from the pixel format in
			 * Win32. Eventually we need to fix the image code in
			 * Tk to use the Windows native image ordering. This
			 * would speed up the image code for all of the common
			 * sizes.
			 */

		    case NBBY * sizeof(unsigned):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }







|







1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
			 * image format is different from the pixel format in
			 * Win32. Eventually we need to fix the image code in
			 * Tk to use the Windows native image ordering. This
			 * would speed up the image code for all of the common
			 * sizes.
			 */

		    case NBBY * sizeof(pixel):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
			 * image format is different from the pixel format in
			 * Win32. Eventually we need to fix the image code in
			 * Tk to use the Windows native image ordering. This
			 * would speed up the image code for all of the common
			 * sizes.
			 */

		    case NBBY * sizeof(unsigned):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }







|







1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
			 * image format is different from the pixel format in
			 * Win32. Eventually we need to fix the image code in
			 * Tk to use the Windows native image ordering. This
			 * would speed up the image code for all of the common
			 * sizes.
			 */

		    case NBBY * sizeof(pixel):
			*destLongPtr++ = i;
			break;
#endif
		    default:
			XPutPixel(imagePtr, x - xStart, y - yStart,
				(unsigned) i);
		    }
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999

void
TkImgResetDither(
    PhotoInstance *instancePtr)
{
    if (instancePtr->error) {
	memset(instancePtr->error, 0,
		(size_t) instancePtr->modelPtr->width
		* instancePtr->modelPtr->height * 3 * sizeof(schar));
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|










2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022

void
TkImgResetDither(
    PhotoInstance *instancePtr)
{
    if (instancePtr->error) {
	memset(instancePtr->error, 0,
	       /*(size_t)*/ (instancePtr->masterPtr->width
		* instancePtr->masterPtr->height * 3 * sizeof(schar)));
    }
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkImgPhoto.c.
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*
 * Bit definitions for use with ParseSubcommandOptions: each bit is set in the
 * allowedOptions parameter on a call to ParseSubcommandOptions if that option
 * is allowed for the current photo image subcommand. On return, the bit is
 * set in the options field of the SubcommandOptions structure if that option
 * was specified.
 *
 * OPT_ALPHA:			Set if -alpha option allowed/specified.
 * OPT_BACKGROUND:		Set if -format option allowed/specified.
 * OPT_COMPOSITE:		Set if -compositingrule option allowed/spec'd.
 * OPT_FORMAT:			Set if -format option allowed/specified.
 * OPT_FROM:			Set if -from option allowed/specified.
 * OPT_GRAYSCALE:		Set if -grayscale option allowed/specified.
 * OPT_SHRINK:			Set if -shrink option allowed/specified.
 * OPT_SUBSAMPLE:		Set if -subsample option allowed/spec'd.
 * OPT_TO:			Set if -to option allowed/specified.
 * OPT_WITHALPHA:		Set if -withalpha option allowed/specified.
 * OPT_ZOOM:			Set if -zoom option allowed/specified.
 */

#define OPT_ALPHA	1
#define OPT_BACKGROUND	2
#define OPT_COMPOSITE	4
#define OPT_FORMAT	8
#define OPT_FROM	0x10
#define OPT_GRAYSCALE	0x20
#define OPT_SHRINK	0x40
#define OPT_SUBSAMPLE	0x80
#define OPT_TO		0x100
#define OPT_WITHALPHA	0x200
#define OPT_ZOOM	0x400

/*
 * List of option names. The order here must match the order of declarations
 * of the OPT_* constants above.
 */

static const char *const optionNames[] = {
    "-alpha",
    "-background",
    "-compositingrule",
    "-format",
    "-from",
    "-grayscale",
    "-shrink",
    "-subsample",
    "-to",
    "-withalpha",
    "-zoom",
    NULL
};

/*
 * Message to generate when an attempt to resize an image fails due to memory
 * problems.
 */

#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
	"not enough free memory for image buffer"

/*
 * Functions used in the type record for photo images.
 */

static int		ImgPhotoCreate(Tcl_Interp *interp, const char *name,
			    int objc, Tcl_Obj *const objv[],
			    const Tk_ImageType *typePtr, Tk_ImageModel model,
			    ClientData *clientDataPtr);
static void		ImgPhotoDelete(ClientData clientData);
static int		ImgPhotoPostscript(ClientData clientData,
			    Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, int x, int y, int width,
			    int height, int prepass);

/*
 * The type record itself for photo images:
 */







<








<



<
|
|
|
|
|
|
|
|
<
|







<








<



















|
|
|







44
45
46
47
48
49
50

51
52
53
54
55
56
57
58

59
60
61

62
63
64
65
66
67
68
69

70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
 * Bit definitions for use with ParseSubcommandOptions: each bit is set in the
 * allowedOptions parameter on a call to ParseSubcommandOptions if that option
 * is allowed for the current photo image subcommand. On return, the bit is
 * set in the options field of the SubcommandOptions structure if that option
 * was specified.
 *

 * OPT_BACKGROUND:		Set if -format option allowed/specified.
 * OPT_COMPOSITE:		Set if -compositingrule option allowed/spec'd.
 * OPT_FORMAT:			Set if -format option allowed/specified.
 * OPT_FROM:			Set if -from option allowed/specified.
 * OPT_GRAYSCALE:		Set if -grayscale option allowed/specified.
 * OPT_SHRINK:			Set if -shrink option allowed/specified.
 * OPT_SUBSAMPLE:		Set if -subsample option allowed/spec'd.
 * OPT_TO:			Set if -to option allowed/specified.

 * OPT_ZOOM:			Set if -zoom option allowed/specified.
 */


#define OPT_BACKGROUND	1
#define OPT_COMPOSITE	2
#define OPT_FORMAT	4
#define OPT_FROM	8
#define OPT_GRAYSCALE	0x10
#define OPT_SHRINK	0x20
#define OPT_SUBSAMPLE	0x40
#define OPT_TO		0x80

#define OPT_ZOOM	0x100

/*
 * List of option names. The order here must match the order of declarations
 * of the OPT_* constants above.
 */

static const char *const optionNames[] = {

    "-background",
    "-compositingrule",
    "-format",
    "-from",
    "-grayscale",
    "-shrink",
    "-subsample",
    "-to",

    "-zoom",
    NULL
};

/*
 * Message to generate when an attempt to resize an image fails due to memory
 * problems.
 */

#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \
	"not enough free memory for image buffer"

/*
 * Functions used in the type record for photo images.
 */

static int		ImgPhotoCreate(Tcl_Interp *interp, const char *name,
			    int 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
    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);







<



<



















>
>

|
>
>

|

|

|

|







|
|





|






>
>
>







125
126
127
128
129
130
131

132
133
134

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

typedef struct {
    Tk_PhotoImageFormat *formatList;
				/* Pointer to the first in the list of known
				 * photo image formats.*/

    Tk_PhotoImageFormat *oldFormatList;
				/* Pointer to the first in the list of known
				 * photo image formats.*/

    int initialized;		/* Set to 1 if we've initialized the
				 * structure. */
} ThreadSpecificData;
static Tcl_ThreadDataKey dataKey;

/*
 * Default configuration
 */

#define DEF_PHOTO_GAMMA		"1"
#define DEF_PHOTO_HEIGHT	"0"
#define DEF_PHOTO_PALETTE	""
#define DEF_PHOTO_WIDTH		"0"

/*
 * Information used for parsing configuration specifications:
 */

static const Tk_ConfigSpec configSpecs[] = {
    {TK_CONFIG_STRING, "-data", NULL, NULL,
	 NULL, -1, TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-file", NULL, NULL,
	 NULL, Tk_Offset(PhotoModel, fileString), TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_STRING, "-format", NULL, NULL,
	 NULL, -1, TK_CONFIG_NULL_OK, NULL},
    {TK_CONFIG_DOUBLE, "-gamma", NULL, NULL,
	 DEF_PHOTO_GAMMA, Tk_Offset(PhotoModel, gamma), 0, NULL},
    {TK_CONFIG_INT, "-height", NULL, NULL,
	 DEF_PHOTO_HEIGHT, Tk_Offset(PhotoModel, userHeight), 0, NULL},
    {TK_CONFIG_UID, "-palette", NULL, NULL,
	 DEF_PHOTO_PALETTE, Tk_Offset(PhotoModel, palette), 0, NULL},
    {TK_CONFIG_INT, "-width", NULL, NULL,
	 DEF_PHOTO_WIDTH, Tk_Offset(PhotoModel, userWidth), 0, NULL},
    {TK_CONFIG_END, NULL, NULL, NULL, NULL, 0, 0, NULL}
};

/*
 * Forward declarations
 */

static void		PhotoFormatThreadExitProc(void *clientData);
static int		ImgPhotoCmd(void *clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);
static int		ParseSubcommandOptions(
			    struct SubcommandOptions *optPtr,
			    Tcl_Interp *interp, int allowedOptions,
			    int *indexPtr, int objc, Tcl_Obj *const objv[]);
static void		ImgPhotoCmdDeletedProc(void *clientData);
static int		ImgPhotoConfigureModel(Tcl_Interp *interp,
			    PhotoModel *modelPtr, int objc,
			    Tcl_Obj *const objv[], int flags);
static int		ToggleComplexAlphaIfNeeded(PhotoModel *mPtr);
static int		ImgPhotoSetSize(PhotoModel *modelPtr, int width,
			    int height);
static int		ImgStringWrite(Tcl_Interp *interp,
			    Tcl_Obj *formatString,
			    Tk_PhotoImageBlock *blockPtr);
static char *		ImgGetPhoto(PhotoModel *modelPtr,
			    Tk_PhotoImageBlock *blockPtr,
			    struct SubcommandOptions *optPtr);
static int		MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *formatString,
			    Tk_PhotoImageFormat **imageFormatPtr,
			    int *widthPtr, int *heightPtr, int *oldformat);
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
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);
    }
}







<





<







222
223
224
225
226
227
228

229
230
231
232
233

234
235
236
237
238
239
240
PhotoFormatThreadExitProc(
    TCL_UNUSED(void *))	/* not used */
{
    Tk_PhotoImageFormat *freePtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));


    while (tsdPtr->oldFormatList != NULL) {
	freePtr = tsdPtr->oldFormatList;
	tsdPtr->oldFormatList = tsdPtr->oldFormatList->nextPtr;
	ckfree(freePtr);
    }

    while (tsdPtr->formatList != NULL) {
	freePtr = tsdPtr->formatList;
	tsdPtr->formatList = tsdPtr->formatList->nextPtr;
	ckfree((char *)freePtr->name);
	ckfree(freePtr);
    }
}
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
 * 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;
    }







<




















<


















<



|
<
<







254
255
256
257
258
259
260

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

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298

299
300
301
302


303
304
305
306
307
308
309
 * Side effects:
 *	The new image file format is entered into a table used in the photo
 *	image "read" and "write" subcommands.
 *
 *----------------------------------------------------------------------
 */


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


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 (isupper((unsigned char) *formatPtr->name)) {
	copyPtr->nextPtr = tsdPtr->oldFormatList;
	tsdPtr->oldFormatList = copyPtr;
    } else {


	/* for compatibility with aMSN: make a copy of formatPtr->name */
	char *name = (char *)ckalloc(strlen(formatPtr->name) + 1);
	strcpy(name, formatPtr->name);
	copyPtr->name = name;
	copyPtr->nextPtr = tsdPtr->formatList;
	tsdPtr->formatList = copyPtr;
    }
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
    const char *name,		/* Name to use for image. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    ClientData *clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    PhotoModel *modelPtr;

    /*
     * Allocate and initialize the photo image model record.
     */

    modelPtr = (PhotoModel *)ckalloc(sizeof(PhotoModel));
    memset(modelPtr, 0, sizeof(PhotoModel));
    modelPtr->tkModel = model;
    modelPtr->interp = interp;
    modelPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
	    modelPtr, ImgPhotoCmdDeletedProc);
    modelPtr->palette = NULL;
    modelPtr->pix32 = NULL;
    modelPtr->instancePtr = NULL;
    modelPtr->validRegion = TkCreateRegion();







|










|







333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
    const char *name,		/* Name to use for image. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[],	/* Argument objects for options (doesn't
				 * include image name or type). */
    TCL_UNUSED(const Tk_ImageType *),/* Pointer to our type record (not used). */
    Tk_ImageModel model,	/* Token for image, to be used by us in later
				 * callbacks. */
    void **clientDataPtr)	/* Store manager's token for image here; it
				 * will be returned in later callbacks. */
{
    PhotoModel *modelPtr;

    /*
     * Allocate and initialize the photo image model record.
     */

    modelPtr = (PhotoModel *)ckalloc(sizeof(PhotoModel));
    memset(modelPtr, 0, sizeof(PhotoModel));
    modelPtr->tkMaster = model;
    modelPtr->interp = interp;
    modelPtr->imageCmd = Tcl_CreateObjCommand(interp, name, ImgPhotoCmd,
	    modelPtr, ImgPhotoCmdDeletedProc);
    modelPtr->palette = NULL;
    modelPtr->pix32 = NULL;
    modelPtr->instancePtr = NULL;
    modelPtr->validRegion = TkCreateRegion();
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417

418

419
420

421
422
423
424
425
426
427
428
429
 *	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) {







|















|
>

>


>

|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgPhotoCmd(
    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, dataWidth, dataHeight, listObjc;
    int index;
    struct SubcommandOptions options;
    Tcl_Obj **listObjv, **srcObjv;
    unsigned char *pixelPtr;
    Tk_PhotoImageBlock block;
    Tk_Window tkwin;
    Tk_PhotoImageFormat *imageFormat;
    int length;
    int imageWidth, imageHeight, matched, oldformat = 0;
    Tcl_Channel chan;
    Tk_PhotoHandle srcHandle;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
453
454
455
456
457
458
459
460

461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510

511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
    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 {







|
>










|













|








|






|







|

>

|








|




|








|







448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
    case PHOTO_CGET: {
	const char *arg;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    return TCL_ERROR;
	}
	arg = Tcl_GetString(objv[2]);
	length = objv[2]->length;
	if (strncmp(arg,"-data", length) == 0) {
	    if (modelPtr->dataString) {
		Tcl_SetObjResult(interp, modelPtr->dataString);
	    }
	} else if (strncmp(arg,"-format", length) == 0) {
	    if (modelPtr->format) {
		Tcl_SetObjResult(interp, modelPtr->format);
	    }
	} else {
	    Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs,
		    (char *)modelPtr, Tcl_GetString(objv[2]), 0);
	}
	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, " {}", (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);
	    Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp));
	    Tcl_SetObjResult(interp, obj);
	    return TCL_OK;

	} else if (objc == 3) {
	    const char *arg = Tcl_GetString(objv[2]);

	    length = 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 {
		return Tk_ConfigureInfo(interp, Tk_MainWindow(interp),
			configSpecs, (char *) modelPtr, arg, 0);
	    }
	} else {
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

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







|



|


<
<
<



|







570
571
572
573
574
575
576
577
578
579
580
581
582
583



584
585
586
587
588
589
590
591
592
593
594

	srcHandle = Tk_FindPhoto(interp, Tcl_GetString(options.name));
	if (srcHandle == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image \"%s\" doesn't exist or is not a photo image",
		    Tcl_GetString(options.name)));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO",
		    Tcl_GetString(options.name), (char *)NULL);
	    return TCL_ERROR;
	}
	Tk_PhotoGetImage(srcHandle, &block);
	if ((options.fromX > block.width) || (options.fromY > 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
	    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);







>
|
|
|
|
|
|
|
|
|
>
>
>











<
<
<


|



>
|
|
<
<




|
<







|










|

>
>
>








|
>
>
>











<
<
<
<





>
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<
|
|
|
|
|
|
|
>
|
>
>
>
>
>







629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659



660
661
662
663
664
665
666
667
668


669
670
671
672
673

674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719




720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737

738
739
740
741
742
743
744
745
746
747
748
749
750
751
752

753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
	    options.toY2 = options.toY + height * options.zoomY;
	}

	/*
	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
	 */

	if (block.pixelPtr) {
	    block.pixelPtr += options.fromX * block.pixelSize
		    + options.fromY * block.pitch;
	    block.width = options.fromX2 - options.fromX;
	    block.height = options.fromY2 - options.fromY;
	    result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) modelPtr,
		    &block, options.toX, options.toY, options.toX2 - options.toX,
		    options.toY2 - options.toY, options.zoomX, options.zoomY,
		    options.subsampleX, options.subsampleY,
		    options.compositingRule);
	} 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, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (block.pixelPtr || (options.options & OPT_SHRINK)) {
	    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
		    modelPtr->width, modelPtr->height);


	}
	return result;

    case PHOTO_DATA: {
	char *data;


	/*
	 * photo data command - first parse and check any options given.
	 */

	Tk_ImageStringWriteProc *stringWriteProc = NULL;

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	options.fromX = 0;
	options.fromY = 0;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name != NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?");
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (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;
	}





	/*
	 * Search for an appropriate image string format handler.
	 */

	if (options.options & OPT_FORMAT) {
	    matched = 0;
	    for (imageFormat = tsdPtr->formatList; imageFormat != NULL;
		imageFormat = imageFormat->nextPtr) {
		if ((strncasecmp(Tcl_GetString(options.format),
			imageFormat->name, strlen(imageFormat->name)) == 0)) {
		    matched = 1;
		    if (imageFormat->stringWriteProc != NULL) {
			stringWriteProc = imageFormat->stringWriteProc;
			break;
		    }
		}
	    }

	    if (stringWriteProc == NULL) {
		oldformat = 1;
		for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL;
			imageFormat = imageFormat->nextPtr) {
		    if ((strncasecmp(Tcl_GetString(options.format),
			    imageFormat->name,
			    strlen(imageFormat->name)) == 0)) {
			matched = 1;
			if (imageFormat->stringWriteProc != NULL) {
			    stringWriteProc = imageFormat->stringWriteProc;
			    break;
			}
		    }
		}
	    }

	    if (stringWriteProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"image string format \"%s\" is %s",
			Tcl_GetString(options.format),
			(matched ? "not supported" : "unknown")));
		Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
			Tcl_GetString(options.format), NULL);
		if (options.background) {
		    Tk_FreeColor(options.background);
		}
		return TCL_ERROR;
	    }
	} else {
	    stringWriteProc = ImgStringWrite;
	}

	/*
	 * Call the handler's string write function to write out the image.
	 */

	data = ImgGetPhoto(modelPtr, &block, &options);
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890



















































891


892






893
894







895










896

























































897
898







899
900
901
902
903
904
905
906
907
908
909

910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932

933
934
935
936
937
938
939
940
941
	    if (result == TCL_OK) {
		Tcl_DStringResult(interp, &buffer);
	    } else {
		Tcl_DStringFree(&buffer);
	    }
	} else {
	    typedef int (*NewStringWriteProc)(Tcl_Interp *interp,
		    Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr,
		    void *dummy);

	    result = ((NewStringWriteProc)(void *)stringWriteProc)(interp,
		    options.format, &block, NULL);
	}
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
        if (freeObj != NULL) {
            Tcl_DecrRefCount(freeObj);
        }
	return result;

      dataErrorExit:
        if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}
        if (freeObj != NULL) {
            Tcl_DecrRefCount(freeObj);
        }
	return TCL_ERROR;
    }

    case PHOTO_GET: {
	/*
	 * photo get command - first parse and check parameters.
	 */

	Tcl_Obj *channels[4];
	int channelCount = 3;

        index = 3;
        memset(&options, 0, sizeof(options));
        options.name = NULL;
        if (ParseSubcommandOptions(&options, interp, OPT_WITHALPHA,
                &index, objc, objv) != TCL_OK) {
            return TCL_ERROR;
        }
        if (options.name == NULL || index < objc) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?-withalpha?");
	    return TCL_ERROR;
	}
        if (options.options & OPT_WITHALPHA) {
            channelCount = 4;
        }

	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "%s get: coordinates out of range",
		    Tcl_GetString(objv[0])));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
		    NULL);
	    return TCL_ERROR;
	}

	/*
	 * Extract the value of the desired pixel and format it as a list.
	 */

	pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	channels[0] = Tcl_NewWideIntObj(pixelPtr[0]);
	channels[1] = Tcl_NewWideIntObj(pixelPtr[1]);
	channels[2] = Tcl_NewWideIntObj(pixelPtr[2]);
	channels[3] = Tcl_NewWideIntObj(pixelPtr[3]);
	Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels));
	return TCL_OK;
    }

    case PHOTO_PUT: {
	Tcl_Obj *format, *data;

	/*
	 * photo put command - first parse the options.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "data ?-option value ...?");
	    return TCL_ERROR;
	}




















































	/*


	 * See if there's a format that can read the data






	 */








	if (MatchStringFormat(interp, objv[2], options.format, &imageFormat,










		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {

























































	    return TCL_ERROR;
	}








	if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
	    options.toX2 = options.toX + imageWidth;
	    options.toY2 = options.toY + imageHeight;
	}
	if (imageWidth > options.toX2 - options.toX) {
	    imageWidth = options.toX2 - options.toX;
	}
	if (imageHeight > options.toY2 - options.toY) {
	    imageHeight = options.toY2 - options.toY;
	}

	format = options.format;
	data = objv[2];
	if (oldformat) {
	    if (format) {
		format = (Tcl_Obj *) Tcl_GetString(format);
	    }
	    data = (Tcl_Obj *) Tcl_GetString(data);
	}

	if (imageFormat->stringReadProc(interp, data, format,
		(Tk_PhotoHandle) modelPtr, options.toX, options.toY,
		options.toX2 - options.toX,
		options.toY2 - options.toY, 0, 0) != TCL_OK) {
	    return TCL_ERROR;
	}
	/*
	 * SB: is the next line really needed? The stringReadProc
	 * writes image data with Tk_PhotoPutBlock(), which in turn
	 * takes care to notify the changed image and to set/unset the
	 * IMAGE_CHANGED bit.
	 */
	modelPtr->flags |= IMAGE_CHANGED;


	return TCL_OK;
    }
    case PHOTO_READ: {
	Tcl_Obj *format;

	/*
	 * photo read command - first parse the options specified.
	 */








|
<


|







<
<
<

<
<
<
<
<
<
<
<
<
<
<
<







|
<

<
<
<
<
<
<
<
|
|


<
<
<
<










|








|
|
|
<
|



|
<
<

|





<









>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
>
>
|
>
>
>
>
>
>
|

>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
>
>
>
>
>
>
>


|
|

<
|
<
<
|
<
>
|
|
<
<
|
<
|
<
|
|
|
<
|
<
<
<
<
<
<
<
<
<
|
>
|
|







784
785
786
787
788
789
790
791

792
793
794
795
796
797
798
799
800
801



802












803
804
805
806
807
808
809
810

811







812
813
814
815




816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837

838
839
840
841
842


843
844
845
846
847
848
849

850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

1012


1013

1014
1015
1016


1017

1018

1019
1020
1021

1022









1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
	    if (result == TCL_OK) {
		Tcl_DStringResult(interp, &buffer);
	    } else {
		Tcl_DStringFree(&buffer);
	    }
	} else {
	    typedef int (*NewStringWriteProc)(Tcl_Interp *interp,
		    Tcl_Obj *formatString, Tk_PhotoImageBlock *blockPtr);


	    result = ((NewStringWriteProc)(void *)stringWriteProc)(interp,
		    options.format, &block);
	}
	if (options.background) {
	    Tk_FreeColor(options.background);
	}
	if (data) {
	    ckfree(data);
	}



	return result;












    }

    case PHOTO_GET: {
	/*
	 * photo get command - first parse and check parameters.
	 */

	Tcl_Obj *channels[3];









	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y");
	    return TCL_ERROR;
	}




	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    return TCL_ERROR;
	}
	if ((x < 0) || (x >= 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;
	channels[0] = Tcl_NewIntObj(pixelPtr[0]);
	channels[1] = Tcl_NewIntObj(pixelPtr[1]);
	channels[2] = Tcl_NewIntObj(pixelPtr[2]);

	Tcl_SetObjResult(interp, Tcl_NewListObj(3, channels));
	return TCL_OK;
    }

    case PHOTO_PUT:


	/*
	 * photo put command - first parse the options and colors specified.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;

	if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "data ?-option value ...?");
	    return TCL_ERROR;
	}

	if (MatchStringFormat(interp, options.name ? objv[2]:NULL,
		options.format, &imageFormat, &imageWidth,
		&imageHeight, &oldformat) == TCL_OK) {
	    Tcl_Obj *format, *data;

	    if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
		options.toX2 = options.toX + imageWidth;
		options.toY2 = options.toY + imageHeight;
	    }
	    if (imageWidth > options.toX2 - options.toX) {
		imageWidth = options.toX2 - options.toX;
	    }
	    if (imageHeight > options.toY2 - options.toY) {
		imageHeight = options.toY2 - options.toY;
	    }
	    format = options.format;
	    data = objv[2];
	    if (oldformat) {
		if (format) {
		    format = (Tcl_Obj *) Tcl_GetString(format);
		}
		data = (Tcl_Obj *) Tcl_GetString(data);
	    }
	    if (imageFormat->stringReadProc(interp, data, format,
		    (Tk_PhotoHandle) modelPtr, options.toX, options.toY,
		    imageWidth, imageHeight, 0, 0) != TCL_OK) {
		return TCL_ERROR;
	    }
	    modelPtr->flags |= IMAGE_CHANGED;
	    return TCL_OK;
	}
	if (options.options & OPT_FORMAT) {
	    return TCL_ERROR;
	}
	Tcl_ResetResult(interp);
	if (Tcl_ListObjGetElements(interp, options.name,
		&dataHeight, &srcObjv) != TCL_OK) {
	    return TCL_ERROR;
	}
	tkwin = Tk_MainWindow(interp);
	block.pixelPtr = NULL;
	dataWidth = 0;
	pixelPtr = NULL;
	for (y = 0; y < dataHeight; ++y) {
	    if (Tcl_ListObjGetElements(interp, srcObjv[y],
		    &listObjc, &listObjv) != TCL_OK) {
		break;
	    }

	    if (y == 0) {
		if (listObjc == 0) {
		    /*
		     * Lines must be non-empty...
		     */

		    break;
		}
		dataWidth = listObjc;
		/*
		 * Memory allocation overflow protection.
		 * May not be able to trigger/ demo / test this.
		 */

		if (dataWidth > (int)((UINT_MAX/3) / dataHeight)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"photo image dimensions exceed Tcl memory limits", -1));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"OVERFLOW", NULL);
		    break;
		}

		pixelPtr = ckalloc(dataWidth * dataHeight * 3);
		block.pixelPtr = pixelPtr;
	    } else if (listObjc != dataWidth) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"all elements of color list must have the same"
			" number of elements", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NON_RECTANGULAR", NULL);
		break;
	    }

	    for (x = 0; x < dataWidth; ++x) {
		const char *colorString = Tcl_GetString(listObjv[x]);
		XColor color;
		int tmpr, tmpg, tmpb;

		/*
		 * We do not use Tk_GetColorFromObj() because we absolutely do
		 * not want to invoke the fallback code.
		 */

		if (colorString[0] == '#') {
		    if (isxdigit(UCHAR(colorString[1])) &&
			    isxdigit(UCHAR(colorString[2])) &&
			    isxdigit(UCHAR(colorString[3]))) {
			if (colorString[4] == '\0') {
			    /* Got #rgb */
			    sscanf(colorString+1, "%1x%1x%1x",
				    &tmpr, &tmpg, &tmpb);
			    *pixelPtr++ = tmpr * 0x11;
			    *pixelPtr++ = tmpg * 0x11;
			    *pixelPtr++ = tmpb * 0x11;
			    continue;
			} else if (isxdigit(UCHAR(colorString[4])) &&
				isxdigit(UCHAR(colorString[5])) &&
				isxdigit(UCHAR(colorString[6])) &&
				colorString[7] == '\0') {
			    /* Got #rrggbb */
			    sscanf(colorString+1, "%2x%2x%2x",
				    &tmpr, &tmpg, &tmpb);
			    *pixelPtr++ = tmpr;
			    *pixelPtr++ = tmpg;
			    *pixelPtr++ = tmpb;
			    continue;
			}
		    }
		}

		if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin),
			colorString, &color)) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "can't parse color \"%s\"", colorString));
		    Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL);
		    break;
		}
		*pixelPtr++ = color.red >> 8;
		*pixelPtr++ = color.green >> 8;
		*pixelPtr++ = color.blue >> 8;
	    }
	    if (x < dataWidth) {
		break;
	    }
	}
	if (y < dataHeight || dataHeight == 0 || dataWidth == 0) {
	    if (block.pixelPtr != NULL) {
		ckfree(block.pixelPtr);
	    }
	    if (y < dataHeight) {
		return TCL_ERROR;
	    }
	    return TCL_OK;
	}

	/*
	 * Fill in default values for the -to option, then copy the block in
	 * using Tk_PhotoPutBlock.
	 */

	if (!(options.options & OPT_TO) || (options.toX2 < 0)) {
	    options.toX2 = options.toX + dataWidth;
	    options.toY2 = options.toY + dataHeight;
	}

	block.width = dataWidth;


	block.height = dataHeight;

	block.pitch = dataWidth * 3;
	block.pixelSize = 3;
	block.offset[0] = 0;


	block.offset[1] = 1;

	block.offset[2] = 2;

	block.offset[3] = 0;
	result = Tk_PhotoPutBlock(interp, modelPtr, &block,
		options.toX, options.toY, options.toX2 - options.toX,

		options.toY2 - options.toY,









		TK_PHOTO_COMPOSITE_SET);
	ckfree(block.pixelPtr);
	return result;

    case PHOTO_READ: {
	Tcl_Obj *format;

	/*
	 * photo read command - first parse the options specified.
	 */

956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
	/*
	 * 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.
	 */

	chan = Tcl_OpenFileChannel(interp,
		Tcl_GetString(options.name), "r", 0);
	if (chan == NULL) {
	    return TCL_ERROR;
	}
	if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
		!= TCL_OK) {
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}
	if (Tcl_SetChannelOption(interp, chan, "-encoding", "binary")
		!= TCL_OK) {
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}

	if (MatchFileFormat(interp, chan,
		Tcl_GetString(options.name), options.format, &imageFormat,
		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {







|














<
<
<
<
<







1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069





1070
1071
1072
1073
1074
1075
1076
	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't get image from a file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * Open the image file and look for a handler for it.
	 */

	chan = Tcl_OpenFileChannel(interp,
		Tcl_GetString(options.name), "r", 0);
	if (chan == NULL) {
	    return TCL_ERROR;
	}
	if (Tcl_SetChannelOption(interp, chan, "-translation", "binary")
		!= TCL_OK) {





	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}

	if (MatchFileFormat(interp, chan,
		Tcl_GetString(options.name), options.format, &imageFormat,
		&imageWidth, &imageHeight, &oldformat) != TCL_OK) {
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011

	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 {







|







1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098

	if ((options.fromX > imageWidth) || (options.fromY > imageHeight)
		|| (options.fromX2 > imageWidth)
		|| (options.fromY2 > imageHeight)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside source image",
		    -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    Tcl_Close(NULL, chan);
	    return TCL_ERROR;
	}
	if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) {
	    width = imageWidth - options.fromX;
	    height = imageHeight - options.fromY;
	} else {
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033

	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







|







1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120

	if (options.options & OPT_SHRINK) {
	    if (ImgPhotoSetSize(modelPtr, options.toX + width,
		    options.toY + height) != TCL_OK) {
		Tcl_ResetResult(interp);
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
		Tcl_Close(NULL, chan);
		return TCL_ERROR;
	    }
	}

	/*
	 * Call the handler's file read function to read the data into the
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
	}

	if (y < modelPtr->height) {
	    /*
	     * Tell the core image code that part of the image has changed.
	     */

	    Tk_ImageChanged(modelPtr->tkModel, x, y,
		    (modelPtr->width - x), (modelPtr->height - y),
		    modelPtr->width, modelPtr->height);
	}
	return TCL_OK;

    case PHOTO_TRANS: {
	static const char *const photoTransOptions[] = {







|







1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
	}

	if (y < modelPtr->height) {
	    /*
	     * Tell the core image code that part of the image has changed.
	     */

	    Tk_ImageChanged(modelPtr->tkMaster, x, y,
		    (modelPtr->width - x), (modelPtr->height - y),
		    modelPtr->width, modelPtr->height);
	}
	return TCL_OK;

    case PHOTO_TRANS: {
	static const char *const photoTransOptions[] = {
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244







1245

1246
1247
1248
1249







1250




1251
1252

1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
	if (Tcl_GetIndexFromObj(interp, objv[2], photoTransOptions, "option",
		0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	switch ((enum transOptions) index) {
	case PHOTO_TRANS_GET: {
	    int boolMode;

	    /*
	     * parse fixed args and option
	     */

	    if (objc > 6 || objc < 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y ?-option?");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
		return TCL_ERROR;
	    }

	    index = 4;
	    memset(&options, 0, sizeof(options));
	    if (ParseSubcommandOptions(&options, interp,
		    OPT_ALPHA, &index, objc, objv) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		    || (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency get: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }

	    /*
	     * Extract and return the desired value
	     */
	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		Tcl_SetObjResult(interp, Tcl_NewBooleanObj( ! pixelPtr[3]));
	    } else {
		Tcl_SetObjResult(interp, Tcl_NewWideIntObj(pixelPtr[3]));
	    }
	    return TCL_OK;
	}

	case PHOTO_TRANS_SET: {
	    int newVal, boolMode;
	    XRectangle setBox;
	    TkRegion modRegion;

	    /*
	     * Parse args and option, check for valid values
	     */

	    if (objc < 6 || objc > 7) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y newVal ?-option?");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
		return TCL_ERROR;
	    }

	    index = 5;
	    memset(&options, 0, sizeof(options));
	    if (ParseSubcommandOptions(&options, interp,
		    OPT_ALPHA, &index, objc, objv) != TCL_OK) {
		return TCL_ERROR;
	    }
	    if (index < objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"unknown option \"%s\": must be -alpha",
			Tcl_GetString(objv[index])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION",
			NULL);
		return TCL_ERROR;
	    }
	    boolMode = 1;
	    if (options.options & OPT_ALPHA) {
		boolMode = 0;
	    }

	    if ((x < 0) || (x >= modelPtr->width)
		|| (y < 0) || (y >= modelPtr->height)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"%s transparency set: coordinates out of range",
			Tcl_GetString(objv[0])));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES",
			NULL);
		return TCL_ERROR;
	    }

	    if (boolMode) {
		if (Tcl_GetBooleanFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
	    } else {
		if (Tcl_GetIntFromObj(interp, objv[5], &newVal) != TCL_OK) {
		    return TCL_ERROR;
		}
		if (newVal < 0 || newVal > 255) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "invalid alpha value \"%d\": "
			    "must be integer between 0 and 255", newVal));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "BAD_VALUE", NULL);
		    return TCL_ERROR;
		}
	    }

	    /*
	     * Set new alpha value for the pixel
	     */

	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;
	    if (boolMode) {
		pixelPtr[3] = newVal ? 0 : 255;
	    } else {
		pixelPtr[3] = newVal;
	    }

	    /*
	     * Update the validRegion of the image
	     */

	    setBox.x = x;
	    setBox.y = y;
	    setBox.width = 1;
	    setBox.height = 1;







	    modRegion = TkCreateRegion();

	    TkUnionRectWithRegion(&setBox, modRegion, modRegion);
	    if (pixelPtr[3]) {
		TkUnionRectWithRegion(&setBox, modelPtr->validRegion,
			modelPtr->validRegion);







	    } else {




		TkSubtractRegion(modelPtr->validRegion, modRegion,
			modelPtr->validRegion);

	    }
	    TkDestroyRegion(modRegion);

	    /*
	     * Inform the generic image code that the image
	     * has (potentially) changed.
	     */

	    Tk_ImageChanged(modelPtr->tkModel, x, y, 1, 1,
		    modelPtr->width, modelPtr->height);
	    modelPtr->flags &= ~IMAGE_CHANGED;
	    return TCL_OK;
	}

	}
	Tcl_Panic("unexpected fallthrough");







<
<
<
<
<
<
|
|






<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|



<
<
<

|
|
<
<
<




|

<

<
<
<
<
|
|



|
<
<
|
<
<
<
|


<
<
<
<
<
<
<
<
<
<
<
<
<






|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





>
>
>
>
>
>
>
|
>
|
<
|

>
>
>
>
>
>
>

>
>
>
>
|

>

<






|







1185
1186
1187
1188
1189
1190
1191






1192
1193
1194
1195
1196
1197
1198
1199




















1200
1201
1202
1203
1204
1205
1206
1207
1208
1209



1210
1211
1212



1213
1214
1215
1216
1217
1218

1219




1220
1221
1222
1223
1224
1225


1226



1227
1228
1229













1230
1231
1232
1233
1234
1235
1236
1237
1238

































1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253

1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271

1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
	if (Tcl_GetIndexFromObj(interp, objv[2], photoTransOptions, "option",
		0, &index) != TCL_OK) {
	    return TCL_ERROR;
	}

	switch ((enum transOptions) index) {
	case PHOTO_TRANS_GET: {






	    if (objc != 5) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) {
		return TCL_ERROR;
	    }




















	    if ((x < 0) || (x >= 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;
	    }




	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;

	    Tcl_SetObjResult(interp, Tcl_NewBooleanObj(pixelPtr[3] == 0));



	    return TCL_OK;
	}

	case PHOTO_TRANS_SET: {
	    int transFlag;
	    XRectangle setBox;






	    if (objc != 6) {
		Tcl_WrongNumArgs(interp, 3, objv, "x y boolean");
		return TCL_ERROR;
	    }
	    if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK)
		    || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)


		    || (Tcl_GetBooleanFromObj(interp, objv[5],



		    &transFlag) != TCL_OK)) {
		return TCL_ERROR;
	    }













	    if ((x < 0) || (x >= 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;
	    }


































	    setBox.x = x;
	    setBox.y = y;
	    setBox.width = 1;
	    setBox.height = 1;
	    pixelPtr = modelPtr->pix32 + (y * modelPtr->width + x) * 4;

	    if (transFlag) {
		/*
		 * Make pixel transparent.
		 */

		TkRegion clearRegion = TkCreateRegion();

		TkUnionRectWithRegion(&setBox, clearRegion, clearRegion);

		TkSubtractRegion(modelPtr->validRegion, clearRegion,
			modelPtr->validRegion);
		TkDestroyRegion(clearRegion);

		/*
		 * Set the alpha value correctly.
		 */

		pixelPtr[3] = 0;
	    } else {
		/*
		 * Make pixel opaque.
		 */

		TkUnionRectWithRegion(&setBox, modelPtr->validRegion,
			modelPtr->validRegion);
		pixelPtr[3] = 255;
	    }


	    /*
	     * Inform the generic image code that the image
	     * has (potentially) changed.
	     */

	    Tk_ImageChanged(modelPtr->tkMaster, x, y, 1, 1,
		    modelPtr->width, modelPtr->height);
	    modelPtr->flags &= ~IMAGE_CHANGED;
	    return TCL_OK;
	}

	}
	Tcl_Panic("unexpected fallthrough");
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302



1303
1304
1305
1306
1307
1308
1309
1310
1311



1312
1313
1314
1315
1316
1317
1318
	/*
	 * 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]







|


















>
>
>








|
>
>
>







1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
	/*
	 * Prevent file system access in safe interpreters.
	 */

	if (Tcl_IsSafe(interp)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "can't write image to a file in a safe interpreter", -1));
	    Tcl_SetErrorCode(interp, "TK", "SAFE", "PHOTO_FILE", (char *)NULL);
	    return TCL_ERROR;
	}

	/*
	 * photo write command - first parse and check any options given.
	 */

	index = 2;
	memset(&options, 0, sizeof(options));
	options.name = NULL;
	options.format = NULL;
	if (ParseSubcommandOptions(&options, interp,
		OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND,
		&index, objc, objv) != TCL_OK) {
	    return TCL_ERROR;
	}
	if ((options.name == NULL) || (index < objc)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "fileName ?-option value ...?");
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}
	if ((options.fromX > modelPtr->width)
		|| (options.fromY > modelPtr->height)
		|| (options.fromX2 > modelPtr->width)
		|| (options.fromY2 > modelPtr->height)) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "coordinates for -from option extend outside image", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}

	/*
	 * Fill in default values for unspecified parameters. Note that a
	 * missing -format flag results in us having a guess from the file
	 * extension. [Bug 2983824]
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
			    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.
	     */








<














<







1367
1368
1369
1370
1371
1372
1373

1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387

1388
1389
1390
1391
1392
1393
1394
			    strlen(imageFormat->name)) == 0)) {
		matched = 1;
		if (imageFormat->fileWriteProc != NULL) {
		    break;
		}
	    }
	}

	if (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;
		    }
		}
	    }
	}

	if (usedExt && !matched) {
	    /*
	     * If we didn't find one and we're using file extensions as the
	     * basis for the guessing, go back and look again without
	     * prejudice. Supports old broken code.
	     */

1385
1386
1387
1388
1389
1390
1391
1392



1393
1394
1395
1396
1397
1398
1399
			"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.
	 */








|
>
>
>







1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
			"image file format \"%s\" is unknown", fmtString));
	    } else {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"image file format \"%s\" has no file writing capability",
			fmtString));
	    }
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    fmtString, (char *)NULL);
	    if (options.background) {
		Tk_FreeColor(options.background);
	    }
	    return TCL_ERROR;
	}

	/*
	 * Call the handler's file write function to write out the image.
	 */

1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
/*
 *----------------------------------------------------------------------
 *
 * ParseSubcommandOptions --
 *
 *	This function is invoked to process one of the options which may be
 *	specified for the photo image subcommands, namely, -from, -to, -zoom,
 *	-subsample, -format, -shrink, -compositingrule, -alpha, -boolean and
 *	-withalpha.
 *	Parsing starts at the index in *optIndexPtr and stops at the end of
 *	objv[] or at the first value that does not belong to an option.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Fields in *optPtr get filled in. The value of optIndexPtr is updated
 *	to contain the index of the first element in argv[] that was not
 *	parsed, or argc if the end of objv[] was reached.
 *
 *----------------------------------------------------------------------
 */

static int
ParseSubcommandOptions(
    struct SubcommandOptions *optPtr,







|
<
<
<





|
<
<







1475
1476
1477
1478
1479
1480
1481
1482



1483
1484
1485
1486
1487
1488


1489
1490
1491
1492
1493
1494
1495
/*
 *----------------------------------------------------------------------
 *
 * ParseSubcommandOptions --
 *
 *	This function is invoked to process one of the options which may be
 *	specified for the photo image subcommands, namely, -from, -to, -zoom,
 *	-subsample, -format, -shrink, and -compositingrule.



 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	Fields in *optPtr get filled in.


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

static int
ParseSubcommandOptions(
    struct SubcommandOptions *optPtr,
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
    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;
	}







|
|
|










|







1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
    Tcl_Obj *const objv[])	/* Arguments to be parsed. */
{
    static const char *const compositingRules[] = {
	"overlay", "set",	/* Note that these must match the
				 * TK_PHOTO_COMPOSITE_* constants. */
	NULL
    };
    int index, length, argIndex;
    int c, bit, currentBit;
    int values[4], numValues, maxValues;
    const char *option, *expandedOption, *needed;
    const char *const *listPtr;
    Tcl_Obj *msgObj;

    for (index = *optIndexPtr; index < objc; *optIndexPtr = ++index) {
	/*
	 * We can have one value specified without an option; it goes into
	 * optPtr->name.
	 */

	expandedOption = option = Tcl_GetStringFromObj(objv[index], &length);
	if (option[0] != '-') {
	    if (optPtr->name == NULL) {
		optPtr->name = objv[index];
		continue;
	    }
	    break;
	}
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
	     * The -background option takes a single XColor value.
	     */

	    if (index + 1 >= objc) {
		goto oneValueRequired;
	    }
	    *optIndexPtr = ++index;
	    optPtr->background = Tk_GetColor(interp, Tk_MainWindow(interp),
		    Tk_GetUid(Tcl_GetString(objv[index])));
	    if (!optPtr->background) {
		return TCL_ERROR;
	    }
	} else if (bit == OPT_FORMAT) {
	    /*
	     * The -format option takes a single string value. Note that
	     * parsing this is outside the scope of this function.







|
|







1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
	     * The -background option takes a single XColor value.
	     */

	    if (index + 1 >= objc) {
		goto oneValueRequired;
	    }
	    *optIndexPtr = ++index;
	    optPtr->background = Tk_AllocColorFromObj(interp, Tk_MainWindow(interp),
		    objv[index]);
	    if (!optPtr->background) {
		return TCL_ERROR;
	    }
	} else if (bit == OPT_FORMAT) {
	    /*
	     * The -format option takes a single string value. Note that
	     * parsing this is outside the scope of this function.
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
	    index++;
	    if (Tcl_GetIndexFromObj(interp, objv[index], compositingRules,
		    "compositing rule", 0, &optPtr->compositingRule)
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	    *optIndexPtr = index;
	} else if (bit == OPT_TO || bit == OPT_FROM
		|| bit == OPT_SUBSAMPLE || bit == OPT_ZOOM) {
	    const char *val;

	    maxValues = ((bit == OPT_FROM) || (bit == OPT_TO)) ? 4 : 2;
	    argIndex = index + 1;
	    for (numValues = 0; numValues < maxValues; ++numValues) {
		if (argIndex >= objc) {
		    break;







|
<







1605
1606
1607
1608
1609
1610
1611
1612

1613
1614
1615
1616
1617
1618
1619
	    index++;
	    if (Tcl_GetIndexFromObj(interp, objv[index], compositingRules,
		    "compositing rule", 0, &optPtr->compositingRule)
		    != TCL_OK) {
		return TCL_ERROR;
	    }
	    *optIndexPtr = index;
	} else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) {

	    const char *val;

	    maxValues = ((bit == OPT_FROM) || (bit == OPT_TO)) ? 4 : 2;
	    argIndex = index + 1;
	    for (numValues = 0; numValues < maxValues; ++numValues) {
		if (argIndex >= objc) {
		    break;
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
    /*
     * 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 --







|






|





|



















|







1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
    /*
     * Exception generation.
     */

  oneValueRequired:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "the \"%s\" option requires a value", expandedOption));
    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", (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, ", ", -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", (char *)NULL);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoConfigureModel --
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
    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;
		}
	    }
	}
    }

    /*







|
|



<

<
|
|
|
|
|


<

<



|


|
|


<

<



|







1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797

1798

1799
1800
1801
1802
1803
1804
1805

1806

1807
1808
1809
1810
1811
1812
1813
1814
1815
1816

1817

1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
    int flags)			/* Flags to pass to Tk_ConfigureWidget, such
				 * as TK_CONFIG_ARGV_ONLY. */
{
    PhotoInstance *instancePtr;
    const char *oldFileString, *oldPaletteString;
    Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL;
    Tcl_Obj *tempdata, *tempformat;
    int i, length;
    int result, imageWidth, imageHeight, oldformat;
    double oldGamma;
    Tcl_Channel chan;
    Tk_PhotoImageFormat *imageFormat;



    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", -1));
		    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", -1));
		    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);







|
<


<














|

|







1849
1850
1851
1852
1853
1854
1855
1856

1857
1858

1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
    oldGamma = modelPtr->gamma;

    /*
     * Process the configuration options specified.
     */

    if (Tk_ConfigureWidget(interp, Tk_MainWindow(interp), configSpecs,
	    objc, (const char **)objv, (char *) modelPtr, flags|TK_CONFIG_OBJS) != TCL_OK) {

	goto errorExit;
    }


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

	(void) Tcl_GetByteArrayFromObj(data, &bytesize);
	if (bytesize) {
	    Tcl_IncrRefCount(data);
	} else {
	    data = NULL;
	}
	if (modelPtr->dataString) {
	    Tcl_DecrRefCount(modelPtr->dataString);
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
     * 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,







|




















|








<
<
<
<
|
|











|







1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941




1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
     * is correctly allocated for this image.
     */

    if (ImgPhotoSetSize(modelPtr, modelPtr->width,
	    modelPtr->height) != TCL_OK) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj(
		TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	Tcl_SetErrorCode(interp, "TK", "MALLOC", (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;
	}





	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", (char *)NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	if (oldformat && tempformat) {
	    tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
	}
	result = imageFormat->fileReadProc(interp, chan,
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
		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);







|







1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
		modelPtr->format, &imageFormat, &imageWidth,
		&imageHeight, &oldformat) != TCL_OK) {
	    goto errorExit;
	}
	if (ImgPhotoSetSize(modelPtr, imageWidth, imageHeight) != TCL_OK) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    goto errorExit;
	}
	tempformat = modelPtr->format;
	tempdata = modelPtr->dataString;
	if (oldformat) {
	    if (tempformat) {
		tempformat = (Tcl_Obj *) Tcl_GetString(tempformat);
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
	TkImgPhotoConfigureInstance(instancePtr);
    }

    /*
     * Inform the generic image code that the image has (potentially) changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    modelPtr->flags &= ~IMAGE_CHANGED;

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {







|







2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
	TkImgPhotoConfigureInstance(instancePtr);
    }

    /*
     * Inform the generic image code that the image has (potentially) changed.
     */

    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
    modelPtr->flags &= ~IMAGE_CHANGED;

    if (oldData != NULL) {
	Tcl_DecrRefCount(oldData);
    }
    if (oldFormat != NULL) {
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089

2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
static int
ToggleComplexAlphaIfNeeded(
    PhotoModel *mPtr)
{
    size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) *
	    (size_t)MAX(mPtr->userHeight, mPtr->height) * 4;
    unsigned char *c = mPtr->pix32;
    unsigned char *end = c + len;

    /*
     * Set the COMPLEX_ALPHA flag if we have an image with partially
     * transparent bits.
     */

    mPtr->flags &= ~COMPLEX_ALPHA;
    if (c == NULL) {
	return 0;
    }

    c += 3;			/* Start at first alpha byte. */
    for (; c < end; c += 4) {
	if (*c && *c != 255) {
     	    mPtr->flags |= COMPLEX_ALPHA;
	    break;
	}
    }
    return (mPtr->flags & COMPLEX_ALPHA);
}

/*







|










>



|







2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
static int
ToggleComplexAlphaIfNeeded(
    PhotoModel *mPtr)
{
    size_t len = (size_t)MAX(mPtr->userWidth, mPtr->width) *
	    (size_t)MAX(mPtr->userHeight, mPtr->height) * 4;
    unsigned char *c = mPtr->pix32;
    unsigned char *end;

    /*
     * 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;
	}
    }
    return (mPtr->flags & COMPLEX_ALPHA);
}

/*
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoDelete(
    ClientData modelData)	/* Pointer to PhotoModel structure for image.
				 * Must not have any more instances. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;

    while ((instancePtr = modelPtr->instancePtr) != NULL) {
	if (instancePtr->refCount > 0) {
	    Tcl_Panic("tried to delete photo image when instances still exist");
	}
	Tcl_CancelIdleCall(TkImgDisposeInstance, instancePtr);
	TkImgDisposeInstance(instancePtr);
    }
    modelPtr->tkModel = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->pix32 != NULL) {
	ckfree(modelPtr->pix32);
    }
    if (modelPtr->validRegion != NULL) {







|












|







2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
 *	Resources associated with the image get freed.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoDelete(
    void *modelData)	/* Pointer to PhotoModel structure for image.
				 * Must not have any more instances. */
{
    PhotoModel *modelPtr = (PhotoModel *)modelData;
    PhotoInstance *instancePtr;

    while ((instancePtr = modelPtr->instancePtr) != NULL) {
	if (instancePtr->refCount > 0) {
	    Tcl_Panic("tried to delete photo image when instances still exist");
	}
	Tcl_CancelIdleCall(TkImgDisposeInstance, instancePtr);
	TkImgDisposeInstance(instancePtr);
    }
    modelPtr->tkMaster = NULL;
    if (modelPtr->imageCmd != NULL) {
	Tcl_DeleteCommandFromToken(modelPtr->interp, modelPtr->imageCmd);
    }
    if (modelPtr->pix32 != NULL) {
	ckfree(modelPtr->pix32);
    }
    if (modelPtr->validRegion != NULL) {
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    ClientData clientData)	/* Pointer to PhotoModel structure for
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkModel != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkModel));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoSetSize --







|





|
|







2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
 *	The image is deleted.
 *
 *----------------------------------------------------------------------
 */

static void
ImgPhotoCmdDeletedProc(
    void *clientData)	/* Pointer to PhotoModel structure for
				 * image. */
{
    PhotoModel *modelPtr = (PhotoModel *)clientData;

    modelPtr->imageCmd = NULL;
    if (modelPtr->tkMaster != NULL) {
	Tk_DeleteImage(modelPtr->interp, Tk_NameOfImage(modelPtr->tkMaster));
    }
}

/*
 *----------------------------------------------------------------------
 *
 * ImgPhotoSetSize --
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
	    }
	    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);







|


















<
|














|


















<







|





|







2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462

2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496

2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
	    }
	    matched = 1;
	    if (formatPtr->fileMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-file option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_FILE_FORMAT", (char *)NULL);
		return TCL_ERROR;
	    }
	}
	if (formatPtr->fileMatchProc != NULL) {
	    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);

	    if (formatPtr->fileMatchProc(chan, fileName, formatObj,
		    widthPtr, heightPtr, interp)) {
		if (*widthPtr < 1) {
		    *widthPtr = 1;
		}
		if (*heightPtr < 1) {
		    *heightPtr = 1;
		}
		break;
	    }
	}
    }

    if (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", (char *)NULL);
		    return TCL_ERROR;
		}
	    }
	    if (formatPtr->fileMatchProc != NULL) {
		(void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
		if (formatPtr->fileMatchProc(chan, fileName, (Tcl_Obj *)
			formatString, widthPtr, heightPtr, interp)) {
		    if (*widthPtr < 1) {
			*widthPtr = 1;
		    }
		    if (*heightPtr < 1) {
			*heightPtr = 1;
		    }
		    break;
		}
	    }
	}
    }


    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, (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;
    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;
    (void) Tcl_Seek(chan, Tcl_LongAsWide(0L), SEEK_SET);
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
				 * is returned here. */
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here. */
    int *oldformat)		/* Returns 1 if the old image API is used. */
{
    int matched = 0, useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr, *defaultFormatPtr = NULL;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *formatString = NULL;

    if (formatObj) {
	formatString = Tcl_GetString(formatObj);
    }

    /*
     * Scan through the table of file format handlers to find one which can
     * handle the image.
     */

    for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
	    formatPtr = formatPtr->nextPtr) {
	/*
	 * To keep the behaviour of older versions (Tk <= 8.6), the default
	 * list-of-lists string format is checked last. Remember its position.
	 */

	if (strncasecmp("default", formatPtr->name, strlen(formatPtr->name))
		== 0) {
	    defaultFormatPtr = formatPtr;
	}

	if (formatObj != NULL) {
	    if (strncasecmp(formatString,
		    formatPtr->name, strlen(formatPtr->name)) != 0) {
		continue;
	    }
	    matched = 1;
	    if (formatPtr->stringMatchProc == NULL) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"-data option isn't supported for %s images",
			formatString));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			"NOT_DATA_FORMAT", NULL);
		return TCL_ERROR;
	    }
	}

	/*
	 * If this is the default format, and it was not passed as -format
	 * option, skip the stringMatchProc test. It'll be done later
	 */

	if (formatObj == NULL && formatPtr == defaultFormatPtr) {
	    continue;
	}

	if ((formatPtr->stringMatchProc != NULL)
		&& (formatPtr->stringReadProc != NULL)
		&& formatPtr->stringMatchProc(data, formatObj,
			widthPtr, heightPtr, interp)) {
	    break;
	}
    }

#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9
    if (formatPtr == NULL) {
	useoldformat = 1;
	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;
		formatPtr = formatPtr->nextPtr) {
	    if (formatObj != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {
		    continue;
		}
		matched = 1;
		if (formatPtr->stringMatchProc == NULL) {
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "-data option isn't supported for %s images",
			    formatString));
		    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
			    "NOT_DATA_FORMAT", NULL);
		    return TCL_ERROR;
		}
	    }
	    if ((formatPtr->stringMatchProc != NULL)
		    && (formatPtr->stringReadProc != NULL)
		    && formatPtr->stringMatchProc(
			    (Tcl_Obj *) Tcl_GetString(data),
			    (Tcl_Obj *) formatString,
			    widthPtr, heightPtr, interp)) {
		break;
	    }
	}
    }
#endif

    if (formatPtr == NULL) {
	/*
	 * Try the default format as last resort (only if no -format option
	 * was passed).
	 */

	if ( formatObj == NULL && defaultFormatPtr == NULL) {
	    Tcl_Panic("default image format handler not registered");
	}
	if ( formatObj == NULL
		&& defaultFormatPtr->stringMatchProc != NULL
		&& defaultFormatPtr->stringReadProc != NULL
		&& defaultFormatPtr->stringMatchProc(data, formatObj,
		widthPtr, heightPtr, interp) != 0) {
	    useoldformat = 0;
	    formatPtr = defaultFormatPtr;
	} else if ((formatObj != NULL) && !matched) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image format \"%s\" is not supported", formatString));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    formatString, NULL);
	    return TCL_ERROR;
	} else {

            /*
             * Some lower level routine (stringMatchProc) may have already set
             * a specific error message, so just return this. Otherwise return
             * a generic image data error.
             */

            if (Tcl_GetString(Tcl_GetObjResult(interp))[0] == '\0') {
                Tcl_SetObjResult(interp, Tcl_NewStringObj(
                        "couldn't recognize image data", -1));
	        Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		        "UNRECOGNIZED_DATA", NULL);
            }
	    return TCL_ERROR;
	}
    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;

    /*
     * Some stringMatchProc might have left error messages and error codes in
     * interp.	Clear them before return.
     */
    Tcl_ResetResult(interp);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FindPhoto --







|















<
<
<
<
<
<
<
<
<
<











|



<
<
<
<
<
<
<
<
<
<








<















|













<
<

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



|
<

<
<
<
<
<
<
<
<
|
|
|
|
|
|
<




<
<
<
<
<
<







2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572










2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587










2588
2589
2590
2591
2592
2593
2594
2595

2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624


2625















2626
2627
2628
2629
2630

2631








2632
2633
2634
2635
2636
2637

2638
2639
2640
2641






2642
2643
2644
2645
2646
2647
2648
				 * is returned here. */
    int *widthPtr, int *heightPtr,
				/* The dimensions of the image are returned
				 * here. */
    int *oldformat)		/* Returns 1 if the old image API is used. */
{
    int matched = 0, useoldformat = 0;
    Tk_PhotoImageFormat *formatPtr;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
    const char *formatString = NULL;

    if (formatObj) {
	formatString = Tcl_GetString(formatObj);
    }

    /*
     * Scan through the table of file format handlers to find one which can
     * handle the image.
     */

    for (formatPtr = tsdPtr->formatList; formatPtr != NULL;
	    formatPtr = formatPtr->nextPtr) {










	if (formatObj != NULL) {
	    if (strncasecmp(formatString,
		    formatPtr->name, strlen(formatPtr->name)) != 0) {
		continue;
	    }
	    matched = 1;
	    if (formatPtr->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 ((formatPtr->stringMatchProc != NULL)
		&& (formatPtr->stringReadProc != NULL)
		&& formatPtr->stringMatchProc(data, formatObj,
			widthPtr, heightPtr, interp)) {
	    break;
	}
    }


    if (formatPtr == NULL) {
	useoldformat = 1;
	for (formatPtr = tsdPtr->oldFormatList; formatPtr != NULL;
		formatPtr = formatPtr->nextPtr) {
	    if (formatObj != NULL) {
		if (strncasecmp(formatString,
			formatPtr->name, strlen(formatPtr->name)) != 0) {
		    continue;
		}
		matched = 1;
		if (formatPtr->stringMatchProc == NULL) {
		    Tcl_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 ((formatPtr->stringMatchProc != NULL)
		    && (formatPtr->stringReadProc != NULL)
		    && formatPtr->stringMatchProc(
			    (Tcl_Obj *) Tcl_GetString(data),
			    (Tcl_Obj *) formatString,
			    widthPtr, heightPtr, interp)) {
		break;
	    }
	}
    }


    if (formatPtr == NULL) {















	if ((formatObj != NULL) && !matched) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "image format \"%s\" is not supported", formatString));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT",
		    formatString, (char *)NULL);

	} else {








	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "couldn't recognize image data", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO",
		    "UNRECOGNIZED_DATA", (char *)NULL);
	}
	return TCL_ERROR;

    }

    *imageFormatPtr = formatPtr;
    *oldformat = useoldformat;






    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_FindPhoto --
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
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;
}








|
|







2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
Tk_PhotoHandle
Tk_FindPhoto(
    Tcl_Interp *interp,		/* Interpreter (application) in which image
				 * exists. */
    const char *imageName)	/* Name of the desired photo image. */
{
    const Tk_ImageType *typePtr;
    void *clientData =
	    Tk_GetImageMasterData(interp, imageName, &typePtr);

    if ((typePtr == NULL) || (typePtr->name != tkPhotoImageType.name)) {
	return NULL;
    }
    return clientData;
}

2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
     *
     * 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))) {







|
|
|



















|
















|







2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (modelPtr->pix32 && (sourceBlock.pixelPtr >= modelPtr->pix32)
	    && (sourceBlock.pixelPtr < modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4)) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }


    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (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.
	 *







|







2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
    /*
     * Add this new block to the region which specifies which data is valid.
     */

    if (alphaOffset) {
	/*
	 * This block is grossly inefficient. For each row in the image, it
	 * finds each contiguous string of nontransparent pixels, then marks
	 * those areas as valid in the validRegion mask. This makes drawing
	 * very efficient, because of the way we use X: we just say, here's
	 * your mask, and here's your data. We need not worry about the
	 * current background color, etc. But this costs us a lot on the image
	 * setup. Still, image setup only happens once, whereas the drawing
	 * happens many times, so this might be the best way to go.
	 *
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159

    Tk_DitherPhoto((Tk_PhotoHandle)modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, x, y, width, height,
	    modelPtr->width, modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:







|







3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110

    Tk_DitherPhoto((Tk_PhotoHandle)modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkMaster, x, y, width, height,
	    modelPtr->width, modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
     *
     * 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))) {







|
|
|



















|















|







3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
3210
3211
3212
3213
3214
3215
3216
3217
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
     *
     * To find out, just comparing the pointers is not enough - they might have
     * different values and still point to the same block of memory. (e.g.
     * if the -from option was passed to [imageName copy])
     */
    sourceBlock = *blockPtr;
    memToFree = NULL;
    if (modelPtr->pix32 && (sourceBlock.pixelPtr >= modelPtr->pix32)
	    && (sourceBlock.pixelPtr < modelPtr->pix32 + modelPtr->width
	    * modelPtr->height * 4)) {
	/*
	 * Fix 5c51be6411: avoid reading
	 *
	 *	(sourceBlock.pitch - sourceBlock.width * sourceBlock.pixelSize)
	 *
	 * bytes past the end of modelPtr->pix32[] when
	 *
	 *	blockPtr->pixelPtr > (modelPtr->pix32 +
	 *		4 * modelPtr->width * modelPtr->height -
	 *		sourceBlock.height * sourceBlock.pitch)
	 */
	unsigned int cpyLen = (sourceBlock.height - 1) * sourceBlock.pitch +
		sourceBlock.width * sourceBlock.pixelSize;

	sourceBlock.pixelPtr = (unsigned char *)attemptckalloc(cpyLen);
	if (sourceBlock.pixelPtr == NULL) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	memToFree = sourceBlock.pixelPtr;
	memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, cpyLen);
    }

    xEnd = x + width;
    yEnd = y + height;
    if ((xEnd > modelPtr->width) || (yEnd > modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(xEnd, modelPtr->width),
		MAX(yEnd, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    goto errorExit;
	}
    }

    if ((y < modelPtr->ditherY) || ((y == modelPtr->ditherY)
	    && (x < modelPtr->ditherX))) {
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396

			if (!alphaOffset || (alpha == 255)) {
			    *destPtr++ = srcPtr[0];
			    *destPtr++ = srcPtr[greenOffset];
			    *destPtr++ = srcPtr[blueOffset];
			    *destPtr++ = 255;
			    continue;
 			}

			if (compRule==TK_PHOTO_COMPOSITE_SET || !destPtr[3]) {
			    /*
			     * Either this is the SET rule (we overwrite
			     * whatever is there) or the destination is
			     * entirely blank. In both cases, we just set the
			     * destination to the source.







|







3333
3334
3335
3336
3337
3338
3339
3340
3341
3342
3343
3344
3345
3346
3347

			if (!alphaOffset || (alpha == 255)) {
			    *destPtr++ = srcPtr[0];
			    *destPtr++ = srcPtr[greenOffset];
			    *destPtr++ = srcPtr[blueOffset];
			    *destPtr++ = 255;
			    continue;
			}

			if (compRule==TK_PHOTO_COMPOSITE_SET || !destPtr[3]) {
			    /*
			     * Either this is the SET rule (we overwrite
			     * whatever is there) or the destination is
			     * entirely blank. In both cases, we just set the
			     * destination to the source.
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
3515

    Tk_DitherPhoto((Tk_PhotoHandle) modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, x, y, width, height, modelPtr->width,
	    modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:







|







3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466

    Tk_DitherPhoto((Tk_PhotoHandle) modelPtr, x, y, width, height);

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkMaster, x, y, width, height, modelPtr->width,
	    modelPtr->height);

    if (memToFree) ckfree(memToFree);

    return TCL_OK;

  errorExit:
3634
3635
3636
3637
3638
3639
3640

3641
3642

3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */


    memset(modelPtr->pix32, 0,
	    ((size_t)modelPtr->width * modelPtr->height * 4));

    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgResetDither(instancePtr);
    }

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkModel, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand --







>
|
|
>









|







3585
3586
3587
3588
3589
3590
3591
3592
3593
3594
3595
3596
3597
3598
3599
3600
3601
3602
3603
3604
3605
3606
3607
3608
3609
3610
3611
3612
    modelPtr->validRegion = TkCreateRegion();

    /*
     * Clear out the 32-bit pixel storage array. Clear out the dithering error
     * arrays for each instance.
     */

    if (modelPtr->pix32) {
	memset(modelPtr->pix32, 0,
		((size_t)modelPtr->width * modelPtr->height * 4));
    }
    for (instancePtr = modelPtr->instancePtr; instancePtr != NULL;
	    instancePtr = instancePtr->nextPtr) {
	TkImgResetDither(instancePtr);
    }

    /*
     * Tell the core image code that this image has changed.
     */

    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, modelPtr->width,
	    modelPtr->height, modelPtr->width, modelPtr->height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand --
3690
3691
3692
3693
3694
3695
3696
3697
3698
3699
3700
3701
3702
3703
3704
3705
3706
3707
3708
    }
    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;
}

/*
 *----------------------------------------------------------------------







|



|







3643
3644
3645
3646
3647
3648
3649
3650
3651
3652
3653
3654
3655
3656
3657
3658
3659
3660
3661
    }
    if ((width != modelPtr->width) || (height != modelPtr->height)) {
	if (ImgPhotoSetSize(modelPtr, MAX(width, modelPtr->width),
		MAX(height, modelPtr->height)) == TCL_ERROR) {
	    if (interp != NULL) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
		Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	    }
	    return TCL_ERROR;
	}
	Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0, modelPtr->width,
		modelPtr->height);
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
3765
3766
3767
3768
3769
3770
3771
3772
3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
    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;
}

/*
 *----------------------------------------------------------------------
 *







|



|







3718
3719
3720
3721
3722
3723
3724
3725
3726
3727
3728
3729
3730
3731
3732
3733
3734
3735
3736
    modelPtr->userWidth = width;
    modelPtr->userHeight = height;
    if (ImgPhotoSetSize(modelPtr, ((width > 0) ? width: modelPtr->width),
	    ((height > 0) ? height: modelPtr->height)) == TCL_ERROR) {
	if (interp != NULL) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
	    Tcl_SetErrorCode(interp, "TK", "MALLOC", (char *)NULL);
	}
	return TCL_ERROR;
    }
    Tk_ImageChanged(modelPtr->tkMaster, 0, 0, 0, 0,
	    modelPtr->width, modelPtr->height);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
			srcPtr += blockPtr->pixelSize;
			destPtr += newPixelSize;
		    }
		    srcPtr += blockPtr->pitch -
			    blockPtr->width * blockPtr->pixelSize;
		}
	    } else {
	 	int gray = (unsigned char) (((optPtr->background->red>>8) * 11
			+ (optPtr->background->green>>8) * 16
			+ (optPtr->background->blue>>8) * 5 + 16) >> 5);

		for (y = blockPtr->height; y > 0; y--) {
		    for (x = blockPtr->width; x > 0; x--) {
			destPtr[0] += ((255 - *srcPtr) *
				(gray-destPtr[0])) / 255;







|







3904
3905
3906
3907
3908
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
			srcPtr += blockPtr->pixelSize;
			destPtr += newPixelSize;
		    }
		    srcPtr += blockPtr->pitch -
			    blockPtr->width * blockPtr->pixelSize;
		}
	    } else {
		int gray = (unsigned char) (((optPtr->background->red>>8) * 11
			+ (optPtr->background->green>>8) * 16
			+ (optPtr->background->blue>>8) * 5 + 16) >> 5);

		for (y = blockPtr->height; y > 0; y--) {
		    for (x = blockPtr->width; x > 0; x--) {
			destPtr[0] += ((255 - *srcPtr) *
				(gray-destPtr[0])) / 255;
3995
3996
3997
3998
3999
4000
4001



















































4002
4003
4004
4005
4006
4007
4008
	    blockPtr->offset[2] = 0;
	    blockPtr->offset[3]= 1;
	}
	return data;
    }
    return NULL;
}




















































/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoGetImage --
 *
 *	This function is called to obtain image data from a photo image. This







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







3948
3949
3950
3951
3952
3953
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964
3965
3966
3967
3968
3969
3970
3971
3972
3973
3974
3975
3976
3977
3978
3979
3980
3981
3982
3983
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000
4001
4002
4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
	    blockPtr->offset[2] = 0;
	    blockPtr->offset[3]= 1;
	}
	return data;
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * ImgStringWrite --
 *
 *	Default string write function. The data is formatted in the default
 *	format as accepted by the "<img> put" command.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	See the user documentation.
 *
 *----------------------------------------------------------------------
 */

static int
ImgStringWrite(
    Tcl_Interp *interp,
    Tcl_Obj *formatString,
    Tk_PhotoImageBlock *blockPtr)
{
    int greenOffset, blueOffset;
    Tcl_Obj *data;

    greenOffset = blockPtr->offset[1] - blockPtr->offset[0];
    blueOffset = blockPtr->offset[2] - blockPtr->offset[0];

    data = Tcl_NewObj();
    if ((blockPtr->width > 0) && (blockPtr->height > 0)) {
	int row, col;

	for (row=0; row<blockPtr->height; row++) {
	    Tcl_Obj *line = Tcl_NewObj();
	    unsigned char *pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0]
		    + row * blockPtr->pitch;

	    for (col=0; col<blockPtr->width; col++) {
		Tcl_AppendPrintfToObj(line, "%s#%02x%02x%02x",
			col ? " " : "", *pixelPtr,
			pixelPtr[greenOffset], pixelPtr[blueOffset]);
		pixelPtr += blockPtr->pixelSize;
	    }
	    Tcl_ListObjAppendElement(NULL, data, line);
	}
    }
    Tcl_SetObjResult(interp, data);
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoGetImage --
 *
 *	This function is called to obtain image data from a photo image. This
4057
4058
4059
4060
4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
 *	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,







|




















|







|







4061
4062
4063
4064
4065
4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
4088
4089
4090
4091
4092
4093
4094
4095
4096
4097
4098
4099
4100
4101
4102
4103
4104
 *	None.
 *
 *--------------------------------------------------------------
 */

static int
ImgPhotoPostscript(
    void *clientData,	/* Handle for the photo image. */
    Tcl_Interp *interp,		/* Interpreter. */
    TCL_UNUSED(Tk_Window),		/* (unused) */
    Tk_PostscriptInfo psInfo,	/* Postscript info. */
    int x, int y,		/* First pixel to output. */
    int width, int height,	/* Width and height of area. */
    TCL_UNUSED(int))		/* (unused) */
{
    Tk_PhotoImageBlock block;

    Tk_PhotoGetImage(clientData, &block);
    block.pixelPtr += y * block.pitch + x * block.pixelSize;

    return Tk_PostscriptPhoto(interp, &block, psInfo, width, height);
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoPutBlock_NoComposite, Tk_PhotoPutZoomedBlock_NoComposite --
 *
 * These backward-compatibility functions just exist to fill slots in stubs
 * table. For the behaviour of *_NoComposite, refer to the corresponding
 * function without the extra suffix, except that the compositing rule is
 * always "overlay" and the function always panics on memory-allocation
 * failure.
 *
 *----------------------------------------------------------------------
 */

void
Tk_PhotoPutBlock_NoComposite(
    Tk_PhotoHandle handle,
    Tk_PhotoImageBlock *blockPtr,
    int x, int y, int width, int height)
{
    if (Tk_PhotoPutBlock(NULL, handle, blockPtr, x, y, width, height,
4119
4120
4121
4122
4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic,
 * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic
 *
 * Backward compatability functions for preserving the old behaviour (i.e.
 * panic on memory allocation failure) so that extensions do not need to be
 * significantly updated to take account of TIP #116. These call the new
 * interface (i.e. the interface without the extra suffix), but panic if an
 * error condition is returned.
 *
 *----------------------------------------------------------------------
 */







|







4123
4124
4125
4126
4127
4128
4129
4130
4131
4132
4133
4134
4135
4136
4137

/*
 *----------------------------------------------------------------------
 *
 * Tk_PhotoExpand_Panic, Tk_PhotoPutBlock_Panic,
 * Tk_PhotoPutZoomedBlock_Panic, Tk_PhotoSetSize_Panic
 *
 * Backward compatibility functions for preserving the old behaviour (i.e.
 * panic on memory allocation failure) so that extensions do not need to be
 * significantly updated to take account of TIP #116. These call the new
 * interface (i.e. the interface without the extra suffix), but panic if an
 * error condition is returned.
 *
 *----------------------------------------------------------------------
 */
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
4187
4188
    Tk_PhotoHandle handle,
    int width, int height)
{
    if (Tk_PhotoSetSize(NULL, handle, width, height) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}
#endif /* TK_NO_DEPRECATED */

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * tab-width: 8
 * End:
 */







<









4176
4177
4178
4179
4180
4181
4182

4183
4184
4185
4186
4187
4188
4189
4190
4191
    Tk_PhotoHandle handle,
    int width, int height)
{
    if (Tk_PhotoSetSize(NULL, handle, width, height) != TCL_OK) {
	Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE);
    }
}


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * tab-width: 8
 * End:
 */
Changes to generic/tkImgPhoto.h.
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51







52
53
54
55
56
57
58
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations of the structures we define.
 */

#define PhotoMaster PhotoModel
typedef struct ColorTableId	ColorTableId;
typedef struct ColorTable	ColorTable;
typedef struct PhotoInstance	PhotoInstance;
typedef struct PhotoModel	PhotoModel;

/*
 * A signed 8-bit integral type. If chars are unsigned and the compiler isn't
 * an ANSI one, then we have to use short instead (which wastes space) to get
 * signed behavior.
 */

#if defined(__STDC__) || defined(_AIX)
    typedef signed char schar;
#else
#   ifndef __CHAR_UNSIGNED__
	typedef char schar;
#   else
	typedef short schar;
#   endif
#endif








/*
 * The maximum number of pixels to transmit to the server in a single
 * XPutImage call.
 */

#define MAX_PIXELS 65536








|



|

















>
>
>
>
>
>
>







23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include "tkUnixInt.h"
#endif

/*
 * Forward declarations of the structures we define.
 */

#define PhotoModel PhotoMaster
typedef struct ColorTableId	ColorTableId;
typedef struct ColorTable	ColorTable;
typedef struct PhotoInstance	PhotoInstance;
typedef struct PhotoMaster	PhotoMaster;

/*
 * A signed 8-bit integral type. If chars are unsigned and the compiler isn't
 * an ANSI one, then we have to use short instead (which wastes space) to get
 * signed behavior.
 */

#if defined(__STDC__) || defined(_AIX)
    typedef signed char schar;
#else
#   ifndef __CHAR_UNSIGNED__
	typedef char schar;
#   else
	typedef short schar;
#   endif
#endif

/*
 * An unsigned 32-bit integral type, used for pixel values. We use int rather
 * than long here to accommodate those systems where longs are 64 bits.
 */

typedef unsigned int pixel;

/*
 * The maximum number of pixels to transmit to the server in a single
 * XPutImage call.
 */

#define MAX_PIXELS 65536

83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
 * structure of the following type is used to store the allocated pixel values
 * and other information:
 */

struct ColorTable {
    ColorTableId id;		/* Information used in selecting this color
				 * table. */
#if TCL_MAJOR_VERSION > 8
    size_t	refCount;		/* Number of instances using this map. */
    size_t liveRefCount;		/* Number of instances which are actually in
				 * use, using this map. */
    int	flags;			/* See below. */
#else
    int	flags;			/* See below. */
    unsigned int	refCount;		/* Number of instances using this map. */
    unsigned int liveRefCount;		/* Number of instances which are actually in
				 * use, using this map. */
#endif
    int	numColors;		/* Number of colors allocated for this map. */

    XVisualInfo	visualInfo;	/* Information about the visual for windows
				 * using this color table. */

    unsigned redValues[256];	/* Maps 8-bit values of red intensity to a
				 * pixel value or index in pixelMap. */
    unsigned greenValues[256];	/* Ditto for green intensity. */
    unsigned blueValues[256];	/* Ditto for blue intensity. */
    unsigned long *pixelMap;	/* Actual pixel values allocated. */

    unsigned char colorQuant[3][256];
				/* Maps 8-bit intensities to quantized
				 * intensities. The first index is 0 for red,
				 * 1 for green, 2 for blue. */
};







<
<
<
<

<
<
|
|

<





|

|
|







90
91
92
93
94
95
96




97


98
99
100

101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
 * structure of the following type is used to store the allocated pixel values
 * and other information:
 */

struct ColorTable {
    ColorTableId id;		/* Information used in selecting this color
				 * table. */




    int	flags;			/* See below. */


    int	refCount;		/* Number of instances using this map. */
    int liveRefCount;		/* Number of instances which are actually in
				 * use, using this map. */

    int	numColors;		/* Number of colors allocated for this map. */

    XVisualInfo	visualInfo;	/* Information about the visual for windows
				 * using this color table. */

    pixel redValues[256];	/* Maps 8-bit values of red intensity to a
				 * pixel value or index in pixelMap. */
    pixel greenValues[256];	/* Ditto for green intensity. */
    pixel blueValues[256];	/* Ditto for blue intensity. */
    unsigned long *pixelMap;	/* Actual pixel values allocated. */

    unsigned char colorQuant[3][256];
				/* Maps 8-bit intensities to quantized
				 * intensities. The first index is 0 for red,
				 * 1 for green, 2 for blue. */
};
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#define DISPOSE_PENDING		4
#define MAP_COLORS		8

/*
 * Definition of the data associated with each photo image model.
 */

struct PhotoModel {
    Tk_ImageModel tkModel;	/* Tk's token for image model. NULL means the
				 * image is being deleted. */
    Tcl_Interp *interp;		/* Interpreter associated with the application
				 * using this image. */
    Tcl_Command imageCmd;	/* Token for image command (used to delete it
				 * when the image goes away). NULL means the
				 * image command has already been deleted. */
    int	flags;			/* Sundry flags, defined below. */







|
|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#define DISPOSE_PENDING		4
#define MAP_COLORS		8

/*
 * Definition of the data associated with each photo image model.
 */

struct PhotoMaster {
    Tk_ImageMaster tkMaster;	/* Tk's token for image model. NULL means the
				 * image is being deleted. */
    Tcl_Interp *interp;		/* Interpreter associated with the application
				 * using this image. */
    Tcl_Command imageCmd;	/* Token for image command (used to delete it
				 * when the image goes away). NULL means the
				 * image command has already been deleted. */
    int	flags;			/* Sundry flags, defined below. */
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    TkRegion validRegion;	/* Tk region indicating which parts of the
				 * image have valid image data. */
    PhotoInstance *instancePtr;	/* First in the list of instances associated
				 * with this model. */
};

/*
 * Bit definitions for the flags field of a PhotoModel.
 * COLOR_IMAGE:			1 means that the image has different color
 *				components.
 * IMAGE_CHANGED:		1 means that the instances of this image need
 *				to be redithered.
 * COMPLEX_ALPHA:		1 means that the instances of this image have
 *				alpha values that aren't 0 or 255, and so need
 *				the copy-merge-replace renderer .







|







165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
    TkRegion validRegion;	/* Tk region indicating which parts of the
				 * image have valid image data. */
    PhotoInstance *instancePtr;	/* First in the list of instances associated
				 * with this model. */
};

/*
 * Bit definitions for the flags field of a PhotoMaster.
 * COLOR_IMAGE:			1 means that the image has different color
 *				components.
 * IMAGE_CHANGED:		1 means that the instances of this image need
 *				to be redithered.
 * COMPLEX_ALPHA:		1 means that the instances of this image have
 *				alpha values that aren't 0 or 255, and so need
 *				the copy-merge-replace renderer .
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216

/*
 * The following data structure represents all of the instances of a photo
 * image in windows on a given screen that are using the same colormap.
 */

struct PhotoInstance {
    PhotoModel *modelPtr;	/* Pointer to model for image. */
    Display *display;		/* Display for windows using this instance. */
    Colormap colormap;		/* The image may only be used in windows with
				 * this particular colormap. */
    PhotoInstance *nextPtr;	/* Pointer to the next instance in the list of
				 * instances associated with this model. */
#if TCL_MAJOR_VERSION > 8
    size_t refCount;		/* Number of instances using this structure. */
#else
    unsigned int refCount;	/* Number of instances using this structure. */
#endif
    Tk_Uid palette;		/* Palette for these particular instances. */
    double gamma;		/* Gamma value for these instances. */
    Tk_Uid defaultPalette;	/* Default palette to use if a palette is not
				 * specified for the model. */
    ColorTable *colorTablePtr;	/* Pointer to information about colors
				 * allocated for image display in windows like
				 * this one. */







|





<
|
<
<
<







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

205



206
207
208
209
210
211
212

/*
 * The following data structure represents all of the instances of a photo
 * image in windows on a given screen that are using the same colormap.
 */

struct PhotoInstance {
    PhotoMaster *masterPtr;	/* Pointer to model for image. */
    Display *display;		/* Display for windows using this instance. */
    Colormap colormap;		/* The image may only be used in windows with
				 * this particular colormap. */
    PhotoInstance *nextPtr;	/* Pointer to the next instance in the list of
				 * instances associated with this model. */

    int refCount;		/* Number of instances using this structure. */



    Tk_Uid palette;		/* Palette for these particular instances. */
    double gamma;		/* Gamma value for these instances. */
    Tk_Uid defaultPalette;	/* Default palette to use if a palette is not
				 * specified for the model. */
    ColorTable *colorTablePtr;	/* Pointer to information about colors
				 * allocated for image display in windows like
				 * this one. */
Deleted generic/tkImgSVGnano.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
/*
 * tkImgSVGnano.c
 *
 *	A photo file handler for SVG files.
 *
 * Copyright (c) 2013-14 Mikko Mononen memon@inside.org
 * Copyright (c) 2018 Christian Gollwitzer auriocus@gmx.de
 * Copyright (c) 2018 Christian Werner https://www.androwish.org/
 * Copyright (c) 2018 Rene Zaumseil r.zaumseil@freenet.de
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * This handler is build using the original nanosvg library files from
 * https://github.com/memononen/nanosvg
 *
 */

#include "tkInt.h"
#define NANOSVG_malloc	ckalloc
#define NANOSVG_realloc	ckrealloc
#define NANOSVG_free	ckfree
#define NANOSVG_SCOPE MODULE_SCOPE
#define NANOSVG_ALL_COLOR_KEYWORDS
#define NANOSVG_IMPLEMENTATION
#include "nanosvg.h"
#define NANOSVGRAST_IMPLEMENTATION
#include "nanosvgrast.h"

/* Additional parameters to nsvgRasterize() */

typedef struct {
    double scale;
    int scaleToHeight;
    int scaleToWidth;
} RastOpts;

/*
 * Per interp cache of last NSVGimage which was matched to
 * be immediately rasterized after the match. This helps to
 * eliminate double parsing of the SVG file/string.
 */

typedef struct {
    /* A poiner to remember if it is the same svn image (data)
     * It is a Tcl_Channel if image created by -file option
     * or a Tcl_Obj, if image is created with the -data option
     */
    ClientData dataOrChan;
    Tcl_DString formatString;
    NSVGimage *nsvgImage;
    RastOpts ropts;
} NSVGcache;

static int		FileMatchSVG(Tcl_Channel chan, const char *fileName,
			    Tcl_Obj *format, int *widthPtr, int *heightPtr,
			    Tcl_Interp *interp);
static int		FileReadSVG(Tcl_Interp *interp, Tcl_Channel chan,
			    const char *fileName, Tcl_Obj *format,
			    Tk_PhotoHandle imageHandle, int destX, int destY,
			    int width, int height, int srcX, int srcY);
static int		StringMatchSVG(Tcl_Obj *dataObj, Tcl_Obj *format,
			    int *widthPtr, int *heightPtr, Tcl_Interp *interp);
static int		StringReadSVG(Tcl_Interp *interp, Tcl_Obj *dataObj,
			    Tcl_Obj *format, Tk_PhotoHandle imageHandle,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY);
static NSVGimage *	ParseSVGWithOptions(Tcl_Interp *interp,
			    const char *input, TkSizeT length, Tcl_Obj *format,
			    RastOpts *ropts);
static int		RasterizeSVG(Tcl_Interp *interp,
			    Tk_PhotoHandle imageHandle, NSVGimage *nsvgImage,
			    int destX, int destY, int width, int height,
			    int srcX, int srcY, RastOpts *ropts);
static double		GetScaleFromParameters(NSVGimage *nsvgImage,
			    RastOpts *ropts, int *widthPtr, int *heightPtr);
static NSVGcache *	GetCachePtr(Tcl_Interp *interp);
static int		CacheSVG(Tcl_Interp *interp, ClientData dataOrChan,
			    Tcl_Obj *formatObj, NSVGimage *nsvgImage,
			    RastOpts *ropts);
static NSVGimage *	GetCachedSVG(Tcl_Interp *interp, ClientData dataOrChan,
			    Tcl_Obj *formatObj, RastOpts *ropts);
static void		CleanCache(Tcl_Interp *interp);
static void		FreeCache(ClientData clientData, Tcl_Interp *interp);

/*
 * The format record for the SVG nano file format:
 */

Tk_PhotoImageFormat tkImgFmtSVGnano = {
    "svg",			/* name */
    FileMatchSVG,		/* fileMatchProc */
    StringMatchSVG,		/* stringMatchProc */
    FileReadSVG,		/* fileReadProc */
    StringReadSVG,		/* stringReadProc */
    NULL,			/* fileWriteProc */
    NULL,			/* stringWriteProc */
    NULL
};

/*
 *----------------------------------------------------------------------
 *
 * FileMatchSVG --
 *
 *	This function is invoked by the photo image type to see if a file
 *	contains image data in SVG format.
 *
 * Results:
 *	The return value is >0 if the file can be successfully parsed,
 *	and 0 otherwise.
 *
 * Side effects:
 *	The file is saved in the internal cache for further use.
 *
 *----------------------------------------------------------------------
 */

static int
FileMatchSVG(
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    TkSizeT length;
    Tcl_Obj *dataObj = Tcl_NewObj();
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;
    (void)fileName;

    CleanCache(interp);
    if (Tcl_ReadChars(chan, dataObj, -1, 0) == TCL_IO_FAILURE) {
	/* in case of an error reading the file */
	Tcl_DecrRefCount(dataObj);
	return 0;
    }
    data = TkGetStringFromObj(dataObj, &length);
    nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts);
    Tcl_DecrRefCount(dataObj);
    if (nsvgImage != NULL) {
        GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr);
        if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) {
	    nsvgDelete(nsvgImage);
	    return 0;
        }
        if (!CacheSVG(interp, chan, formatObj, nsvgImage, &ropts)) {
	    nsvgDelete(nsvgImage);
        }
        return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * FileReadSVG --
 *
 *	This function is called by the photo image type to read SVG format
 *	data from a file and write it into a given photo image.
 *
 * Results:
 *	A standard TCL completion code. If TCL_ERROR is returned then an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	The access position in file f is changed, and new data is added to the
 *	image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
FileReadSVG(
    Tcl_Interp *interp,
    Tcl_Channel chan,
    const char *fileName,
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, chan, formatObj, &ropts);
    (void)fileName;

    if (nsvgImage == NULL) {
        Tcl_Obj *dataObj = Tcl_NewObj();

	if (Tcl_ReadChars(chan, dataObj, -1, 0) == TCL_IO_FAILURE) {
	    /* in case of an error reading the file */
	    Tcl_DecrRefCount(dataObj);
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("read error", -1));
	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "READ_ERROR", NULL);
	    return TCL_ERROR;
	}
	data = TkGetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
	Tcl_DecrRefCount(dataObj);
	if (nsvgImage == NULL) {
	    return TCL_ERROR;
	}
    }
    return RasterizeSVG(interp, imageHandle, nsvgImage, destX, destY,
		width, height, srcX, srcY, &ropts);
}

/*
 *----------------------------------------------------------------------
 *
 * StringMatchSVG --
 *
 *	This function is invoked by the photo image type to see if a string
 *	contains image data in SVG format.
 *
 * Results:
 *	The return value is >0 if the file can be successfully parsed,
 *	and 0 otherwise.
 *
 * Side effects:
 *	The file is saved in the internal cache for further use.
 *
 *----------------------------------------------------------------------
 */

static int
StringMatchSVG(
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    int *widthPtr, int *heightPtr,
    Tcl_Interp *interp)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage;

    CleanCache(interp);
    data = TkGetStringFromObj(dataObj, &length);
    nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj, &ropts);
    if (nsvgImage != NULL) {
        GetScaleFromParameters(nsvgImage, &ropts, widthPtr, heightPtr);
        if ((*widthPtr <= 0.0) || (*heightPtr <= 0.0)) {
	    nsvgDelete(nsvgImage);
	    return 0;
        }
        if (!CacheSVG(interp, dataObj, formatObj, nsvgImage, &ropts)) {
	    nsvgDelete(nsvgImage);
        }
        return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * StringReadSVG --
 *
 *	This function is called by the photo image type to read SVG format
 *	data from a string and write it into a given photo image.
 *
 * Results:
 *	A standard TCL completion code. If TCL_ERROR is returned then an error
 *	message is left in the interp's result.
 *
 * Side effects:
 *	New data is added to the image given by imageHandle.
 *
 *----------------------------------------------------------------------
 */

static int
StringReadSVG(
    Tcl_Interp *interp,
    Tcl_Obj *dataObj,
    Tcl_Obj *formatObj,
    Tk_PhotoHandle imageHandle,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY)
{
    TkSizeT length;
    const char *data;
    RastOpts ropts;
    NSVGimage *nsvgImage = GetCachedSVG(interp, dataObj, formatObj, &ropts);

    if (nsvgImage == NULL) {
        data = TkGetStringFromObj(dataObj, &length);
	nsvgImage = ParseSVGWithOptions(interp, data, length, formatObj,
			    &ropts);
    }
    if (nsvgImage == NULL) {
	return TCL_ERROR;
    }
    return RasterizeSVG(interp, imageHandle, nsvgImage, destX, destY,
		width, height, srcX, srcY, &ropts);
}

/*
 *----------------------------------------------------------------------
 *
 * ParseSVGWithOptions --
 *
 *	This function is called to parse the given input string as SVG.
 *
 * Results:
 *	Return a newly create NSVGimage on success, and NULL otherwise.
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static NSVGimage *
ParseSVGWithOptions(
    Tcl_Interp *interp,
    const char *input,
    TkSizeT length,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    Tcl_Obj **objv = NULL;
    int objc = 0;
    double dpi = 96.0;
    char *inputCopy = NULL;
    NSVGimage *nsvgImage;
    int parameterScaleSeen = 0;
    static const char *const fmtOptions[] = {
        "-dpi", "-scale", "-scaletoheight", "-scaletowidth", NULL
    };
    enum fmtOptionsEnum {
	OPT_DPI, OPT_SCALE, OPT_SCALE_TO_HEIGHT, OPT_SCALE_TO_WIDTH
    };

    /*
     * The parser destroys the original input string,
     * therefore first duplicate.
     */

    inputCopy = (char *)attemptckalloc(length+1);
    if (inputCopy == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc data buffer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto error;
    }
    memcpy(inputCopy, input, length);
    inputCopy[length] = '\0';

    /*
     * Process elements of format specification as a list.
     */

    ropts->scale = 1.0;
    ropts->scaleToHeight = 0;
    ropts->scaleToWidth = 0;
    if ((formatObj != NULL) &&
	    Tcl_ListObjGetElements(interp, formatObj, &objc, &objv) != TCL_OK) {
        goto error;
    }
    for (; objc > 0 ; objc--, objv++) {
	int optIndex;

	/*
	 * Ignore the "svg" part of the format specification.
	 */

	if (!strcasecmp(Tcl_GetString(objv[0]), "svg")) {
	    continue;
	}

	if (Tcl_GetIndexFromObjStruct(interp, objv[0], fmtOptions,
		sizeof(char *), "option", 0, &optIndex) == TCL_ERROR) {
	    goto error;
	}

	if (objc < 2) {
	    ckfree(inputCopy);
	    inputCopy = NULL;
	    Tcl_WrongNumArgs(interp, 1, objv, "value");
	    goto error;
	}

	objc--;
	objv++;

	/*
	 * check that only one scale option is given
	 */
	switch ((enum fmtOptionsEnum)optIndex) {
	case OPT_SCALE:
	case OPT_SCALE_TO_HEIGHT:
	case OPT_SCALE_TO_WIDTH:
	    if ( parameterScaleSeen ) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"only one of -scale, -scaletoheight, -scaletowidth may be given", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    parameterScaleSeen = 1;
	    break;
	default:
	    break;
	}

	/*
	 * Decode parameters
	 */
	switch ((enum fmtOptionsEnum) optIndex) {
	case OPT_DPI:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &dpi) == TCL_ERROR) {
	        goto error;
	    }
	    if (dpi < 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-dpi value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_DPI",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE:
	    if (Tcl_GetDoubleFromObj(interp, objv[0], &ropts->scale) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scale <= 0.0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scale value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_HEIGHT:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToHeight) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToHeight <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletoheight value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	case OPT_SCALE_TO_WIDTH:
	    if (Tcl_GetIntFromObj(interp, objv[0], &ropts->scaleToWidth) ==
		TCL_ERROR) {
	        goto error;
	    }
	    if (ropts->scaleToWidth <= 0) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"-scaletowidth value must be positive", -1));
		Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "BAD_SCALE",
			NULL);
		goto error;
	    }
	    break;
	}
    }

    nsvgImage = nsvgParse(inputCopy, "px", (float) dpi);
    if (nsvgImage == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot parse SVG image", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "PARSE_ERROR", NULL);
	goto error;
    }
    ckfree(inputCopy);
    return nsvgImage;

error:
    if (inputCopy != NULL) {
        ckfree(inputCopy);
    }
    return NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * RasterizeSVG --
 *
 *	This function is called to rasterize the given nsvgImage and
 *	fill the imageHandle with data.
 *
 * Results:
 *	A standard TCL completion code. If TCL_ERROR is returned then an error
 *	message is left in the interp's result.
 *
 *
 * Side effects:
 *	On error the given nsvgImage will be deleted.
 *
 *----------------------------------------------------------------------
 */

static int
RasterizeSVG(
    Tcl_Interp *interp,
    Tk_PhotoHandle imageHandle,
    NSVGimage *nsvgImage,
    int destX, int destY,
    int width, int height,
    int srcX, int srcY,
    RastOpts *ropts)
{
    int w, h, c;
    NSVGrasterizer *rast;
    unsigned char *imgData;
    Tk_PhotoImageBlock svgblock;
    double scale;
    (void)srcX;
    (void)srcY;

    scale = GetScaleFromParameters(nsvgImage, ropts, &w, &h);

    rast = nsvgCreateRasterizer();
    if (rast == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot initialize rasterizer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "RASTERIZER_ERROR",
		NULL);
	goto cleanAST;
    }
    imgData = (unsigned char *)attemptckalloc(w * h *4);
    if (imgData == NULL) {
	Tcl_SetObjResult(interp, Tcl_NewStringObj("cannot alloc image buffer", -1));
	Tcl_SetErrorCode(interp, "TK", "IMAGE", "SVG", "OUT_OF_MEMORY", NULL);
	goto cleanRAST;
    }
    nsvgRasterize(rast, nsvgImage, 0, 0,
	    (float) scale, imgData, w, h, w * 4);
    /* transfer the data to a photo block */
    svgblock.pixelPtr = imgData;
    svgblock.width = w;
    svgblock.height = h;
    svgblock.pitch = w * 4;
    svgblock.pixelSize = 4;
    for (c = 0; c <= 3; c++) {
	svgblock.offset[c] = c;
    }
    if (Tk_PhotoExpand(interp, imageHandle,
		destX + width, destY + height) != TCL_OK) {
	goto cleanRAST;
    }
    if (Tk_PhotoPutBlock(interp, imageHandle, &svgblock, destX, destY,
		width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) {
	goto cleanimg;
    }
    ckfree(imgData);
    nsvgDeleteRasterizer(rast);
    nsvgDelete(nsvgImage);
    return TCL_OK;

cleanimg:
    ckfree(imgData);

cleanRAST:
    nsvgDeleteRasterizer(rast);

cleanAST:
    nsvgDelete(nsvgImage);
    return TCL_ERROR;
}

/*
 *----------------------------------------------------------------------
 *
 * GetScaleFromParameters --
 *
 *	Get the scale value from the already parsed parameters -scale,
 *	-scaletoheight and -scaletowidth.
 *
 *	The image width and height is also returned.
 *
 * Results:
 *	The evaluated or configured scale value, or 0.0 on failure
 *
 * Side effects:
 *	heightPtr and widthPtr are set to height and width of the image.
 *
 *----------------------------------------------------------------------
 */

static double
GetScaleFromParameters(
    NSVGimage *nsvgImage,
    RastOpts *ropts,
    int *widthPtr,
    int *heightPtr)
{
    double scale;
    int width, height;

    if ((nsvgImage->width == 0.0) || (nsvgImage->height == 0.0)) {
        width = height = 0;
        scale = 1.0;
    } else if (ropts->scaleToHeight > 0) {
	/*
	 * Fixed height
	 */
	height = ropts->scaleToHeight;
	scale = height / nsvgImage->height;
	width = (int) ceil(nsvgImage->width * scale);
    } else if (ropts->scaleToWidth > 0) {
	/*
	 * Fixed width
	 */
	width = ropts->scaleToWidth;
	scale = width / nsvgImage->width;
	height = (int) ceil(nsvgImage->height * scale);
    } else {
	/*
	 * Scale factor
	 */
	scale = ropts->scale;
	width = (int) ceil(nsvgImage->width * scale);
	height = (int) ceil(nsvgImage->height * scale);
    }

    *heightPtr = height;
    *widthPtr = width;
    return scale;
}

/*
 *----------------------------------------------------------------------
 *
 * GetCachePtr --
 *
 *	This function is called to get the per interpreter used
 *	svg image cache.
 *
 * Results:
 * 	Return a pointer to the used cache.
 *
 * Side effects:
 *	Initialize the cache on the first call.
 *
 *----------------------------------------------------------------------
 */

static NSVGcache *
GetCachePtr(
    Tcl_Interp *interp
) {
    NSVGcache *cachePtr = (NSVGcache *)Tcl_GetAssocData(interp, "tksvgnano", NULL);
    if (cachePtr == NULL) {
	cachePtr = (NSVGcache *)ckalloc(sizeof(NSVGcache));
	cachePtr->dataOrChan = NULL;
	Tcl_DStringInit(&cachePtr->formatString);
	cachePtr->nsvgImage = NULL;
	Tcl_SetAssocData(interp, "tksvgnano", FreeCache, cachePtr);
    }
    return cachePtr;
}

/*
 *----------------------------------------------------------------------
 *
 * CacheSVG --
 *
 *	Add the given svg image informations to the cache for further usage.
 *
 * Results:
 *	Return 1 on success, and 0 otherwise.
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static int
CacheSVG(
    Tcl_Interp *interp,
    ClientData dataOrChan,
    Tcl_Obj *formatObj,
    NSVGimage *nsvgImage,
    RastOpts *ropts)
{
    TkSizeT length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);

    if (cachePtr != NULL) {
        cachePtr->dataOrChan = dataOrChan;
	if (formatObj != NULL) {
	    data = TkGetStringFromObj(formatObj, &length);
	    Tcl_DStringAppend(&cachePtr->formatString, data, length);
	}
	cachePtr->nsvgImage = nsvgImage;
	cachePtr->ropts = *ropts;
	return 1;
    }
    return 0;
}

/*
 *----------------------------------------------------------------------
 *
 * GetCachedSVG --
 *
 *	Try to get the NSVGimage from the internal cache.
 *
 * Results:
 *	Return the found NSVGimage on success, and NULL otherwise.
 *
 * Side effects:
 *	Calls the CleanCache() function.
 *
 *----------------------------------------------------------------------
 */

static NSVGimage *
GetCachedSVG(
    Tcl_Interp *interp,
    ClientData dataOrChan,
    Tcl_Obj *formatObj,
    RastOpts *ropts)
{
    TkSizeT length;
    const char *data;
    NSVGcache *cachePtr = GetCachePtr(interp);
    NSVGimage *nsvgImage = NULL;

    if ((cachePtr != NULL) && (cachePtr->nsvgImage != NULL) &&
	(cachePtr->dataOrChan == dataOrChan)) {
        if (formatObj != NULL) {
	    data = TkGetStringFromObj(formatObj, &length);
	    if (strcmp(data, Tcl_DStringValue(&cachePtr->formatString)) == 0) {
	        nsvgImage = cachePtr->nsvgImage;
		*ropts = cachePtr->ropts;
		cachePtr->nsvgImage = NULL;
	    }
	} else if (Tcl_DStringLength(&cachePtr->formatString) == 0) {
	    nsvgImage = cachePtr->nsvgImage;
	    *ropts = cachePtr->ropts;
	    cachePtr->nsvgImage = NULL;
	}
    }
    CleanCache(interp);
    return nsvgImage;
}

/*
 *----------------------------------------------------------------------
 *
 * CleanCache --
 *
 *	Reset the cache and delete the saved image in it.
 *
 * Results:
 *
 * Side effects:
 *
 *----------------------------------------------------------------------
 */

static void
CleanCache(Tcl_Interp *interp)
{
    NSVGcache *cachePtr = GetCachePtr(interp);

    if (cachePtr != NULL) {
        cachePtr->dataOrChan = NULL;
        Tcl_DStringSetLength(&cachePtr->formatString, 0);
	if (cachePtr->nsvgImage != NULL) {
	    nsvgDelete(cachePtr->nsvgImage);
	    cachePtr->nsvgImage = NULL;
	}
    }
}

/*
 *----------------------------------------------------------------------
 *
 * FreeCache --
 *
 *	This function is called to clean up the internal cache data.
 *
 * Results:
 *
 * Side effects:
 *	Existing image data in the cache and the cache will be deleted.
 *
 *----------------------------------------------------------------------
 */

static void
FreeCache(ClientData clientData, Tcl_Interp *interp)
{
    NSVGcache *cachePtr = (NSVGcache *)clientData;
    (void)interp;

    Tcl_DStringFree(&cachePtr->formatString);
    if (cachePtr->nsvgImage != NULL) {
        nsvgDelete(cachePtr->nsvgImage);
    }
    ckfree(cachePtr);
}

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<




















































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































Changes to generic/tkImgUtil.c.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
     */

    dataWidth = image->bytes_per_line;
    if (dataWidth % alignment) {
	dataWidth += (alignment - (dataWidth % alignment));
    }

    data = (char *)ckalloc(dataWidth * image->height);

    destPtr = data;
    for (i = 0; i < image->height; i++) {
	srcPtr = &image->data[i * image->bytes_per_line];
	for (j = 0; j < dataWidth; j++) {
	    if (j >= image->bytes_per_line) {
		*destPtr = 0;







|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
     */

    dataWidth = image->bytes_per_line;
    if (dataWidth % alignment) {
	dataWidth += (alignment - (dataWidth % alignment));
    }

    data = ckalloc(dataWidth * image->height);

    destPtr = data;
    for (i = 0; i < image->height; i++) {
	srcPtr = &image->data[i * image->bytes_per_line];
	for (j = 0; j < dataWidth; j++) {
	    if (j >= image->bytes_per_line) {
		*destPtr = 0;
Changes to generic/tkInt.decls.
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	    Display *display, Drawable drawable, GC gc, GC outlineGC)
}
declare 21 {
    int TkFindStateNum(Tcl_Interp *interp, const char *option,
	    const TkStateMap *mapPtr, const char *strKey)
}
declare 22 {
    const char *TkFindStateString(const TkStateMap *mapPtr, int numKey)
}
declare 23 {
    void TkFocusDeadWindow(TkWindow *winPtr)
}
declare 24 {
    int TkFocusFilterEvent(TkWindow *winPtr, XEvent *eventPtr)
}







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
	    Display *display, Drawable drawable, GC gc, GC outlineGC)
}
declare 21 {
    int TkFindStateNum(Tcl_Interp *interp, const char *option,
	    const TkStateMap *mapPtr, const char *strKey)
}
declare 22 {
    CONST86 char *TkFindStateString(const TkStateMap *mapPtr, int numKey)
}
declare 23 {
    void TkFocusDeadWindow(TkWindow *winPtr)
}
declare 24 {
    int TkFocusFilterEvent(TkWindow *winPtr, XEvent *eventPtr)
}
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	    TkWindow *destPtr, int leaveType, int enterType,
	    Tcl_QueuePosition position)
}
declare 45 {
    void TkInstallFrameMenu(Tk_Window tkwin)
}
declare 46 {
    const char *TkKeysymToString(KeySym keysym)
}
declare 47 {
    int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[])
}
declare 48 {
    double TkLineToPoint(double end1Ptr[], double end2Ptr[], double pointPtr[])
}







|







178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
	    TkWindow *destPtr, int leaveType, int enterType,
	    Tcl_QueuePosition position)
}
declare 45 {
    void TkInstallFrameMenu(Tk_Window tkwin)
}
declare 46 {
    CONST86 char *TkKeysymToString(KeySym keysym)
}
declare 47 {
    int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[])
}
declare 48 {
    double TkLineToPoint(double end1Ptr[], double end2Ptr[], double pointPtr[])
}
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
declare 78 {
    int TkReadBitmapFile(Display *display, Drawable d, const char *filename,
	    unsigned int *width_return, unsigned int *height_return,
	    Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return)
}
declare 79 {
    int TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
	    int width, int height, int dx, int dy, Region damageRgn)
}
declare 80 {
    void TkSelDeadWindow(TkWindow *winPtr)
}
declare 81 {
    void TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr)
}







|







284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
declare 78 {
    int TkReadBitmapFile(Display *display, Drawable d, const char *filename,
	    unsigned int *width_return, unsigned int *height_return,
	    Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return)
}
declare 79 {
    int TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
	    int width, int height, int dx, int dy, TkRegion damageRgn)
}
declare 80 {
    void TkSelDeadWindow(TkWindow *winPtr)
}
declare 81 {
    void TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr)
}
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    TkMainInfo *TkGetMainInfoList(void)
}
declare 108 {
    int TkGetWindowFromObj(Tcl_Interp *interp, Tk_Window tkwin,
	    Tcl_Obj *objPtr, Tk_Window *windowPtr)
}
declare 109 {
    const char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
}
declare 110 {
    void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont)
}
declare 111 {
    Tcl_Obj *TkpGetSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 112 {
    void TkpMenuThreadInit(void)
}
declare 113 {
    int XClipBox(Region rgn, XRectangle *rect_return)
}
declare 114 {
    Region XCreateRegion(void)
}
declare 115 {
    int XDestroyRegion(Region rgn)
}
declare 116 {
    int XIntersectRegion(Region sra, Region srcb, Region dr_return)
}
declare 117 {
    int XRectInRegion(Region rgn, int x, int y, unsigned int width,
	    unsigned int height)
}
declare 118 {
    int XSetRegion(Display *display, GC gc, Region rgn)
}
declare 119 {
    int XUnionRectWithRegion(XRectangle *rect,
	    Region src, Region dr_return)
}
declare 121 aqua {
    Pixmap TkpCreateNativeBitmap(Display *display, const void *source)
}
declare 122 aqua {
    void TkpDefineNativeBitmaps(void)
}







|












|


|


|


|


|



|


|
|







385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
    TkMainInfo *TkGetMainInfoList(void)
}
declare 108 {
    int TkGetWindowFromObj(Tcl_Interp *interp, Tk_Window tkwin,
	    Tcl_Obj *objPtr, Tk_Window *windowPtr)
}
declare 109 {
    CONST86 char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr)
}
declare 110 {
    void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont)
}
declare 111 {
    Tcl_Obj *TkpGetSystemDefault(Tk_Window tkwin,
	    const char *dbName, const char *className)
}
declare 112 {
    void TkpMenuThreadInit(void)
}
declare 113 {
    int TkClipBox(TkRegion rgn, XRectangle *rect_return)
}
declare 114 {
    TkRegion TkCreateRegion(void)
}
declare 115 {
    int TkDestroyRegion(TkRegion rgn)
}
declare 116 {
    int TkIntersectRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return)
}
declare 117 {
    int TkRectInRegion(TkRegion rgn, int x, int y, unsigned int width,
	    unsigned int height)
}
declare 118 {
    int TkSetRegion(Display *display, GC gc, TkRegion rgn)
}
declare 119 {
    int TkUnionRectWithRegion(XRectangle *rect,
	    TkRegion src, TkRegion dr_return)
}
declare 121 aqua {
    Pixmap TkpCreateNativeBitmap(Display *display, const void *source)
}
declare 122 aqua {
    void TkpDefineNativeBitmaps(void)
}
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
declare 138 {
    KeySym TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr)
}
declare 139 {
    void TkpInitKeymapInfo(TkDisplay *dispPtr)
}
declare 140 {
    Region TkPhotoGetValidRegion(Tk_PhotoHandle handle)
}
declare 141 {
    TkWindow **TkWmStackorderToplevel(TkWindow *parentPtr)
}
declare 142 {
    void TkFocusFree(TkMainInfo *mainPtr)
}
declare 143 {
    void TkClipCleanup(TkDisplay *dispPtr)
}
declare 144 {
    void TkGCCleanup(TkDisplay *dispPtr)
}
declare 145 {
    int XSubtractRegion(Region sra, Region srcb, Region dr_return)
}
declare 146 {
    void TkStylePkgInit(TkMainInfo *mainPtr)
}
declare 147 {
    void TkStylePkgFree(TkMainInfo *mainPtr)
}







|














|







448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
declare 138 {
    KeySym TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr)
}
declare 139 {
    void TkpInitKeymapInfo(TkDisplay *dispPtr)
}
declare 140 {
    TkRegion TkPhotoGetValidRegion(Tk_PhotoHandle handle)
}
declare 141 {
    TkWindow **TkWmStackorderToplevel(TkWindow *parentPtr)
}
declare 142 {
    void TkFocusFree(TkMainInfo *mainPtr)
}
declare 143 {
    void TkClipCleanup(TkDisplay *dispPtr)
}
declare 144 {
    void TkGCCleanup(TkDisplay *dispPtr)
}
declare 145 {
    int TkSubtractRegion(TkRegion sra, TkRegion srcb, TkRegion dr_return)
}
declare 146 {
    void TkStylePkgInit(TkMainInfo *mainPtr)
}
declare 147 {
    void TkStylePkgFree(TkMainInfo *mainPtr)
}
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
}
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 {







|







534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
}
declare 162 {
    struct TkTextIndex *TkTextMakeByteIndex(TkTextBTree tree,
	    const struct TkText *textPtr, int lineIndex,
	    int byteIndex, struct TkTextIndex *indexPtr)
}
declare 163 {
    int TkTextPrintIndex(const struct TkText *textPtr,
	    const struct TkTextIndex *indexPtr, char *string)
}
declare 164 {
    struct TkTextSegment *TkTextSetMark(struct TkText *textPtr,
	    const char *name, struct TkTextIndex *indexPtr)
}
declare 165 {
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
	    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)







|


|
|



|


|
|



|


|
|



|


|
|



|


|
|



|


|
|







563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
	    struct TkTextDispChunk *chunkPtr, int x, int y,
	    int height, int baseline, Display *display,
	    Drawable dst, int screenY)
}
# Next group of functions exposed due to [Bug 2768945].
declare 169 {
    int TkStateParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 170 {
    CONST86 char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 171 {
    int TkCanvasDashParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 172 {
    CONST86 char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 173 {
    int TkOffsetParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 174 {
    CONST86 char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 175 {
    int TkPixelParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 176 {
    CONST86 char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 177 {
    int TkOrientParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 178 {
    CONST86 char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}
declare 179 {
    int TkSmoothParseProc(ClientData clientData, Tcl_Interp *interp,
	    Tk_Window tkwin, const char *value, char *widgRec, int offset)
}
declare 180 {
    CONST86 char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin,
	    char *widgRec, int offset, Tcl_FreeProc **freeProcPtr)
}

# Angled text API, exposed for Emiliano Gavilán's RBC work.
declare 181 {
    void TkDrawAngledTextLayout(Display *display, Drawable drawable, GC gc,
	    Tk_TextLayout layout, int x, int y, double angle, int firstChar,
	    int lastChar)
638
639
640
641
642
643
644
645
646
647
648
649

650
651
652
653
654
655
656
# Support for aqua's inability to draw outside [NSView drawRect:]
declare 185 macosx {
    void TkpRedrawWidget(Tk_Window tkwin)
}
declare 186 macosx {
    int TkpWillDrawWidget(Tk_Window tkwin)
}

# Debugging / testing functions for photo images
declare 187 {
    int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, Tcl_Obj *data,
            Tcl_Obj *formatString, int *widthPtr, int *heightPtr)

}


##############################################################################

# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.







<
<

<
<
>







638
639
640
641
642
643
644


645


646
647
648
649
650
651
652
653
# Support for aqua's inability to draw outside [NSView drawRect:]
declare 185 macosx {
    void TkpRedrawWidget(Tk_Window tkwin)
}
declare 186 macosx {
    int TkpWillDrawWidget(Tk_Window tkwin)
}


declare 187 {


    void TkUnusedStubEntry(void)
}


##############################################################################

# Define the platform specific internal Tcl interface. These functions are
# only available on the designated platform.
914
915
916
917
918
919
920
921
922
923
924

925
926
927
928
929
930
931
}
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 {







<
|
|
<
>







911
912
913
914
915
916
917

918
919

920
921
922
923
924
925
926
927
}
declare 9 aqua {
    void TkMacOSXClearMenubarActive(void)
}
declare 10 aqua {
    int TkMacOSXDispatchMenuEvent(int menuID, int index)
}

declare 11 aqua {
    void TkMacOSXInstallCursor(int resizeOverride)

}
declare 12 aqua {
    void TkMacOSXHandleTearoffMenu(void)
}
declare 14 aqua {
    int TkMacOSXDoHLEvent(void *theEvent)
}
declare 16 aqua {
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
#declare 33 aqua {
#    void TkMacOSXUnregisterMacWindow(void *portPtr)
#}
declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    Region TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
    void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry)
}
declare 37 aqua {
    void TkMacOSXWindowOffset(void *wRef, int *xOffset, int *yOffset)
}







|







985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
#declare 33 aqua {
#    void TkMacOSXUnregisterMacWindow(void *portPtr)
#}
declare 34 aqua {
    int TkMacOSXUseMenuID(short macID)
}
declare 35 aqua {
    TkRegion TkMacOSXVisableClipRgn(TkWindow *winPtr)
}
declare 36 aqua {
    void TkMacOSXWinBounds(TkWindow *winPtr, void *geometry)
}
declare 37 aqua {
    void TkMacOSXWindowOffset(void *wRef, int *xOffset, int *yOffset)
}
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
declare 45 aqua {
    void TkMacOSXPreprocessMenu(void)
}
declare 46 aqua {
    int TkpIsWindowFloating(void *window)
}
declare 47 aqua {
    Tk_Window TkpGetCapture(void)
}
declare 49 aqua {
    Tk_Window TkMacOSXGetContainer(TkWindow *winPtr)
}
declare 50 aqua {
    int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state)
}
declare 51 aqua {
    void TkGenWMDestroyEvent(Tk_Window tkwin)
}







|


|







1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
declare 45 aqua {
    void TkMacOSXPreprocessMenu(void)
}
declare 46 aqua {
    int TkpIsWindowFloating(void *window)
}
declare 47 aqua {
    Tk_Window TkMacOSXGetCapture(void)
}
declare 49 aqua {
    Tk_Window TkGetTransientMaster(TkWindow *winPtr)
}
declare 50 aqua {
    int TkGenerateButtonEvent(int x, int y, Window window, unsigned int state)
}
declare 51 aqua {
    void TkGenWMDestroyEvent(Tk_Window tkwin)
}
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
	    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)







<
|
|
|
<
|







1331
1332
1333
1334
1335
1336
1337

1338
1339
1340

1341
1342
1343
1344
1345
1346
1347
1348
	    KeySym *k, Status *s)
}
declare 80 win {
    int TkPutImage(unsigned long *colors, int ncolors, Display *display,
	    Drawable d, GC gc, XImage *image, int src_x, int src_y,
	    int dest_x, int dest_y, unsigned int width, unsigned int height)
}

declare 81 win {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
	    int clip_y_origin, XRectangle rectangles[], int n, int ordering)

}
declare 82 win {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 83 win {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567

1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068

2069
2070
2071
2072
2073
    int XReparentWindow(Display *d, Window w, Window p, int x, int y)
}
declare 137 win {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}
declare 138 win {
    Region XPolygonRegion(XPoint *pts, int n, int rule)
}
declare 139 win {
    int XPointInRegion(Region rgn, int x, int y)
}
# For XIM
declare 140 win {
    XVaNestedList XVaCreateNestedList(int dummy, ...)
}
declare 141 win {
    char *XSetICValues(XIC xic, ...)
}
declare 142 win {
    char *XGetICValues(XIC xic, ...)
}
declare 143 win {
    void XSetICFocus(XIC xic)
}
declare 147 win {
    void XFreeFontSet(Display *display, XFontSet fontset)
}
declare 148 win {
    int XCloseIM(XIM im)
}
declare 149 win {
    Bool XRegisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 150 win {
    Bool XUnregisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 151 win {
    char *XSetLocaleModifiers(const char *modifier_list)
}
declare 152 win {
    XIM XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name,
	    char *res_class)
}
declare 153 win {
    char *XGetIMValues(XIM im, ...)
}
declare 154 win {
    char *XSetIMValues(XIM im, ...)
}
declare 155 win {
    XFontSet XCreateFontSet(Display *display, _Xconst char *base_font_name_list,
	    char ***missing_charset_list, int *missing_charset_count, char **def_string)
}
declare 156 win {
    void XFreeStringList(char **list)
}
declare 157 win {
    KeySym XkbKeycodeToKeysym(Display *d, unsigned int k, int g, int i)
}
declare 158 win {
    Display *XkbOpenDisplay(const char *name, int *ev_rtrn, int *err_rtrn,
	    int *major_rtrn, int *minor_rtrn, int *reason)

}

################################
# X functions for MacOSX

declare 0 macosx {
    int XSetDashes(Display *display, GC gc, int dash_offset,
	    _Xconst char *dash_list, int n)
}
declare 1 macosx {
    XModifierKeymap *XGetModifierMapping(Display *d)
}
declare 2 macosx {
    XImage *XCreateImage(Display *d, Visual *v, unsigned int ui1, int i1,
	    int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3,
	    int i4)
}
declare 3 macosx {
    XImage *XGetImage(Display *d, Drawable dr, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, unsigned long ul, int i3)
}
declare 4 macosx {
    char *XGetAtomName(Display *d, Atom a)
}
declare 5 macosx {
    char *XKeysymToString(KeySym k)
}
declare 6 macosx {
    Colormap XCreateColormap(Display *d, Window w, Visual *v, int i)
}
declare 7 macosx {
    GContext XGContextFromGC(GC g)
}
# second parameter was of type KeyCode
declare 8 macosx {
    KeySym XKeycodeToKeysym(Display *d, unsigned int k, int i)
}
declare 9 macosx {
    KeySym XStringToKeysym(_Xconst char *c)
}
declare 10 macosx {
    Window XRootWindow(Display *d, int i)
}
declare 11 macosx {
    XErrorHandler XSetErrorHandler(XErrorHandler x)
}
declare 12 macosx {
    Status XAllocColor(Display *d, Colormap c, XColor *xp)
}
declare 13 macosx {
    int XBell(Display *d, int i)
}
declare 14 macosx {
    int XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1,
	    int i2, _Xconst unsigned char *c, int i3)
}
declare 15 macosx {
    int XChangeWindowAttributes(Display *d, Window w, unsigned long ul,
	    XSetWindowAttributes *x)
}
declare 16 macosx {
    int XConfigureWindow(Display *d, Window w, unsigned int i,
	    XWindowChanges *x)
}
declare 17 macosx {
    int XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 18 macosx {
    int XCopyPlane(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1,
	    unsigned int ui2, int i3, int i4, unsigned long ul)
}
declare 19 macosx {
    Pixmap XCreateBitmapFromData(Display *display, Drawable d,
	    _Xconst char *data, unsigned int width, unsigned int height)
}
declare 20 macosx {
    int XDefineCursor(Display *d, Window w, Cursor c)
}
declare 21 macosx {
    int XDestroyWindow(Display *d, Window w)
}
declare 22 macosx {
    int XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 23 macosx {
    int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)
}
declare 24 macosx {
    int XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 25 macosx {
    int XFillArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 26 macosx {
    int XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x,
	    int i1, int i2, int i3)
}
declare 27 macosx {
    int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i)
}
declare 28 macosx {
    int XFreeColormap(Display *d, Colormap c)
}
declare 29 macosx {
    int XFreeColors(Display *d, Colormap c,
	    unsigned long *ulp, int i, unsigned long ul)
}
declare 30 macosx {
    int XFreeModifiermap(XModifierKeymap *x)
}
declare 31 macosx {
    Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1,
	    int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3,
	    unsigned int *ui4)
}
declare 32 macosx {
    int XGetWindowProperty(Display *d, Window w, Atom a1, long l1, long l2,
	    Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1,
	    unsigned long *ulp2, unsigned char **cpp)
}
declare 33 macosx {
    int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t)
}
declare 34 macosx {
    int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui,
	    int i1, int i2, Window w2, Cursor c, Time t)
}
declare 35 macosx {
    KeyCode XKeysymToKeycode(Display *d, KeySym k)
}
declare 36 macosx {
    int XMapWindow(Display *d, Window w)
}
declare 37 macosx {
    int XMoveResizeWindow(Display *d, Window w, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 38 macosx {
    int XMoveWindow(Display *d, Window w, int i1, int i2)
}
declare 39 macosx {
    Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3,
	    int *i1, int *i2, int *i3, int *i4, unsigned int *ui)
}
declare 40 macosx {
    int XRaiseWindow(Display *d, Window w)
}
declare 41 macosx {
    int XRefreshKeyboardMapping(XMappingEvent *x)
}
declare 42 macosx {
    int XResizeWindow(Display *d, Window w, unsigned int ui1,
	    unsigned int ui2)
}
declare 43 macosx {
    int XSelectInput(Display *d, Window w, long l)
}
declare 44 macosx {
    Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x)
}
declare 45 macosx {
    int XSetIconName(Display *d, Window w, _Xconst char *c)
}
declare 46 macosx {
    int XSetInputFocus(Display *d, Window w, int i, Time t)
}
declare 47 macosx {
    int XSetSelectionOwner(Display *d, Atom a, Window w, Time t)
}
declare 48 macosx {
    int XSetWindowBackground(Display *d, Window w, unsigned long ul)
}
declare 49 macosx {
    int XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p)
}
declare 50 macosx {
    int XSetWindowBorder(Display *d, Window w, unsigned long ul)
}
declare 51 macosx {
    int XSetWindowBorderPixmap(Display *d, Window w, Pixmap p)
}
declare 52 macosx {
    int XSetWindowBorderWidth(Display *d, Window w, unsigned int ui)
}
declare 53 macosx {
    int XSetWindowColormap(Display *d, Window w, Colormap c)
}
declare 54 macosx {
    int XUngrabKeyboard(Display *d, Time t)
}
declare 55 macosx {
    int XUngrabPointer(Display *d, Time t)
}
declare 56 macosx {
    int XUnmapWindow(Display *d, Window w)
}
declare 57 macosx {
    int TkPutImage(unsigned long *colors, int ncolors, Display *display,
	    Drawable d, GC gc, XImage *image, int src_x, int src_y,
	    int dest_x, int dest_y, unsigned int width, unsigned int height)
}
declare 58 macosx {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 59 macosx {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
}
declare 60 macosx {
    int XFreeGC(Display *display, GC gc)
}
declare 61 macosx {
    Atom XInternAtom(Display *display, _Xconst char *atom_name,
	    Bool only_if_exists)
}
declare 62 macosx {
    int XSetBackground(Display *display, GC gc, unsigned long foreground)
}
declare 63 macosx {
    int XSetForeground(Display *display, GC gc, unsigned long foreground)
}
declare 64 macosx {
    int XSetClipMask(Display *display, GC gc, Pixmap pixmap)
}
declare 65 macosx {
    int XSetClipOrigin(Display *display, GC gc,
	    int clip_x_origin, int clip_y_origin)
}
declare 66 macosx {
    int XSetTSOrigin(Display *display, GC gc,
	    int ts_x_origin, int ts_y_origin)
}
declare 67 macosx {
    int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values)
}
declare 68 macosx {
    int XSetFont(Display *display, GC gc, Font font)
}
declare 69 macosx {
    int XSetArcMode(Display *display, GC gc, int arc_mode)
}
declare 70 macosx {
    int XSetStipple(Display *display, GC gc, Pixmap stipple)
}
declare 71 macosx {
    int XSetFillRule(Display *display, GC gc, int fill_rule)
}
declare 72 macosx {
    int XSetFillStyle(Display *display, GC gc, int fill_style)
}
declare 73 macosx {
    int XSetFunction(Display *display, GC gc, int function)
}
declare 74 macosx {
    int XSetLineAttributes(Display *display, GC gc, unsigned int line_width,
	    int line_style, int cap_style, int join_style)
}
declare 75 macosx {
    int _XInitImageFuncPtrs(XImage *image)
}
declare 76 macosx {
    XIC XCreateIC(XIM xim, ...)
}
declare 77 macosx {
    XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask,
	    XVisualInfo *vinfo_template, int *nitems_return)
}
declare 78 macosx {
    void XSetWMClientMachine(Display *display, Window w,
	    XTextProperty *text_prop)
}
declare 79 macosx {
    Status XStringListToTextProperty(char **list, int count,
	    XTextProperty *text_prop_return)
}
declare 80 macosx {
    int XDrawSegments(Display *display, Drawable d, GC gc,
	    XSegment *segments, int nsegments)
}
declare 81 macosx {
    int XForceScreenSaver(Display *display, int mode)
}
declare 82 macosx {
    int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1,
	    int x2, int y2)
}
declare 83 macosx {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}
declare 84 macosx {
    int XClearWindow(Display *d, Window w)
}
declare 85 macosx {
    int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
}
declare 86 macosx {
    int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
	    int npoints, int mode)
}
declare 87 macosx {
    int XWarpPointer(Display *display, Window src_w, Window dest_w,
	    int src_x, int src_y, unsigned int src_width,
	    unsigned int src_height, int dest_x, int dest_y)
}
declare 88 macosx {
    int XQueryColor(Display *display, Colormap colormap, XColor *def_in_out)
}
declare 89 macosx {
    int XQueryColors(Display *display, Colormap colormap,
	    XColor *defs_in_out, int ncolors)
}
declare 90 macosx {
    Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3,
	    Window **w4, unsigned int *ui)
}
declare 91 macosx {
    int XSync(Display *display, Bool discard)
}
declare 92 macosx {
    Bool XTranslateCoordinates(Display *d, Window w1, Window w2, int i1,
	    int i2, int *i3, int *i4, Window *w3)
}
declare 93 macosx {
    int XDeleteProperty(Display *d, Window w, Atom a)
}
declare 94 macosx {
    int XFreeCursor(Display *d, Cursor c)
}
declare 95 macosx {
    int XGetInputFocus(Display *d, Window *w, int *i)
}
declare 96 macosx {
    int XmbLookupString(XIC xi, XKeyPressedEvent *xk, char *c, int i,
	    KeySym *k, Status *s)
}
declare 97 macosx {
    int XNextEvent(Display *d, XEvent *x)
}
declare 98 macosx {
    int XPutBackEvent(Display *d, XEvent *x)
}
declare 99 macosx {
    int XSetCommand(Display *d, Window w, char **c, int i)
}
declare 100 macosx {
    int XWindowEvent(Display *d, Window w, long l, XEvent *x)
}
declare 101 macosx {
    Status XGetWindowAttributes(Display *d, Window w, XWindowAttributes *x)
}
declare 102 macosx {
    Status XGetWMColormapWindows(Display *d, Window w, Window **wpp, int *ip)
}
declare 103 macosx {
    Status XIconifyWindow(Display *d, Window w, int i)
}
declare 104 macosx {
    Status XWithdrawWindow(Display *d, Window w, int i)
}
declare 105 macosx {
    XHostAddress *XListHosts(Display *d, int *i, Bool *b)
}
declare 106 macosx {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
       int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
declare 107 macosx {
    int XFlush(Display *display)
}
declare 108 macosx {
    int XGrabServer(Display *display)
}
declare 109 macosx {
    int XUngrabServer(Display *display)
}
declare 110 macosx {
    int XFree(void *data)
}
declare 111 macosx {
    int XNoOp(Display *display)
}
declare 112 macosx {
    XAfterFunction XSynchronize(Display *display, Bool onoff)
}
declare 113 macosx {
    Status XLookupColor(Display *d, Colormap c1, _Xconst char *c2,
	    XColor *x1, XColor *x2)
}
declare 114 macosx {
    VisualID XVisualIDFromVisual(Visual *visual)
}
declare 120 macosx {
    int XOffsetRegion(Region rgn, int dx, int dy)
}
declare 121 macosx {
    int XUnionRegion(Region srca, Region srcb, Region dr_return)
}
declare 122 macosx {
    Window XCreateWindow(Display *display, Window parent, int x, int y,
	    unsigned int width, unsigned int height,
	    unsigned int border_width, int depth, unsigned int clazz,
	    Visual *visual, unsigned long value_mask,
	    XSetWindowAttributes *attributes)
}
declare 129 macosx {
    int XLowerWindow(Display *d, Window w)
}
declare 130 macosx {
    int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 131 macosx {
    int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n)
}
declare 132 macosx {
    int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n)
}
declare 136 macosx {
    int XReparentWindow(Display *d, Window w, Window p, int x, int y)
}
declare 137 macosx {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}
declare 138 macosx {
    Region XPolygonRegion(XPoint *pts, int n, int rule)
}
declare 139 macosx {
    int XPointInRegion(Region rgn, int x, int y)
}
declare 140 macosx {
    XVaNestedList XVaCreateNestedList(int dummy, ...)
}
declare 141 macosx {
    char *XSetICValues(XIC xic, ...)
}
declare 142 macosx {
    char *XGetICValues(XIC xic, ...)
}
declare 143 macosx {
    void XSetICFocus(XIC xic)
}
declare 144 macosx {
    void XDestroyIC(XIC xic)
}
declare 145 macosx {
    Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
	    XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2)
}
declare 146 macosx {
    Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2,
	    unsigned int ui1, unsigned int ui2, XColor _Xconst *x1,
	    XColor _Xconst *x2)
}
declare 147 macosx {
    void XFreeFontSet(Display *display, XFontSet fontset)
}
declare 148 macosx {
    int XCloseIM(XIM im)
}
declare 149 macosx {
    Bool XRegisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 150 macosx {
    Bool XUnregisterIMInstantiateCallback(Display *dpy, struct _XrmHashBucketRec *rbd,
	    char *res_name, char *res_class, XIDProc callback, XPointer client_data)
}
declare 151 macosx {
    char *XSetLocaleModifiers(const char *modifier_list)
}
declare 152 macosx {
    XIM XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name,
	    char *res_class)
}
declare 153 macosx {
    char *XGetIMValues(XIM im, ...)
}
declare 154 macosx {
    char *XSetIMValues(XIM im, ...)
}
declare 155 macosx {
    XFontSet XCreateFontSet(Display *display, _Xconst char *base_font_name_list,
	    char ***missing_charset_list, int *missing_charset_count, char **def_string)
}
declare 156 macosx {
    void XFreeStringList(char **list)
}
declare 157 macosx {
    KeySym XkbKeycodeToKeysym(Display *d, unsigned int k, int g, int i)
}
declare 158 macosx {
    Display *XkbOpenDisplay(const char *name, int *ev_rtrn, int *err_rtrn,
	    int *major_rtrn, int *minor_rtrn, int *reason)

}

# Local Variables:
# mode: tcl
# End:







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

<
<
>



|

|



|


|




|



|


|


|


|


<
|
|

|


|


|


|


|


|



|



|



|



|




|



|


|


|



|


|



|



|



|


|


|



|


|




|




|


|



|


|


|



|


|



|


|


|



|


|


|


|


|


|


|


|


|


|


|


|


|


|


|




|



|



|


|



|


|


|


|



|



|


|


|


|


|


|


|


|



|


|


|



|



|



|



|


|



|



|


|


|



|




|


|



|



|


<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|



|


|


|


|


|


|


<
<
<
<
|


|
|

<
<
<
<
<
<
<
<
<
<
|


<
<
<
<
<
<
<
<
<
<
<
<
|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


|



|




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
|


|
<
<
>





1496
1497
1498
1499
1500
1501
1502
























































1503


1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537

1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828












































1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850




1851
1852
1853
1854
1855
1856










1857
1858
1859












1860
1861
1862
1863
1864


















1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876


































1877
1878
1879
1880


1881
1882
1883
1884
1885
1886
    int XReparentWindow(Display *d, Window w, Window p, int x, int y)
}
declare 137 win {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}
























































declare 158 win {


    void TkUnusedStubEntry(void)
}

################################
# X functions for Aqua

declare 0 aqua {
    int XSetDashes(Display *display, GC gc, int dash_offset,
	    _Xconst char *dash_list, int n)
}
declare 1 aqua {
    XModifierKeymap *XGetModifierMapping(Display *d)
}
declare 2 aqua {
    XImage *XCreateImage(Display *d, Visual *v, unsigned int ui1, int i1,
	    int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3,
	    int i4)
}
declare 3 aqua {
    XImage *XGetImage(Display *d, Drawable dr, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, unsigned long ul, int i3)
}
declare 4 aqua {
    char *XGetAtomName(Display *d, Atom a)
}
declare 5 aqua {
    char *XKeysymToString(KeySym k)
}
declare 6 aqua {
    Colormap XCreateColormap(Display *d, Window w, Visual *v, int i)
}
declare 7 aqua {
    GContext XGContextFromGC(GC g)
}

declare 8 aqua {
    KeySym XKeycodeToKeysym(Display *d, KeyCode k, int i)
}
declare 9 aqua {
    KeySym XStringToKeysym(_Xconst char *c)
}
declare 10 aqua {
    Window XRootWindow(Display *d, int i)
}
declare 11 aqua {
    XErrorHandler XSetErrorHandler(XErrorHandler x)
}
declare 12 aqua {
    Status XAllocColor(Display *d, Colormap c, XColor *xp)
}
declare 13 aqua {
    int XBell(Display *d, int i)
}
declare 14 aqua {
    int XChangeProperty(Display *d, Window w, Atom a1, Atom a2, int i1,
	    int i2, _Xconst unsigned char *c, int i3)
}
declare 15 aqua {
    int XChangeWindowAttributes(Display *d, Window w, unsigned long ul,
	    XSetWindowAttributes *x)
}
declare 16 aqua {
    int XConfigureWindow(Display *d, Window w, unsigned int i,
	    XWindowChanges *x)
}
declare 17 aqua {
    int XCopyArea(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 18 aqua {
    int XCopyPlane(Display *d, Drawable dr1, Drawable dr2, GC g, int i1,
	    int i2, unsigned int ui1,
	    unsigned int ui2, int i3, int i4, unsigned long ul)
}
declare 19 aqua {
    Pixmap XCreateBitmapFromData(Display *display, Drawable d,
	    _Xconst char *data, unsigned int width, unsigned int height)
}
declare 20 aqua {
    int XDefineCursor(Display *d, Window w, Cursor c)
}
declare 21 aqua {
    int XDestroyWindow(Display *d, Window w)
}
declare 22 aqua {
    int XDrawArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 23 aqua {
    int XDrawLines(Display *d, Drawable dr, GC g, XPoint *x, int i1, int i2)
}
declare 24 aqua {
    int XDrawRectangle(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 25 aqua {
    int XFillArc(Display *d, Drawable dr, GC g, int i1, int i2,
	    unsigned int ui1, unsigned int ui2, int i3, int i4)
}
declare 26 aqua {
    int XFillPolygon(Display *d, Drawable dr, GC g, XPoint *x,
	    int i1, int i2, int i3)
}
declare 27 aqua {
    int XFillRectangles(Display *d, Drawable dr, GC g, XRectangle *x, int i)
}
declare 28 aqua {
    int XFreeColormap(Display *d, Colormap c)
}
declare 29 aqua {
    int XFreeColors(Display *d, Colormap c,
	    unsigned long *ulp, int i, unsigned long ul)
}
declare 30 aqua {
    int XFreeModifiermap(XModifierKeymap *x)
}
declare 31 aqua {
    Status XGetGeometry(Display *d, Drawable dr, Window *w, int *i1,
	    int *i2, unsigned int *ui1, unsigned int *ui2, unsigned int *ui3,
	    unsigned int *ui4)
}
declare 32 aqua {
    int XGetWindowProperty(Display *d, Window w, Atom a1, long l1, long l2,
	    Bool b, Atom a2, Atom *ap, int *ip, unsigned long *ulp1,
	    unsigned long *ulp2, unsigned char **cpp)
}
declare 33 aqua {
    int XGrabKeyboard(Display *d, Window w, Bool b, int i1, int i2, Time t)
}
declare 34 aqua {
    int XGrabPointer(Display *d, Window w1, Bool b, unsigned int ui,
	    int i1, int i2, Window w2, Cursor c, Time t)
}
declare 35 aqua {
    KeyCode XKeysymToKeycode(Display *d, KeySym k)
}
declare 36 aqua {
    int XMapWindow(Display *d, Window w)
}
declare 37 aqua {
    int XMoveResizeWindow(Display *d, Window w, int i1, int i2,
	    unsigned int ui1, unsigned int ui2)
}
declare 38 aqua {
    int XMoveWindow(Display *d, Window w, int i1, int i2)
}
declare 39 aqua {
    Bool XQueryPointer(Display *d, Window w1, Window *w2, Window *w3,
	    int *i1, int *i2, int *i3, int *i4, unsigned int *ui)
}
declare 40 aqua {
    int XRaiseWindow(Display *d, Window w)
}
declare 41 aqua {
    int XRefreshKeyboardMapping(XMappingEvent *x)
}
declare 42 aqua {
    int XResizeWindow(Display *d, Window w, unsigned int ui1,
	    unsigned int ui2)
}
declare 43 aqua {
    int XSelectInput(Display *d, Window w, long l)
}
declare 44 aqua {
    Status XSendEvent(Display *d, Window w, Bool b, long l, XEvent *x)
}
declare 45 aqua {
    int XSetIconName(Display *d, Window w, _Xconst char *c)
}
declare 46 aqua {
    int XSetInputFocus(Display *d, Window w, int i, Time t)
}
declare 47 aqua {
    int XSetSelectionOwner(Display *d, Atom a, Window w, Time t)
}
declare 48 aqua {
    int XSetWindowBackground(Display *d, Window w, unsigned long ul)
}
declare 49 aqua {
    int XSetWindowBackgroundPixmap(Display *d, Window w, Pixmap p)
}
declare 50 aqua {
    int XSetWindowBorder(Display *d, Window w, unsigned long ul)
}
declare 51 aqua {
    int XSetWindowBorderPixmap(Display *d, Window w, Pixmap p)
}
declare 52 aqua {
    int XSetWindowBorderWidth(Display *d, Window w, unsigned int ui)
}
declare 53 aqua {
    int XSetWindowColormap(Display *d, Window w, Colormap c)
}
declare 54 aqua {
    int XUngrabKeyboard(Display *d, Time t)
}
declare 55 aqua {
    int XUngrabPointer(Display *d, Time t)
}
declare 56 aqua {
    int XUnmapWindow(Display *d, Window w)
}
declare 57 aqua {
    int TkPutImage(unsigned long *colors, int ncolors, Display *display,
	    Drawable d, GC gc, XImage *image, int src_x, int src_y,
	    int dest_x, int dest_y, unsigned int width, unsigned int height)
}
declare 58 aqua {
    Status XParseColor(Display *display, Colormap map,
          _Xconst char *spec, XColor *colorPtr)
}
declare 59 aqua {
    GC XCreateGC(Display *display, Drawable d,
	    unsigned long valuemask, XGCValues *values)
}
declare 60 aqua {
    int XFreeGC(Display *display, GC gc)
}
declare 61 aqua {
    Atom XInternAtom(Display *display, _Xconst char *atom_name,
	    Bool only_if_exists)
}
declare 62 aqua {
    int XSetBackground(Display *display, GC gc, unsigned long foreground)
}
declare 63 aqua {
    int XSetForeground(Display *display, GC gc, unsigned long foreground)
}
declare 64 aqua {
    int XSetClipMask(Display *display, GC gc, Pixmap pixmap)
}
declare 65 aqua {
    int XSetClipOrigin(Display *display, GC gc,
	    int clip_x_origin, int clip_y_origin)
}
declare 66 aqua {
    int XSetTSOrigin(Display *display, GC gc,
	    int ts_x_origin, int ts_y_origin)
}
declare 67 aqua {
    int XChangeGC(Display *d, GC gc, unsigned long mask, XGCValues *values)
}
declare 68 aqua {
    int XSetFont(Display *display, GC gc, Font font)
}
declare 69 aqua {
    int XSetArcMode(Display *display, GC gc, int arc_mode)
}
declare 70 aqua {
    int XSetStipple(Display *display, GC gc, Pixmap stipple)
}
declare 71 aqua {
    int XSetFillRule(Display *display, GC gc, int fill_rule)
}
declare 72 aqua {
    int XSetFillStyle(Display *display, GC gc, int fill_style)
}
declare 73 aqua {
    int XSetFunction(Display *display, GC gc, int function)
}
declare 74 aqua {
    int XSetLineAttributes(Display *display, GC gc, unsigned int line_width,
	    int line_style, int cap_style, int join_style)
}
declare 75 aqua {
    int _XInitImageFuncPtrs(XImage *image)
}
declare 76 aqua {
    XIC XCreateIC(XIM xim, ...)
}
declare 77 aqua {
    XVisualInfo *XGetVisualInfo(Display *display, long vinfo_mask,
	    XVisualInfo *vinfo_template, int *nitems_return)
}
declare 78 aqua {
    void XSetWMClientMachine(Display *display, Window w,
	    XTextProperty *text_prop)
}
declare 79 aqua {
    Status XStringListToTextProperty(char **list, int count,
	    XTextProperty *text_prop_return)
}
declare 80 aqua {
    int XDrawSegments(Display *display, Drawable d, GC gc,
	    XSegment *segments, int nsegments)
}
declare 81 aqua {
    int XForceScreenSaver(Display *display, int mode)
}
declare 82 aqua {
    int XDrawLine(Display *d, Drawable dr, GC g, int x1, int y1,
	    int x2, int y2)
}
declare 83 aqua {
    int XFillRectangle(Display *display, Drawable d, GC gc,
	    int x, int y, unsigned int width, unsigned int height)
}
declare 84 aqua {
    int XClearWindow(Display *d, Window w)
}
declare 85 aqua {
    int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y)
}
declare 86 aqua {
    int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points,
	    int npoints, int mode)
}
declare 87 aqua {
    int XWarpPointer(Display *display, Window src_w, Window dest_w,
	    int src_x, int src_y, unsigned int src_width,
	    unsigned int src_height, int dest_x, int dest_y)
}
declare 88 aqua {
    int XQueryColor(Display *display, Colormap colormap, XColor *def_in_out)
}
declare 89 aqua {
    int XQueryColors(Display *display, Colormap colormap,
	    XColor *defs_in_out, int ncolors)
}
declare 90 aqua {
    Status XQueryTree(Display *d, Window w1, Window *w2, Window *w3,
	    Window **w4, unsigned int *ui)
}
declare 91 aqua {
    int XSync(Display *display, Bool discard)
}












































declare 106 aqua {
    int XSetClipRectangles(Display *display, GC gc, int clip_x_origin,
       int clip_y_origin, XRectangle rectangles[], int n, int ordering)
}
declare 107 aqua {
    int XFlush(Display *display)
}
declare 108 aqua {
    int XGrabServer(Display *display)
}
declare 109 aqua {
    int XUngrabServer(Display *display)
}
declare 110 aqua {
    int XFree(void *data)
}
declare 111 aqua {
    int XNoOp(Display *display)
}
declare 112 aqua {
    XAfterFunction XSynchronize(Display *display, Bool onoff)
}




declare 114 aqua {
    VisualID XVisualIDFromVisual(Visual *visual)
}
declare 120 aqua {
    int XOffsetRegion(void *rgn, int dx, int dy)
}










declare 129 aqua {
    int XLowerWindow(Display *d, Window w)
}












declare 137 aqua {
    int XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
	    int sx, int sy, int dx, int dy,
	    unsigned int w, unsigned int h)
}


















declare 144 aqua {
    void XDestroyIC(XIC xic)
}
declare 145 aqua {
    Cursor XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
	    XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2)
}
declare 146 aqua {
    Cursor XCreateGlyphCursor(Display *d, Font f1, Font f2,
	    unsigned int ui1, unsigned int ui2, XColor _Xconst *x1,
	    XColor _Xconst *x2)
}


































declare 157 aqua {
    KeySym XkbKeycodeToKeysym(Display *d, unsigned int k, int g, int i)
}
declare 158 aqua {


    void TkUnusedStubEntry(void)
}

# Local Variables:
# mode: tcl
# End:
Changes to generic/tkInt.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21


22
23
24
25
26
27

28
29
30
31
32
33
34
/*
 * 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

#ifndef _TKPORT
#include "tkPort.h"
#endif



/*
 * Ensure WORDS_BIGENDIAN is defined correctly:
 * Needs to happen here in addition to configure to work with fat compiles on
 * Darwin (where configure runs only once for multiple architectures).
 */


#ifdef HAVE_SYS_TYPES_H
#    include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#    include <sys/param.h>
#endif
#ifdef BYTE_ORDER








|












>
>






>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
 * tkInt.h --
 *
 *	Declarations for things used internally by the Tk functions but not
 *	exported outside the module.
 *
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998 Scriptics Corporation.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKINT
#define _TKINT

#ifndef _TKPORT
#include "tkPort.h"
#endif

#define TK_OPTION_ENUM_VAR		((int)(sizeof(Tk_OptionType)&(sizeof(int)-1))<<6)

/*
 * Ensure WORDS_BIGENDIAN is defined correctly:
 * Needs to happen here in addition to configure to work with fat compiles on
 * Darwin (where configure runs only once for multiple architectures).
 */

#include <stdio.h>
#ifdef HAVE_SYS_TYPES_H
#    include <sys/types.h>
#endif
#ifdef HAVE_SYS_PARAM_H
#    include <sys/param.h>
#endif
#ifdef BYTE_ORDER
69
70
71
72
73
74
75
76
77

78
79
80
81
82
83
84
85
86
87
88

89
90


91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#   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)







|
|
>
|
|
<
<
<
<
<
|
|
<
<
>


>
>
|





|












|


|





|


|







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





84
85


86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#   elif defined(__GNUC__) && (__GNUC__ > 2)
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__) __attribute__((unused))
#   else
#	define TCL_UNUSED(T) T JOIN(dummy, __LINE__)
#   endif
#endif

#if defined(_WIN32) && (TCL_MAJOR_VERSION < 9) && (TCL_MINOR_VERSION < 7)
# if TCL_UTF_MAX > 3
#   define Tcl_WCharToUtfDString(a,b,c) Tcl_WinTCharToUtf((TCHAR *)(a),(b)*sizeof(WCHAR),c)
#   define Tcl_UtfToWCharDString(a,b,c) (WCHAR *)Tcl_WinUtfToTChar(a,b,c)
# else





#   define Tcl_WCharToUtfDString ((char * (*)(const WCHAR *, int len, Tcl_DString *))Tcl_UniCharToUtfDString)
#   define Tcl_UtfToWCharDString ((WCHAR * (*)(const char *, int len, Tcl_DString *))Tcl_UtfToUniCharDString)


# endif
#endif

#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)
#   define TKFLEXARRAY
#elif defined(__GNUC__) && (__GNUC__ > 2)
#   define TKFLEXARRAY 0
#else
#   define TKFLEXARRAY 1
#endif

#ifndef Tcl_GetParent
#   define Tcl_GetParent Tcl_GetMaster
#endif

/*
 * Macros used to cast between pointers and integers (e.g. when storing an int
 * in ClientData), on 64-bit architectures they avoid gcc warning about "cast
 * to/from pointer from/to integer of different size".
 */

#if !defined(INT2PTR) && !defined(PTR2INT)
#   if defined(HAVE_INTPTR_T) || defined(intptr_t)
#	define INT2PTR(p) ((void*)(intptr_t)(p))
#	define PTR2INT(p) ((int)(intptr_t)(p))
#   else
#	define INT2PTR(p) ((void*)(p))
#	define PTR2INT(p) ((int)(p))
#   endif
#endif
#if !defined(UINT2PTR) && !defined(PTR2UINT)
#   if defined(HAVE_UINTPTR_T) || defined(uintptr_t)
#	define UINT2PTR(p) ((void*)(uintptr_t)(p))
#	define PTR2UINT(p) ((unsigned int)(uintptr_t)(p))
#   else
#	define UINT2PTR(p) ((void*)(p))
#	define PTR2UINT(p) ((unsigned int)(p))
#   endif
#endif

#ifndef TCL_Z_MODIFIER
#   if defined(_WIN64)
#	define TCL_Z_MODIFIER	"I"
#   elif defined(__GNUC__) && !defined(_WIN32)
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
 * Opaque type declarations:
 */

typedef struct TkColormap TkColormap;
typedef struct TkFontAttributes TkFontAttributes;
typedef struct TkGrabEvent TkGrabEvent;
typedef struct TkpCursor_ *TkpCursor;
#define TkRegion Region
typedef struct TkStressedCmap TkStressedCmap;
typedef struct TkBindInfo_ *TkBindInfo;
typedef struct Busy *TkBusy;

/*
 * One of the following structures is maintained for each cursor in use in the
 * system. This structure is used by tkCursor.c and the various system-
 * specific cursor files.
 */

typedef struct TkCursor {
    Tk_Cursor cursor;		/* System specific identifier for cursor. */
    Display *display;		/* Display containing cursor. Needed for
				 * disposal and retrieval of cursors. */
    TkSizeT resourceRefCount;	/* Number of active uses of this cursor (each
				 * active use corresponds to a call to
				 * Tk_AllocPreserveFromObj or Tk_Preserve). If
				 * this count is 0, then this structure is no
				 * longer valid and it isn't present in a hash
				 * table: it is being kept around only because
				 * there are objects referring to it. The
				 * structure is freed when resourceRefCount
				 * and objRefCount are both 0. */
    TkSizeT objRefCount;		/* Number of Tcl objects that reference this
				 * structure.. */
    Tcl_HashTable *otherTable;	/* Second table (other than idTable) used to
				 * index this entry. */
    Tcl_HashEntry *hashPtr;	/* Entry in otherTable for this structure
				 * (needed when deleting). */
    Tcl_HashEntry *idHashPtr;	/* Entry in idTable for this structure (needed
				 * when deleting). */







|














|








|







137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
 * Opaque type declarations:
 */

typedef struct TkColormap TkColormap;
typedef struct TkFontAttributes TkFontAttributes;
typedef struct TkGrabEvent TkGrabEvent;
typedef struct TkpCursor_ *TkpCursor;
typedef struct TkRegion_ *TkRegion;
typedef struct TkStressedCmap TkStressedCmap;
typedef struct TkBindInfo_ *TkBindInfo;
typedef struct Busy *TkBusy;

/*
 * One of the following structures is maintained for each cursor in use in the
 * system. This structure is used by tkCursor.c and the various system-
 * specific cursor files.
 */

typedef struct TkCursor {
    Tk_Cursor cursor;		/* System specific identifier for cursor. */
    Display *display;		/* Display containing cursor. Needed for
				 * disposal and retrieval of cursors. */
    int resourceRefCount;	/* Number of active uses of this cursor (each
				 * active use corresponds to a call to
				 * Tk_AllocPreserveFromObj or Tk_Preserve). If
				 * this count is 0, then this structure is no
				 * longer valid and it isn't present in a hash
				 * table: it is being kept around only because
				 * there are objects referring to it. The
				 * structure is freed when resourceRefCount
				 * and objRefCount are both 0. */
    int objRefCount;		/* Number of Tcl objects that reference this
				 * structure.. */
    Tcl_HashTable *otherTable;	/* Second table (other than idTable) used to
				 * index this entry. */
    Tcl_HashEntry *hashPtr;	/* Entry in otherTable for this structure
				 * (needed when deleting). */
    Tcl_HashEntry *idHashPtr;	/* Entry in idTable for this structure (needed
				 * when deleting). */
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

/*
 * One of the following structures is maintained for each display containing a
 * window managed by Tk. In part, the structure is used to store thread-
 * specific data, since each thread will have its own TkDisplay structure.
 */

typedef enum TkLockUsage {LU_IGNORE, LU_CAPS, LU_SHIFT} TkLockUsage;

typedef struct TkDisplay {
    Display *display;		/* Xlib's info about display. */
    struct TkDisplay *nextPtr;	/* Next in list of all displays. */
    char *name;			/* Name of display (with any screen identifier
				 * removed). Malloc-ed. */
    Time lastEventTime;		/* Time of last event received for this
				 * display. */







<
<







196
197
198
199
200
201
202


203
204
205
206
207
208
209

/*
 * One of the following structures is maintained for each display containing a
 * window managed by Tk. In part, the structure is used to store thread-
 * specific data, since each thread will have its own TkDisplay structure.
 */



typedef struct TkDisplay {
    Display *display;		/* Xlib's info about display. */
    struct TkDisplay *nextPtr;	/* Next in list of all displays. */
    char *name;			/* Name of display (with any screen identifier
				 * removed). Malloc-ed. */
    Time lastEventTime;		/* Time of last event received for this
				 * display. */
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
				 * modifier, than this is zero. */
    unsigned int metaModMask;	/* Has one bit set to indicate the modifier
				 * corresponding to the "Meta" key. If no such
				 * modifier, then this is zero. */
    unsigned int altModMask;	/* Has one bit set to indicate the modifier
				 * corresponding to the "Meta" key. If no such
				 * modifier, then this is zero. */
    TkLockUsage lockUsage;
				/* Indicates how to interpret lock
				 * modifier. */
    int numModKeyCodes;		/* Number of entries in modKeyCodes array
				 * below. */
    KeyCode *modKeyCodes;	/* Pointer to an array giving keycodes for all
				 * of the keys that have modifiers associated
				 * with them. Malloc'ed, but may be NULL. */







|







237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
				 * modifier, than this is zero. */
    unsigned int metaModMask;	/* Has one bit set to indicate the modifier
				 * corresponding to the "Meta" key. If no such
				 * modifier, then this is zero. */
    unsigned int altModMask;	/* Has one bit set to indicate the modifier
				 * corresponding to the "Meta" key. If no such
				 * modifier, then this is zero. */
    enum {LU_IGNORE, LU_CAPS, LU_SHIFT} lockUsage;
				/* Indicates how to interpret lock
				 * modifier. */
    int numModKeyCodes;		/* Number of entries in modKeyCodes array
				 * below. */
    KeyCode *modKeyCodes;	/* Pointer to an array giving keycodes for all
				 * of the keys that have modifiers associated
				 * with them. Malloc'ed, but may be NULL. */
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
     * Information used by tkError.c only:
     */

    struct TkErrorHandler *errorPtr;
				/* First in list of error handlers for this
				 * display. NULL means no handlers exist at
				 * present. */
    TkSizeT deleteCount;		/* Counts # of handlers deleted since last
				 * time inactive handlers were garbage-
				 * collected. When this number gets big,
				 * handlers get cleaned up. */

    /*
     * Used by tkEvent.c only:
     */







|







311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
     * Information used by tkError.c only:
     */

    struct TkErrorHandler *errorPtr;
				/* First in list of error handlers for this
				 * display. NULL means no handlers exist at
				 * present. */
    int deleteCount;		/* Counts # of handlers deleted since last
				 * time inactive handlers were garbage-
				 * collected. When this number gets big,
				 * handlers get cleaned up. */

    /*
     * Used by tkEvent.c only:
     */
370
371
372
373
374
375
376






377
378
379
380
381
382
383
384
385

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







>
>
>
>
>
>
|
|







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

    Tcl_HashTable maintainHashTable;
				/* Hash table that maps from a container's
				 * Tk_Window token to a list of windows managed
				 * by that container. */
    int geomInit;

    /*
     * Information used by tkGrid.c, tkPack.c, tkPlace.c, tkPointer.c,
     * and ttkMacOSXTheme.c:
     */

#define TkGetContainer(tkwin) (Tk_TopWinHierarchy((TkWindow *)tkwin) ? NULL : \
	(((TkWindow *)tkwin)->maintainerPtr != NULL ? \
	 ((TkWindow *)tkwin)->maintainerPtr : ((TkWindow *)tkwin)->parentPtr))

    /*
     * Information used by tkGet.c only:
     */

    Tcl_HashTable uidTable;	/* Stores all Tk_Uid used in a thread. */
    int uidInit;		/* 0 means uidTable needs initializing. */
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
				 * Packer structures. */

    /*
     * Information used by tkPlace.c only.
     */

    int placeInit;		/* 0 means tables below need initializing. */
    Tcl_HashTable containerTable;	/* Maps from Tk_Window token to the Container
				 * structure for the window, if it exists. */
    Tcl_HashTable contentTable;	/* Maps from Tk_Window token to the Content
				 * structure for the window, if it exists. */

    /*
     * Information used by tkSelect.c and tkClipboard.c only:
     */

    struct TkSelectionInfo *selectionInfoPtr;







|

|







452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
				 * Packer structures. */

    /*
     * Information used by tkPlace.c only.
     */

    int placeInit;		/* 0 means tables below need initializing. */
    Tcl_HashTable masterTable;	/* Maps from Tk_Window toke to the Master
				 * structure for the window, if it exists. */
    Tcl_HashTable slaveTable;	/* Maps from Tk_Window toke to the Slave
				 * structure for the window, if it exists. */

    /*
     * Information used by tkSelect.c and tkClipboard.c only:
     */

    struct TkSelectionInfo *selectionInfoPtr;
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572

573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588


589
590
591
592
593


594
595
596
597
598
599
600
    TkColormap *cmapPtr;	/* First in list of all non-default colormaps
				 * allocated for this display. */

    /*
     * Miscellaneous information:
     */

#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIM inputMethod;		/* Input method for this display. */
    XIMStyle inputStyle;	/* Input style selected for this display. */
    XFontSet inputXfs;		/* XFontSet cached for over-the-spot XIM. */
#endif /* TK_USE_INPUT_METHODS */
    Tcl_HashTable winTable;	/* Maps from X window ids to TkWindow ptrs. */

    TkSizeT refCount;		/* Reference count of how many Tk applications
				 * are using this display. Used to clean up
				 * the display when we no longer have any Tk
				 * applications using it. */

    /*
     * The following field were all added for Tk8.3
     */

#if TCL_MAJOR_VERSION < 9
#if !defined(TK_NO_DEPRECATED)
    int mouseButtonState;	/* Current mouse button state for this
				 * display. NOT USED as of 8.6.10 */
    Window mouseButtonWindow;	/* Window the button state was set in, added
				 * in Tk 8.4. */
#else
    int notused1;
    XID notused2;
#endif /* !TK_NO_DEPRECATED */
#endif
    Tk_Window warpWindow;
    Tk_Window warpMainwin;	/* For finding the root window for warping
				 * purposes. */
    int warpX;
    int warpY;

    /*
     * The following field(s) were all added for Tk8.4
     */

    unsigned int flags;		/* Various flag values: these are all defined
				 * in below. */
    TkCaret caret;		/* Information about the caret for this
				 * display. This is not a pointer. */

    int iconDataSize;		/* Size of default iconphoto image data. */
    unsigned char *iconDataPtr;	/* Default iconphoto image data, if set. */

    int ximGeneration;          /* Used to invalidate XIC */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIM inputMethod;		/* Input method for this display. */
    XIMStyle inputStyle;	/* Input style selected for this display. */
    XFontSet inputXfs;		/* XFontSet cached for over-the-spot XIM. */
#endif /* TK_USE_INPUT_METHODS */
} TkDisplay;

/*
 * Flag values for TkDisplay flags.
 *  TK_DISPLAY_COLLAPSE_MOTION_EVENTS:	(default on)
 *	Indicates that we should collapse motion events on this display
 *  TK_DISPLAY_USE_IM:			(default on, set via tk.tcl)
 *	Whether to use input methods for this display
 *  TK_DISPLAY_WM_TRACING:		(default off)
 *	Whether we should do wm tracing on this display.


 */

#define TK_DISPLAY_COLLAPSE_MOTION_EVENTS	(1 << 0)
#define TK_DISPLAY_USE_IM			(1 << 1)
#define TK_DISPLAY_WM_TRACING			(1 << 3)



/*
 * One of the following structures exists for each error handler created by a
 * call to Tk_CreateErrorHandler. The structure is managed by tkError.c.
 */

typedef struct TkErrorHandler {







|






|








<
<




<
<
<
<
<

















>

<
<
<
<











>
>





>
>







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548


549
550
551
552





553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571




572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
    TkColormap *cmapPtr;	/* First in list of all non-default colormaps
				 * allocated for this display. */

    /*
     * Miscellaneous information:
     */

#ifdef TK_USE_INPUT_METHODS
    XIM inputMethod;		/* Input method for this display. */
    XIMStyle inputStyle;	/* Input style selected for this display. */
    XFontSet inputXfs;		/* XFontSet cached for over-the-spot XIM. */
#endif /* TK_USE_INPUT_METHODS */
    Tcl_HashTable winTable;	/* Maps from X window ids to TkWindow ptrs. */

    int refCount;		/* Reference count of how many Tk applications
				 * are using this display. Used to clean up
				 * the display when we no longer have any Tk
				 * applications using it. */

    /*
     * The following field were all added for Tk8.3
     */



    int mouseButtonState;	/* Current mouse button state for this
				 * display. NOT USED as of 8.6.10 */
    Window mouseButtonWindow;	/* Window the button state was set in, added
				 * in Tk 8.4. */





    Tk_Window warpWindow;
    Tk_Window warpMainwin;	/* For finding the root window for warping
				 * purposes. */
    int warpX;
    int warpY;

    /*
     * The following field(s) were all added for Tk8.4
     */

    unsigned int flags;		/* Various flag values: these are all defined
				 * in below. */
    TkCaret caret;		/* Information about the caret for this
				 * display. This is not a pointer. */

    int iconDataSize;		/* Size of default iconphoto image data. */
    unsigned char *iconDataPtr;	/* Default iconphoto image data, if set. */
#ifdef TK_USE_INPUT_METHODS
    int ximGeneration;          /* Used to invalidate XIC */




#endif /* TK_USE_INPUT_METHODS */
} TkDisplay;

/*
 * Flag values for TkDisplay flags.
 *  TK_DISPLAY_COLLAPSE_MOTION_EVENTS:	(default on)
 *	Indicates that we should collapse motion events on this display
 *  TK_DISPLAY_USE_IM:			(default on, set via tk.tcl)
 *	Whether to use input methods for this display
 *  TK_DISPLAY_WM_TRACING:		(default off)
 *	Whether we should do wm tracing on this display.
 *  TK_DISPLAY_IN_WARP:			(default off)
 *	Indicates that we are in a pointer warp
 */

#define TK_DISPLAY_COLLAPSE_MOTION_EVENTS	(1 << 0)
#define TK_DISPLAY_USE_IM			(1 << 1)
#define TK_DISPLAY_WM_TRACING			(1 << 3)
#define TK_DISPLAY_IN_WARP			(1 << 4)
#define TK_DISPLAY_USE_XKB			(1 << 5)

/*
 * One of the following structures exists for each error handler created by a
 * call to Tk_CreateErrorHandler. The structure is managed by tkError.c.
 */

typedef struct TkErrorHandler {
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
/*
 * Tk keeps one of the following data structures for each main window (created
 * by a call to TkCreateMainWindow). It stores information that is shared by
 * all of the windows associated with a particular main window.
 */

typedef struct TkMainInfo {
    TkSizeT refCount;		/* Number of windows whose "mainPtr" fields
				 * point here. When this becomes zero, can
				 * free up the structure (the reference count
				 * is zero because windows can get deleted in
				 * almost any order; the main window isn't
				 * necessarily the last one deleted). */
    struct TkWindow *winPtr;	/* Pointer to main window. */
    Tcl_Interp *interp;		/* Interpreter associated with application. */
    Tcl_HashTable nameTable;	/* Hash table mapping path names to TkWindow
				 * structs for all windows related to this
				 * main window. Managed by tkWindow.c. */
#if TCL_MAJOR_VERSION > 8
    size_t deletionEpoch;		/* Incremented by window deletions. */
#else
    long deletionEpoch;
#endif
    Tk_BindingTable bindingTable;
				/* Used in conjunction with "bind" command to
				 * bind events to Tcl commands. */
    TkBindInfo bindInfo;	/* Information used by tkBind.c on a per
				 * application basis. */
    struct TkFontInfo *fontInfoPtr;
				/* Information used by tkFont.c on a per







|










<
|
<
<
<







637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654

655



656
657
658
659
660
661
662
/*
 * Tk keeps one of the following data structures for each main window (created
 * by a call to TkCreateMainWindow). It stores information that is shared by
 * all of the windows associated with a particular main window.
 */

typedef struct TkMainInfo {
    int refCount;		/* Number of windows whose "mainPtr" fields
				 * point here. When this becomes zero, can
				 * free up the structure (the reference count
				 * is zero because windows can get deleted in
				 * almost any order; the main window isn't
				 * necessarily the last one deleted). */
    struct TkWindow *winPtr;	/* Pointer to main window. */
    Tcl_Interp *interp;		/* Interpreter associated with application. */
    Tcl_HashTable nameTable;	/* Hash table mapping path names to TkWindow
				 * structs for all windows related to this
				 * main window. Managed by tkWindow.c. */

    long deletionEpoch;		/* Incremented by window deletions. */



    Tk_BindingTable bindingTable;
				/* Used in conjunction with "bind" command to
				 * bind events to Tcl commands. */
    TkBindInfo bindInfo;	/* Information used by tkBind.c on a per
				 * application basis. */
    struct TkFontInfo *fontInfoPtr;
				/* Information used by tkFont.c on a per
691
692
693
694
695
696
697






698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
    int strictMotif;		/* This is linked to the tk_strictMotif global
				 * variable. */
    int alwaysShowSelection;	/* This is linked to the
				 * ::tk::AlwaysShowSelection variable. */
    struct TkMainInfo *nextPtr;	/* Next in list of all main windows managed by
				 * this process. */
    Tcl_HashTable busyTable;	/* Information used by [tk busy] command. */






} TkMainInfo;

/*
 * Tk keeps the following data structure for each of it's builtin bitmaps.
 * This structure is only used by tkBitmap.c and other platform specific
 * bitmap files.
 */

typedef struct {
    const void *source;		/* Bits for bitmap. */
    int width, height;		/* Dimensions of bitmap. */
    int native;			/* 0 means generic (X style) bitmap, 1 means
    				 * native style bitmap. */
} TkPredefBitmap;

/*
 * Tk keeps one of the following structures for each window. Some of the
 * information (like size and location) is a shadow of information managed by
 * the X server, and some is special information used here, such as event and
 * geometry management information. This information is (mostly) managed by







>
>
>
>
>
>












|







685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
    int strictMotif;		/* This is linked to the tk_strictMotif global
				 * variable. */
    int alwaysShowSelection;	/* This is linked to the
				 * ::tk::AlwaysShowSelection variable. */
    struct TkMainInfo *nextPtr;	/* Next in list of all main windows managed by
				 * this process. */
    Tcl_HashTable busyTable;	/* Information used by [tk busy] command. */
    Tcl_ObjCmdProc *tclUpdateObjProc;
				/* Saved Tcl [update] command, used to restore
				 * Tcl's version of [update] after Tk is shut
				 * down */
    unsigned int ttkNbTabsStickBit;
				/* Information used by ttk::notebook. */
} TkMainInfo;

/*
 * Tk keeps the following data structure for each of it's builtin bitmaps.
 * This structure is only used by tkBitmap.c and other platform specific
 * bitmap files.
 */

typedef struct {
    const void *source;		/* Bits for bitmap. */
    int width, height;		/* Dimensions of bitmap. */
    int native;			/* 0 means generic (X style) bitmap, 1 means
				 * native style bitmap. */
} TkPredefBitmap;

/*
 * Tk keeps one of the following structures for each window. Some of the
 * information (like size and location) is a shadow of information managed by
 * the X server, and some is special information used here, such as event and
 * geometry management information. This information is (mostly) managed by
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

    /*
     * Information kept by the event manager (tkEvent.c):
     */

    TkEventHandler *handlerList;/* First in list of event handlers declared
				 * for this window, or NULL if none. */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    XIC inputContext;		/* XIM input context. */
#endif /* TK_USE_INPUT_METHODS */

    /*
     * Information used for event bindings (see "bind" and "bindtags" commands
     * in tkCmds.c):
     */







|







791
792
793
794
795
796
797
798
799
800
801
802
803
804
805

    /*
     * Information kept by the event manager (tkEvent.c):
     */

    TkEventHandler *handlerList;/* First in list of event handlers declared
				 * for this window, or NULL if none. */
#ifdef TK_USE_INPUT_METHODS
    XIC inputContext;		/* XIM input context. */
#endif /* TK_USE_INPUT_METHODS */

    /*
     * Information used for event bindings (see "bind" and "bindtags" commands
     * in tkCmds.c):
     */
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892







893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
    /* The remaining fields of internal border. */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;

    int minReqWidth;		/* Minimum requested width. */
    int minReqHeight;		/* Minimum requested height. */
#if defined(TK_USE_INPUT_METHODS) || (TCL_MAJOR_VERSION > 8)
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
    char *geomMgrName;          /* Records the name of the geometry manager. */
    struct TkWindow *maintainerPtr;
				/* The geometry container for this window. The
				 * value is NULL if the window has no container or
				 * if its container is its parent. */
#if !defined(TK_USE_INPUT_METHODS) && (TCL_MAJOR_VERSION < 9)
    XIC inputContext;		/* XIM input context. */
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
} TkWindow;








/*
 * Real definition of some events. Note that these events come from outside
 * but have internally generated pieces added to them.
 */

typedef struct {
    XKeyEvent keyEvent;		/* The real event from X11. */
#ifdef _WIN32
    char trans_chars[XMaxTransChars];
                            /* translated characters */
    unsigned char nbytes;
#elif !defined(MAC_OSC_TK)
    char *charValuePtr;		/* A pointer to a string that holds the key's
				 * %A substitution text (before backslash
				 * adding), or NULL if that has not been
				 * computed yet. If non-NULL, this string was
				 * allocated with ckalloc(). */
    TkSizeT charValueLen;	/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
#endif
} TkKeyEvent;

/*
 * Flags passed to TkpMakeMenuWindow's 'transient' argument.
 */

#define TK_MAKE_MENU_TEAROFF	0	/* Only non-transient case. */
#define TK_MAKE_MENU_POPUP	1
#define TK_MAKE_MENU_DROPDOWN	2

/* See TIP #494 */
#ifndef TCL_IO_FAILURE
#   define TCL_IO_FAILURE (-1)
#endif
/* See TIP #537 */
#ifndef TCL_INDEX_NONE
#   define TCL_INDEX_NONE (-1)
#endif

/*
 * The following structure is used with TkMakeEnsemble to create ensemble
 * commands and optionally to create sub-ensembles.
 */

typedef struct TkEnsemble {
    const char *name;







|







<
<
<
<


>
>
>
>
>
>
>











|





|














<
<
<
<
<
<
<
<
<







872
873
874
875
876
877
878
879
880
881
882
883
884
885
886




887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927









928
929
930
931
932
933
934
    /* The remaining fields of internal border. */
    int internalBorderRight;
    int internalBorderTop;
    int internalBorderBottom;

    int minReqWidth;		/* Minimum requested width. */
    int minReqHeight;		/* Minimum requested height. */
#ifdef TK_USE_INPUT_METHODS
    int ximGeneration;          /* Used to invalidate XIC */
#endif /* TK_USE_INPUT_METHODS */
    char *geomMgrName;          /* Records the name of the geometry manager. */
    struct TkWindow *maintainerPtr;
				/* The geometry container for this window. The
				 * value is NULL if the window has no container or
				 * if its container is its parent. */




} TkWindow;

/*
 * String tables:
 */

MODULE_SCOPE const char *const tkStateStrings[];
MODULE_SCOPE const char *const tkCompoundStrings[];

/*
 * Real definition of some events. Note that these events come from outside
 * but have internally generated pieces added to them.
 */

typedef struct {
    XKeyEvent keyEvent;		/* The real event from X11. */
#ifdef _WIN32
    char trans_chars[XMaxTransChars];
                            /* translated characters */
    unsigned char nbytes;
#elif !defined(MAC_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(). */
    int charValueLen;		/* Length of string in charValuePtr when that
				 * is non-NULL. */
    KeySym keysym;		/* Key symbol computed after input methods
				 * have been invoked */
#endif
} TkKeyEvent;

/*
 * Flags passed to TkpMakeMenuWindow's 'transient' argument.
 */

#define TK_MAKE_MENU_TEAROFF	0	/* Only non-transient case. */
#define TK_MAKE_MENU_POPUP	1
#define TK_MAKE_MENU_DROPDOWN	2










/*
 * The following structure is used with TkMakeEnsemble to create ensemble
 * commands and optionally to create sub-ensembles.
 */

typedef struct TkEnsemble {
    const char *name;
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
 * representation of a clip_mask in a GC.
 */

typedef struct TkpClipMask {
    int type;			/* TKP_CLIP_PIXMAP or TKP_CLIP_REGION. */
    union {
	Pixmap pixmap;
	Region region;
    } value;
} TkpClipMask;

#define TKP_CLIP_PIXMAP 0
#define TKP_CLIP_REGION 1

/*







|







952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
 * representation of a clip_mask in a GC.
 */

typedef struct TkpClipMask {
    int type;			/* TKP_CLIP_PIXMAP or TKP_CLIP_REGION. */
    union {
	Pixmap pixmap;
	TkRegion region;
    } value;
} TkpClipMask;

#define TKP_CLIP_PIXMAP 0
#define TKP_CLIP_REGION 1

/*
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047

1048
1049
1050
1051
1052
1053
1054
 * bits.
 */

#define META_MASK	(AnyModifier<<1)
#define ALT_MASK	(AnyModifier<<2)
#define EXTENDED_MASK	(AnyModifier<<3)

/*
 * Buttons 8 and 9 are the Xbuttons (left and right side-buttons). On Windows/Mac, those
 * are known as Buttons 4 and 5. At script level, they also get the numbers 4 and 5.
 */

#ifndef Button8
# define Button8 8
#endif
#ifndef Button9
# define Button9 9
#endif

#ifndef Button6Mask
# define Button6Mask (1<<13)
#endif
#ifndef Button7Mask
# define Button7Mask (1<<14)
#endif
#ifndef Button8Mask
# define Button8Mask (AnyModifier<<4)
#endif
#ifndef Button9Mask
# define Button9Mask (AnyModifier<<5)
#endif

/*
 * Mask that selects any of the state bits corresponding to buttons, plus
 * masks that select individual buttons' bits:
 */

#define ALL_BUTTONS \
	(Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask \
		|Button6Mask|Button7Mask|Button8Mask|Button9Mask)



/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */

MODULE_SCOPE const Tcl_ObjType tkBorderObjType;







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|
|

>







1001
1002
1003
1004
1005
1006
1007

























1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
 * bits.
 */

#define META_MASK	(AnyModifier<<1)
#define ALT_MASK	(AnyModifier<<2)
#define EXTENDED_MASK	(AnyModifier<<3)


























/*
 * Mask that selects any of the state bits corresponding to buttons, plus
 * masks that select individual buttons' bits:
 */

#define ALL_BUTTONS \
	(Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)


MODULE_SCOPE unsigned TkGetButtonMask(unsigned);

/*
 * Object types not declared in tkObj.c need to be mentioned here so they can
 * be properly registered with Tcl:
 */

MODULE_SCOPE const Tcl_ObjType tkBorderObjType;
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
 * outside world:
 */

MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod;
MODULE_SCOPE Tk_ImageType	tkBitmapImageType;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF;
MODULE_SCOPE void		(*tkHandleEventProc) (XEvent* eventPtr);
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtDefault;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtSVGnano;
MODULE_SCOPE TkMainInfo		*tkMainWindowList;
MODULE_SCOPE Tk_ImageType	tkPhotoImageType;
MODULE_SCOPE Tcl_HashTable	tkPredefBitmapTable;

MODULE_SCOPE const char *const tkWebColors[20];

/*
 * The definition of pi, at least from the perspective of double-precision
 * floats.
 */

#ifndef PI
#ifdef M_PI
#define PI	M_PI
#else
#define PI	3.14159265358979323846
#endif
#endif

/*
 * Support for Clang Static Analyzer <http://clang-analyzer.llvm.org>
 */

#if defined(PURIFY) && defined(__clang__)
#if __has_feature(attribute_analyzer_noreturn) && \
	!defined(Tcl_Panic) && defined(Tcl_Panic_TCL_DECLARED)
void Tcl_Panic(const char *, ...) __attribute__((analyzer_noreturn));
#endif







<


<




















|







1034
1035
1036
1037
1038
1039
1040

1041
1042

1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
 * outside world:
 */

MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod;
MODULE_SCOPE Tk_ImageType	tkBitmapImageType;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF;
MODULE_SCOPE void		(*tkHandleEventProc) (XEvent* eventPtr);

MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG;
MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM;

MODULE_SCOPE TkMainInfo		*tkMainWindowList;
MODULE_SCOPE Tk_ImageType	tkPhotoImageType;
MODULE_SCOPE Tcl_HashTable	tkPredefBitmapTable;

MODULE_SCOPE const char *const tkWebColors[20];

/*
 * The definition of pi, at least from the perspective of double-precision
 * floats.
 */

#ifndef PI
#ifdef M_PI
#define PI	M_PI
#else
#define PI	3.14159265358979323846
#endif
#endif

/*
 * Support for Clang Static Analyzer <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
#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,







|



>







1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
#include "tkIntDecls.h"

#ifdef __cplusplus
extern "C" {
#endif

/*
 * Themed widget set init function, and handler called when Tk is destroyed.
 */

MODULE_SCOPE int	Ttk_Init(Tcl_Interp *interp);
MODULE_SCOPE void	Ttk_TkDestroyedHandler(Tcl_Interp *interp);

/*
 * Internal functions shared among Tk modules but not exported to the outside
 * world:
 */

MODULE_SCOPE int	Tk_BellObjCmd(ClientData clientData,
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
			    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,







<
<
<







1218
1219
1220
1221
1222
1223
1224



1225
1226
1227
1228
1229
1230
1231
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SelectionObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_SendObjCmd(ClientData clientData,
			    Tcl_Interp *interp,int objc,
			    Tcl_Obj *const objv[]);



MODULE_SCOPE int	Tk_SpinboxObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_TextObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_TkwaitObjCmd(ClientData clientData,
1273
1274
1275
1276
1277
1278
1279




1280
1281

1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324

1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354




1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365

1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407


1408
1409
1410
1411
1412

1413
1414
1415
1416

1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WinfoObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);





MODULE_SCOPE int	TkSetGeometryContainer(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name);

MODULE_SCOPE void	TkFreeGeometryContainer(Tk_Window tkwin,
			    const char *name);

MODULE_SCOPE void	TkEventInit(void);
MODULE_SCOPE void	TkRegisterObjTypes(void);
MODULE_SCOPE int	TkDeadAppObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const argv[]);
MODULE_SCOPE int	TkCanvasGetCoordObj(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tcl_Obj *obj,
			    double *doublePtr);
MODULE_SCOPE int	TkGetDoublePixels(Tcl_Interp *interp, Tk_Window tkwin,
			    const char *string, double *doublePtr);
MODULE_SCOPE int	TkPostscriptImage(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, XImage *ximage,
			    int x, int y, int width, int height);
#if TCL_MAJOR_VERSION > 8
MODULE_SCOPE int TkCanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp,
    Tk_Window tkwin, const char *value, char *widgRec, size_t offset);
MODULE_SCOPE const char *TkCanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin,
    char *widgRec, size_t offset, Tcl_FreeProc **freeProcPtr);
#else
#define TkCanvasTagsParseProc Tk_CanvasTagsParseProc
#define TkCanvasTagsPrintProc Tk_CanvasTagsPrintProc
#endif
MODULE_SCOPE void       TkMapTopFrame(Tk_Window tkwin);
MODULE_SCOPE XEvent *	TkpGetBindingXEvent(Tcl_Interp *interp);
MODULE_SCOPE void	TkCreateExitHandler(Tcl_ExitProc *proc,
			    ClientData clientData);
MODULE_SCOPE void	TkDeleteExitHandler(Tcl_ExitProc *proc,
			    ClientData clientData);
MODULE_SCOPE Tcl_ExitProc	TkFinalize;
MODULE_SCOPE Tcl_ExitProc	TkFinalizeThread;
MODULE_SCOPE void	TkpBuildRegionFromAlphaData(Region region,
			    unsigned x, unsigned y, unsigned width,
			    unsigned height, unsigned char *dataPtr,
			    unsigned pixelStride, unsigned lineStride);
MODULE_SCOPE void	TkAppendPadAmount(Tcl_Obj *bufferObj,
			    const char *buffer, int pad1, int pad2);
MODULE_SCOPE int	TkParsePadAmount(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj *objPtr,
			    int *pad1Ptr, int *pad2Ptr);
MODULE_SCOPE void       TkFocusSplit(TkWindow *winPtr);
MODULE_SCOPE void       TkFocusJoin(TkWindow *winPtr);

MODULE_SCOPE void	TkpDrawCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, int x, int y);
MODULE_SCOPE void	TkpDrawAngledCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, double x, double y, double angle);
MODULE_SCOPE int	TkpMeasureCharsInContext(Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, int maxLength, int flags,
			    int *lengthPtr);
MODULE_SCOPE void	TkUnderlineCharsInContext(Display *display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *string, int numBytes, int x, int y,
			    int firstByte, int lastByte);
MODULE_SCOPE void	TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
			    int c, struct TkFontAttributes *faPtr);
MODULE_SCOPE void	TkpDrawFrameEx(Tk_Window tkwin, Drawable drawable,
			    Tk_3DBorder border, int highlightWidth,
			    int borderWidth, int relief);
MODULE_SCOPE void	TkpShowBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpHideBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpMakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
MODULE_SCOPE void	TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef,
			    Window *parentPtr, Tk_Window tkParent,
			    TkBusy busy);
MODULE_SCOPE int	TkBackgroundEvalObjv(Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv, int flags);




MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp,
			    const char *nsname, const char *name,
			    ClientData clientData, const TkEnsemble *map);
MODULE_SCOPE int	TkInitTkCmd(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE int	TkInitFontchooser(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE void	TkInitEmbeddedConfigurationInformation(
			    Tcl_Interp *interp);
MODULE_SCOPE void	TkDoWarpWrtWin(TkDisplay *dispPtr);
MODULE_SCOPE void	TkpWarpPointer(TkDisplay *dispPtr);

MODULE_SCOPE int	TkListCreateFrame(ClientData clientData,
			    Tcl_Interp *interp, Tcl_Obj *listObj,
			    int toplevel, Tcl_Obj *nameObj);
MODULE_SCOPE void	TkRotatePoint(double originX, double originY,
			    double sine, double cosine, double *xPtr,
			    double *yPtr);
MODULE_SCOPE int TkGetIntForIndex(Tcl_Obj *, TkSizeT, int lastOK, TkSizeT*);

#define TkNewIndexObj(value) Tcl_NewWideIntObj((Tcl_WideInt)(value + 1) - 1)

#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, const char* spec,
				XColor * colorPtr);
#endif
#if !defined(_WIN32) && !defined(__CYGWIN__) /* UNIX and MacOSX */
#undef TkPutImage
#define TkPutImage(colors, ncolors, display, pixels, gc, image, srcx, srcy, destx, desty, width, height) \
	XPutImage(display, pixels, gc, image, srcx, srcy, destx, desty, width, height);
#else
#undef XPutImage
#define XPutImage(display, pixels, gc, image, srcx, srcy, destx, desty, width, height) \
	TkPutImage(NULL, 0, display, pixels, gc, image, srcx, srcy, destx, desty, width, height);
#endif

/*
 * These macros are just wrappers for the equivalent X Region calls.
 */
#define TkClipBox XClipBox
#define TkCreateRegion XCreateRegion
#define TkDestroyRegion XDestroyRegion
#define TkIntersectRegion XIntersectRegion
#define TkRectInRegion XRectInRegion
#define TkSetRegion XSetRegion
#define TkSubtractRegion XSubtractRegion
#define TkUnionRectWithRegion XUnionRectWithRegion

#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(Region clipRegion);
#endif



#if !defined(__cplusplus) && !defined(c_plusplus)
# define c_class class
#endif


#if TCL_UTF_MAX > 4
#   define TkUtfToUniChar(src, ch) (size_t)(((int (*)(const char *, int *))Tcl_UtfToUniChar)(src, ch))
#   define TkUniCharToUtf(ch, src) (size_t)(((int (*)(int, char *))Tcl_UniCharToUtf)(ch, src))
#   define TkUtfPrev Tcl_UtfPrev

#else
    MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE size_t TkUniCharToUtf(int, char *);
    MODULE_SCOPE const char *TkUtfPrev(const char *, const char *);
#endif

#if TCL_MAJOR_VERSION > 8
#define TkGetStringFromObj(objPtr, lenPtr) \
	(((objPtr)->bytes ? 0 : Tcl_GetString(objPtr)), \
	*(lenPtr) = (objPtr)->length, (objPtr)->bytes)
MODULE_SCOPE unsigned char *TkGetByteArrayFromObj(Tcl_Obj *objPtr,
	size_t *lengthPtr);
#else
#define TkGetStringFromObj Tcl_GetStringFromObj
#define TkGetByteArrayFromObj Tcl_GetByteArrayFromObj
#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,







>
>
>
>


>



<


|








<
<
<
<
<
<
<
<
<



|




|










>


















|
<
<









>
>
>
>







<
<
<

>



<
<
<
<
<
<








<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

|

>
>





>
|
|
|

>

|
|

<
|
<
<
<
<
<
<
<
<
<







1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255

1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266









1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305


1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325



1326
1327
1328
1329
1330






1331
1332
1333
1334
1335
1336
1337
1338






















1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358

1359









1360
1361
1362
1363
1364
1365
1366
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WinfoObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
MODULE_SCOPE int	Tk_WmObjCmd(ClientData clientData, Tcl_Interp *interp,
			    int objc, Tcl_Obj *const objv[]);

MODULE_SCOPE int	Tk_GetDoublePixelsFromObj(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj *objPtr,
			    double *doublePtr);
#define TkSetGeometryContainer TkSetGeometryMaster
MODULE_SCOPE int	TkSetGeometryContainer(Tcl_Interp *interp,
			    Tk_Window tkwin, const char *name);
#define TkFreeGeometryContainer TkFreeGeometryMaster
MODULE_SCOPE void	TkFreeGeometryContainer(Tk_Window tkwin,
			    const char *name);


MODULE_SCOPE void	TkRegisterObjTypes(void);
MODULE_SCOPE int	TkDeadAppObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]);
MODULE_SCOPE int	TkCanvasGetCoordObj(Tcl_Interp *interp,
			    Tk_Canvas canvas, Tcl_Obj *obj,
			    double *doublePtr);
MODULE_SCOPE int	TkGetDoublePixels(Tcl_Interp *interp, Tk_Window tkwin,
			    const char *string, double *doublePtr);
MODULE_SCOPE int	TkPostscriptImage(Tcl_Interp *interp, Tk_Window tkwin,
			    Tk_PostscriptInfo psInfo, XImage *ximage,
			    int x, int y, int width, int height);









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,
			    ClientData clientData);
MODULE_SCOPE Tcl_ExitProc	TkFinalize;
MODULE_SCOPE Tcl_ExitProc	TkFinalizeThread;
MODULE_SCOPE void	TkpBuildRegionFromAlphaData(TkRegion region,
			    unsigned x, unsigned y, unsigned width,
			    unsigned height, unsigned char *dataPtr,
			    unsigned pixelStride, unsigned lineStride);
MODULE_SCOPE void	TkAppendPadAmount(Tcl_Obj *bufferObj,
			    const char *buffer, int pad1, int pad2);
MODULE_SCOPE int	TkParsePadAmount(Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj *objPtr,
			    int *pad1Ptr, int *pad2Ptr);
MODULE_SCOPE void       TkFocusSplit(TkWindow *winPtr);
MODULE_SCOPE void       TkFocusJoin(TkWindow *winPtr);
MODULE_SCOPE int	TkpAlwaysShowSelection(Tk_Window tkwin);
MODULE_SCOPE void	TkpDrawCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, int x, int y);
MODULE_SCOPE void	TkpDrawAngledCharsInContext(Display * display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, double x, double y, double angle);
MODULE_SCOPE int	TkpMeasureCharsInContext(Tk_Font tkfont,
			    const char *source, int numBytes, int rangeStart,
			    int rangeLength, int maxLength, int flags,
			    int *lengthPtr);
MODULE_SCOPE void	TkUnderlineCharsInContext(Display *display,
			    Drawable drawable, GC gc, Tk_Font tkfont,
			    const char *string, int numBytes, int x, int y,
			    int firstByte, int lastByte);
MODULE_SCOPE void	TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont,
			    int c, struct TkFontAttributes *faPtr);
MODULE_SCOPE Tcl_Obj *	TkNewWindowObj(Tk_Window tkwin);


MODULE_SCOPE void	TkpShowBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpHideBusyWindow(TkBusy busy);
MODULE_SCOPE void	TkpMakeTransparentWindowExist(Tk_Window tkwin,
			    Window parent);
MODULE_SCOPE void	TkpCreateBusy(Tk_FakeWin *winPtr, Tk_Window tkRef,
			    Window *parentPtr, Tk_Window tkParent,
			    TkBusy busy);
MODULE_SCOPE int	TkBackgroundEvalObjv(Tcl_Interp *interp,
			    int objc, Tcl_Obj *const *objv, int flags);
MODULE_SCOPE void	TkSendVirtualEvent(Tk_Window tgtWin,
			    const char *eventName, Tcl_Obj *detail);
MODULE_SCOPE void	TkDrawDottedRect(Display *disp, Drawable d, GC gc,
			    int x, int y, int width, int height);
MODULE_SCOPE Tcl_Command TkMakeEnsemble(Tcl_Interp *interp,
			    const char *nsname, const char *name,
			    ClientData clientData, const TkEnsemble *map);
MODULE_SCOPE int	TkInitTkCmd(Tcl_Interp *interp,
			    ClientData clientData);
MODULE_SCOPE int	TkInitFontchooser(Tcl_Interp *interp,
			    ClientData clientData);



MODULE_SCOPE void	TkpWarpPointer(TkDisplay *dispPtr);
MODULE_SCOPE void	TkpCancelWarp(TkDisplay *dispPtr);
MODULE_SCOPE int	TkListCreateFrame(ClientData clientData,
			    Tcl_Interp *interp, Tcl_Obj *listObj,
			    int toplevel, Tcl_Obj *nameObj);







#ifdef _WIN32
#define TkParseColor XParseColor
#else
MODULE_SCOPE Status TkParseColor (Display * display,
				Colormap map, const char* spec,
				XColor * colorPtr);
#endif






















#ifdef HAVE_XFT
MODULE_SCOPE void	TkUnixSetXftClipRegion(TkRegion clipRegion);
#endif

MODULE_SCOPE void	TkpCopyRegion(TkRegion dst, TkRegion src);

#if !defined(__cplusplus) && !defined(c_plusplus)
# define c_class class
#endif

/* Tcl 8.6 has a different definition of Tcl_UniChar than other Tcl versions for TCL_UTF_MAX > 3 */
#if TCL_UTF_MAX > (3 + (TCL_MAJOR_VERSION == 8 && TCL_MINOR_VERSION == 6))
#   define TkUtfToUniChar Tcl_UtfToUniChar
#   define TkUniCharToUtf Tcl_UniCharToUtf
#   define TkUtfPrev Tcl_UtfPrev
#   define TkUtfAtIndex Tcl_UtfAtIndex
#else
    MODULE_SCOPE int TkUtfToUniChar(const char *, int *);
    MODULE_SCOPE int TkUniCharToUtf(int, char *);
    MODULE_SCOPE const char *TkUtfPrev(const char *, const char *);

    MODULE_SCOPE const char *TkUtfAtIndex(const char *src, int index);









#endif

/*
 * Unsupported commands.
 */

MODULE_SCOPE int	TkUnsupported1ObjCmd(ClientData clientData,
Changes to generic/tkIntDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
 * 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

#include "X11/Xutil.h"

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif

struct TkText;
typedef struct TkTextBTree_ *TkTextBTree;








|








<
<







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


18
19
20
21
22
23
24
/*
 * tkIntDecls.h --
 *
 *	This file contains the declarations for all unsupported
 *	functions that are exported by the Tk library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 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



#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT
#endif

struct TkText;
typedef struct TkTextBTree_ *TkTextBTree;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
				int numPoints, Display *display,
				Drawable drawable, GC gc, GC outlineGC);
/* 21 */
EXTERN int		TkFindStateNum(Tcl_Interp *interp,
				const char *option, const TkStateMap *mapPtr,
				const char *strKey);
/* 22 */
EXTERN const char *	TkFindStateString(const TkStateMap *mapPtr,
				int numKey);
/* 23 */
EXTERN void		TkFocusDeadWindow(TkWindow *winPtr);
/* 24 */
EXTERN int		TkFocusFilterEvent(TkWindow *winPtr,
				XEvent *eventPtr);
/* 25 */







|







100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
				int numPoints, Display *display,
				Drawable drawable, GC gc, GC outlineGC);
/* 21 */
EXTERN int		TkFindStateNum(Tcl_Interp *interp,
				const char *option, const TkStateMap *mapPtr,
				const char *strKey);
/* 22 */
EXTERN CONST86 char *	TkFindStateString(const TkStateMap *mapPtr,
				int numKey);
/* 23 */
EXTERN void		TkFocusDeadWindow(TkWindow *winPtr);
/* 24 */
EXTERN int		TkFocusFilterEvent(TkWindow *winPtr,
				XEvent *eventPtr);
/* 25 */
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* 44 */
EXTERN void		TkInOutEvents(XEvent *eventPtr, TkWindow *sourcePtr,
				TkWindow *destPtr, int leaveType,
				int enterType, Tcl_QueuePosition position);
/* 45 */
EXTERN void		TkInstallFrameMenu(Tk_Window tkwin);
/* 46 */
EXTERN const char *	TkKeysymToString(KeySym keysym);
/* 47 */
EXTERN int		TkLineToArea(double end1Ptr[], double end2Ptr[],
				double rectPtr[]);
/* 48 */
EXTERN double		TkLineToPoint(double end1Ptr[], double end2Ptr[],
				double pointPtr[]);
/* 49 */







|







163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
/* 44 */
EXTERN void		TkInOutEvents(XEvent *eventPtr, TkWindow *sourcePtr,
				TkWindow *destPtr, int leaveType,
				int enterType, Tcl_QueuePosition position);
/* 45 */
EXTERN void		TkInstallFrameMenu(Tk_Window tkwin);
/* 46 */
EXTERN CONST86 char *	TkKeysymToString(KeySym keysym);
/* 47 */
EXTERN int		TkLineToArea(double end1Ptr[], double end2Ptr[],
				double rectPtr[]);
/* 48 */
EXTERN double		TkLineToPoint(double end1Ptr[], double end2Ptr[],
				double pointPtr[]);
/* 49 */
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
				unsigned int *width_return,
				unsigned int *height_return,
				Pixmap *bitmap_return, int *x_hot_return,
				int *y_hot_return);
/* 79 */
EXTERN int		TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
				int width, int height, int dx, int dy,
				Region damageRgn);
/* 80 */
EXTERN void		TkSelDeadWindow(TkWindow *winPtr);
/* 81 */
EXTERN void		TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);
/* 82 */
EXTERN void		TkSelInit(Tk_Window tkwin);
/* 83 */







|







250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
				unsigned int *width_return,
				unsigned int *height_return,
				Pixmap *bitmap_return, int *x_hot_return,
				int *y_hot_return);
/* 79 */
EXTERN int		TkScrollWindow(Tk_Window tkwin, GC gc, int x, int y,
				int width, int height, int dx, int dy,
				TkRegion damageRgn);
/* 80 */
EXTERN void		TkSelDeadWindow(TkWindow *winPtr);
/* 81 */
EXTERN void		TkSelEventProc(Tk_Window tkwin, XEvent *eventPtr);
/* 82 */
EXTERN void		TkSelInit(Tk_Window tkwin);
/* 83 */
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
/* 107 */
EXTERN TkMainInfo *	TkGetMainInfoList(void);
/* 108 */
EXTERN int		TkGetWindowFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				Tk_Window *windowPtr);
/* 109 */
EXTERN const char *	TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
				Tcl_DString *dsPtr);
/* 110 */
EXTERN void		TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);
/* 111 */
EXTERN Tcl_Obj *	TkpGetSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);
/* 112 */
EXTERN void		TkpMenuThreadInit(void);
/* 113 */
EXTERN int		XClipBox(Region rgn, XRectangle *rect_return);
/* 114 */
EXTERN Region		XCreateRegion(void);
/* 115 */
EXTERN int		XDestroyRegion(Region rgn);
/* 116 */
EXTERN int		XIntersectRegion(Region sra, Region srcb,
				Region dr_return);
/* 117 */
EXTERN int		XRectInRegion(Region rgn, int x, int y,
				unsigned int width, unsigned int height);
/* 118 */
EXTERN int		XSetRegion(Display *display, GC gc, Region rgn);
/* 119 */
EXTERN int		XUnionRectWithRegion(XRectangle *rect, Region src,
				Region dr_return);
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
/* 121 */
EXTERN Pixmap		TkpCreateNativeBitmap(Display *display,
				const void *source);
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */







|









|

|

|

|
|

|


|

|
|







320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
/* 107 */
EXTERN TkMainInfo *	TkGetMainInfoList(void);
/* 108 */
EXTERN int		TkGetWindowFromObj(Tcl_Interp *interp,
				Tk_Window tkwin, Tcl_Obj *objPtr,
				Tk_Window *windowPtr);
/* 109 */
EXTERN CONST86 char *	TkpGetString(TkWindow *winPtr, XEvent *eventPtr,
				Tcl_DString *dsPtr);
/* 110 */
EXTERN void		TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont);
/* 111 */
EXTERN Tcl_Obj *	TkpGetSystemDefault(Tk_Window tkwin,
				const char *dbName, const char *className);
/* 112 */
EXTERN void		TkpMenuThreadInit(void);
/* 113 */
EXTERN int		TkClipBox(TkRegion rgn, XRectangle *rect_return);
/* 114 */
EXTERN TkRegion		TkCreateRegion(void);
/* 115 */
EXTERN int		TkDestroyRegion(TkRegion rgn);
/* 116 */
EXTERN int		TkIntersectRegion(TkRegion sra, TkRegion srcb,
				TkRegion dr_return);
/* 117 */
EXTERN int		TkRectInRegion(TkRegion rgn, int x, int y,
				unsigned int width, unsigned int height);
/* 118 */
EXTERN int		TkSetRegion(Display *display, GC gc, TkRegion rgn);
/* 119 */
EXTERN int		TkUnionRectWithRegion(XRectangle *rect, TkRegion src,
				TkRegion dr_return);
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
/* 121 */
EXTERN Pixmap		TkpCreateNativeBitmap(Display *display,
				const void *source);
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
EXTERN void		TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
				XEvent *eventPtr);
/* 138 */
EXTERN KeySym		TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr);
/* 139 */
EXTERN void		TkpInitKeymapInfo(TkDisplay *dispPtr);
/* 140 */
EXTERN Region		TkPhotoGetValidRegion(Tk_PhotoHandle handle);
/* 141 */
EXTERN TkWindow **	TkWmStackorderToplevel(TkWindow *parentPtr);
/* 142 */
EXTERN void		TkFocusFree(TkMainInfo *mainPtr);
/* 143 */
EXTERN void		TkClipCleanup(TkDisplay *dispPtr);
/* 144 */
EXTERN void		TkGCCleanup(TkDisplay *dispPtr);
/* 145 */
EXTERN int		XSubtractRegion(Region sra, Region srcb,
				Region dr_return);
/* 146 */
EXTERN void		TkStylePkgInit(TkMainInfo *mainPtr);
/* 147 */
EXTERN void		TkStylePkgFree(TkMainInfo *mainPtr);
/* 148 */
EXTERN Tk_Window	TkToplevelWindowForCommand(Tcl_Interp *interp,
				const char *cmdName);







|









|
|







386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
EXTERN void		TkpSetKeycodeAndState(Tk_Window tkwin, KeySym keySym,
				XEvent *eventPtr);
/* 138 */
EXTERN KeySym		TkpGetKeySym(TkDisplay *dispPtr, XEvent *eventPtr);
/* 139 */
EXTERN void		TkpInitKeymapInfo(TkDisplay *dispPtr);
/* 140 */
EXTERN TkRegion		TkPhotoGetValidRegion(Tk_PhotoHandle handle);
/* 141 */
EXTERN TkWindow **	TkWmStackorderToplevel(TkWindow *parentPtr);
/* 142 */
EXTERN void		TkFocusFree(TkMainInfo *mainPtr);
/* 143 */
EXTERN void		TkClipCleanup(TkDisplay *dispPtr);
/* 144 */
EXTERN void		TkGCCleanup(TkDisplay *dispPtr);
/* 145 */
EXTERN int		TkSubtractRegion(TkRegion sra, TkRegion srcb,
				TkRegion dr_return);
/* 146 */
EXTERN void		TkStylePkgInit(TkMainInfo *mainPtr);
/* 147 */
EXTERN void		TkStylePkgFree(TkMainInfo *mainPtr);
/* 148 */
EXTERN Tk_Window	TkToplevelWindowForCommand(Tcl_Interp *interp,
				const char *cmdName);
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
				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 */







|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
				const struct TkTextIndex *srcPtr, int count,
				struct TkTextIndex *dstPtr);
/* 162 */
EXTERN struct TkTextIndex * TkTextMakeByteIndex(TkTextBTree tree,
				const struct TkText *textPtr, int lineIndex,
				int byteIndex, struct TkTextIndex *indexPtr);
/* 163 */
EXTERN int		TkTextPrintIndex(const struct TkText *textPtr,
				const struct TkTextIndex *indexPtr,
				char *string);
/* 164 */
EXTERN struct TkTextSegment * TkTextSetMark(struct TkText *textPtr,
				const char *name,
				struct TkTextIndex *indexPtr);
/* 165 */
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
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,







|
<

|
|
|



|
<

|
|
|



|
<

|
|
|



|
<

|
|
|



|
<

|
|
|



|
<

|
|
|







482
483
484
485
486
487
488
489

490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
505

506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521

522
523
524
525
526
527
528
529

530
531
532
533
534
535
536
537
538
539
540
EXTERN void		TkTextInsertDisplayProc(struct TkText *textPtr,
				struct TkTextDispChunk *chunkPtr, int x,
				int y, int height, int baseline,
				Display *display, Drawable dst, int screenY);
/* 169 */
EXTERN int		TkStateParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);

/* 170 */
EXTERN CONST86 char *	TkStatePrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 171 */
EXTERN int		TkCanvasDashParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);

/* 172 */
EXTERN CONST86 char *	TkCanvasDashPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 173 */
EXTERN int		TkOffsetParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);

/* 174 */
EXTERN CONST86 char *	TkOffsetPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 175 */
EXTERN int		TkPixelParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);

/* 176 */
EXTERN CONST86 char *	TkPixelPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 177 */
EXTERN int		TkOrientParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);

/* 178 */
EXTERN CONST86 char *	TkOrientPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 179 */
EXTERN int		TkSmoothParseProc(ClientData clientData,
				Tcl_Interp *interp, Tk_Window tkwin,
				const char *value, char *widgRec, int offset);

/* 180 */
EXTERN CONST86 char *	TkSmoothPrintProc(ClientData clientData,
				Tk_Window tkwin, char *widgRec, int offset,
				Tcl_FreeProc **freeProcPtr);
/* 181 */
EXTERN void		TkDrawAngledTextLayout(Display *display,
				Drawable drawable, GC gc,
				Tk_TextLayout layout, int x, int y,
				double angle, int firstChar, int lastChar);
/* 182 */
EXTERN void		TkUnderlineAngledTextLayout(Display *display,
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
EXTERN void		TkpRedrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 186 */
EXTERN int		TkpWillDrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
/* 187 */
EXTERN int		TkDebugPhotoStringMatchDef(Tcl_Interp *inter,
				Tcl_Obj *data, Tcl_Obj *formatString,
				int *widthPtr, int *heightPtr);

typedef struct TkIntStubs {
    int magic;
    void *hooks;

    TkWindow * (*tkAllocWindow) (TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr); /* 0 */
    void (*tkBezierPoints) (double control[], int numSteps, double *coordPtr); /* 1 */







|
<
<







555
556
557
558
559
560
561
562


563
564
565
566
567
568
569
EXTERN void		TkpRedrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 186 */
EXTERN int		TkpWillDrawWidget(Tk_Window tkwin);
#endif /* MACOSX */
/* 187 */
EXTERN void		TkUnusedStubEntry(void);



typedef struct TkIntStubs {
    int magic;
    void *hooks;

    TkWindow * (*tkAllocWindow) (TkDisplay *dispPtr, int screenNum, TkWindow *parentPtr); /* 0 */
    void (*tkBezierPoints) (double control[], int numSteps, double *coordPtr); /* 1 */
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
    Time (*tkCurrentTime) (TkDisplay *dispPtr); /* 15 */
    void (*tkDeleteAllImages) (TkMainInfo *mainPtr); /* 16 */
    void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */
    void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */
    void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */
    void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */
    int (*tkFindStateNum) (Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey); /* 21 */
    const char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */
    void (*tkFocusDeadWindow) (TkWindow *winPtr); /* 23 */
    int (*tkFocusFilterEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 24 */
    TkWindow * (*tkFocusKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 25 */
    void (*tkFontPkgInit) (TkMainInfo *mainPtr); /* 26 */
    void (*tkFontPkgFree) (TkMainInfo *mainPtr); /* 27 */
    void (*tkFreeBindingTags) (TkWindow *winPtr); /* 28 */
    void (*tkpFreeCursor) (TkCursor *cursorPtr); /* 29 */







|







583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
    Time (*tkCurrentTime) (TkDisplay *dispPtr); /* 15 */
    void (*tkDeleteAllImages) (TkMainInfo *mainPtr); /* 16 */
    void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */
    void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */
    void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */
    void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */
    int (*tkFindStateNum) (Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey); /* 21 */
    CONST86 char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */
    void (*tkFocusDeadWindow) (TkWindow *winPtr); /* 23 */
    int (*tkFocusFilterEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 24 */
    TkWindow * (*tkFocusKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 25 */
    void (*tkFontPkgInit) (TkMainInfo *mainPtr); /* 26 */
    void (*tkFontPkgFree) (TkMainInfo *mainPtr); /* 27 */
    void (*tkFreeBindingTags) (TkWindow *winPtr); /* 28 */
    void (*tkpFreeCursor) (TkCursor *cursorPtr); /* 29 */
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
    void (*tkGetPointerCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 39 */
    void (*tkGetServerInfo) (Tcl_Interp *interp, Tk_Window tkwin); /* 40 */
    void (*tkGrabDeadWindow) (TkWindow *winPtr); /* 41 */
    int (*tkGrabState) (TkWindow *winPtr); /* 42 */
    void (*tkIncludePoint) (Tk_Item *itemPtr, double *pointPtr); /* 43 */
    void (*tkInOutEvents) (XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 44 */
    void (*tkInstallFrameMenu) (Tk_Window tkwin); /* 45 */
    const char * (*tkKeysymToString) (KeySym keysym); /* 46 */
    int (*tkLineToArea) (double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 47 */
    double (*tkLineToPoint) (double end1Ptr[], double end2Ptr[], double pointPtr[]); /* 48 */
    int (*tkMakeBezierCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 49 */
    void (*tkMakeBezierPostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 50 */
    void (*tkOptionClassChanged) (TkWindow *winPtr); /* 51 */
    void (*tkOptionDeadWindow) (TkWindow *winPtr); /* 52 */
    int (*tkOvalToArea) (double *ovalPtr, double *rectPtr); /* 53 */







|







607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
    void (*tkGetPointerCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 39 */
    void (*tkGetServerInfo) (Tcl_Interp *interp, Tk_Window tkwin); /* 40 */
    void (*tkGrabDeadWindow) (TkWindow *winPtr); /* 41 */
    int (*tkGrabState) (TkWindow *winPtr); /* 42 */
    void (*tkIncludePoint) (Tk_Item *itemPtr, double *pointPtr); /* 43 */
    void (*tkInOutEvents) (XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 44 */
    void (*tkInstallFrameMenu) (Tk_Window tkwin); /* 45 */
    CONST86 char * (*tkKeysymToString) (KeySym keysym); /* 46 */
    int (*tkLineToArea) (double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 47 */
    double (*tkLineToPoint) (double end1Ptr[], double end2Ptr[], double pointPtr[]); /* 48 */
    int (*tkMakeBezierCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 49 */
    void (*tkMakeBezierPostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 50 */
    void (*tkOptionClassChanged) (TkWindow *winPtr); /* 51 */
    void (*tkOptionDeadWindow) (TkWindow *winPtr); /* 52 */
    int (*tkOvalToArea) (double *ovalPtr, double *rectPtr); /* 53 */
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
    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 */







|







640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
    int (*tkPositionInTree) (TkWindow *winPtr, TkWindow *treePtr); /* 72 */
    void (*tkpRedirectKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 73 */
    void (*tkpSetMainMenubar) (Tcl_Interp *interp, Tk_Window tkwin, const char *menuName); /* 74 */
    int (*tkpUseWindow) (Tcl_Interp *interp, Tk_Window tkwin, const char *string); /* 75 */
    void (*reserved76)(void);
    void (*tkQueueEventForAllChildren) (TkWindow *winPtr, XEvent *eventPtr); /* 77 */
    int (*tkReadBitmapFile) (Display *display, Drawable d, const char *filename, unsigned int *width_return, unsigned int *height_return, Pixmap *bitmap_return, int *x_hot_return, int *y_hot_return); /* 78 */
    int (*tkScrollWindow) (Tk_Window tkwin, GC gc, int x, int y, int width, int height, int dx, int dy, TkRegion damageRgn); /* 79 */
    void (*tkSelDeadWindow) (TkWindow *winPtr); /* 80 */
    void (*tkSelEventProc) (Tk_Window tkwin, XEvent *eventPtr); /* 81 */
    void (*tkSelInit) (Tk_Window tkwin); /* 82 */
    void (*tkSelPropProc) (XEvent *eventPtr); /* 83 */
    void (*reserved84)(void);
    void (*tkSetWindowMenuBar) (Tcl_Interp *interp, Tk_Window tkwin, const char *oldMenuName, const char *menuName); /* 85 */
    KeySym (*tkStringToKeysym) (const char *name); /* 86 */
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705

706

707
708
709
710
711
712
713
714
715

716

717
718
719
720
721
722
723
724
725
726

727

728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
    Tcl_Obj * (*tkDebugConfig) (Tcl_Interp *interp, Tk_OptionTable table); /* 102 */
    Tcl_Obj * (*tkDebugFont) (Tk_Window tkwin, const char *name); /* 103 */
    int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */
    Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */
    TkDisplay * (*tkGetDisplayList) (void); /* 106 */
    TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */
    int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */
    const char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */
    void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */
    Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 111 */
    void (*tkpMenuThreadInit) (void); /* 112 */
    int (*xClipBox) (Region rgn, XRectangle *rect_return); /* 113 */
    Region (*xCreateRegion) (void); /* 114 */
    int (*xDestroyRegion) (Region rgn); /* 115 */
    int (*xIntersectRegion) (Region sra, Region srcb, Region dr_return); /* 116 */
    int (*xRectInRegion) (Region rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */
    int (*xSetRegion) (Display *display, GC gc, Region rgn); /* 118 */
    int (*xUnionRectWithRegion) (XRectangle *rect, Region src, Region dr_return); /* 119 */
    void (*reserved120)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved121)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved121)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */

    void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */

    Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved122)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved122)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */

    void (*reserved122)(void); /* Dummy entry for stubs table backwards compatibility */

    void (*tkpDefineNativeBitmaps) (void); /* 122 */
#endif /* AQUA */
    void (*reserved123)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved124)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved124)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */

    void (*reserved124)(void); /* Dummy entry for stubs table backwards compatibility */

    Pixmap (*tkpGetNativeAppBitmap) (Display *display, const char *name, int *width, int *height); /* 124 */
#endif /* AQUA */
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    void (*reserved129)(void);
    void (*reserved130)(void);
    void (*reserved131)(void);
    void (*reserved132)(void);
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*tkpDrawHighlightBorder) (Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); /* 135 */
    void (*tkSetFocusWin) (TkWindow *winPtr, int force); /* 136 */
    void (*tkpSetKeycodeAndState) (Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); /* 137 */
    KeySym (*tkpGetKeySym) (TkDisplay *dispPtr, XEvent *eventPtr); /* 138 */
    void (*tkpInitKeymapInfo) (TkDisplay *dispPtr); /* 139 */
    Region (*tkPhotoGetValidRegion) (Tk_PhotoHandle handle); /* 140 */
    TkWindow ** (*tkWmStackorderToplevel) (TkWindow *parentPtr); /* 141 */
    void (*tkFocusFree) (TkMainInfo *mainPtr); /* 142 */
    void (*tkClipCleanup) (TkDisplay *dispPtr); /* 143 */
    void (*tkGCCleanup) (TkDisplay *dispPtr); /* 144 */
    int (*xSubtractRegion) (Region sra, Region srcb, Region dr_return); /* 145 */
    void (*tkStylePkgInit) (TkMainInfo *mainPtr); /* 146 */
    void (*tkStylePkgFree) (TkMainInfo *mainPtr); /* 147 */
    Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, const char *cmdName); /* 148 */
    const Tk_OptionSpec * (*tkGetOptionSpec) (const char *name, Tk_OptionTable optionTable); /* 149 */
    int (*tkMakeRawCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 150 */
    void (*tkMakeRawCurvePostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 151 */
    void (*tkpDrawFrame) (Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); /* 152 */
    void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 153 */
    void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 154 */
    void (*reserved155)(void);
    int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 156 */
    int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 157 */
    int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 158 */
    int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */
    int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 160 */
    int (*tkTextIndexForwBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 161 */
    struct TkTextIndex * (*tkTextMakeByteIndex) (TkTextBTree tree, const struct TkText *textPtr, int lineIndex, int byteIndex, struct TkTextIndex *indexPtr); /* 162 */
    TkSizeT (*tkTextPrintIndex) (const struct TkText *textPtr, const struct TkTextIndex *indexPtr, char *string); /* 163 */
    struct TkTextSegment * (*tkTextSetMark) (struct TkText *textPtr, const char *name, struct TkTextIndex *indexPtr); /* 164 */
    int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 165 */
    void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */
    int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */
    void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */
    int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 169 */
    const char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 170 */
    int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 171 */
    const char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 172 */
    int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 173 */
    const char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 174 */
    int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 175 */
    const char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 176 */
    int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 177 */
    const char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 178 */
    int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, TkSizeT offset); /* 179 */
    const char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, TkSizeT offset, Tcl_FreeProc **freeProcPtr); /* 180 */
    void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */
    void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */
    int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */
    void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved185)(void);
#endif /* UNIX */







|



|
|
|
|
|
|
|








>

>









>

>










>

>

















|




|

















|





|
|
|
|
|
|
|
|
|
|
|
|







670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
    Tcl_Obj * (*tkDebugConfig) (Tcl_Interp *interp, Tk_OptionTable table); /* 102 */
    Tcl_Obj * (*tkDebugFont) (Tk_Window tkwin, const char *name); /* 103 */
    int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */
    Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */
    TkDisplay * (*tkGetDisplayList) (void); /* 106 */
    TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */
    int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */
    CONST86 char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */
    void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */
    Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 111 */
    void (*tkpMenuThreadInit) (void); /* 112 */
    int (*tkClipBox) (TkRegion rgn, XRectangle *rect_return); /* 113 */
    TkRegion (*tkCreateRegion) (void); /* 114 */
    int (*tkDestroyRegion) (TkRegion rgn); /* 115 */
    int (*tkIntersectRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 116 */
    int (*tkRectInRegion) (TkRegion rgn, int x, int y, unsigned int width, unsigned int height); /* 117 */
    int (*tkSetRegion) (Display *display, GC gc, TkRegion rgn); /* 118 */
    int (*tkUnionRectWithRegion) (XRectangle *rect, TkRegion src, TkRegion dr_return); /* 119 */
    void (*reserved120)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved121)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved121)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
# if TCL_MAJOR_VERSION < 9
    void (*reserved121)(void); /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    Pixmap (*tkpCreateNativeBitmap) (Display *display, const void *source); /* 121 */
#endif /* AQUA */
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved122)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved122)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
# if TCL_MAJOR_VERSION < 9
    void (*reserved122)(void); /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    void (*tkpDefineNativeBitmaps) (void); /* 122 */
#endif /* AQUA */
    void (*reserved123)(void);
#if !(defined(_WIN32) || defined(MAC_OSX_TK)) /* X11 */
    void (*reserved124)(void);
#endif /* X11 */
#if defined(_WIN32) /* WIN */
    void (*reserved124)(void);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
# if TCL_MAJOR_VERSION < 9
    void (*reserved124)(void); /* Dummy entry for stubs table backwards compatibility */
# endif /* TCL_MAJOR_VERSION < 9 */
    Pixmap (*tkpGetNativeAppBitmap) (Display *display, const char *name, int *width, int *height); /* 124 */
#endif /* AQUA */
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    void (*reserved129)(void);
    void (*reserved130)(void);
    void (*reserved131)(void);
    void (*reserved132)(void);
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*tkpDrawHighlightBorder) (Tk_Window tkwin, GC fgGC, GC bgGC, int highlightWidth, Drawable drawable); /* 135 */
    void (*tkSetFocusWin) (TkWindow *winPtr, int force); /* 136 */
    void (*tkpSetKeycodeAndState) (Tk_Window tkwin, KeySym keySym, XEvent *eventPtr); /* 137 */
    KeySym (*tkpGetKeySym) (TkDisplay *dispPtr, XEvent *eventPtr); /* 138 */
    void (*tkpInitKeymapInfo) (TkDisplay *dispPtr); /* 139 */
    TkRegion (*tkPhotoGetValidRegion) (Tk_PhotoHandle handle); /* 140 */
    TkWindow ** (*tkWmStackorderToplevel) (TkWindow *parentPtr); /* 141 */
    void (*tkFocusFree) (TkMainInfo *mainPtr); /* 142 */
    void (*tkClipCleanup) (TkDisplay *dispPtr); /* 143 */
    void (*tkGCCleanup) (TkDisplay *dispPtr); /* 144 */
    int (*tkSubtractRegion) (TkRegion sra, TkRegion srcb, TkRegion dr_return); /* 145 */
    void (*tkStylePkgInit) (TkMainInfo *mainPtr); /* 146 */
    void (*tkStylePkgFree) (TkMainInfo *mainPtr); /* 147 */
    Tk_Window (*tkToplevelWindowForCommand) (Tcl_Interp *interp, const char *cmdName); /* 148 */
    const Tk_OptionSpec * (*tkGetOptionSpec) (const char *name, Tk_OptionTable optionTable); /* 149 */
    int (*tkMakeRawCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 150 */
    void (*tkMakeRawCurvePostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 151 */
    void (*tkpDrawFrame) (Tk_Window tkwin, Tk_3DBorder border, int highlightWidth, int borderWidth, int relief); /* 152 */
    void (*tkCreateThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 153 */
    void (*tkDeleteThreadExitHandler) (Tcl_ExitProc *proc, ClientData clientData); /* 154 */
    void (*reserved155)(void);
    int (*tkpTestembedCmd) (ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 156 */
    int (*tkpTesttextCmd) (ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 157 */
    int (*tkSelGetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 158 */
    int (*tkTextGetIndex) (Tcl_Interp *interp, struct TkText *textPtr, const char *string, struct TkTextIndex *indexPtr); /* 159 */
    int (*tkTextIndexBackBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 160 */
    int (*tkTextIndexForwBytes) (const struct TkText *textPtr, const struct TkTextIndex *srcPtr, int count, struct TkTextIndex *dstPtr); /* 161 */
    struct TkTextIndex * (*tkTextMakeByteIndex) (TkTextBTree tree, const struct TkText *textPtr, int lineIndex, int byteIndex, struct TkTextIndex *indexPtr); /* 162 */
    int (*tkTextPrintIndex) (const struct TkText *textPtr, const struct TkTextIndex *indexPtr, char *string); /* 163 */
    struct TkTextSegment * (*tkTextSetMark) (struct TkText *textPtr, const char *name, struct TkTextIndex *indexPtr); /* 164 */
    int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 165 */
    void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */
    int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */
    void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */
    int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 169 */
    CONST86 char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */
    int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 171 */
    CONST86 char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */
    int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 173 */
    CONST86 char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */
    int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 175 */
    CONST86 char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */
    int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 177 */
    CONST86 char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */
    int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 179 */
    CONST86 char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */
    void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */
    void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */
    int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */
    void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */
#if !defined(_WIN32) && !defined(MAC_OSX_TCL) /* UNIX */
    void (*reserved185)(void);
#endif /* UNIX */
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved186)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* MACOSX */
    int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 187 */
} TkIntStubs;

extern const TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}
#endif







|







797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
#endif /* UNIX */
#if defined(_WIN32) /* WIN */
    void (*reserved186)(void);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    int (*tkpWillDrawWidget) (Tk_Window tkwin); /* 186 */
#endif /* MACOSX */
    void (*tkUnusedStubEntry) (void); /* 187 */
} TkIntStubs;

extern const TkIntStubs *tkIntStubsPtr;

#ifdef __cplusplus
}
#endif
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
	(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 \







|
|
|
|
|
|
|
|
|
|
|
|
|
|







1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
	(tkIntStubsPtr->tkpGetString) /* 109 */
#define TkpGetSubFonts \
	(tkIntStubsPtr->tkpGetSubFonts) /* 110 */
#define TkpGetSystemDefault \
	(tkIntStubsPtr->tkpGetSystemDefault) /* 111 */
#define TkpMenuThreadInit \
	(tkIntStubsPtr->tkpMenuThreadInit) /* 112 */
#define TkClipBox \
	(tkIntStubsPtr->tkClipBox) /* 113 */
#define TkCreateRegion \
	(tkIntStubsPtr->tkCreateRegion) /* 114 */
#define TkDestroyRegion \
	(tkIntStubsPtr->tkDestroyRegion) /* 115 */
#define TkIntersectRegion \
	(tkIntStubsPtr->tkIntersectRegion) /* 116 */
#define TkRectInRegion \
	(tkIntStubsPtr->tkRectInRegion) /* 117 */
#define TkSetRegion \
	(tkIntStubsPtr->tkSetRegion) /* 118 */
#define TkUnionRectWithRegion \
	(tkIntStubsPtr->tkUnionRectWithRegion) /* 119 */
/* Slot 120 is reserved */
#ifdef MAC_OSX_TK /* AQUA */
#define TkpCreateNativeBitmap \
	(tkIntStubsPtr->tkpCreateNativeBitmap) /* 121 */
#endif /* AQUA */
#ifdef MAC_OSX_TK /* AQUA */
#define TkpDefineNativeBitmaps \
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
	(tkIntStubsPtr->tkWmStackorderToplevel) /* 141 */
#define TkFocusFree \
	(tkIntStubsPtr->tkFocusFree) /* 142 */
#define TkClipCleanup \
	(tkIntStubsPtr->tkClipCleanup) /* 143 */
#define TkGCCleanup \
	(tkIntStubsPtr->tkGCCleanup) /* 144 */
#define XSubtractRegion \
	(tkIntStubsPtr->xSubtractRegion) /* 145 */
#define TkStylePkgInit \
	(tkIntStubsPtr->tkStylePkgInit) /* 146 */
#define TkStylePkgFree \
	(tkIntStubsPtr->tkStylePkgFree) /* 147 */
#define TkToplevelWindowForCommand \
	(tkIntStubsPtr->tkToplevelWindowForCommand) /* 148 */
#define TkGetOptionSpec \







|
|







1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
	(tkIntStubsPtr->tkWmStackorderToplevel) /* 141 */
#define TkFocusFree \
	(tkIntStubsPtr->tkFocusFree) /* 142 */
#define TkClipCleanup \
	(tkIntStubsPtr->tkClipCleanup) /* 143 */
#define TkGCCleanup \
	(tkIntStubsPtr->tkGCCleanup) /* 144 */
#define TkSubtractRegion \
	(tkIntStubsPtr->tkSubtractRegion) /* 145 */
#define TkStylePkgInit \
	(tkIntStubsPtr->tkStylePkgInit) /* 146 */
#define TkStylePkgFree \
	(tkIntStubsPtr->tkStylePkgFree) /* 147 */
#define TkToplevelWindowForCommand \
	(tkIntStubsPtr->tkToplevelWindowForCommand) /* 148 */
#define TkGetOptionSpec \
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198













1199
1200
1201
1202
1203
1204
1205
1206














1207
1208
1209
1210
1211
1212
1213
1214


1215

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








|
|








>
>
>
>
>
>
>
>
>
>
>
>
>








>
>
>
>
>
>
>
>
>
>
>
>
>
>








>
>

>
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
#define TkpRedrawWidget \
	(tkIntStubsPtr->tkpRedrawWidget) /* 185 */
#endif /* MACOSX */
#ifdef MAC_OSX_TCL /* MACOSX */
#define TkpWillDrawWidget \
	(tkIntStubsPtr->tkpWillDrawWidget) /* 186 */
#endif /* MACOSX */
#define TkUnusedStubEntry \
	(tkIntStubsPtr->tkUnusedStubEntry) /* 187 */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

/*
 * On X11, these macros are just wrappers for the equivalent X Region calls.
 */
#if !(defined(_WIN32) || defined(__CYGWIN__) || defined(MAC_OSX_TK)) /* X11 */

#undef TkClipBox
#undef TkCreateRegion
#undef TkDestroyRegion
#undef TkIntersectRegion
#undef TkRectInRegion
#undef TkSetRegion
#undef TkSubtractRegion
#undef TkUnionRectWithRegion
#undef TkpCmapStressed_
#undef TkpSync_
#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_

#define TkClipBox(rgn, rect) XClipBox((Region) rgn, rect)
#define TkCreateRegion() (TkRegion) XCreateRegion()
#define TkDestroyRegion(rgn) XDestroyRegion((Region) rgn)
#define TkIntersectRegion(a, b, r) XIntersectRegion((Region) a, \
	(Region) b, (Region) r)
#define TkRectInRegion(r, x, y, w, h) XRectInRegion((Region) r, x, y, w, h)
#define TkSetRegion(d, gc, rgn) XSetRegion(d, gc, (Region) rgn)
#define TkSubtractRegion(a, b, r) XSubtractRegion((Region) a, \
	(Region) b, (Region) r)
#define TkUnionRectWithRegion(rect, src, ret) XUnionRectWithRegion(rect, \
	(Region) src, (Region) ret)

#endif /* UNIX */

#if !defined(MAC_OSX_TK)
#   undef TkpWillDrawWidget
#   undef TkpRedrawWidget
#   define TkpWillDrawWidget(w) 0
#   define TkpRedrawWidget(w)
#endif

#undef TkUnusedStubEntry

#endif /* _TKINTDECLS */

Changes to generic/tkIntPlatDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
 * 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
166
167
168
169
170
171
172
173

174
175
176
177
178
179
180
EXTERN void		TkAboutDlg(void);
/* 8 */
EXTERN unsigned int	TkMacOSXButtonKeyState(void);
/* 9 */
EXTERN void		TkMacOSXClearMenubarActive(void);
/* 10 */
EXTERN int		TkMacOSXDispatchMenuEvent(int menuID, int index);
/* Slot 11 is reserved */

/* 12 */
EXTERN void		TkMacOSXHandleTearoffMenu(void);
/* Slot 13 is reserved */
/* 14 */
EXTERN int		TkMacOSXDoHLEvent(void *theEvent);
/* Slot 15 is reserved */
/* 16 */







|
>







166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
EXTERN void		TkAboutDlg(void);
/* 8 */
EXTERN unsigned int	TkMacOSXButtonKeyState(void);
/* 9 */
EXTERN void		TkMacOSXClearMenubarActive(void);
/* 10 */
EXTERN int		TkMacOSXDispatchMenuEvent(int menuID, int index);
/* 11 */
EXTERN void		TkMacOSXInstallCursor(int resizeOverride);
/* 12 */
EXTERN void		TkMacOSXHandleTearoffMenu(void);
/* Slot 13 is reserved */
/* 14 */
EXTERN int		TkMacOSXDoHLEvent(void *theEvent);
/* Slot 15 is reserved */
/* 16 */
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
EXTERN void		TkMacOSXSetUpGraphicsPort(GC gc, void *destPort);
/* 32 */
EXTERN void		TkMacOSXUpdateClipRgn(TkWindow *winPtr);
/* Slot 33 is reserved */
/* 34 */
EXTERN int		TkMacOSXUseMenuID(short macID);
/* 35 */
EXTERN Region		TkMacOSXVisableClipRgn(TkWindow *winPtr);
/* 36 */
EXTERN void		TkMacOSXWinBounds(TkWindow *winPtr, void *geometry);
/* 37 */
EXTERN void		TkMacOSXWindowOffset(void *wRef, int *xOffset,
				int *yOffset);
/* 38 */
EXTERN int		TkSetMacColor(unsigned long pixel, void *macColor);







|







212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
EXTERN void		TkMacOSXSetUpGraphicsPort(GC gc, void *destPort);
/* 32 */
EXTERN void		TkMacOSXUpdateClipRgn(TkWindow *winPtr);
/* Slot 33 is reserved */
/* 34 */
EXTERN int		TkMacOSXUseMenuID(short macID);
/* 35 */
EXTERN TkRegion		TkMacOSXVisableClipRgn(TkWindow *winPtr);
/* 36 */
EXTERN void		TkMacOSXWinBounds(TkWindow *winPtr, void *geometry);
/* 37 */
EXTERN void		TkMacOSXWindowOffset(void *wRef, int *xOffset,
				int *yOffset);
/* 38 */
EXTERN int		TkSetMacColor(unsigned long pixel, void *macColor);
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
/* 44 */
EXTERN MacDrawable *	TkMacOSXGetHostToplevel(TkWindow *winPtr);
/* 45 */
EXTERN void		TkMacOSXPreprocessMenu(void);
/* 46 */
EXTERN int		TkpIsWindowFloating(void *window);
/* 47 */
EXTERN Tk_Window	TkpGetCapture(void);
/* Slot 48 is reserved */
/* 49 */
EXTERN Tk_Window	TkMacOSXGetContainer(TkWindow *winPtr);
/* 50 */
EXTERN int		TkGenerateButtonEvent(int x, int y, Window window,
				unsigned int state);
/* 51 */
EXTERN void		TkGenWMDestroyEvent(Tk_Window tkwin);
/* 52 */
EXTERN void		TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag);







|


|







238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
/* 44 */
EXTERN MacDrawable *	TkMacOSXGetHostToplevel(TkWindow *winPtr);
/* 45 */
EXTERN void		TkMacOSXPreprocessMenu(void);
/* 46 */
EXTERN int		TkpIsWindowFloating(void *window);
/* 47 */
EXTERN Tk_Window	TkMacOSXGetCapture(void);
/* Slot 48 is reserved */
/* 49 */
EXTERN Tk_Window	TkGetTransientMaster(TkWindow *winPtr);
/* 50 */
EXTERN int		TkGenerateButtonEvent(int x, int y, Window window,
				unsigned int state);
/* 51 */
EXTERN void		TkGenWMDestroyEvent(Tk_Window tkwin);
/* 52 */
EXTERN void		TkMacOSXSetDrawingEnabled(TkWindow *winPtr, int flag);
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
    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 */







|







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
    void (*tkpSetCapture) (TkWindow *winPtr); /* 4 */
    void (*tkpSetCursor) (TkpCursor cursor); /* 5 */
    void (*tkpWmSetState) (TkWindow *winPtr, int state); /* 6 */
    void (*tkAboutDlg) (void); /* 7 */
    unsigned int (*tkMacOSXButtonKeyState) (void); /* 8 */
    void (*tkMacOSXClearMenubarActive) (void); /* 9 */
    int (*tkMacOSXDispatchMenuEvent) (int menuID, int index); /* 10 */
    void (*tkMacOSXInstallCursor) (int resizeOverride); /* 11 */
    void (*tkMacOSXHandleTearoffMenu) (void); /* 12 */
    void (*reserved13)(void);
    int (*tkMacOSXDoHLEvent) (void *theEvent); /* 14 */
    void (*reserved15)(void);
    Window (*tkMacOSXGetXWindow) (void *macWinPtr); /* 16 */
    int (*tkMacOSXGrowToplevel) (void *whichWindow, XPoint start); /* 17 */
    void (*tkMacOSXHandleMenuSelect) (short theMenu, unsigned short theItem, int optionKeyPressed); /* 18 */
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
    void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */
    void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */
    void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */
    void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */
    void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */
    void (*reserved33)(void);
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    Region (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
    void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
    void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */
    int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */
    void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */
    void (*reserved40)(void);
    int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */
    Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */
    MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */
    MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */
    void (*tkMacOSXPreprocessMenu) (void); /* 45 */
    int (*tkpIsWindowFloating) (void *window); /* 46 */
    Tk_Window (*tkpGetCapture) (void); /* 47 */
    void (*reserved48)(void);
    Tk_Window (*tkMacOSXGetContainer) (TkWindow *winPtr); /* 49 */
    int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
    void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
    void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
    unsigned long (*tkpGetMS) (void); /* 53 */
    void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */
#endif /* AQUA */







|











|

|







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
    void (*tkMacOSXSetHelpMenuItemCount) (void); /* 28 */
    void (*tkMacOSXSetScrollbarGrow) (TkWindow *winPtr, int flag); /* 29 */
    void (*tkMacOSXSetUpClippingRgn) (Drawable drawable); /* 30 */
    void (*tkMacOSXSetUpGraphicsPort) (GC gc, void *destPort); /* 31 */
    void (*tkMacOSXUpdateClipRgn) (TkWindow *winPtr); /* 32 */
    void (*reserved33)(void);
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    TkRegion (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
    void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
    void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */
    int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */
    void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */
    void (*reserved40)(void);
    int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */
    Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */
    MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */
    MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */
    void (*tkMacOSXPreprocessMenu) (void); /* 45 */
    int (*tkpIsWindowFloating) (void *window); /* 46 */
    Tk_Window (*tkMacOSXGetCapture) (void); /* 47 */
    void (*reserved48)(void);
    Tk_Window (*tkGetTransientMaster) (TkWindow *winPtr); /* 49 */
    int (*tkGenerateButtonEvent) (int x, int y, Window window, unsigned int state); /* 50 */
    void (*tkGenWMDestroyEvent) (Tk_Window tkwin); /* 51 */
    void (*tkMacOSXSetDrawingEnabled) (TkWindow *winPtr, int flag); /* 52 */
    unsigned long (*tkpGetMS) (void); /* 53 */
    void * (*tkMacOSXDrawable) (Drawable drawable); /* 54 */
    int (*tkpScanWindowId) (Tcl_Interp *interp, const char *string, Window *idPtr); /* 55 */
#endif /* AQUA */
623
624
625
626
627
628
629
630

631
632
633
634
635
636
637
	(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 \







|
>







624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
	(tkIntPlatStubsPtr->tkAboutDlg) /* 7 */
#define TkMacOSXButtonKeyState \
	(tkIntPlatStubsPtr->tkMacOSXButtonKeyState) /* 8 */
#define TkMacOSXClearMenubarActive \
	(tkIntPlatStubsPtr->tkMacOSXClearMenubarActive) /* 9 */
#define TkMacOSXDispatchMenuEvent \
	(tkIntPlatStubsPtr->tkMacOSXDispatchMenuEvent) /* 10 */
#define TkMacOSXInstallCursor \
	(tkIntPlatStubsPtr->tkMacOSXInstallCursor) /* 11 */
#define TkMacOSXHandleTearoffMenu \
	(tkIntPlatStubsPtr->tkMacOSXHandleTearoffMenu) /* 12 */
/* Slot 13 is reserved */
#define TkMacOSXDoHLEvent \
	(tkIntPlatStubsPtr->tkMacOSXDoHLEvent) /* 14 */
/* Slot 15 is reserved */
#define TkMacOSXGetXWindow \
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
	(tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */
#define TkMacOSXGetHostToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGetHostToplevel) /* 44 */
#define TkMacOSXPreprocessMenu \
	(tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */
#define TkpIsWindowFloating \
	(tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */
#define TkpGetCapture \
	(tkIntPlatStubsPtr->tkpGetCapture) /* 47 */
/* Slot 48 is reserved */
#define TkMacOSXGetContainer \
	(tkIntPlatStubsPtr->tkMacOSXGetContainer) /* 49 */
#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */
#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */
#define TkpGetMS \







|
|

|
|







689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
	(tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */
#define TkMacOSXGetHostToplevel \
	(tkIntPlatStubsPtr->tkMacOSXGetHostToplevel) /* 44 */
#define TkMacOSXPreprocessMenu \
	(tkIntPlatStubsPtr->tkMacOSXPreprocessMenu) /* 45 */
#define TkpIsWindowFloating \
	(tkIntPlatStubsPtr->tkpIsWindowFloating) /* 46 */
#define TkMacOSXGetCapture \
	(tkIntPlatStubsPtr->tkMacOSXGetCapture) /* 47 */
/* Slot 48 is reserved */
#define TkGetTransientMaster \
	(tkIntPlatStubsPtr->tkGetTransientMaster) /* 49 */
#define TkGenerateButtonEvent \
	(tkIntPlatStubsPtr->tkGenerateButtonEvent) /* 50 */
#define TkGenWMDestroyEvent \
	(tkIntPlatStubsPtr->tkGenWMDestroyEvent) /* 51 */
#define TkMacOSXSetDrawingEnabled \
	(tkIntPlatStubsPtr->tkMacOSXSetDrawingEnabled) /* 52 */
#define TkpGetMS \
787
788
789
790
791
792
793


794

795
796
797
798
799
800
801
802
#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 */







>
>
|
>




<
<
<

789
790
791
792
793
794
795
796
797
798
799
800
801
802
803



804
#undef TkUnixContainerId_
#undef TkUnixDoOneXEvent_
#undef TkUnixSetMenubar_
#undef TkWmCleanup_
#undef TkSendCleanup_
#undef TkpTestsendCmd_
#undef TkGenerateActivateEvents_

#define TkMacOSXGetContainer TkGetTransientMaster
#undef TkMacOSXIsCharacterMissing
#define TkMacOSXIsCharacterMissing(tkfont) ((void)tkfont, 0)

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT




#endif /* _TKINTPLATDECLS */
Changes to generic/tkIntXlibDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

27
28
29
30


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
 * 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

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tkInt.decls script.
 */

#ifndef _TCL
#   include <tcl.h>
#endif

#ifndef EXTERN

#   define EXTERN extern TCL_STORAGE_CLASS
#endif

#include "X11/Xutil.h"



#ifdef BUILD_tk
#  undef TCL_STORAGE_CLASS
#  define TCL_STORAGE_CLASS DLLEXPORT
#else
#  ifndef TCL_STORAGE_CLASS
#    define TCL_STORAGE_CLASS DLLIMPORT
#  endif
#endif

#if defined(MAC_OSX_TK) && !defined(MAC_OSX_TCL)
#  define MAC_OSX_TCL 1
#endif

typedef int (*XAfterFunction) (	    /* WARNING, this type not in Xlib spec */
    Display*		/* display */
);

/* !BEGIN!: Do not edit below this line. */








|
















|
>
|
<
|

>
>


|
|
<
<
<
<
<
<
<
<







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

29
30
31
32
33
34
35
36








37
38
39
40
41
42
43
/*
 * tkIntXlibDecls.h --
 *
 *	This file contains the declarations for all platform dependent
 *	unsupported functions that are exported by the Tk library.  These
 *	interfaces are not guaranteed to remain the same between
 *	versions.  Use at your own risk.
 *
 * Copyright (c) 1998-1999 Scriptics Corporation.
 * All rights reserved.
 */

#ifndef _TKINTXLIBDECLS
#define _TKINTXLIBDECLS

/*
 * WARNING: This file is automatically generated by the tools/genStubs.tcl
 * script.  Any modifications to the function declarations below should be made
 * in the generic/tkInt.decls script.
 */

#ifndef _TCL
#   include <tcl.h>
#endif

/* Some (older) versions of X11/Xutil.h have a wrong signature of those
   two functions, so move them out of the way temporarily. */
#define XOffsetRegion _XOffsetRegion

#define XUnionRegion _XUnionRegion
#include "X11/Xutil.h"
#undef XOffsetRegion
#undef XUnionRegion

#ifdef BUILD_tk
#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLEXPORT








#endif

typedef int (*XAfterFunction) (	    /* WARNING, this type not in Xlib spec */
    Display*		/* display */
);

/* !BEGIN!: Do not edit below this line. */
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 */







|
>
>
>







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
				char *c, int i, KeySym *k, Status *s);
/* 80 */
EXTERN int		TkPutImage(unsigned long *colors, int ncolors,
				Display *display, Drawable d, GC gc,
				XImage *image, int src_x, int src_y,
				int dest_x, int dest_y, unsigned int width,
				unsigned int height);
/* 81 */
EXTERN int		XSetClipRectangles(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin,
				XRectangle rectangles[], int n, int ordering);
/* 82 */
EXTERN Status		XParseColor(Display *display, Colormap map,
				_Xconst char *spec, XColor *colorPtr);
/* 83 */
EXTERN GC		XCreateGC(Display *display, Drawable d,
				unsigned long valuemask, XGCValues *values);
/* 84 */
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
/* 136 */
EXTERN int		XReparentWindow(Display *d, Window w, Window p,
				int x, int y);
/* 137 */
EXTERN int		XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
				int sx, int sy, int dx, int dy,
				unsigned int w, unsigned int h);
/* 138 */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
EXTERN void		XSetICFocus(XIC xic);
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
/* 147 */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
EXTERN int		XCloseIM(XIM im);
/* 149 */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 150 */
EXTERN Bool		XUnregisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 151 */
EXTERN char *		XSetLocaleModifiers(const char *modifier_list);
/* 152 */
EXTERN XIM		XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb,
				char *res_name, char *res_class);
/* 153 */
EXTERN char *		XGetIMValues(XIM im, ...);
/* 154 */
EXTERN char *		XSetIMValues(XIM im, ...);
/* 155 */
EXTERN XFontSet		XCreateFontSet(Display *display,
				_Xconst char *base_font_name_list,
				char ***missing_charset_list,
				int *missing_charset_count,
				char **def_string);
/* 156 */
EXTERN void		XFreeStringList(char **list);
/* 157 */
EXTERN KeySym		XkbKeycodeToKeysym(Display *d, unsigned int k, int g,
				int i);
/* 158 */
EXTERN Display *	XkbOpenDisplay(const char *name, int *ev_rtrn,
				int *err_rtrn, int *major_rtrn,
				int *minor_rtrn, int *reason);
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
/* 0 */
EXTERN int		XSetDashes(Display *display, GC gc, int dash_offset,
				_Xconst char *dash_list, int n);
/* 1 */
EXTERN XModifierKeymap * XGetModifierMapping(Display *d);
/* 2 */
EXTERN XImage *		XCreateImage(Display *d, Visual *v, unsigned int ui1,







|
<
|
<
|
<
|
<
|
<
|
<



|
<
|
<
|
<
<
<
<
|
<
<
<
<
|
<
|
<
<
|
<
|
<
|
<
<
<
<
<
|
<
|
<
<

|
<
<

|







412
413
414
415
416
417
418
419

420

421

422

423

424

425
426
427
428

429

430




431




432

433


434

435

436





437

438


439
440


441
442
443
444
445
446
447
448
449
/* 136 */
EXTERN int		XReparentWindow(Display *d, Window w, Window p,
				int x, int y);
/* 137 */
EXTERN int		XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
				int sx, int sy, int dx, int dy,
				unsigned int w, unsigned int h);
/* Slot 138 is reserved */

/* Slot 139 is reserved */

/* Slot 140 is reserved */

/* Slot 141 is reserved */

/* Slot 142 is reserved */

/* Slot 143 is reserved */

/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
/* Slot 147 is reserved */

/* Slot 148 is reserved */

/* Slot 149 is reserved */




/* Slot 150 is reserved */




/* Slot 151 is reserved */

/* Slot 152 is reserved */


/* Slot 153 is reserved */

/* Slot 154 is reserved */

/* Slot 155 is reserved */





/* Slot 156 is reserved */

/* Slot 157 is reserved */


/* 158 */
EXTERN void		TkUnusedStubEntry(void);


#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* 0 */
EXTERN int		XSetDashes(Display *display, GC gc, int dash_offset,
				_Xconst char *dash_list, int n);
/* 1 */
EXTERN XModifierKeymap * XGetModifierMapping(Display *d);
/* 2 */
EXTERN XImage *		XCreateImage(Display *d, Visual *v, unsigned int ui1,
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
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 */







|







459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
EXTERN char *		XKeysymToString(KeySym k);
/* 6 */
EXTERN Colormap		XCreateColormap(Display *d, Window w, Visual *v,
				int i);
/* 7 */
EXTERN GContext		XGContextFromGC(GC g);
/* 8 */
EXTERN KeySym		XKeycodeToKeysym(Display *d, KeyCode k, int i);
/* 9 */
EXTERN KeySym		XStringToKeysym(_Xconst char *c);
/* 10 */
EXTERN Window		XRootWindow(Display *d, int i);
/* 11 */
EXTERN XErrorHandler	XSetErrorHandler(XErrorHandler x);
/* 12 */
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
EXTERN int		XQueryColors(Display *display, Colormap colormap,
				XColor *defs_in_out, int ncolors);
/* 90 */
EXTERN Status		XQueryTree(Display *d, Window w1, Window *w2,
				Window *w3, Window **w4, unsigned int *ui);
/* 91 */
EXTERN int		XSync(Display *display, Bool discard);
/* 92 */
EXTERN Bool		XTranslateCoordinates(Display *d, Window w1,
				Window w2, int i1, int i2, int *i3, int *i4,
				Window *w3);
/* 93 */
EXTERN int		XDeleteProperty(Display *d, Window w, Atom a);
/* 94 */
EXTERN int		XFreeCursor(Display *d, Cursor c);
/* 95 */
EXTERN int		XGetInputFocus(Display *d, Window *w, int *i);
/* 96 */
EXTERN int		XmbLookupString(XIC xi, XKeyPressedEvent *xk,
				char *c, int i, KeySym *k, Status *s);
/* 97 */
EXTERN int		XNextEvent(Display *d, XEvent *x);
/* 98 */
EXTERN int		XPutBackEvent(Display *d, XEvent *x);
/* 99 */
EXTERN int		XSetCommand(Display *d, Window w, char **c, int i);
/* 100 */
EXTERN int		XWindowEvent(Display *d, Window w, long l, XEvent *x);
/* 101 */
EXTERN Status		XGetWindowAttributes(Display *d, Window w,
				XWindowAttributes *x);
/* 102 */
EXTERN Status		XGetWMColormapWindows(Display *d, Window w,
				Window **wpp, int *ip);
/* 103 */
EXTERN Status		XIconifyWindow(Display *d, Window w, int i);
/* 104 */
EXTERN Status		XWithdrawWindow(Display *d, Window w, int i);
/* 105 */
EXTERN XHostAddress *	XListHosts(Display *d, int *i, Bool *b);
/* 106 */
EXTERN int		XSetClipRectangles(Display *display, GC gc,
				int clip_x_origin, int clip_y_origin,
				XRectangle rectangles[], int n, int ordering);
/* 107 */
EXTERN int		XFlush(Display *display);
/* 108 */
EXTERN int		XGrabServer(Display *display);
/* 109 */
EXTERN int		XUngrabServer(Display *display);
/* 110 */
EXTERN int		XFree(void *data);
/* 111 */
EXTERN int		XNoOp(Display *display);
/* 112 */
EXTERN XAfterFunction	XSynchronize(Display *display, Bool onoff);
/* 113 */
EXTERN Status		XLookupColor(Display *d, Colormap c1,
				_Xconst char *c2, XColor *x1, XColor *x2);
/* 114 */
EXTERN VisualID		XVisualIDFromVisual(Visual *visual);
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
/* 120 */
EXTERN int		XOffsetRegion(Region rgn, int dx, int dy);
/* 121 */
EXTERN int		XUnionRegion(Region srca, Region srcb,
				Region dr_return);
/* 122 */
EXTERN Window		XCreateWindow(Display *display, Window parent, int x,
				int y, unsigned int width,
				unsigned int height,
				unsigned int border_width, int depth,
				unsigned int clazz, Visual *visual,
				unsigned long value_mask,
				XSetWindowAttributes *attributes);
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* 129 */
EXTERN int		XLowerWindow(Display *d, Window w);
/* 130 */
EXTERN int		XFillArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 131 */
EXTERN int		XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a,
				int n);
/* 132 */
EXTERN int		XDrawRectangles(Display *d, Drawable dr, GC gc,
				XRectangle *r, int n);
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
/* 136 */
EXTERN int		XReparentWindow(Display *d, Window w, Window p,
				int x, int y);
/* 137 */
EXTERN int		XPutImage(Display *d, Drawable dr, GC gc, XImage *im,
				int sx, int sy, int dx, int dy,
				unsigned int w, unsigned int h);
/* 138 */
EXTERN Region		XPolygonRegion(XPoint *pts, int n, int rule);
/* 139 */
EXTERN int		XPointInRegion(Region rgn, int x, int y);
/* 140 */
EXTERN XVaNestedList	XVaCreateNestedList(int dummy, ...);
/* 141 */
EXTERN char *		XSetICValues(XIC xic, ...);
/* 142 */
EXTERN char *		XGetICValues(XIC xic, ...);
/* 143 */
EXTERN void		XSetICFocus(XIC xic);
/* 144 */
EXTERN void		XDestroyIC(XIC xic);
/* 145 */
EXTERN Cursor		XCreatePixmapCursor(Display *d, Pixmap p1, Pixmap p2,
				XColor *x1, XColor *x2, unsigned int ui1,
				unsigned int ui2);
/* 146 */
EXTERN Cursor		XCreateGlyphCursor(Display *d, Font f1, Font f2,
				unsigned int ui1, unsigned int ui2,
				XColor _Xconst *x1, XColor _Xconst *x2);
/* 147 */
EXTERN void		XFreeFontSet(Display *display, XFontSet fontset);
/* 148 */
EXTERN int		XCloseIM(XIM im);
/* 149 */
EXTERN Bool		XRegisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 150 */
EXTERN Bool		XUnregisterIMInstantiateCallback(Display *dpy,
				struct _XrmHashBucketRec *rbd,
				char *res_name, char *res_class,
				XIDProc callback, XPointer client_data);
/* 151 */
EXTERN char *		XSetLocaleModifiers(const char *modifier_list);
/* 152 */
EXTERN XIM		XOpenIM(Display *dpy, struct _XrmHashBucketRec *rdb,
				char *res_name, char *res_class);
/* 153 */
EXTERN char *		XGetIMValues(XIM im, ...);
/* 154 */
EXTERN char *		XSetIMValues(XIM im, ...);
/* 155 */
EXTERN XFontSet		XCreateFontSet(Display *display,
				_Xconst char *base_font_name_list,
				char ***missing_charset_list,
				int *missing_charset_count,
				char **def_string);
/* 156 */
EXTERN void		XFreeStringList(char **list);
/* 157 */
EXTERN KeySym		XkbKeycodeToKeysym(Display *d, unsigned int k, int g,
				int i);
/* 158 */
EXTERN Display *	XkbOpenDisplay(const char *name, int *ev_rtrn,
				int *err_rtrn, int *major_rtrn,
				int *minor_rtrn, int *reason);
#endif /* MACOSX */

typedef struct TkIntXlibStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */







|
<
<
<
|
<
|
<
|
<
|
<
<
|
<
|
<
|
<
|
<
|
<
<
|
<
<
|
<
|
<
|
<
















|
<
<








|
|
<
<
|
<
<
<
<
<
<
<








|
<
<
|
<
<
|
<
<



|
<
<




|
<
|
<
|
<
|
<
|
<
|
<










|
<
|
<
|
<
<
<
<
|
<
<
<
<
|
<
|
<
<
|
<
|
<
|
<
<
<
<
<
|
<




|
<
<
|







698
699
700
701
702
703
704
705



706

707

708

709


710

711

712

713

714


715


716

717

718

719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735


736
737
738
739
740
741
742
743
744
745


746







747
748
749
750
751
752
753
754
755


756


757


758
759
760
761


762
763
764
765
766

767

768

769

770

771

772
773
774
775
776
777
778
779
780
781
782

783

784




785




786

787


788

789

790





791

792
793
794
795
796


797
798
799
800
801
802
803
804
EXTERN int		XQueryColors(Display *display, Colormap colormap,
				XColor *defs_in_out, int ncolors);
/* 90 */
EXTERN Status		XQueryTree(Display *d, Window w1, Window *w2,
				Window *w3, Window **w4, unsigned int *ui);
/* 91 */
EXTERN int		XSync(Display *display, Bool discard);
/* Slot 92 is reserved */



/* Slot 93 is reserved */

/* Slot 94 is reserved */

/* Slot 95 is reserved */

/* Slot 96 is reserved */


/* Slot 97 is reserved */

/* Slot 98 is reserved */

/* Slot 99 is reserved */

/* Slot 100 is reserved */

/* Slot 101 is reserved */


/* Slot 102 is reserved */


/* Slot 103 is reserved */

/* Slot 104 is reserved */

/* Slot 105 is reserved */

/* 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);
/* Slot 113 is reserved */


/* 114 */
EXTERN VisualID		XVisualIDFromVisual(Visual *visual);
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
/* 120 */
EXTERN int		XOffsetRegion(void *rgn, int dx, int dy);
/* Slot 121 is reserved */


/* Slot 122 is reserved */







/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
/* 129 */
EXTERN int		XLowerWindow(Display *d, Window w);
/* Slot 130 is reserved */


/* Slot 131 is reserved */


/* Slot 132 is reserved */


/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
/* Slot 136 is reserved */


/* 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);
/* Slot 138 is reserved */

/* Slot 139 is reserved */

/* Slot 140 is reserved */

/* Slot 141 is reserved */

/* Slot 142 is reserved */

/* Slot 143 is reserved */

/* 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);
/* Slot 147 is reserved */

/* Slot 148 is reserved */

/* Slot 149 is reserved */




/* Slot 150 is reserved */




/* Slot 151 is reserved */

/* Slot 152 is reserved */


/* Slot 153 is reserved */

/* Slot 154 is reserved */

/* Slot 155 is reserved */





/* Slot 156 is reserved */

/* 157 */
EXTERN KeySym		XkbKeycodeToKeysym(Display *d, unsigned int k, int g,
				int i);
/* 158 */
EXTERN void		TkUnusedStubEntry(void);


#endif /* AQUA */

typedef struct TkIntXlibStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
    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 */







|







878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
    int (*xUngrabPointer) (Display *d, Time t); /* 74 */
    int (*xUnmapWindow) (Display *d, Window w); /* 75 */
    int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 76 */
    void (*xDestroyIC) (XIC x); /* 77 */
    Bool (*xFilterEvent) (XEvent *x, Window w); /* 78 */
    int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 79 */
    int (*tkPutImage) (unsigned long *colors, int ncolors, Display *display, Drawable d, GC gc, XImage *image, int src_x, int src_y, int dest_x, int dest_y, unsigned int width, unsigned int height); /* 80 */
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 81 */
    Status (*xParseColor) (Display *display, Colormap map, _Xconst char *spec, XColor *colorPtr); /* 82 */
    GC (*xCreateGC) (Display *display, Drawable d, unsigned long valuemask, XGCValues *values); /* 83 */
    int (*xFreeGC) (Display *display, GC gc); /* 84 */
    Atom (*xInternAtom) (Display *display, _Xconst char *atom_name, Bool only_if_exists); /* 85 */
    int (*xSetBackground) (Display *display, GC gc, unsigned long foreground); /* 86 */
    int (*xSetForeground) (Display *display, GC gc, unsigned long foreground); /* 87 */
    int (*xSetClipMask) (Display *display, GC gc, Pixmap pixmap); /* 88 */
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
    int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
    int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
    int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */
    int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */
    int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */
    int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */
    XVaNestedList (*xVaCreateNestedList) (int dummy, ...); /* 140 */
    char * (*xSetICValues) (XIC xic, ...); /* 141 */
    char * (*xGetICValues) (XIC xic, ...); /* 142 */
    void (*xSetICFocus) (XIC xic); /* 143 */
    void (*reserved144)(void);
    void (*reserved145)(void);
    void (*reserved146)(void);
    void (*xFreeFontSet) (Display *display, XFontSet fontset); /* 147 */
    int (*xCloseIM) (XIM im); /* 148 */
    Bool (*xRegisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 149 */
    Bool (*xUnregisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 150 */
    char * (*xSetLocaleModifiers) (const char *modifier_list); /* 151 */
    XIM (*xOpenIM) (Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name, char *res_class); /* 152 */
    char * (*xGetIMValues) (XIM im, ...); /* 153 */
    char * (*xSetIMValues) (XIM im, ...); /* 154 */
    XFontSet (*xCreateFontSet) (Display *display, _Xconst char *base_font_name_list, char ***missing_charset_list, int *missing_charset_count, char **def_string); /* 155 */
    void (*xFreeStringList) (char **list); /* 156 */
    KeySym (*xkbKeycodeToKeysym) (Display *d, unsigned int k, int g, int i); /* 157 */
    Display * (*xkbOpenDisplay) (const char *name, int *ev_rtrn, int *err_rtrn, int *major_rtrn, int *minor_rtrn, int *reason); /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
    int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
    XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */
    XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */
    XImage * (*xGetImage) (Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); /* 3 */
    char * (*xGetAtomName) (Display *d, Atom a); /* 4 */
    char * (*xKeysymToString) (KeySym k); /* 5 */
    Colormap (*xCreateColormap) (Display *d, Window w, Visual *v, int i); /* 6 */
    GContext (*xGContextFromGC) (GC g); /* 7 */
    KeySym (*xKeycodeToKeysym) (Display *d, unsigned int k, int i); /* 8 */
    KeySym (*xStringToKeysym) (_Xconst char *c); /* 9 */
    Window (*xRootWindow) (Display *d, int i); /* 10 */
    XErrorHandler (*xSetErrorHandler) (XErrorHandler x); /* 11 */
    Status (*xAllocColor) (Display *d, Colormap c, XColor *xp); /* 12 */
    int (*xBell) (Display *d, int i); /* 13 */
    int (*xChangeProperty) (Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); /* 14 */
    int (*xChangeWindowAttributes) (Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); /* 15 */







|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|
|
|

|








|







935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
    int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
    int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
    int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */
    int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */
    int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    void (*reserved138)(void);
    void (*reserved139)(void);
    void (*reserved140)(void);
    void (*reserved141)(void);
    void (*reserved142)(void);
    void (*reserved143)(void);
    void (*reserved144)(void);
    void (*reserved145)(void);
    void (*reserved146)(void);
    void (*reserved147)(void);
    void (*reserved148)(void);
    void (*reserved149)(void);
    void (*reserved150)(void);
    void (*reserved151)(void);
    void (*reserved152)(void);
    void (*reserved153)(void);
    void (*reserved154)(void);
    void (*reserved155)(void);
    void (*reserved156)(void);
    void (*reserved157)(void);
    void (*tkUnusedStubEntry) (void); /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */
    XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */
    XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */
    XImage * (*xGetImage) (Display *d, Drawable dr, int i1, int i2, unsigned int ui1, unsigned int ui2, unsigned long ul, int i3); /* 3 */
    char * (*xGetAtomName) (Display *d, Atom a); /* 4 */
    char * (*xKeysymToString) (KeySym k); /* 5 */
    Colormap (*xCreateColormap) (Display *d, Window w, Visual *v, int i); /* 6 */
    GContext (*xGContextFromGC) (GC g); /* 7 */
    KeySym (*xKeycodeToKeysym) (Display *d, KeyCode k, int i); /* 8 */
    KeySym (*xStringToKeysym) (_Xconst char *c); /* 9 */
    Window (*xRootWindow) (Display *d, int i); /* 10 */
    XErrorHandler (*xSetErrorHandler) (XErrorHandler x); /* 11 */
    Status (*xAllocColor) (Display *d, Colormap c, XColor *xp); /* 12 */
    int (*xBell) (Display *d, int i); /* 13 */
    int (*xChangeProperty) (Display *d, Window w, Atom a1, Atom a2, int i1, int i2, _Xconst unsigned char *c, int i3); /* 14 */
    int (*xChangeWindowAttributes) (Display *d, Window w, unsigned long ul, XSetWindowAttributes *x); /* 15 */
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
    int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
    int (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */
    int (*xWarpPointer) (Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); /* 87 */
    int (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */
    int (*xQueryColors) (Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); /* 89 */
    Status (*xQueryTree) (Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); /* 90 */
    int (*xSync) (Display *display, Bool discard); /* 91 */
    Bool (*xTranslateCoordinates) (Display *d, Window w1, Window w2, int i1, int i2, int *i3, int *i4, Window *w3); /* 92 */
    int (*xDeleteProperty) (Display *d, Window w, Atom a); /* 93 */
    int (*xFreeCursor) (Display *d, Cursor c); /* 94 */
    int (*xGetInputFocus) (Display *d, Window *w, int *i); /* 95 */
    int (*xmbLookupString) (XIC xi, XKeyPressedEvent *xk, char *c, int i, KeySym *k, Status *s); /* 96 */
    int (*xNextEvent) (Display *d, XEvent *x); /* 97 */
    int (*xPutBackEvent) (Display *d, XEvent *x); /* 98 */
    int (*xSetCommand) (Display *d, Window w, char **c, int i); /* 99 */
    int (*xWindowEvent) (Display *d, Window w, long l, XEvent *x); /* 100 */
    Status (*xGetWindowAttributes) (Display *d, Window w, XWindowAttributes *x); /* 101 */
    Status (*xGetWMColormapWindows) (Display *d, Window w, Window **wpp, int *ip); /* 102 */
    Status (*xIconifyWindow) (Display *d, Window w, int i); /* 103 */
    Status (*xWithdrawWindow) (Display *d, Window w, int i); /* 104 */
    XHostAddress * (*xListHosts) (Display *d, int *i, Bool *b); /* 105 */
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 106 */
    int (*xFlush) (Display *display); /* 107 */
    int (*xGrabServer) (Display *display); /* 108 */
    int (*xUngrabServer) (Display *display); /* 109 */
    int (*xFree) (void *data); /* 110 */
    int (*xNoOp) (Display *display); /* 111 */
    XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */
    Status (*xLookupColor) (Display *d, Colormap c1, _Xconst char *c2, XColor *x1, XColor *x2); /* 113 */
    VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */
    void (*reserved115)(void);
    void (*reserved116)(void);
    void (*reserved117)(void);
    void (*reserved118)(void);
    void (*reserved119)(void);
    int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */
    int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */
    Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */
    void (*reserved123)(void);
    void (*reserved124)(void);
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    int (*xLowerWindow) (Display *d, Window w); /* 129 */
    int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */
    int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */
    int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*reserved135)(void);
    int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */
    int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */
    XVaNestedList (*xVaCreateNestedList) (int dummy, ...); /* 140 */
    char * (*xSetICValues) (XIC xic, ...); /* 141 */
    char * (*xGetICValues) (XIC xic, ...); /* 142 */
    void (*xSetICFocus) (XIC xic); /* 143 */
    void (*xDestroyIC) (XIC xic); /* 144 */
    Cursor (*xCreatePixmapCursor) (Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2); /* 145 */
    Cursor (*xCreateGlyphCursor) (Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2); /* 146 */
    void (*xFreeFontSet) (Display *display, XFontSet fontset); /* 147 */
    int (*xCloseIM) (XIM im); /* 148 */
    Bool (*xRegisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 149 */
    Bool (*xUnregisterIMInstantiateCallback) (Display *dpy, struct _XrmHashBucketRec *rbd, char *res_name, char *res_class, XIDProc callback, XPointer client_data); /* 150 */
    char * (*xSetLocaleModifiers) (const char *modifier_list); /* 151 */
    XIM (*xOpenIM) (Display *dpy, struct _XrmHashBucketRec *rdb, char *res_name, char *res_class); /* 152 */
    char * (*xGetIMValues) (XIM im, ...); /* 153 */
    char * (*xSetIMValues) (XIM im, ...); /* 154 */
    XFontSet (*xCreateFontSet) (Display *display, _Xconst char *base_font_name_list, char ***missing_charset_list, int *missing_charset_count, char **def_string); /* 155 */
    void (*xFreeStringList) (char **list); /* 156 */
    KeySym (*xkbKeycodeToKeysym) (Display *d, unsigned int k, int g, int i); /* 157 */
    Display * (*xkbOpenDisplay) (const char *name, int *ev_rtrn, int *err_rtrn, int *major_rtrn, int *minor_rtrn, int *reason); /* 158 */
#endif /* MACOSX */
} TkIntXlibStubs;

extern const TkIntXlibStubs *tkIntXlibStubsPtr;

#ifdef __cplusplus
}
#endif







|
|
|
|
|
|
|
|
|
|
|
|
|
|







|






|
|
|







|
|
|



|

|
|
|
|
|
|



|
|
|
|
|
|
|
|
|
|

|
|







1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
    int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */
    int (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */
    int (*xWarpPointer) (Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); /* 87 */
    int (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */
    int (*xQueryColors) (Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); /* 89 */
    Status (*xQueryTree) (Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); /* 90 */
    int (*xSync) (Display *display, Bool discard); /* 91 */
    void (*reserved92)(void);
    void (*reserved93)(void);
    void (*reserved94)(void);
    void (*reserved95)(void);
    void (*reserved96)(void);
    void (*reserved97)(void);
    void (*reserved98)(void);
    void (*reserved99)(void);
    void (*reserved100)(void);
    void (*reserved101)(void);
    void (*reserved102)(void);
    void (*reserved103)(void);
    void (*reserved104)(void);
    void (*reserved105)(void);
    int (*xSetClipRectangles) (Display *display, GC gc, int clip_x_origin, int clip_y_origin, XRectangle rectangles[], int n, int ordering); /* 106 */
    int (*xFlush) (Display *display); /* 107 */
    int (*xGrabServer) (Display *display); /* 108 */
    int (*xUngrabServer) (Display *display); /* 109 */
    int (*xFree) (void *data); /* 110 */
    int (*xNoOp) (Display *display); /* 111 */
    XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */
    void (*reserved113)(void);
    VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */
    void (*reserved115)(void);
    void (*reserved116)(void);
    void (*reserved117)(void);
    void (*reserved118)(void);
    void (*reserved119)(void);
    int (*xOffsetRegion) (void *rgn, int dx, int dy); /* 120 */
    void (*reserved121)(void);
    void (*reserved122)(void);
    void (*reserved123)(void);
    void (*reserved124)(void);
    void (*reserved125)(void);
    void (*reserved126)(void);
    void (*reserved127)(void);
    void (*reserved128)(void);
    int (*xLowerWindow) (Display *d, Window w); /* 129 */
    void (*reserved130)(void);
    void (*reserved131)(void);
    void (*reserved132)(void);
    void (*reserved133)(void);
    void (*reserved134)(void);
    void (*reserved135)(void);
    void (*reserved136)(void);
    int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */
    void (*reserved138)(void);
    void (*reserved139)(void);
    void (*reserved140)(void);
    void (*reserved141)(void);
    void (*reserved142)(void);
    void (*reserved143)(void);
    void (*xDestroyIC) (XIC xic); /* 144 */
    Cursor (*xCreatePixmapCursor) (Display *d, Pixmap p1, Pixmap p2, XColor *x1, XColor *x2, unsigned int ui1, unsigned int ui2); /* 145 */
    Cursor (*xCreateGlyphCursor) (Display *d, Font f1, Font f2, unsigned int ui1, unsigned int ui2, XColor _Xconst *x1, XColor _Xconst *x2); /* 146 */
    void (*reserved147)(void);
    void (*reserved148)(void);
    void (*reserved149)(void);
    void (*reserved150)(void);
    void (*reserved151)(void);
    void (*reserved152)(void);
    void (*reserved153)(void);
    void (*reserved154)(void);
    void (*reserved155)(void);
    void (*reserved156)(void);
    KeySym (*xkbKeycodeToKeysym) (Display *d, unsigned int k, int g, int i); /* 157 */
    void (*tkUnusedStubEntry) (void); /* 158 */
#endif /* AQUA */
} TkIntXlibStubs;

extern const TkIntXlibStubs *tkIntXlibStubsPtr;

#ifdef __cplusplus
}
#endif
1396
1397
1398
1399
1400
1401
1402
1403

1404
1405
1406
1407
1408
1409
1410
	(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 \







|
>







1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
	(tkIntXlibStubsPtr->xDestroyIC) /* 77 */
#define XFilterEvent \
	(tkIntXlibStubsPtr->xFilterEvent) /* 78 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 79 */
#define TkPutImage \
	(tkIntXlibStubsPtr->tkPutImage) /* 80 */
#define XSetClipRectangles \
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 81 */
#define XParseColor \
	(tkIntXlibStubsPtr->xParseColor) /* 82 */
#define XCreateGC \
	(tkIntXlibStubsPtr->xCreateGC) /* 83 */
#define XFreeGC \
	(tkIntXlibStubsPtr->xFreeGC) /* 84 */
#define XInternAtom \
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528


1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
	(tkIntXlibStubsPtr->xDrawPoint) /* 134 */
#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 135 */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xUnregisterIMInstantiateCallback) /* 150 */
#define XSetLocaleModifiers \


	(tkIntXlibStubsPtr->xSetLocaleModifiers) /* 151 */
#define XOpenIM \
	(tkIntXlibStubsPtr->xOpenIM) /* 152 */
#define XGetIMValues \
	(tkIntXlibStubsPtr->xGetIMValues) /* 153 */
#define XSetIMValues \
	(tkIntXlibStubsPtr->xSetIMValues) /* 154 */
#define XCreateFontSet \
	(tkIntXlibStubsPtr->xCreateFontSet) /* 155 */
#define XFreeStringList \
	(tkIntXlibStubsPtr->xFreeStringList) /* 156 */
#define XkbKeycodeToKeysym \
	(tkIntXlibStubsPtr->xkbKeycodeToKeysym) /* 157 */
#define XkbOpenDisplay \
	(tkIntXlibStubsPtr->xkbOpenDisplay) /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TCL /* MACOSX */
#define XSetDashes \
	(tkIntXlibStubsPtr->xSetDashes) /* 0 */
#define XGetModifierMapping \
	(tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */
#define XCreateImage \
	(tkIntXlibStubsPtr->xCreateImage) /* 2 */
#define XGetImage \







<
|
<
|
<
|
<
|
<
|
<
|



<
|
<
|
<
<
<
<
<
>
>
|
<
|
<
|
<
|
<
|
<
|
<
|
|
|

|







1398
1399
1400
1401
1402
1403
1404

1405

1406

1407

1408

1409

1410
1411
1412
1413

1414

1415





1416
1417
1418

1419

1420

1421

1422

1423

1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
	(tkIntXlibStubsPtr->xDrawPoint) /* 134 */
#define XDrawPoints \
	(tkIntXlibStubsPtr->xDrawPoints) /* 135 */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */

/* Slot 138 is reserved */

/* Slot 139 is reserved */

/* Slot 140 is reserved */

/* Slot 141 is reserved */

/* Slot 142 is reserved */

/* Slot 143 is reserved */
/* Slot 144 is reserved */
/* Slot 145 is reserved */
/* Slot 146 is reserved */

/* Slot 147 is reserved */

/* Slot 148 is reserved */





/* Slot 149 is reserved */
/* Slot 150 is reserved */
/* Slot 151 is reserved */

/* Slot 152 is reserved */

/* Slot 153 is reserved */

/* Slot 154 is reserved */

/* Slot 155 is reserved */

/* Slot 156 is reserved */

/* Slot 157 is reserved */
#define TkUnusedStubEntry \
	(tkIntXlibStubsPtr->tkUnusedStubEntry) /* 158 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#define XSetDashes \
	(tkIntXlibStubsPtr->xSetDashes) /* 0 */
#define XGetModifierMapping \
	(tkIntXlibStubsPtr->xGetModifierMapping) /* 1 */
#define XCreateImage \
	(tkIntXlibStubsPtr->xCreateImage) /* 2 */
#define XGetImage \
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834


1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862


1863
	(tkIntXlibStubsPtr->xQueryColor) /* 88 */
#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 89 */
#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 90 */
#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 91 */
#define XTranslateCoordinates \
	(tkIntXlibStubsPtr->xTranslateCoordinates) /* 92 */
#define XDeleteProperty \
	(tkIntXlibStubsPtr->xDeleteProperty) /* 93 */
#define XFreeCursor \
	(tkIntXlibStubsPtr->xFreeCursor) /* 94 */
#define XGetInputFocus \
	(tkIntXlibStubsPtr->xGetInputFocus) /* 95 */
#define XmbLookupString \
	(tkIntXlibStubsPtr->xmbLookupString) /* 96 */
#define XNextEvent \
	(tkIntXlibStubsPtr->xNextEvent) /* 97 */
#define XPutBackEvent \
	(tkIntXlibStubsPtr->xPutBackEvent) /* 98 */
#define XSetCommand \
	(tkIntXlibStubsPtr->xSetCommand) /* 99 */
#define XWindowEvent \
	(tkIntXlibStubsPtr->xWindowEvent) /* 100 */
#define XGetWindowAttributes \
	(tkIntXlibStubsPtr->xGetWindowAttributes) /* 101 */
#define XGetWMColormapWindows \
	(tkIntXlibStubsPtr->xGetWMColormapWindows) /* 102 */
#define XIconifyWindow \
	(tkIntXlibStubsPtr->xIconifyWindow) /* 103 */
#define XWithdrawWindow \
	(tkIntXlibStubsPtr->xWithdrawWindow) /* 104 */
#define XListHosts \
	(tkIntXlibStubsPtr->xListHosts) /* 105 */
#define XSetClipRectangles \
	(tkIntXlibStubsPtr->xSetClipRectangles) /* 106 */
#define XFlush \
	(tkIntXlibStubsPtr->xFlush) /* 107 */
#define XGrabServer \
	(tkIntXlibStubsPtr->xGrabServer) /* 108 */
#define XUngrabServer \
	(tkIntXlibStubsPtr->xUngrabServer) /* 109 */
#define XFree \
	(tkIntXlibStubsPtr->xFree) /* 110 */
#define XNoOp \
	(tkIntXlibStubsPtr->xNoOp) /* 111 */
#define XSynchronize \
	(tkIntXlibStubsPtr->xSynchronize) /* 112 */
#define XLookupColor \
	(tkIntXlibStubsPtr->xLookupColor) /* 113 */
#define XVisualIDFromVisual \
	(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
#define XOffsetRegion \
	(tkIntXlibStubsPtr->xOffsetRegion) /* 120 */
#define XUnionRegion \
	(tkIntXlibStubsPtr->xUnionRegion) /* 121 */
#define XCreateWindow \
	(tkIntXlibStubsPtr->xCreateWindow) /* 122 */
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
#define XLowerWindow \
	(tkIntXlibStubsPtr->xLowerWindow) /* 129 */
#define XFillArcs \
	(tkIntXlibStubsPtr->xFillArcs) /* 130 */
#define XDrawArcs \
	(tkIntXlibStubsPtr->xDrawArcs) /* 131 */
#define XDrawRectangles \
	(tkIntXlibStubsPtr->xDrawRectangles) /* 132 */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */
#define XReparentWindow \
	(tkIntXlibStubsPtr->xReparentWindow) /* 136 */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */
#define XPolygonRegion \
	(tkIntXlibStubsPtr->xPolygonRegion) /* 138 */
#define XPointInRegion \
	(tkIntXlibStubsPtr->xPointInRegion) /* 139 */
#define XVaCreateNestedList \
	(tkIntXlibStubsPtr->xVaCreateNestedList) /* 140 */
#define XSetICValues \
	(tkIntXlibStubsPtr->xSetICValues) /* 141 */
#define XGetICValues \
	(tkIntXlibStubsPtr->xGetICValues) /* 142 */
#define XSetICFocus \
	(tkIntXlibStubsPtr->xSetICFocus) /* 143 */
#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 144 */
#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 145 */
#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 146 */
#define XFreeFontSet \
	(tkIntXlibStubsPtr->xFreeFontSet) /* 147 */
#define XCloseIM \
	(tkIntXlibStubsPtr->xCloseIM) /* 148 */
#define XRegisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xRegisterIMInstantiateCallback) /* 149 */
#define XUnregisterIMInstantiateCallback \
	(tkIntXlibStubsPtr->xUnregisterIMInstantiateCallback) /* 150 */
#define XSetLocaleModifiers \


	(tkIntXlibStubsPtr->xSetLocaleModifiers) /* 151 */
#define XOpenIM \
	(tkIntXlibStubsPtr->xOpenIM) /* 152 */
#define XGetIMValues \
	(tkIntXlibStubsPtr->xGetIMValues) /* 153 */
#define XSetIMValues \
	(tkIntXlibStubsPtr->xSetIMValues) /* 154 */
#define XCreateFontSet \
	(tkIntXlibStubsPtr->xCreateFontSet) /* 155 */
#define XFreeStringList \
	(tkIntXlibStubsPtr->xFreeStringList) /* 156 */
#define XkbKeycodeToKeysym \
	(tkIntXlibStubsPtr->xkbKeycodeToKeysym) /* 157 */
#define XkbOpenDisplay \
	(tkIntXlibStubsPtr->xkbOpenDisplay) /* 158 */
#endif /* MACOSX */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#if !defined(_WIN32) && !defined(__CYGWIN__) && !defined(MAC_OSX_TCL) /* X11, Except MacOS/Cygwin */
EXTERN Display *XkbOpenDisplay(const char *, int *, int *, int *, int *, int *);
#endif

#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT



#endif /* _TKINTXLIBDECLS */







|
|
|
|
|
|
|
|
<
<
<
<
<
<
<
<
<
|
<
|
<
|
<
|
<
|
<
|














<
|









<
|
<
|








<
|
<
|
<
|



<
|


<
|
<
|
<
|
<
|
<
|
<
|






<
|
<
|
<
<
<
<
<
>
>
|
<
|
<
|
<
|
<
|
<
|


|
|
|





<
<
<
<



>
>

1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620









1621

1622

1623

1624

1625

1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640

1641
1642
1643
1644
1645
1646
1647
1648
1649
1650

1651

1652
1653
1654
1655
1656
1657
1658
1659
1660

1661

1662

1663
1664
1665
1666

1667
1668
1669

1670

1671

1672

1673

1674

1675
1676
1677
1678
1679
1680
1681

1682

1683





1684
1685
1686

1687

1688

1689

1690

1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701




1702
1703
1704
1705
1706
1707
	(tkIntXlibStubsPtr->xQueryColor) /* 88 */
#define XQueryColors \
	(tkIntXlibStubsPtr->xQueryColors) /* 89 */
#define XQueryTree \
	(tkIntXlibStubsPtr->xQueryTree) /* 90 */
#define XSync \
	(tkIntXlibStubsPtr->xSync) /* 91 */
/* Slot 92 is reserved */
/* Slot 93 is reserved */
/* Slot 94 is reserved */
/* Slot 95 is reserved */
/* Slot 96 is reserved */
/* Slot 97 is reserved */
/* Slot 98 is reserved */
/* Slot 99 is reserved */









/* Slot 100 is reserved */

/* Slot 101 is reserved */

/* Slot 102 is reserved */

/* Slot 103 is reserved */

/* Slot 104 is reserved */

/* Slot 105 is reserved */
#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 */

/* Slot 113 is reserved */
#define XVisualIDFromVisual \
	(tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */
/* Slot 115 is reserved */
/* Slot 116 is reserved */
/* Slot 117 is reserved */
/* Slot 118 is reserved */
/* Slot 119 is reserved */
#define XOffsetRegion \
	(tkIntXlibStubsPtr->xOffsetRegion) /* 120 */

/* Slot 121 is reserved */

/* Slot 122 is reserved */
/* Slot 123 is reserved */
/* Slot 124 is reserved */
/* Slot 125 is reserved */
/* Slot 126 is reserved */
/* Slot 127 is reserved */
/* Slot 128 is reserved */
#define XLowerWindow \
	(tkIntXlibStubsPtr->xLowerWindow) /* 129 */

/* Slot 130 is reserved */

/* Slot 131 is reserved */

/* Slot 132 is reserved */
/* Slot 133 is reserved */
/* Slot 134 is reserved */
/* Slot 135 is reserved */

/* Slot 136 is reserved */
#define XPutImage \
	(tkIntXlibStubsPtr->xPutImage) /* 137 */

/* Slot 138 is reserved */

/* Slot 139 is reserved */

/* Slot 140 is reserved */

/* Slot 141 is reserved */

/* Slot 142 is reserved */

/* Slot 143 is reserved */
#define XDestroyIC \
	(tkIntXlibStubsPtr->xDestroyIC) /* 144 */
#define XCreatePixmapCursor \
	(tkIntXlibStubsPtr->xCreatePixmapCursor) /* 145 */
#define XCreateGlyphCursor \
	(tkIntXlibStubsPtr->xCreateGlyphCursor) /* 146 */

/* Slot 147 is reserved */

/* Slot 148 is reserved */





/* Slot 149 is reserved */
/* Slot 150 is reserved */
/* Slot 151 is reserved */

/* Slot 152 is reserved */

/* Slot 153 is reserved */

/* Slot 154 is reserved */

/* Slot 155 is reserved */

/* Slot 156 is reserved */
#define XkbKeycodeToKeysym \
	(tkIntXlibStubsPtr->xkbKeycodeToKeysym) /* 157 */
#define TkUnusedStubEntry \
	(tkIntXlibStubsPtr->tkUnusedStubEntry) /* 158 */
#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */





#undef TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#undef TkUnusedStubEntry

#endif /* _TKINTXLIBDECLS */
Changes to generic/tkListbox.c.
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "default.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

typedef struct {
    Tk_OptionTable listboxOptionTable;
				/* Table defining configuration options
				 * available for the listbox. */
    Tk_OptionTable itemAttrOptionTable;
				/* Table defining configuration options







<

<
<
|
<







8
9
10
11
12
13
14

15


16

17
18
19
20
21
22
23
 * Copyright (c) 1990-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */


#include "default.h"


#include "tkInt.h"


typedef struct {
    Tk_OptionTable listboxOptionTable;
				/* Table defining configuration options
				 * available for the listbox. */
    Tk_OptionTable itemAttrOptionTable;
				/* Table defining configuration options
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
 * below.
 */

enum state {
    STATE_DISABLED, STATE_NORMAL
};

static const char *const stateStrings[] = {
    "disabled", "normal", NULL
};

enum activeStyle {
    ACTIVE_STYLE_DOTBOX, ACTIVE_STYLE_NONE, ACTIVE_STYLE_UNDERLINE
};

static const char *const activeStyleStrings[] = {
    "dotbox", "none", "underline", NULL
};

/*
 * The optionSpecs table defines the valid configuration options for the
 * listbox widget.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-activestyle", "activeStyle", "ActiveStyle",
	DEF_LISTBOX_ACTIVE_STYLE, TCL_INDEX_NONE, offsetof(Listbox, activeStyle),
	0, activeStyleStrings, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_LISTBOX_BG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, normalBorder),
	 0, DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_LISTBOX_BORDER_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, borderWidth),
	 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_LISTBOX_CURSOR, TCL_INDEX_NONE, offsetof(Listbox, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	 "DisabledForeground", DEF_LISTBOX_DISABLED_FG, TCL_INDEX_NONE,
	 offsetof(Listbox, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	 "ExportSelection", DEF_LISTBOX_EXPORT_SELECTION, TCL_INDEX_NONE,
	 offsetof(Listbox, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	 NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	 DEF_LISTBOX_FONT, TCL_INDEX_NONE, offsetof(Listbox, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	 DEF_LISTBOX_FG, TCL_INDEX_NONE, offsetof(Listbox, fgColorPtr), 0, 0, 0},
    {TK_OPTION_INT, "-height", "height", "Height",
	 DEF_LISTBOX_HEIGHT, TCL_INDEX_NONE, offsetof(Listbox, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_LISTBOX_HIGHLIGHT_BG, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_LISTBOX_HIGHLIGHT, TCL_INDEX_NONE, offsetof(Listbox, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, TCL_INDEX_NONE,
	 offsetof(Listbox, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_LISTBOX_JUSTIFY, TCL_INDEX_NONE, offsetof(Listbox, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_LISTBOX_RELIEF, TCL_INDEX_NONE, offsetof(Listbox, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	 DEF_LISTBOX_SELECT_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selBorder),
	 0, DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	 "BorderWidth", DEF_LISTBOX_SELECT_BD, TCL_INDEX_NONE,
	 offsetof(Listbox, selBorderWidth), 0, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	 DEF_LISTBOX_SELECT_FG_COLOR, TCL_INDEX_NONE, offsetof(Listbox, selFgColorPtr),
	 TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
	 DEF_LISTBOX_SELECT_MODE, TCL_INDEX_NONE, offsetof(Listbox, selectMode),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
	 DEF_LISTBOX_SET_GRID, TCL_INDEX_NONE, offsetof(Listbox, setGrid), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_LISTBOX_STATE, TCL_INDEX_NONE, offsetof(Listbox, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	 DEF_LISTBOX_TAKE_FOCUS, TCL_INDEX_NONE, offsetof(Listbox, takeFocus),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	 DEF_LISTBOX_WIDTH, TCL_INDEX_NONE, offsetof(Listbox, width), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, xScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, TCL_INDEX_NONE, offsetof(Listbox, yScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-listvariable", "listVariable", "Variable",
	 DEF_LISTBOX_LIST_VARIABLE, TCL_INDEX_NONE, offsetof(Listbox, listVarName),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * The itemAttrOptionSpecs table defines the valid configuration options for
 * listbox items.
 */

static const Tk_OptionSpec itemAttrOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", "background", "Background",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, border),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
     NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, fgColor),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selBorder),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
     NULL, TCL_INDEX_NONE, offsetof(ItemAttr, selFgColor),
     TK_OPTION_NULL_OK|TK_OPTION_DONT_SET_DEFAULT,
     DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, TCL_INDEX_NONE, 0, 0, 0}
};

/*
 * The following tables define the listbox widget commands (and sub-commands)
 * and map the indexes into the string tables into enumerated types used to
 * dispatch the listbox widget command.
 */







<
<
<
<















|


|


|

|

|


|


|
|

|
|

|

|

|

|

|
|

|


|
|

|

|

|


|
|

|


|


|

|
|

|


|

|


|


|

|








|
|
|
<

|

|
|
|
|
|
|
|
<
|
|
|
<
|







212
213
214
215
216
217
218




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

319
320
321
322
323
324
325
326
327
328

329
330
331

332
333
334
335
336
337
338
339
 * below.
 */

enum state {
    STATE_DISABLED, STATE_NORMAL
};





enum activeStyle {
    ACTIVE_STYLE_DOTBOX, ACTIVE_STYLE_NONE, ACTIVE_STYLE_UNDERLINE
};

static const char *const activeStyleStrings[] = {
    "dotbox", "none", "underline", NULL
};

/*
 * The optionSpecs table defines the valid configuration options for the
 * listbox widget.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_STRING_TABLE, "-activestyle", "activeStyle", "ActiveStyle",
	DEF_LISTBOX_ACTIVE_STYLE, -1, Tk_Offset(Listbox, activeStyle),
	0, activeStyleStrings, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_LISTBOX_BG_COLOR, -1, Tk_Offset(Listbox, normalBorder),
	 0, DEF_LISTBOX_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	 NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	 NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_LISTBOX_BORDER_WIDTH, -1, Tk_Offset(Listbox, borderWidth),
	 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_LISTBOX_CURSOR, -1, Tk_Offset(Listbox, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	 "DisabledForeground", DEF_LISTBOX_DISABLED_FG, -1,
	 Tk_Offset(Listbox, dfgColorPtr), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection",
	 "ExportSelection", DEF_LISTBOX_EXPORT_SELECTION, -1,
	 Tk_Offset(Listbox, exportSelection), 0, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
	 NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	 DEF_LISTBOX_FONT, -1, Tk_Offset(Listbox, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	 DEF_LISTBOX_FG, -1, Tk_Offset(Listbox, fgColorPtr), 0, 0, 0},
    {TK_OPTION_INT, "-height", "height", "Height",
	 DEF_LISTBOX_HEIGHT, -1, Tk_Offset(Listbox, height), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_LISTBOX_HIGHLIGHT_BG, -1,
	 Tk_Offset(Listbox, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_LISTBOX_HIGHLIGHT, -1, Tk_Offset(Listbox, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	 "HighlightThickness", DEF_LISTBOX_HIGHLIGHT_WIDTH, -1,
	 Tk_Offset(Listbox, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_LISTBOX_JUSTIFY, -1, Tk_Offset(Listbox, justify), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	 DEF_LISTBOX_RELIEF, -1, Tk_Offset(Listbox, relief), 0, 0, 0},
    {TK_OPTION_BORDER, "-selectbackground", "selectBackground", "Foreground",
	 DEF_LISTBOX_SELECT_COLOR, -1, Tk_Offset(Listbox, selBorder),
	 0, DEF_LISTBOX_SELECT_MONO, 0},
    {TK_OPTION_PIXELS, "-selectborderwidth", "selectBorderWidth",
	 "BorderWidth", DEF_LISTBOX_SELECT_BD, -1,
	 Tk_Offset(Listbox, selBorderWidth), 0, 0, 0},
    {TK_OPTION_COLOR, "-selectforeground", "selectForeground", "Background",
	 DEF_LISTBOX_SELECT_FG_COLOR, -1, Tk_Offset(Listbox, selFgColorPtr),
	 TK_OPTION_NULL_OK, DEF_LISTBOX_SELECT_FG_MONO, 0},
    {TK_OPTION_STRING, "-selectmode", "selectMode", "SelectMode",
	 DEF_LISTBOX_SELECT_MODE, -1, Tk_Offset(Listbox, selectMode),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-setgrid", "setGrid", "SetGrid",
	 DEF_LISTBOX_SET_GRID, -1, Tk_Offset(Listbox, setGrid), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_LISTBOX_STATE, -1, Tk_Offset(Listbox, state),
	0, &tkStateStrings[1], 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	 DEF_LISTBOX_TAKE_FOCUS, -1, Tk_Offset(Listbox, takeFocus),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-width", "width", "Width",
	 DEF_LISTBOX_WIDTH, -1, Tk_Offset(Listbox, width), 0, 0, 0},
    {TK_OPTION_STRING, "-xscrollcommand", "xScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, -1, Tk_Offset(Listbox, xScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-yscrollcommand", "yScrollCommand", "ScrollCommand",
	 DEF_LISTBOX_SCROLL_COMMAND, -1, Tk_Offset(Listbox, yScrollCmd),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-listvariable", "listVariable", "Variable",
	 DEF_LISTBOX_LIST_VARIABLE, -1, Tk_Offset(Listbox, listVarName),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * The itemAttrOptionSpecs table defines the valid configuration options for
 * listbox items.
 */

static const Tk_OptionSpec itemAttrOptionSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, border),
     TK_OPTION_NULL_OK, NULL, 0},

    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
     NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL,
     NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, fgColor),
     TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BORDER, "-selectbackground", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, selBorder),
     TK_OPTION_NULL_OK, NULL, 0},

    {TK_OPTION_COLOR, "-selectforeground", NULL, NULL,
     NULL, -1, Tk_Offset(ItemAttr, selFgColor),
     TK_OPTION_NULL_OK, NULL, 0},

    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, NULL, 0}
};

/*
 * The following tables define the listbox widget commands (and sub-commands)
 * and map the indexes into the string tables into enumerated types used to
 * dispatch the listbox widget command.
 */
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
    "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);







|


|















|












|
|







362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
    "mark", "dragto", NULL
};
enum scancommand {
    SCAN_MARK, SCAN_DRAGTO
};

static const char *const indexNames[] = {
    "active", "anchor", "end", NULL
};
enum indices {
    INDEX_ACTIVE, INDEX_ANCHOR, INDEX_END
};

/*
 * Declarations for procedures defined later in this file.
 */

static void		ChangeListboxOffset(Listbox *listPtr, int offset);
static void		ChangeListboxView(Listbox *listPtr, int index);
static int		ConfigureListbox(Tcl_Interp *interp, Listbox *listPtr,
			    int objc, Tcl_Obj *const objv[]);
static int		ConfigureListboxItem(Tcl_Interp *interp,
			    Listbox *listPtr, ItemAttr *attrs, int objc,
			    Tcl_Obj *const objv[], int index);
static int		ListboxDeleteSubCmd(Listbox *listPtr,
			    int first, int last);
static Tcl_FreeProc	DestroyListbox;
static void		DestroyListboxOptionTables(ClientData clientData,
			    Tcl_Interp *interp);
static void		DisplayListbox(ClientData clientData);
static int		GetListboxIndex(Tcl_Interp *interp, Listbox *listPtr,
			    Tcl_Obj *index, int endIsSize, int *indexPtr);
static int		ListboxInsertSubCmd(Listbox *listPtr,
			    int index, int objc, Tcl_Obj *const objv[]);
static void		ListboxCmdDeletedProc(ClientData clientData);
static void		ListboxComputeGeometry(Listbox *listPtr,
			    int fontChanged, int maxIsStale, int updateGrid);
static void		ListboxEventProc(ClientData clientData,
			    XEvent *eventPtr);
static int		ListboxFetchSelection(ClientData clientData,
			    int offset, char *buffer, int maxBytes);
static void		ListboxLostSelection(ClientData clientData);
static void		GenerateListboxSelectEvent(Listbox *listPtr);
static void		EventuallyRedrawRange(Listbox *listPtr,
			    int first, int last);
static void		ListboxScanTo(Listbox *listPtr, int x, int y);
static int		ListboxSelect(Listbox *listPtr,
			    int first, int last, int select);
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ListboxObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Listbox *listPtr;
    Tk_Window tkwin;
    ListboxOptionTables *optionTables;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    optionTables = (ListboxOptionTables *)Tcl_GetAssocData(interp, "ListboxOptionTables", NULL);
    if (optionTables == NULL) {
	/*
	 * We haven't created the option tables for this widget class yet. Do
	 * it now and save the a pointer to them as the ClientData for the
	 * command, so future invocations will have access to it.
	 */

	optionTables = (ListboxOptionTables *)ckalloc(sizeof(ListboxOptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
	 */

	Tcl_SetAssocData(interp, "ListboxOptionTables",
		DestroyListboxOptionTables, optionTables);







|







<












|







|







458
459
460
461
462
463
464
465
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_ListboxObjCmd(
    ClientData clientData,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Listbox *listPtr;
    Tk_Window tkwin;
    ListboxOptionTables *optionTables;


    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 = 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 = ckalloc(sizeof(ListboxOptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
	 */

	Tcl_SetAssocData(interp, "ListboxOptionTables",
		DestroyListboxOptionTables, optionTables);
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550

    /*
     * Initialize the fields of the structure that won't be initialized by
     * ConfigureListbox, or that ConfigureListbox requires to be initialized
     * already (e.g. resource pointers).
     */

    listPtr			 = (Listbox *)ckalloc(sizeof(Listbox));
    memset(listPtr, 0, sizeof(Listbox));

    listPtr->tkwin		 = tkwin;
    listPtr->display		 = Tk_Display(tkwin);
    listPtr->interp		 = interp;
    listPtr->widgetCmd		 = Tcl_CreateObjCommand(interp,
	    Tk_PathName(listPtr->tkwin), ListboxWidgetObjCmd, listPtr,
	    ListboxCmdDeletedProc);
    listPtr->optionTable	 = optionTables->listboxOptionTable;
    listPtr->itemAttrOptionTable = optionTables->itemAttrOptionTable;
    listPtr->selection		 = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
    Tcl_InitHashTable(listPtr->selection, TCL_ONE_WORD_KEYS);
    listPtr->itemAttrTable	 = (Tcl_HashTable *)ckalloc(sizeof(Tcl_HashTable));
    Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS);
    listPtr->relief		 = TK_RELIEF_RAISED;
    listPtr->textGC		 = NULL;
    listPtr->selFgColorPtr	 = NULL;
    listPtr->selTextGC		 = NULL;
    listPtr->fullLines		 = 1;
    listPtr->xScrollUnit	 = 1;







|










|

|







511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538

    /*
     * Initialize the fields of the structure that won't be initialized by
     * ConfigureListbox, or that ConfigureListbox requires to be initialized
     * already (e.g. resource pointers).
     */

    listPtr			 = ckalloc(sizeof(Listbox));
    memset(listPtr, 0, sizeof(Listbox));

    listPtr->tkwin		 = tkwin;
    listPtr->display		 = Tk_Display(tkwin);
    listPtr->interp		 = interp;
    listPtr->widgetCmd		 = Tcl_CreateObjCommand(interp,
	    Tk_PathName(listPtr->tkwin), ListboxWidgetObjCmd, listPtr,
	    ListboxCmdDeletedProc);
    listPtr->optionTable	 = optionTables->listboxOptionTable;
    listPtr->itemAttrOptionTable = optionTables->itemAttrOptionTable;
    listPtr->selection		 = ckalloc(sizeof(Tcl_HashTable));
    Tcl_InitHashTable(listPtr->selection, TCL_ONE_WORD_KEYS);
    listPtr->itemAttrTable	 = ckalloc(sizeof(Tcl_HashTable));
    Tcl_InitHashTable(listPtr->itemAttrTable, TCL_ONE_WORD_KEYS);
    listPtr->relief		 = TK_RELIEF_RAISED;
    listPtr->textGC		 = NULL;
    listPtr->selFgColorPtr	 = NULL;
    listPtr->selTextGC		 = NULL;
    listPtr->fullLines		 = 1;
    listPtr->xScrollUnit	 = 1;
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
    Tk_SetClass(listPtr->tkwin, "Listbox");
    Tk_SetClassProcs(listPtr->tkwin, &listboxClass, listPtr);
    Tk_CreateEventHandler(listPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ListboxEventProc, listPtr);
    Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING,
	    ListboxFetchSelection, listPtr, XA_STRING);
    if (Tk_InitOptions(interp, listPtr,
	    optionTables->listboxOptionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureListbox(interp, listPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(listPtr->tkwin));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxWidgetObjCmd --







|










|







552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
    Tk_SetClass(listPtr->tkwin, "Listbox");
    Tk_SetClassProcs(listPtr->tkwin, &listboxClass, listPtr);
    Tk_CreateEventHandler(listPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    ListboxEventProc, listPtr);
    Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING,
	    ListboxFetchSelection, listPtr, XA_STRING);
    if (Tk_InitOptions(interp, (char *)listPtr,
	    optionTables->listboxOptionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureListbox(interp, listPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(listPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(listPtr->tkwin));
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxWidgetObjCmd --
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
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;







|







592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
static int
ListboxWidgetObjCmd(
    ClientData clientData,	/* Information about listbox widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Arguments as Tcl_Obj's. */
{
    Listbox *listPtr = clientData;
    int cmdIndex, index;
    int result = TCL_OK;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
	}

	objPtr = Tk_GetOptionValue(interp, listPtr,
		listPtr->optionTable, objv[2], listPtr->tkwin);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	    break;
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, listPtr,
		    listPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);







|











|







667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
	}

	objPtr = Tk_GetOptionValue(interp, (char *) listPtr,
		listPtr->optionTable, objv[2], listPtr->tkwin);
	if (objPtr == NULL) {
	    result = TCL_ERROR;
	    break;
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) listPtr,
		    listPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
	 * 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;
    }








|







713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
	 * the indices in order, adding them to the result if they are
	 * selected.
	 */

	objPtr = Tcl_NewObj();
	for (i = 0; i < listPtr->nElements; i++) {
	    if (Tcl_FindHashEntry(listPtr->selection, KEY(i))) {
		Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewIntObj(i));
	    }
	}
	Tcl_SetObjResult(interp, objPtr);
	result = TCL_OK;
	break;
    }

838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
	if (result != TCL_OK) {
	    break;
	}
	Tcl_SetObjResult(interp, TkNewIndexObj(index));
	result = TCL_OK;
	break;

    case COMMAND_INSERT:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?element ...?");
	    result = TCL_ERROR;







|







826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
	    result = TCL_ERROR;
	    break;
	}
	result = GetListboxIndex(interp, listPtr, objv[2], 1, &index);
	if (result != TCL_OK) {
	    break;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	result = TCL_OK;
	break;

    case COMMAND_INSERT:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?element ...?");
	    result = TCL_ERROR;
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
    }

    case COMMAND_ITEMCONFIGURE: {
	ItemAttr *attrPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index ?-option value ...?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}

	attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
	if (objc <= 4) {
	    objPtr = Tk_GetOptionInfo(interp, attrPtr,
		    listPtr->itemAttrOptionTable,
		    (objc == 4) ? objv[3] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);







|




















|







890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
    }

    case COMMAND_ITEMCONFIGURE: {
	ItemAttr *attrPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index ?-option? ?value? ?-option value ...?");
	    result = TCL_ERROR;
	    break;
	}

	result = GetListboxIndex(interp, listPtr, objv[2], 0, &index);
	if (result != TCL_OK) {
	    break;
	}

	if (index < 0 || index >= listPtr->nElements) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "item number \"%s\" out of range",
		    Tcl_GetString(objv[2])));
	    Tcl_SetErrorCode(interp, "TK", "LISTBOX", "ITEM_INDEX", NULL);
	    result = TCL_ERROR;
	    break;
	}

	attrPtr = ListboxGetItemAttributes(interp, listPtr, index);
	if (objc <= 4) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) attrPtr,
		    listPtr->itemAttrOptionTable,
		    (objc == 4) ? objv[3] : NULL, listPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
		break;
	    }
	    Tcl_SetObjResult(interp, objPtr);
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
	}

	result = Tcl_GetIntFromObj(interp, objv[2], &y);
	if (result != TCL_OK) {
	    break;
	}
	index = NearestListboxElement(listPtr, y);
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(index));
	result = TCL_OK;
	break;
    }

    case COMMAND_SCAN: {
	int x, y, scanCmdIndex;








|







941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
	}

	result = Tcl_GetIntFromObj(interp, objv[2], &y);
	if (result != TCL_OK) {
	    break;
	}
	index = NearestListboxElement(listPtr, y);
	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	result = TCL_OK;
	break;
    }

    case COMMAND_SCAN: {
	int x, y, scanCmdIndex;

1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
	break;
    case COMMAND_SIZE:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    result = TCL_ERROR;
	    break;
	}
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(listPtr->nElements));
	result = TCL_OK;
	break;
    case COMMAND_XVIEW:
	result = ListboxXviewSubCmd(interp, listPtr, objc, objv);
	break;
    case COMMAND_YVIEW:
	result = ListboxYviewSubCmd(interp, listPtr, objc, objv);







|







1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
	break;
    case COMMAND_SIZE:
	if (objc != 2) {
	    Tcl_WrongNumArgs(interp, 2, objv, NULL);
	    result = TCL_ERROR;
	    break;
	}
	Tcl_SetObjResult(interp, Tcl_NewIntObj(listPtr->nElements));
	result = TCL_OK;
	break;
    case COMMAND_XVIEW:
	result = ListboxXviewSubCmd(interp, listPtr, objc, objv);
	break;
    case COMMAND_YVIEW:
	result = ListboxYviewSubCmd(interp, listPtr, objc, objv);
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
    /*
     * Only allow bbox requests for indices that are visible.
     */

    if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
	Tcl_Obj *el, *results[4];
	const char *stringRep;
	int pixelWidth, x, y, result;
	TkSizeT stringLen;
	Tk_FontMetrics fm;

	/*
	 * Compute the pixel width of the requested element.
	 */

	result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el);
	if (result != TCL_OK) {
	    return result;
	}

	stringRep = TkGetStringFromObj(el, &stringLen);
	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);

        if (listPtr->justify == TK_JUSTIFY_LEFT) {
            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
                    - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr);
        } else {
            x = (Tk_Width(tkwin) - pixelWidth)/2
                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
        }
	y = ((index - listPtr->topIndex)*listPtr->lineHeight)
		+ listPtr->inset + listPtr->selBorderWidth;
	results[0] = Tcl_NewWideIntObj(x);
	results[1] = Tcl_NewWideIntObj(y);
	results[2] = Tcl_NewWideIntObj(pixelWidth);
	results[3] = Tcl_NewWideIntObj(fm.linespace);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------







|
<











|














|
|
|
|







1087
1088
1089
1090
1091
1092
1093
1094

1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
    /*
     * Only allow bbox requests for indices that are visible.
     */

    if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) {
	Tcl_Obj *el, *results[4];
	const char *stringRep;
	int pixelWidth, stringLen, x, y, result;

	Tk_FontMetrics fm;

	/*
	 * Compute the pixel width of the requested element.
	 */

	result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el);
	if (result != TCL_OK) {
	    return result;
	}

	stringRep = Tcl_GetStringFromObj(el, &stringLen);
	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);

        if (listPtr->justify == TK_JUSTIFY_LEFT) {
            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
                    - pixelWidth - listPtr->xOffset + GetMaxOffset(listPtr);
        } else {
            x = (Tk_Width(tkwin) - pixelWidth)/2
                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
        }
	y = ((index - listPtr->topIndex)*listPtr->lineHeight)
		+ listPtr->inset + listPtr->selBorderWidth;
	results[0] = Tcl_NewIntObj(x);
	results[1] = Tcl_NewIntObj(y);
	results[2] = Tcl_NewIntObj(pixelWidth);
	results[3] = Tcl_NewIntObj(fm.linespace);
	Tcl_SetObjResult(interp, Tcl_NewListObj(4, results));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305


1306
1307
1308
1309
1310
1311
1312
    } 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;
}

/*







<
<















>
>







1269
1270
1271
1272
1273
1274
1275


1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
    } else if (objc == 3) {
	if (Tcl_GetIntFromObj(interp, objv[2], &index) != TCL_OK) {
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, index*listPtr->xScrollUnit);
    } else {
	switch (Tk_GetScrollInfoObj(interp, objc, objv, &fraction, &count)) {


	case TK_SCROLL_MOVETO:
	    offset = (int) (fraction*listPtr->maxWidth + 0.5);
	    break;
	case TK_SCROLL_PAGES:
	    windowUnits = windowWidth / listPtr->xScrollUnit;
	    if (windowUnits > 2) {
		offset = listPtr->xOffset
			+ count*listPtr->xScrollUnit*(windowUnits-2);
	    } else {
		offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    }
	    break;
	case TK_SCROLL_UNITS:
	    offset = listPtr->xOffset + count*listPtr->xScrollUnit;
	    break;
	default:
	    return TCL_ERROR;
	}
	ChangeListboxOffset(listPtr, offset);
    }
    return TCL_OK;
}

/*
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
	    } 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;
}







<







1356
1357
1358
1359
1360
1361
1362

1363
1364
1365
1366
1367
1368
1369
	    } else {
		index = listPtr->topIndex + count;
	    }
	    break;
	case TK_SCROLL_UNITS:
	    index = listPtr->topIndex + count;
	    break;

	default:
	    return TCL_ERROR;
	}
	ChangeListboxView(listPtr, index);
    }
    return TCL_OK;
}
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
{
    int isNew;
    Tcl_HashEntry *entry;
    ItemAttr *attrs;

    entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, KEY(index), &isNew);
    if (isNew) {
	attrs = (ItemAttr *)ckalloc(sizeof(ItemAttr));
	attrs->border = NULL;
	attrs->selBorder = NULL;
	attrs->fgColor = NULL;
	attrs->selFgColor = NULL;
	Tk_InitOptions(interp, attrs, listPtr->itemAttrOptionTable,
		listPtr->tkwin);
	Tcl_SetHashValue(entry, attrs);
    } else {
	attrs = (ItemAttr *)Tcl_GetHashValue(entry);
    }
    return attrs;
}

/*
 *----------------------------------------------------------------------
 *







|




|



|







1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
{
    int isNew;
    Tcl_HashEntry *entry;
    ItemAttr *attrs;

    entry = Tcl_CreateHashEntry(listPtr->itemAttrTable, KEY(index), &isNew);
    if (isNew) {
	attrs = ckalloc(sizeof(ItemAttr));
	attrs->border = NULL;
	attrs->selBorder = NULL;
	attrs->fgColor = NULL;
	attrs->selFgColor = NULL;
	Tk_InitOptions(interp, (char *)attrs, listPtr->itemAttrOptionTable,
		listPtr->tkwin);
	Tcl_SetHashValue(entry, attrs);
    } else {
	attrs = Tcl_GetHashValue(entry);
    }
    return attrs;
}

/*
 *----------------------------------------------------------------------
 *
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.







|







1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
 *	Everything associated with the listbox is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListbox(
    char *memPtr)		/* Info about listbox widget. */
{
    Listbox *listPtr = (Listbox *)memPtr;
    Tcl_HashEntry *entry;
    Tcl_HashSearch search;

    /*
     * If we have an internal list object, free it.
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListboxOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *dummy)		/* Pointer to the calling interp */
{
    (void)dummy;

    ckfree(clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *







|

<
<







1510
1511
1512
1513
1514
1515
1516
1517
1518


1519
1520
1521
1522
1523
1524
1525
 *
 *----------------------------------------------------------------------
 */

static void
DestroyListboxOptionTables(
    ClientData clientData,	/* Pointer to the OptionTables struct */
    Tcl_Interp *interp)		/* Pointer to the calling interp */
{


    ckfree(clientData);
    return;
}

/*
 *----------------------------------------------------------------------
 *
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, listPtr,
		    listPtr->optionTable, objc, objv,
		    listPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|







1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) listPtr,
		    listPtr->optionTable, objc, objv,
		    listPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
    ItemAttr *attrs,		/* Information about the item to configure */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    int index)			/* Index of the listbox item being configure */
{
    Tk_SavedOptions savedOptions;

    if (Tk_SetOptions(interp, attrs,
	    listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin,
	    &savedOptions, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }
    Tk_FreeSavedOptions(&savedOptions);








|







1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
    ItemAttr *attrs,		/* Information about the item to configure */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    int index)			/* Index of the listbox item being configure */
{
    Tk_SavedOptions savedOptions;

    if (Tk_SetOptions(interp, (char *)attrs,
	    listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin,
	    &savedOptions, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }
    Tk_FreeSavedOptions(&savedOptions);

1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
static void
ListboxWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    Listbox *listPtr = (Listbox *)instanceData;

    if (listPtr->state & STATE_NORMAL) {
	gcValues.foreground = listPtr->fgColorPtr->pixel;
	gcValues.graphics_exposures = False;
	mask = GCForeground | GCFont | GCGraphicsExposures;
    } else if (listPtr->dfgColorPtr != NULL) {
	gcValues.foreground = listPtr->dfgColorPtr->pixel;







|







1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
static void
ListboxWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    Listbox *listPtr = instanceData;

    if (listPtr->state & STATE_NORMAL) {
	gcValues.foreground = listPtr->fgColorPtr->pixel;
	gcValues.graphics_exposures = False;
	mask = GCForeground | GCFont | GCGraphicsExposures;
    } else if (listPtr->dfgColorPtr != NULL) {
	gcValues.foreground = listPtr->dfgColorPtr->pixel;
1837
1838
1839
1840
1841
1842
1843
1844
1845

1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
 *--------------------------------------------------------------
 */

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;







|

>

|
<







1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832

1833
1834
1835
1836
1837
1838
1839
 *--------------------------------------------------------------
 */

static void
DisplayListbox(
    ClientData clientData)	/* Information about window. */
{
    Listbox *listPtr = clientData;
    Tk_Window tkwin = listPtr->tkwin;
    Display *disp = listPtr->display;
    GC gc;
    int i, limit, x, y, prevSelected, freeGC, stringLen;

    Tk_FontMetrics fm;
    Tcl_Obj *curElement;
    Tcl_HashEntry *entry;
    const char *stringRep;
    ItemAttr *attrs;
    Tk_3DBorder selectedBg;
    XGCValues gcValues;
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
     * Redrawing is done in a temporary pixmap that is allocated here and
     * freed at the end of the procedure. All drawing is done to the pixmap,
     * and the pixmap is copied to the screen at the end of the procedure.
     * This provides the smoothest possible visual effects (no flashing on the
     * screen).
     */

    pixmap = Tk_GetPixmap(listPtr->display, Tk_WindowId(tkwin),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
    pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */
    Tk_Fill3DRectangle(tkwin, pixmap, listPtr->normalBorder, 0, 0,
	    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);








|







1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
     * Redrawing is done in a temporary pixmap that is allocated here and
     * freed at the end of the procedure. All drawing is done to the pixmap,
     * and the pixmap is copied to the screen at the end of the procedure.
     * This provides the smoothest possible visual effects (no flashing on the
     * screen).
     */

    pixmap = Tk_GetPixmap(disp, Tk_WindowId(tkwin),
	    Tk_Width(tkwin), Tk_Height(tkwin), Tk_Depth(tkwin));
#else
    pixmap = Tk_WindowId(tkwin);
#endif /* TK_NO_DOUBLE_BUFFERING */
    Tk_Fill3DRectangle(tkwin, pixmap, listPtr->normalBorder, 0, 0,
	    Tk_Width(tkwin), Tk_Height(tkwin), 0, TK_RELIEF_FLAT);

1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
    }
    prevSelected = 0;

    for (i = listPtr->topIndex; i <= limit; i++) {
	int width = Tk_Width(tkwin);	/* zeroth approx to silence warning */

	x = listPtr->inset;
	y = ((i - listPtr->topIndex) * listPtr->lineHeight) + listPtr->inset;
	gc = listPtr->textGC;
	freeGC = 0;

	/*
	 * Lookup this item in the item attributes table, to see if it has
	 * special foreground/background colors.
	 */







|







1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
    }
    prevSelected = 0;

    for (i = listPtr->topIndex; i <= limit; i++) {
	int width = Tk_Width(tkwin);	/* zeroth approx to silence warning */

	x = listPtr->inset;
	y = (i - listPtr->topIndex) * listPtr->lineHeight + listPtr->inset;
	gc = listPtr->textGC;
	freeGC = 0;

	/*
	 * Lookup this item in the item attributes table, to see if it has
	 * special foreground/background colors.
	 */
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971

		/*
		 * If there is attribute information for this item, adjust the
		 * drawing accordingly.
		 */

		if (entry != NULL) {
		    attrs = (ItemAttr *)Tcl_GetHashValue(entry);

		    /*
		     * Default GC has the values from the widget at large.
		     */

		    if (listPtr->selFgColorPtr) {
			gcValues.foreground = listPtr->selFgColorPtr->pixel;







|







1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955

		/*
		 * If there is attribute information for this item, adjust the
		 * drawing accordingly.
		 */

		if (entry != NULL) {
		    attrs = Tcl_GetHashValue(entry);

		    /*
		     * Default GC has the values from the widget at large.
		     */

		    if (listPtr->selFgColorPtr) {
			gcValues.foreground = listPtr->selFgColorPtr->pixel;
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
	    } else {
		/*
		 * If there is an item attributes record for this item, draw
		 * the background box and set the foreground color accordingly.
		 */

		if (entry != NULL) {
		    attrs = (ItemAttr *)Tcl_GetHashValue(entry);
		    gcValues.foreground = listPtr->fgColorPtr->pixel;
		    gcValues.font = Tk_FontId(listPtr->tkfont);
		    gcValues.graphics_exposures = False;
		    mask = GCForeground | GCFont | GCGraphicsExposures;

		    /*
		     * If the item has its own background color, draw it now.







|







2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
	    } else {
		/*
		 * If there is an item attributes record for this item, draw
		 * the background box and set the foreground color accordingly.
		 */

		if (entry != NULL) {
		    attrs = Tcl_GetHashValue(entry);
		    gcValues.foreground = listPtr->fgColorPtr->pixel;
		    gcValues.font = Tk_FontId(listPtr->tkfont);
		    gcValues.graphics_exposures = False;
		    mask = GCForeground | GCFont | GCGraphicsExposures;

		    /*
		     * If the item has its own background color, draw it now.
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
	}

	/*
	 * Draw the actual text of this item.
	 */

        Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
        stringRep = TkGetStringFromObj(curElement, &stringLen);
        textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);

	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	y += fm.ascent + listPtr->selBorderWidth;

        if (listPtr->justify == TK_JUSTIFY_LEFT) {
            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
                    - textWidth - listPtr->xOffset + GetMaxOffset(listPtr);
        } else {
            x = (Tk_Width(tkwin) - textWidth)/2
                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
        }

        Tk_DrawChars(listPtr->display, pixmap, gc, listPtr->tkfont,
		stringRep, stringLen, x, y);

	/*
	 * If this is the active element, apply the activestyle to it.
	 */

	if ((i == listPtr->active) && (listPtr->flags & GOT_FOCUS)) {
	    if (listPtr->activeStyle == ACTIVE_STYLE_UNDERLINE) {
		/*
		 * Underline the text.
		 */

		Tk_UnderlineChars(listPtr->display, pixmap, gc,
			listPtr->tkfont, stringRep, x, y, 0, stringLen);
	    } else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) {
#ifdef _WIN32
		/*
		 * This provides for exact default look and feel on Windows.
		 */

		TkWinDCState state;
		HDC dc;
		RECT rect;

		dc = TkWinGetDrawableDC(listPtr->display, pixmap, &state);
		rect.left = listPtr->inset;
		rect.top = ((i - listPtr->topIndex) * listPtr->lineHeight)
			+ listPtr->inset;
		rect.right = rect.left + width;
		rect.bottom = rect.top + listPtr->lineHeight;
		DrawFocusRect(dc, &rect);
		TkWinReleaseDrawableDC(pixmap, dc, &state);
#else /* !_WIN32 */
		/*
		 * Draw a dotted box around the text.
		 */

		x = listPtr->inset;
		y = ((i - listPtr->topIndex) * listPtr->lineHeight)
			+ listPtr->inset;
		width = Tk_Width(tkwin) - 2*listPtr->inset - 1;

		gcValues.line_style = LineOnOffDash;
		gcValues.line_width = listPtr->selBorderWidth;
		if (gcValues.line_width <= 0) {
		    gcValues.line_width  = 1;
		}
		gcValues.dash_offset = 0;
		gcValues.dashes = 1;

		/*
		 * You would think the XSetDashes was necessary, but it
		 * appears that the default dotting for just saying we want
		 * dashes appears to work correctly.
		 static char dashList[] = { 1 };
		 static int dashLen = sizeof(dashList);
		 XSetDashes(listPtr->display, gc, 0, dashList, dashLen);
		 */

		mask = GCLineWidth | GCLineStyle | GCDashList | GCDashOffset;
		XChangeGC(listPtr->display, gc, mask, &gcValues);
		XDrawRectangle(listPtr->display, pixmap, gc, x, y,
			(unsigned) width, (unsigned) listPtr->lineHeight - 1);
		if (!freeGC) {
		    /*
		     * Don't bother changing if it is about to be freed.
		     */

		    gcValues.line_style = LineSolid;
		    XChangeGC(listPtr->display, gc, GCLineStyle, &gcValues);
		}
#endif /* _WIN32 */
	    }
	}

	if (freeGC) {
	    Tk_FreeGC(listPtr->display, gc);
	}
    }

    /*
     * Redraw the border for the listbox to make sure that it's on top of any
     * of the text of the listbox entries.
     */







|















|












|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<





|

|

<
<
<
<
<
<
<
|
<
<
<
<
<
<
|
<

<
<
<
<






|

<




|







2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097


















2098
2099
2100
2101
2102
2103
2104
2105
2106







2107






2108

2109




2110
2111
2112
2113
2114
2115
2116
2117

2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
	}

	/*
	 * Draw the actual text of this item.
	 */

        Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement);
        stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
        textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen);

	Tk_GetFontMetrics(listPtr->tkfont, &fm);
	y += fm.ascent + listPtr->selBorderWidth;

        if (listPtr->justify == TK_JUSTIFY_LEFT) {
            x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset;
        } else if (listPtr->justify == TK_JUSTIFY_RIGHT) {
            x = Tk_Width(tkwin) - (listPtr->inset + listPtr->selBorderWidth)
                    - textWidth - listPtr->xOffset + GetMaxOffset(listPtr);
        } else {
            x = (Tk_Width(tkwin) - textWidth)/2
                    - listPtr->xOffset + GetMaxOffset(listPtr)/2;
        }

        Tk_DrawChars(disp, pixmap, gc, listPtr->tkfont,
		stringRep, stringLen, x, y);

	/*
	 * If this is the active element, apply the activestyle to it.
	 */

	if ((i == listPtr->active) && (listPtr->flags & GOT_FOCUS)) {
	    if (listPtr->activeStyle == ACTIVE_STYLE_UNDERLINE) {
		/*
		 * Underline the text.
		 */

		Tk_UnderlineChars(disp, pixmap, gc, listPtr->tkfont,
			stringRep, x, y, 0, stringLen);
	    } else if (listPtr->activeStyle == ACTIVE_STYLE_DOTBOX) {


















		/*
		 * Draw a dotted box around the text.
		 */

		x = listPtr->inset;
		y = (i - listPtr->topIndex) * listPtr->lineHeight
			+ listPtr->inset;
		width = Tk_Width(tkwin) - 2*listPtr->inset;








		TkDrawDottedRect(disp, pixmap, gc, x, y,






			width, listPtr->lineHeight);






		if (!freeGC) {
		    /*
		     * Don't bother changing if it is about to be freed.
		     */

		    gcValues.line_style = LineSolid;
		    XChangeGC(disp, gc, GCLineStyle, &gcValues);
		}

	    }
	}

	if (freeGC) {
	    Tk_FreeGC(disp, gc);
	}
    }

    /*
     * Redraw the border for the listbox to make sure that it's on top of any
     * of the text of the listbox entries.
     */
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
		    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);
    Tk_FreePixmap(listPtr->display, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxComputeGeometry --







|
|
<
|







2143
2144
2145
2146
2147
2148
2149
2150
2151

2152
2153
2154
2155
2156
2157
2158
2159
		    listPtr->highlightWidth, pixmap);
	} else {
	    TkpDrawHighlightBorder(tkwin, bgGC, bgGC,
		    listPtr->highlightWidth, pixmap);
	}
    }
#ifndef TK_NO_DOUBLE_BUFFERING
    XCopyArea(disp, pixmap, Tk_WindowId(tkwin), listPtr->textGC, 0, 0,
	    (unsigned) Tk_Width(tkwin), (unsigned) Tk_Height(tkwin), 0, 0);

    Tk_FreePixmap(disp, pixmap);
#endif /* TK_NO_DOUBLE_BUFFERING */
}

/*
 *----------------------------------------------------------------------
 *
 * ListboxComputeGeometry --
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
				 * longer be up-to-date and must be
				 * recomputed. If fontChanged is 1 then this
				 * must be 1. */
    int updateGrid)		/* Non-zero means call Tk_SetGrid or
				 * Tk_UnsetGrid to update gridding for the
				 * window. */
{
    int width, height, pixelWidth, pixelHeight, i, result;
    TkSizeT textLength;
    Tk_FontMetrics fm;
    Tcl_Obj *element;
    const char *text;

    if (fontChanged || maxIsStale) {
	listPtr->xScrollUnit = Tk_TextWidth(listPtr->tkfont, "0", 1);
	if (listPtr->xScrollUnit == 0) {
	    listPtr->xScrollUnit = 1;
	}
	listPtr->maxWidth = 0;
	for (i = 0; i < listPtr->nElements; i++) {
	    /*
	     * Compute the pixel width of the current element.
	     */

	    result = Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &element);
	    if (result != TCL_OK) {
		continue;
	    }
	    text = TkGetStringFromObj(element, &textLength);
	    Tk_GetFontMetrics(listPtr->tkfont, &fm);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
	    if (pixelWidth > listPtr->maxWidth) {
		listPtr->maxWidth = pixelWidth;
	    }
	}
    }







|
<




















|







2183
2184
2185
2186
2187
2188
2189
2190

2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
				 * longer be up-to-date and must be
				 * recomputed. If fontChanged is 1 then this
				 * must be 1. */
    int updateGrid)		/* Non-zero means call Tk_SetGrid or
				 * Tk_UnsetGrid to update gridding for the
				 * window. */
{
    int width, height, pixelWidth, pixelHeight, textLength, i, result;

    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 = Tcl_GetStringFromObj(element, &textLength);
	    Tk_GetFontMetrics(listPtr->tkfont, &fm);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength);
	    if (pixelWidth > listPtr->maxWidth) {
		listPtr->maxWidth = pixelWidth;
	    }
	}
    }
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
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;
	}
    }

    /*







|
<










|







2270
2271
2272
2273
2274
2275
2276
2277

2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
ListboxInsertSubCmd(
    Listbox *listPtr,	/* Listbox that is to get the new elements. */
    int index,			/* Add the new elements before this
				 * element. */
    int objc,			/* Number of new elements to add. */
    Tcl_Obj *const objv[])	/* New elements (one per entry). */
{
    int i, oldMaxWidth, pixelWidth, result, 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;
	}
    }

    /*
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455

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.







|
<







2384
2385
2386
2387
2388
2389
2390
2391

2392
2393
2394
2395
2396
2397
2398

static int
ListboxDeleteSubCmd(
    Listbox *listPtr,	/* Listbox widget to modify. */
    int first,			/* Index of first element to delete. */
    int last)			/* Index of last element to delete. */
{
    int count, i, widthChanged, length, result, pixelWidth;

    Tcl_Obj *newListObj, *element;
    const char *stringRep;
    Tcl_HashEntry *entry;

    /*
     * Adjust the range to fit within the existing elements of the listbox,
     * and make sure there's something to delete.
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
	 * 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;
	    }
	}
    }








|







2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
	 * Check width of the element. We only have to check if widthChanged
	 * has not already been set to 1, because we only need one maxWidth
	 * element to disappear for us to have to recompute the width.
	 */

	if (widthChanged == 0) {
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &element);
	    stringRep = Tcl_GetStringFromObj(element, &length);
	    pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length);
	    if (pixelWidth == listPtr->maxWidth) {
		widthChanged = 1;
	    }
	}
    }

2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
 */

static void
ListboxEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Listbox *listPtr = (Listbox *)clientData;

    if (eventPtr->type == Expose) {
	EventuallyRedrawRange(listPtr,
		NearestListboxElement(listPtr, eventPtr->xexpose.y),
		NearestListboxElement(listPtr, eventPtr->xexpose.y
		+ eventPtr->xexpose.height));
    } else if (eventPtr->type == DestroyNotify) {
	if (!(listPtr->flags & LISTBOX_DELETED)) {
	    listPtr->flags |= LISTBOX_DELETED;
	    Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
	    if (listPtr->setGrid) {
		Tk_UnsetGrid(listPtr->tkwin);
	    }
	    if (listPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayListbox, clientData);
	    }
	    Tcl_EventuallyFree(clientData, (Tcl_FreeProc *) DestroyListbox);
	}
    } else if (eventPtr->type == ConfigureNotify) {
	int vertSpace;

	vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset;
	listPtr->fullLines = vertSpace / listPtr->lineHeight;
	if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) {







|
















|







2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
 */

static void
ListboxEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Listbox *listPtr = clientData;

    if (eventPtr->type == Expose) {
	EventuallyRedrawRange(listPtr,
		NearestListboxElement(listPtr, eventPtr->xexpose.y),
		NearestListboxElement(listPtr, eventPtr->xexpose.y
		+ eventPtr->xexpose.height));
    } else if (eventPtr->type == DestroyNotify) {
	if (!(listPtr->flags & LISTBOX_DELETED)) {
	    listPtr->flags |= LISTBOX_DELETED;
	    Tcl_DeleteCommandFromToken(listPtr->interp, listPtr->widgetCmd);
	    if (listPtr->setGrid) {
		Tk_UnsetGrid(listPtr->tkwin);
	    }
	    if (listPtr->flags & REDRAW_PENDING) {
		Tcl_CancelIdleCall(DisplayListbox, clientData);
	    }
	    Tcl_EventuallyFree(clientData, DestroyListbox);
	}
    } else if (eventPtr->type == ConfigureNotify) {
	int vertSpace;

	vertSpace = Tk_Height(listPtr->tkwin) - 2*listPtr->inset;
	listPtr->fullLines = vertSpace / listPtr->lineHeight;
	if ((listPtr->fullLines*listPtr->lineHeight) < vertSpace) {
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
 *----------------------------------------------------------------------
 */

static void
ListboxCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Listbox *listPtr = (Listbox *)clientData;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this procedure destroys the
     * widget.
     */







|







2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
 *----------------------------------------------------------------------
 */

static void
ListboxCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Listbox *listPtr = clientData;

    /*
     * This procedure could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this procedure destroys the
     * widget.
     */
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765








2766
2767
2768
2769
2770
2771
2772

static int
GetListboxIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Listbox *listPtr,		/* Listbox for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,		/* Specifies an element in the listbox. */
    int lastOK,		/* If 1, "end" refers to the number of entries
				 * in the listbox. If 0, "end" refers to 1
				 * less than the number of entries. */
    int *indexPtr)		/* Where to store converted index. */
{
    int result, index;
    TkSizeT idx;
    const char *stringRep;

    result = TkGetIntForIndex(indexObj, listPtr->nElements - 1, lastOK, &idx);
    if (result == TCL_OK) {
    	if ((idx != TCL_INDEX_NONE) && (idx > (TkSizeT)listPtr->nElements)) {
    	    idx = listPtr->nElements;
    	}
    	*indexPtr = (int)idx;
    	return TCL_OK;
    }

    /*
     * First see if the index is one of the named indices.
     */

    result = Tcl_GetIndexFromObj(NULL, indexObj, indexNames, "", 0, &index);
    if (result == TCL_OK) {
	switch (index) {
	case INDEX_ACTIVE:
	    /* "active" index */
	    *indexPtr = listPtr->active;
	    break;
	case INDEX_ANCHOR:
	    /* "anchor" index */
	    *indexPtr = listPtr->selectAnchor;








	    break;
	}
	return TCL_OK;
    }

    /*
     * The index didn't match any of the named indices; maybe it's an @x,y







|





<


<
<
<
<
<
<
<
<
<














>
>
>
>
>
>
>
>







2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682

2683
2684









2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713

static int
GetListboxIndex(
    Tcl_Interp *interp,		/* For error messages. */
    Listbox *listPtr,		/* Listbox for which the index is being
				 * specified. */
    Tcl_Obj *indexObj,		/* Specifies an element in the listbox. */
    int endIsSize,		/* If 1, "end" refers to the number of entries
				 * in the listbox. If 0, "end" refers to 1
				 * less than the number of entries. */
    int *indexPtr)		/* Where to store converted index. */
{
    int result, index;

    const char *stringRep;










    /*
     * First see if the index is one of the named indices.
     */

    result = Tcl_GetIndexFromObj(NULL, indexObj, indexNames, "", 0, &index);
    if (result == TCL_OK) {
	switch (index) {
	case INDEX_ACTIVE:
	    /* "active" index */
	    *indexPtr = listPtr->active;
	    break;
	case INDEX_ANCHOR:
	    /* "anchor" index */
	    *indexPtr = listPtr->selectAnchor;
	    break;
	case INDEX_END:
	    /* "end" index */
	    if (endIsSize) {
		*indexPtr = listPtr->nElements;
	    } else {
		*indexPtr = listPtr->nElements - 1;
	    }
	    break;
	}
	return TCL_OK;
    }

    /*
     * The index didn't match any of the named indices; maybe it's an @x,y
2792
2793
2794
2795
2796
2797
2798








2799
2800
2801
2802
2803
2804
2805
	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(







>
>
>
>
>
>
>
>







2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
	y = strtol(start, &end, 0);
	if ((start == end) || (*end != '\0')) {
	    goto badIndex;
	}
	*indexPtr = NearestListboxElement(listPtr, y);
	return TCL_OK;
    }

    /*
     * Maybe the index is just an integer.
     */

    if (Tcl_GetIntFromObj(interp, indexObj, indexPtr) == TCL_OK) {
	return TCL_OK;
    }

    /*
     * Everything failed, nothing matched. Throw up an error message.
     */

  badIndex:
    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
 *
 * 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;
    }







|


|


|



|

|
<







3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3074
3075
3076

3077
3078
3079
3080
3081
3082
3083
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static int
ListboxFetchSelection(
    ClientData clientData,	/* Information about listbox widget. */
    int offset,			/* Offset within selection of first byte to be
				 * returned. */
    char *buffer,		/* Location in which to place selection. */
    int maxBytes)		/* Maximum number of bytes to place at buffer,
				 * not including terminating NULL
				 * character. */
{
    Listbox *listPtr = clientData;
    Tcl_DString selection;
    int length, count, needNewline, stringLen, i;

    Tcl_Obj *curElement;
    const char *stringRep;
    Tcl_HashEntry *entry;

    if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) {
	return -1;
    }
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166

3167
3168
3169
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180
	entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
	if (entry != NULL) {
	    if (needNewline) {
		Tcl_DStringAppend(&selection, "\n", 1);
	    }
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &curElement);
	    stringRep = TkGetStringFromObj(curElement, &stringLen);
	    Tcl_DStringAppend(&selection, stringRep, stringLen);
	    needNewline = 1;
	}
    }

    length = Tcl_DStringLength(&selection);
    if (length == 0) {
	return -1;
    }

    /*
     * Copy the requested portion of the selection to the buffer.
     */

    if (length <= offset) {

	count = 0;
    } else {
	count = length - offset;
	if (count > (int)maxBytes) {
	    count = (int)maxBytes;
	}
	memcpy(buffer, Tcl_DStringValue(&selection) + offset, count);
    }
    buffer[count] = '\0';
    Tcl_DStringFree(&selection);
    return count;
}

/*







|














|
>


<
|
|

|







3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117

3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
	entry = Tcl_FindHashEntry(listPtr->selection, KEY(i));
	if (entry != NULL) {
	    if (needNewline) {
		Tcl_DStringAppend(&selection, "\n", 1);
	    }
	    Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i,
		    &curElement);
	    stringRep = Tcl_GetStringFromObj(curElement, &stringLen);
	    Tcl_DStringAppend(&selection, stringRep, stringLen);
	    needNewline = 1;
	}
    }

    length = Tcl_DStringLength(&selection);
    if (length == 0) {
	return -1;
    }

    /*
     * Copy the requested portion of the selection to the buffer.
     */

    count = length - offset;
    if (count <= 0) {
	count = 0;
    } else {

	if (count > maxBytes) {
	    count = maxBytes;
	}
	memcpy(buffer, Tcl_DStringValue(&selection) + offset, (size_t) count);
    }
    buffer[count] = '\0';
    Tcl_DStringFree(&selection);
    return count;
}

/*
3195
3196
3197
3198
3199
3200
3201
3202
3203
3204
3205
3206
3207
3208
3209
 *----------------------------------------------------------------------
 */

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







|







3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
 *----------------------------------------------------------------------
 */

static void
ListboxLostSelection(
    ClientData clientData)	/* Information about listbox widget. */
{
    Listbox *listPtr = clientData;

    if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp))
	    && (listPtr->nElements > 0)) {
	ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
        GenerateListboxSelectEvent(listPtr);
    }
}
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
 *----------------------------------------------------------------------
 */

static void
GenerateListboxSelectEvent(
    Listbox *listPtr)		/* Information about widget. */
{
    Tk_SendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyRedrawRange --
 *







|







3173
3174
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
 *----------------------------------------------------------------------
 */

static void
GenerateListboxSelectEvent(
    Listbox *listPtr)		/* Information about widget. */
{
    TkSendVirtualEvent(listPtr->tkwin, "ListboxSelect", NULL);
}

/*
 *----------------------------------------------------------------------
 *
 * EventuallyRedrawRange --
 *
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
    Listbox *listPtr,	/* Information about widget. */
    int first,			/* Index of first element in list that needs
				 * to be redrawn. */
    int last)			/* Index of last element in list that needs to
				 * be redrawn. May be less than first; these
				 * just bracket a range. */
{
    (void)first;
    (void)last;

    /*
     * We don't have to register a redraw callback if one is already pending,
     * or if the window doesn't exist, or if the window isn't mapped.
     */

    if ((listPtr->flags & REDRAW_PENDING)
	    || (listPtr->flags & LISTBOX_DELETED)
	    || !Tk_IsMapped(listPtr->tkwin)) {
	return;







<
<
<

|







3202
3203
3204
3205
3206
3207
3208



3209
3210
3211
3212
3213
3214
3215
3216
3217
    Listbox *listPtr,	/* Information about widget. */
    int first,			/* Index of first element in list that needs
				 * to be redrawn. */
    int last)			/* Index of last element in list that needs to
				 * be redrawn. May be less than first; these
				 * just bracket a range. */
{



    /*
     * We don't have to a redraw callback if one is already pending,
     * or if the window doesn't exist, or if the window isn't mapped.
     */

    if ((listPtr->flags & REDRAW_PENDING)
	    || (listPtr->flags & LISTBOX_DELETED)
	    || !Tk_IsMapped(listPtr->tkwin)) {
	return;
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
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) {








|



<
<







3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392


3393
3394
3395
3396
3397
3398
3399
ListboxListVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Not used. */
    const char *name2,		/* Not used. */
    int flags)			/* Information about what happened. */
{
    Listbox *listPtr = clientData;
    Tcl_Obj *oldListObj, *varListObj;
    int oldLength, i;
    Tcl_HashEntry *entry;



    /*
     * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
     */

    if (flags & TCL_TRACE_UNSETS) {

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 (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenu.h"
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 */

static int
PreprocessMenu(
    TkMenu *menuPtr)
{
    int index, result, finished;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    Tcl_Preserve(menuPtr);

    /*
     * First, let's process the post command on ourselves. If this command
     * destroys this menu, or if there was an error, we are done.







|







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 */

static int
PreprocessMenu(
    TkMenu *menuPtr)
{
    int index, result, finished;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    Tcl_Preserve(menuPtr);

    /*
     * First, let's process the post command on ourselves. If this command
     * destroys this menu, or if there was an error, we are done.
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
     * 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;
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
 *----------------------------------------------------------------------
 */

int
TkPreprocessMenu(
    TkMenu *menuPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->postCommandGeneration++;
    menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration;
    return PreprocessMenu(menuPtr);
}








|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
 *----------------------------------------------------------------------
 */

int
TkPreprocessMenu(
    TkMenu *menuPtr)
{
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    tsdPtr->postCommandGeneration++;
    menuPtr->postCommandGeneration = tsdPtr->postCommandGeneration;
    return PreprocessMenu(menuPtr);
}

Changes to generic/tkMain.c.
12
13
14
15
16
17
18

19

20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"


extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);


/*
 * The default prompt used when the user has not overridden it.
 */

static const char DEFAULT_PRIMARY_PROMPT[] = "% ";


/*
 * This file can be compiled on Windows in UNICODE mode, as well as
 * on all other platforms using the native encoding. This is done
 * by using the normal Windows functions like _tcscmp, but on
 * platforms which don't have <tchar.h> we have to translate that
 * to strcmp here.
 */
#ifdef _WIN32
#ifdef __cplusplus
extern "C" {
#endif
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntPlatStubs, just
    enough to make it work. See [600b72bfbc] */
typedef struct TclIntPlatStubs {
    int magic;
    void *hooks;
    void (*dummy[16]) (void); /* dummy entries 0-15, not used */
    int (*tclpIsAtty) (int fd); /* 16 */
} TclIntPlatStubs;
extern const TclIntPlatStubs *tclIntPlatStubsPtr;
#ifdef __cplusplus







>
|
>






>


|
|
|
|
<








|







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

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"

#if defined(_WIN32) && !defined(UNICODE) && !defined(STATIC_BUILD)
MODULE_SCOPE void TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *);
#endif

/*
 * The default prompt used when the user has not overridden it.
 */

static const char DEFAULT_PRIMARY_PROMPT[] = "% ";
static const char ENCODING_ERROR[] = "\n\t(encoding error in stderr)";

/*
 * This file can be compiled on Windows in UNICODE mode, as well as on all
 * other platforms using the native encoding. This is done by using the normal
 * Windows functions like _tcscmp, but on platforms which don't have <tchar.h>
 * we have to translate that to strcmp here.

 */
#ifdef _WIN32
#ifdef __cplusplus
extern "C" {
#endif
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntPlatStubs, just
    enough to make it work. See [600b72bfbc] */
typedef struct {
    int magic;
    void *hooks;
    void (*dummy[16]) (void); /* dummy entries 0-15, not used */
    int (*tclpIsAtty) (int fd); /* 16 */
} TclIntPlatStubs;
extern const TclIntPlatStubs *tclIntPlatStubsPtr;
#ifdef __cplusplus
63
64
65
66
67
68
69

70
71
72
73

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

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







>

|


>

|

|






|







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

static inline Tcl_Obj *
NewNativeObj(
    TCHAR *string)
{
    Tcl_Obj *obj;
    Tcl_DString ds;
    const char *str;

#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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176





177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
	     || (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.
 *
 * Results:
 *	None. This function never returns (it exits the process when it's
 *	done).
 *
 * Side effects:
 *	This function initializes the Tk world and then starts interpreting
 *	commands; almost anything could happen, depending on the script being
 *	interpreted.
 *
 *----------------------------------------------------------------------
 */

void
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








|



















|




















|









>





>
>
>
>
>





|
















|
<
|
<

|

|
|







118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209

210

211
212
213
214
215
216
217
218
219
220
221
222
	     || (GetFileType(handle) == FILE_TYPE_UNKNOWN)
	     || (GetFileType(handle) == FILE_TYPE_CHAR);
}
#else
extern int		isatty(int fd);
#endif

typedef struct {
    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.
 *
 * Results:
 *	None. This function never returns (it exits the process when it's
 *	done).
 *
 * Side effects:
 *	This function initializes the Tk world and then starts interpreting
 *	commands; almost anything could happen, depending on the script being
 *	interpreted.
 *
 *----------------------------------------------------------------------
 */

TCL_NORETURN1 void
Tk_MainEx(
    int argc,			/* Number of arguments. */
    TCHAR **argv,		/* Array of argument strings. */
    Tcl_AppInitProc *appInitProc,
				/* Application-specific initialization
				 * function to call after most initialization
				 * but before starting to execute commands. */
    Tcl_Interp *interp)
{
    int i=0;			/* argv[i] index */
    Tcl_Obj *path, *argvPtr, *appName;
    const char *encodingName;
    int code, nullStdin = 0;
    Tcl_Channel chan;
    InteractiveState is;

    if (0 < argc) {
	--argc;			/* "consume" argv[0] */
	++i;
    }

    /*
     * Ensure that we are getting a compatible version of Tcl.
     */

    if (Tcl_InitStubs(interp, "8.6", 0) == NULL) {
	if (Tcl_InitStubs(interp, "8.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:
	    TkCygwinMainEx(argc, argv, appInitProc, interp);

	    /* Only returns when Tk_MainEx() was not found */

	} else {
	    int j;

	    for (j = 1; j < argc; ++j) {
		if (!strcmp(argv[j], "-display")) {
		    goto loadCygwinTk;
		}
	    }
	}
    }
#endif

246
247
248
249
250
251
252

253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
	 *  -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.
     */








>
|
|




|
|


|
|

|


|










<
<

|



|







254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288


289
290
291
292
293
294
295
296
297
298
299
300
301
	 *  -encoding ENCODING FILENAME
	 * or like
	 *  FILENAME
	 * or like
	 *  -file FILENAME		(ancient history support only)
	 */

	/* mind argc is being adjusted as we proceed */
	if ((argc >= 3) && (0 == _tcscmp(TEXT("-encoding"), argv[1]))
		&& ('-' != 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++;
	} else if ((argc >= 2) && (length = _tcslen(argv[1]))
		&& (length > 1) && (0 == _tcsncmp(TEXT("-file"), argv[1], length))
		&& ('-' != argv[2][0])) {
	    Tcl_SetStartupScript(NewNativeObj(argv[2]), NULL);
	    argc -= 2;
	    i += 2;
	}
    }

    path = Tcl_GetStartupScript(&encodingName);
    if (path == NULL) {
	appName = NewNativeObj(argv[0]);
    } else {
	appName = path;
    }
    Tcl_SetVar2Ex(interp, "argv0", NULL, appName, TCL_GLOBAL_ONLY);



    Tcl_SetVar2Ex(interp, "argc", NULL, Tcl_NewIntObj(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.
     */

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
    if (!is.tty) {
	struct stat st;

	nullStdin = fstat(0, &st) || (S_ISCHR(st.st_mode) && !st.st_blocks);
    }
#endif
    Tcl_SetVar2Ex(interp, "tcl_interactive", NULL,
	    Tcl_NewWideIntObj(!path && (is.tty || nullStdin)), TCL_GLOBAL_ONLY);

    /*
     * Invoke application-specific initialization.
     */

    if (appInitProc(interp) != TCL_OK) {
	TkpDisplayWarning(Tcl_GetString(Tcl_GetObjResult(interp)),







|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
    if (!is.tty) {
	struct stat st;

	nullStdin = fstat(0, &st) || (S_ISCHR(st.st_mode) && !st.st_blocks);
    }
#endif
    Tcl_SetVar2Ex(interp, "tcl_interactive", NULL,
	    Tcl_NewBooleanObj(!path && (is.tty || nullStdin)), TCL_GLOBAL_ONLY);

    /*
     * Invoke application-specific initialization.
     */

    if (appInitProc(interp) != TCL_OK) {
	TkpDisplayWarning(Tcl_GetString(Tcl_GetObjResult(interp)),
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413

414
415
416
417
418






419
420
421
422

423
424
425
426
427
428
429
 *	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)) {







|
|



|



>

|

|

>
>
>
>
>
>

<
<

>







405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433


434
435
436
437
438
439
440
441
442
 *	Could be almost arbitrary, depending on the command that's typed.
 *
 *----------------------------------------------------------------------
 */

static void
StdinProc(
    void *clientData,	/* The state of interactive cmd line */
    int mask)			/* Not used. */
{
    char *cmd;
    int code;
    int length;
    InteractiveState *isPtr = (InteractiveState *)clientData;
    Tcl_Channel chan = isPtr->input;
    Tcl_Interp *interp = isPtr->interp;
    (void)mask;

    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), -1);
    cmd = Tcl_DStringAppend(&isPtr->command, "\n", -1);
    Tcl_DStringFree(&isPtr->line);
    if (!Tcl_CommandComplete(cmd)) {
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452

453
454


455
456



457









458
459
460
461
462
463
464
     * 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:







<
|
|
|


<
|
|
>
|
|
>
>
|
|
>
>
>
|
>
>
>
>
>
>
>
>
>







450
451
452
453
454
455
456

457
458
459
460
461

462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
     * otherwise if the command re-enters the event loop we might process
     * commands from stdin before the current command is finished. Among other
     * things, this will trash the text of the command being evaluated.
     */

    Tcl_CreateChannelHandler(chan, 0, StdinProc, isPtr);
    code = Tcl_RecordAndEval(interp, cmd, TCL_EVAL_GLOBAL);

    isPtr->input = 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) {







<
|
|
|
|
|
>







532
533
534
535
536
537
538

539
540
541
542
543
544
545
546
547
548
549
550
551
	    }
	}
    } else {
	code = Tcl_EvalObjEx(interp, promptCmdPtr, TCL_EVAL_GLOBAL);
	if (code != TCL_OK) {
	    Tcl_AddErrorInfo(interp,
		    "\n    (script that generates prompt)");

	    chan = Tcl_GetStdChannel(TCL_STDERR);
	    if (chan != NULL) {
	    if (Tcl_WriteObj(chan, Tcl_GetObjResult(interp)) < 0) {
		Tcl_WriteChars(chan, ENCODING_ERROR, -1);
	    }
		Tcl_WriteChars(chan, "\n", 1);
	    }
	    goto defaultPrompt;
	}
    }

    chan = Tcl_GetStdChannel(TCL_STDOUT);
    if (chan != NULL) {
Changes to generic/tkMenu.c.
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316

static const char *const menuStateStrings[] = {"active", "normal", "disabled", NULL};

static const char *const menuEntryTypeStrings[] = {
    "cascade", "checkbutton", "command", "radiobutton", "separator", NULL
};

/*
 * The following table defines the legal values for the -compound option. It
 * is used with the "enum compound" declaration in tkMenu.h
 */

static const char *const compoundStrings[] = {
    "bottom", "center", "left", "none", "right", "top", NULL
};

static const Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_BG, offsetof(TkMenuEntry, activeBorderPtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_FG,
	offsetof(TkMenuEntry, activeFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-accelerator", NULL, NULL,
	DEF_MENU_ENTRY_ACCELERATOR,
	offsetof(TkMenuEntry, accelPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BITMAP, "-bitmap", NULL, NULL,
	DEF_MENU_ENTRY_BITMAP,
	offsetof(TkMenuEntry, bitmapPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-columnbreak", NULL, NULL,
	DEF_MENU_ENTRY_COLUMN_BREAK,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, columnBreak), 0, NULL, 0},
    {TK_OPTION_STRING, "-command", NULL, NULL,
	DEF_MENU_ENTRY_COMMAND,
	offsetof(TkMenuEntry, commandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_MENU_ENTRY_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuEntry, compound), 0,
	(ClientData) compoundStrings, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	DEF_MENU_ENTRY_FONT,
	offsetof(TkMenuEntry, fontPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	DEF_MENU_ENTRY_FG,
	offsetof(TkMenuEntry, fgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL,
	DEF_MENU_ENTRY_HIDE_MARGIN,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, hideMargin), 0, NULL, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	DEF_MENU_ENTRY_IMAGE,
	offsetof(TkMenuEntry, imagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-label", NULL, NULL,
	DEF_MENU_ENTRY_LABEL,
	offsetof(TkMenuEntry, labelPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, state), 0,
	(ClientData) menuStateStrings, 0},
    {TK_OPTION_INT, "-underline", NULL, NULL,
	DEF_MENU_ENTRY_UNDERLINE, TCL_INDEX_NONE, offsetof(TkMenuEntry, underline), 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkCheckButtonEntryConfigSpecs[] = {
    {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, indicatorOn), 0, NULL, 0},
    {TK_OPTION_STRING, "-offvalue", NULL, NULL,
	DEF_MENU_ENTRY_OFF_VALUE,
	offsetof(TkMenuEntry, offValuePtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING, "-onvalue", NULL, NULL,
	DEF_MENU_ENTRY_ON_VALUE,
	offsetof(TkMenuEntry, onValuePtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	offsetof(TkMenuEntry, indicatorFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	offsetof(TkMenuEntry, selectImagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_CHECK_VARIABLE,
	offsetof(TkMenuEntry, namePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = {
    {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	TCL_INDEX_NONE, offsetof(TkMenuEntry, indicatorOn), 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	offsetof(TkMenuEntry, indicatorFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	offsetof(TkMenuEntry, selectImagePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-value", NULL, NULL,
	DEF_MENU_ENTRY_VALUE,
	offsetof(TkMenuEntry, onValuePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_RADIO_VARIABLE,
	offsetof(TkMenuEntry, namePtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkCascadeEntryConfigSpecs[] = {
    {TK_OPTION_STRING, "-menu", NULL, NULL,
	DEF_MENU_ENTRY_MENU,
	offsetof(TkMenuEntry, namePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkTearoffEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	offsetof(TkMenuEntry, borderPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE, TCL_INDEX_NONE, offsetof(TkMenuEntry, state), 0,
	(ClientData) menuStateStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec *specsArray[] = {
    tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs,
    tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs,
    tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs
};

/*
 * Menu type strings for use with Tcl_GetIndexFromObj.
 */

static const char *const menuTypeStrings[] = {
    "normal", "tearoff", "menubar", NULL
};

static const Tk_OptionSpec tkMenuConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground",
	"Foreground", DEF_MENU_ACTIVE_BG_COLOR,
	offsetof(TkMenu, activeBorderPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_ACTIVE_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth",
	"BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH,
	offsetof(TkMenu, activeBorderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground",
	"Background", DEF_MENU_ACTIVE_FG_COLOR,
	offsetof(TkMenu, activeFgPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_ACTIVE_FG_MONO, 0},
    {TK_OPTION_RELIEF, "-activerelief", "activeRelief", "Relief",
	DEF_MENU_ACTIVE_RELIEF, offsetof(TkMenu, activeReliefPtr),
	TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENU_BG_COLOR, offsetof(TkMenu, borderPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENU_BORDER_WIDTH,
	offsetof(TkMenu, borderWidthPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENU_CURSOR,
	offsetof(TkMenu, cursorPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENU_DISABLED_FG_COLOR,
	offsetof(TkMenu, disabledFgPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK,
	(ClientData) DEF_MENU_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL,
	NULL, 0, TCL_INDEX_NONE, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENU_FONT, offsetof(TkMenu, fontPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENU_FG, offsetof(TkMenu, fgPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_STRING, "-postcommand", "postCommand", "Command",
	DEF_MENU_POST_COMMAND,
	offsetof(TkMenu, postCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENU_RELIEF, offsetof(TkMenu, reliefPtr), TCL_INDEX_NONE, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background",
	DEF_MENU_SELECT_COLOR, offsetof(TkMenu, indicatorFgPtr), TCL_INDEX_NONE, 0,
	(ClientData) DEF_MENU_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENU_TAKE_FOCUS,
	offsetof(TkMenu, takeFocusPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff",
	DEF_MENU_TEAROFF, TCL_INDEX_NONE, offsetof(TkMenu, tearoff), 0, NULL, 0},
    {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand",
	"TearOffCommand", DEF_MENU_TEAROFF_CMD,
	offsetof(TkMenu, tearoffCommandPtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-title", "title", "Title",
	DEF_MENU_TITLE,	 offsetof(TkMenu, titlePtr), TCL_INDEX_NONE,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-type", "type", "Type",
	DEF_MENU_TYPE, offsetof(TkMenu, menuTypePtr), TCL_INDEX_NONE, TK_OPTION_NULL_OK,
	(ClientData) menuTypeStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

/*
 * Command line options. Put here because MenuCmd has to look at them along
 * with MenuWidgetObjCmd.
 */







<
<
<
<
<
<
<
<
<


|



|


|


|


|


|


|

|
|


|


|


|


|


|


|
|

|






|






|


|


|


|


|


|

|





|


|


|


|


|

|





|

|





|

|
|




















|



|


|

<
<
<

|


|

|


|


|


|


|

|

|


|

|

|



|

|


|

|


|
|







103
104
105
106
107
108
109









110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252



253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304

static const char *const menuStateStrings[] = {"active", "normal", "disabled", NULL};

static const char *const menuEntryTypeStrings[] = {
    "cascade", "checkbutton", "command", "radiobutton", "separator", NULL
};










static const Tk_OptionSpec tkBasicMenuEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_BG, Tk_Offset(TkMenuEntry, activeBorderPtr), -1,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", NULL, NULL,
	DEF_MENU_ENTRY_ACTIVE_FG,
	Tk_Offset(TkMenuEntry, activeFgPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-accelerator", NULL, NULL,
	DEF_MENU_ENTRY_ACCELERATOR,
	Tk_Offset(TkMenuEntry, accelPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BITMAP, "-bitmap", NULL, NULL,
	DEF_MENU_ENTRY_BITMAP,
	Tk_Offset(TkMenuEntry, bitmapPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-columnbreak", NULL, NULL,
	DEF_MENU_ENTRY_COLUMN_BREAK,
	-1, Tk_Offset(TkMenuEntry, columnBreak), 0, NULL, 0},
    {TK_OPTION_STRING, "-command", NULL, NULL,
	DEF_MENU_ENTRY_COMMAND,
	Tk_Offset(TkMenuEntry, commandPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_MENU_ENTRY_COMPOUND, -1, Tk_Offset(TkMenuEntry, compound), 0,
	tkCompoundStrings, 0},
    {TK_OPTION_FONT, "-font", NULL, NULL,
	DEF_MENU_ENTRY_FONT,
	Tk_Offset(TkMenuEntry, fontPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", NULL, NULL,
	DEF_MENU_ENTRY_FG,
	Tk_Offset(TkMenuEntry, fgPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-hidemargin", NULL, NULL,
	DEF_MENU_ENTRY_HIDE_MARGIN,
	-1, Tk_Offset(TkMenuEntry, hideMargin), 0, NULL, 0},
    {TK_OPTION_STRING, "-image", NULL, NULL,
	DEF_MENU_ENTRY_IMAGE,
	Tk_Offset(TkMenuEntry, imagePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-label", NULL, NULL,
	DEF_MENU_ENTRY_LABEL,
	Tk_Offset(TkMenuEntry, labelPtr), -1, 0, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE,
	-1, Tk_Offset(TkMenuEntry, state),
	0, menuStateStrings, 0},
    {TK_OPTION_INT, "-underline", NULL, NULL,
	DEF_MENU_ENTRY_UNDERLINE, -1, Tk_Offset(TkMenuEntry, underline), 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkSeparatorEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec tkCheckButtonEntryConfigSpecs[] = {
    {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	-1, Tk_Offset(TkMenuEntry, indicatorOn), 0, NULL, 0},
    {TK_OPTION_STRING, "-offvalue", NULL, NULL,
	DEF_MENU_ENTRY_OFF_VALUE,
	Tk_Offset(TkMenuEntry, offValuePtr), -1, 0, NULL, 0},
    {TK_OPTION_STRING, "-onvalue", NULL, NULL,
	DEF_MENU_ENTRY_ON_VALUE,
	Tk_Offset(TkMenuEntry, onValuePtr), -1, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_CHECK_VARIABLE,
	Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, -1, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkRadioButtonEntryConfigSpecs[] = {
    {TK_OPTION_BOOLEAN, "-indicatoron", NULL, NULL,
	DEF_MENU_ENTRY_INDICATOR,
	-1, Tk_Offset(TkMenuEntry, indicatorOn), 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", NULL, NULL,
	DEF_MENU_ENTRY_SELECT,
	Tk_Offset(TkMenuEntry, indicatorFgPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-selectimage", NULL, NULL,
	DEF_MENU_ENTRY_SELECT_IMAGE,
	Tk_Offset(TkMenuEntry, selectImagePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-value", NULL, NULL,
	DEF_MENU_ENTRY_VALUE,
	Tk_Offset(TkMenuEntry, onValuePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-variable", NULL, NULL,
	DEF_MENU_ENTRY_RADIO_VARIABLE,
	Tk_Offset(TkMenuEntry, namePtr), -1, 0, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, -1, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkCascadeEntryConfigSpecs[] = {
    {TK_OPTION_STRING, "-menu", NULL, NULL,
	DEF_MENU_ENTRY_MENU,
	Tk_Offset(TkMenuEntry, namePtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_END, NULL, NULL, NULL,
	NULL, 0, -1, 0, tkBasicMenuEntryConfigSpecs, 0}
};

static const Tk_OptionSpec tkTearoffEntryConfigSpecs[] = {
    {TK_OPTION_BORDER, "-background", NULL, NULL,
	DEF_MENU_ENTRY_BG,
	Tk_Offset(TkMenuEntry, borderPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-state", NULL, NULL,
	DEF_MENU_ENTRY_STATE, -1, Tk_Offset(TkMenuEntry, state),
	0, menuStateStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

static const Tk_OptionSpec *specsArray[] = {
    tkCascadeEntryConfigSpecs, tkCheckButtonEntryConfigSpecs,
    tkBasicMenuEntryConfigSpecs, tkRadioButtonEntryConfigSpecs,
    tkSeparatorEntryConfigSpecs, tkTearoffEntryConfigSpecs
};

/*
 * Menu type strings for use with Tcl_GetIndexFromObj.
 */

static const char *const menuTypeStrings[] = {
    "normal", "tearoff", "menubar", NULL
};

static const Tk_OptionSpec tkMenuConfigSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground",
	"Foreground", DEF_MENU_ACTIVE_BG_COLOR,
	Tk_Offset(TkMenu, activeBorderPtr), -1, 0,
	(ClientData) DEF_MENU_ACTIVE_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-activeborderwidth", "activeBorderWidth",
	"BorderWidth", DEF_MENU_ACTIVE_BORDER_WIDTH,
	Tk_Offset(TkMenu, activeBorderWidthPtr), -1, 0, NULL, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground",
	"Background", DEF_MENU_ACTIVE_FG_COLOR,
	Tk_Offset(TkMenu, activeFgPtr), -1, 0,
	(ClientData) DEF_MENU_ACTIVE_FG_MONO, 0},



    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENU_BG_COLOR, Tk_Offset(TkMenu, borderPtr), -1, 0,
	(ClientData) DEF_MENU_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENU_BORDER_WIDTH,
	Tk_Offset(TkMenu, borderWidthPtr), -1, 0, NULL, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENU_CURSOR,
	Tk_Offset(TkMenu, cursorPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENU_DISABLED_FG_COLOR,
	Tk_Offset(TkMenu, disabledFgPtr), -1, TK_OPTION_NULL_OK,
	(ClientData) DEF_MENU_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL,
	NULL, 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENU_FONT, Tk_Offset(TkMenu, fontPtr), -1, 0, NULL, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENU_FG, Tk_Offset(TkMenu, fgPtr), -1, 0, NULL, 0},
    {TK_OPTION_STRING, "-postcommand", "postCommand", "Command",
	DEF_MENU_POST_COMMAND,
	Tk_Offset(TkMenu, postCommandPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENU_RELIEF, Tk_Offset(TkMenu, reliefPtr), -1, 0, NULL, 0},
    {TK_OPTION_COLOR, "-selectcolor", "selectColor", "Background",
	DEF_MENU_SELECT_COLOR, Tk_Offset(TkMenu, indicatorFgPtr), -1, 0,
	(ClientData) DEF_MENU_SELECT_MONO, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENU_TAKE_FOCUS,
	Tk_Offset(TkMenu, takeFocusPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_BOOLEAN, "-tearoff", "tearOff", "TearOff",
	DEF_MENU_TEAROFF, -1, Tk_Offset(TkMenu, tearoff), 0, NULL, 0},
    {TK_OPTION_STRING, "-tearoffcommand", "tearOffCommand",
	"TearOffCommand", DEF_MENU_TEAROFF_CMD,
	Tk_Offset(TkMenu, tearoffCommandPtr), -1, TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING, "-title", "title", "Title",
	DEF_MENU_TITLE,	 Tk_Offset(TkMenu, titlePtr), -1,
	TK_OPTION_NULL_OK, NULL, 0},
    {TK_OPTION_STRING_TABLE, "-type", "type", "Type",
	DEF_MENU_TYPE, Tk_Offset(TkMenu, menuTypePtr), -1,
	0, menuTypeStrings, 0},
    {TK_OPTION_END, NULL, NULL, NULL, 0, 0, 0, 0, NULL, 0}
};

/*
 * Command line options. Put here because MenuCmd has to look at them along
 * with MenuWidgetObjCmd.
 */
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
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.
 */








|
|

|








|










|
<
<







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359


360
361
362
363
364
365
366
static int		ConfigureMenuEntry(TkMenuEntry *mePtr,
			    int objc, Tcl_Obj *const objv[]);
static void		DeleteMenuCloneEntries(TkMenu *menuPtr,
			    int first, int last);
static void		DestroyMenuHashTable(ClientData clientData,
			    Tcl_Interp *interp);
static void		DestroyMenuInstance(TkMenu *menuPtr);
static Tcl_FreeProc	DestroyMenuEntry;
static int		GetIndexFromCoords(Tcl_Interp *interp,
			    TkMenu *menuPtr, const char *string,
			    int *indexPtr);
static int		MenuDoYPosition(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *objPtr);
static int		MenuDoXPosition(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *objPtr);
static int		MenuAddOrInsert(Tcl_Interp *interp,
			    TkMenu *menuPtr, Tcl_Obj *indexPtr, int objc,
			    Tcl_Obj *const objv[]);
static void		MenuCmdDeletedProc(ClientData clientData);
static TkMenuEntry *	MenuNewEntry(TkMenu *menuPtr, int index, int type);
static char *		MenuVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static int		MenuWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		MenuWorldChanged(ClientData instanceData);
static int		PostProcessEntry(TkMenuEntry *mePtr);
static void		RecursivelyDeleteMenu(TkMenu *menuPtr);
static void		UnhookCascadeEntry(TkMenuEntry *mePtr);
static void		TkMenuCleanup(ClientData unused);



/*
 * The structure below is a list of procs that respond to certain window
 * manager events. One of these includes a font change, which forces the
 * geometry proc to be called.
 */

409
410
411
412
413
414
415

416
417
418
419
420
421
422
423
    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 ...?");







>
|







395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    Tk_Window newWin;
    TkMenu *menuPtr;
    TkMenuReferences *menuRefPtr;
    int i;
    int index, toplevel;
    const char *windowName;
    static const char *const typeStringList[] = {"-type", NULL};
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
    memset(menuPtr, 0, sizeof(TkMenu));
    menuPtr->tkwin = newWin;
    menuPtr->display = Tk_Display(newWin);
    menuPtr->interp = interp;
    menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr,
	    MenuCmdDeletedProc);
    menuPtr->active = TCL_INDEX_NONE;
    menuPtr->cursorPtr = NULL;
    menuPtr->mainMenuPtr = menuPtr;
    menuPtr->menuType = UNKNOWN_TYPE;
    TkMenuInitializeDrawingFields(menuPtr);

    Tk_SetClass(menuPtr->tkwin, "Menu");
    Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr);
    Tk_CreateEventHandler(newWin,
	    ExposureMask|StructureNotifyMask|ActivateMask,
	    TkMenuEventProc, menuPtr);
    if (Tk_InitOptions(interp, menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin)
	    != TCL_OK) {
    	Tk_DestroyWindow(menuPtr->tkwin);
    	return TCL_ERROR;
    }









|

|








|







442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    memset(menuPtr, 0, sizeof(TkMenu));
    menuPtr->tkwin = newWin;
    menuPtr->display = Tk_Display(newWin);
    menuPtr->interp = interp;
    menuPtr->widgetCmd = Tcl_CreateObjCommand(interp,
	    Tk_PathName(menuPtr->tkwin), MenuWidgetObjCmd, menuPtr,
	    MenuCmdDeletedProc);
    menuPtr->active = -1;
    menuPtr->cursorPtr = NULL;
    menuPtr->masterMenuPtr = menuPtr;
    menuPtr->menuType = UNKNOWN_TYPE;
    TkMenuInitializeDrawingFields(menuPtr);

    Tk_SetClass(menuPtr->tkwin, "Menu");
    Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr);
    Tk_CreateEventHandler(newWin,
	    ExposureMask|StructureNotifyMask|ActivateMask,
	    TkMenuEventProc, menuPtr);
    if (Tk_InitOptions(interp, (char *) menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin)
	    != TCL_OK) {
    	Tk_DestroyWindow(menuPtr->tkwin);
    	return TCL_ERROR;
    }


522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
	     * points to this menu in a cascade entry, we have to clone the
	     * new menu and point the entry to the clone instead of the menu
	     * we are creating. Otherwise, ConfigureMenuEntry will hook up the
	     * platform-specific cascade linkages now that the menu we are
	     * creating exists.
     	     */

     	    if ((menuPtr->mainMenuPtr != menuPtr)
     	    	    || ((menuPtr->mainMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->mainMenuPtr
		    == cascadeListPtr->menuPtr)))) {
		newObjv[0] = Tcl_NewStringObj("-menu", -1);
		newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin),-1);
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
     	    	ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);







|
|
|







509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
	     * points to this menu in a cascade entry, we have to clone the
	     * new menu and point the entry to the clone instead of the menu
	     * we are creating. Otherwise, ConfigureMenuEntry will hook up the
	     * platform-specific cascade linkages now that the menu we are
	     * creating exists.
     	     */

     	    if ((menuPtr->masterMenuPtr != menuPtr)
     	    	    || ((menuPtr->masterMenuPtr == menuPtr)
     	    	    && ((cascadeListPtr->menuPtr->masterMenuPtr
		    == cascadeListPtr->menuPtr)))) {
		newObjv[0] = Tcl_NewStringObj("-menu", -1);
		newObjv[1] = Tcl_NewStringObj(Tk_PathName(menuPtr->tkwin),-1);
		Tcl_IncrRefCount(newObjv[0]);
		Tcl_IncrRefCount(newObjv[1]);
     	    	ConfigureMenuEntry(cascadeListPtr, 2, newObjv);
		Tcl_DecrRefCount(newObjv[0]);
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
    	    listtkwin = topLevelListPtr->tkwin;
    	    TkSetWindowMenuBar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(menuPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuWidgetObjCmd --







|







576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
    	    listtkwin = topLevelListPtr->tkwin;
    	    TkSetWindowMenuBar(menuPtr->interp, listtkwin,
    	    	    Tk_PathName(menuPtr->tkwin), Tk_PathName(menuPtr->tkwin));
    	    topLevelListPtr = nextPtr;
    	}
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(menuPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuWidgetObjCmd --
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
	    sizeof(char *), "option", 0, &option) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_Preserve(menuPtr);

    switch ((enum options) option) {
    case MENU_ACTIVATE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (menuPtr->active == index) {
	    goto done;
	}
	if ((index != TCL_INDEX_NONE) && ((menuPtr->entries[index]->type==SEPARATOR_ENTRY)
		|| (menuPtr->entries[index]->state == ENTRY_DISABLED))) {
	    index = TCL_INDEX_NONE;
	}
	result = TkActivateMenuEntry(menuPtr, index);
	break;
    }
    case MENU_ADD:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type ?-option value ...?");







|





|





|

|







624
625
626
627
628
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: {
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (menuPtr->active == index) {
	    goto done;
	}
	if ((index >= 0) && ((menuPtr->entries[index]->type==SEPARATOR_ENTRY)
		|| (menuPtr->entries[index]->state == ENTRY_DISABLED))) {
	    index = -1;
	}
	result = TkActivateMenuEntry(menuPtr, index);
	break;
    }
    case MENU_ADD:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "type ?-option value ...?");
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849

850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
    case MENU_CGET: {
	Tcl_Obj *resultPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}
	resultPtr = Tk_GetOptionValue(interp, menuPtr,
		tsdPtr->menuOptionTable, objv[2],
		menuPtr->tkwin);
	if (resultPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case MENU_CLONE:
	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "newMenuName ?menuType?");
	    goto error;
	}
	result = CloneMenu(menuPtr, objv[2], (objc == 3) ? NULL : objv[3]);
	break;
    case MENU_CONFIGURE: {
	Tcl_Obj *resultPtr;

	if (objc == 2) {
	    resultPtr = Tk_GetOptionInfo(interp, menuPtr,
		    tsdPtr->menuOptionTable, NULL,
		    menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, menuPtr,
		    tsdPtr->menuOptionTable, objv[2],
		    menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenu(interp, menuPtr, objc - 2, objv + 2);
	}
	if (result != TCL_OK) {
	    goto error;
	}
	break;
    }
    case MENU_DELETE: {
	TkSizeT first, last;
	Tcl_WideInt w;

	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "first ?last?");
	    goto error;
	}

	/*
	 * If 'first' explicitly refers to past the end of the menu, we don't
	 * do anything. [Bug 220950]
	 */

	if (isdigit(UCHAR(Tcl_GetString(objv[2])[0]))
		&& Tcl_GetWideIntFromObj(NULL, objv[2], &w) == TCL_OK) {
	    first = w;
	    if (first >= menuPtr->numEntries) {
		goto done;
	    }
	} else if (GetMenuIndex(interp,menuPtr,objv[2],0,&first) != TCL_OK){
	    goto error;
	}
	if (objc == 3) {
	    last = first;
	} else if (GetMenuIndex(interp,menuPtr,objv[3],0,&last) != TCL_OK) {
	    goto error;
	}

	if (menuPtr->tearoff && (first == 0)) {
	    /*
	     * Sorry, can't delete the tearoff entry; must reconfigure the
	     * menu.
	     */

	    first = 1;
	}
	if ((first == TCL_INDEX_NONE) || (last < first)) {
	    goto done;
	}
	DeleteMenuCloneEntries(menuPtr, first, last);
	break;
    }
    case MENU_ENTRYCGET: {
	TkSizeT index;
	Tcl_Obj *resultPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index option");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	resultPtr = Tk_GetOptionValue(interp, mePtr,
		mePtr->optionTable, objv[3], menuPtr->tkwin);
	Tcl_Release(mePtr);
	if (resultPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case MENU_ENTRYCONFIGURE: {
	TkSizeT index;
	Tcl_Obj *resultPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?-option value ...?");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, mePtr,
		    mePtr->optionTable, NULL, menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else if (objc == 4) {
	    resultPtr = Tk_GetOptionInfo(interp, mePtr,
		    mePtr->optionTable, objv[3], menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenuCloneEntries(interp, menuPtr, index,
		    objc-3, objv+3);
	}
	Tcl_Release(mePtr);
	break;
    }
    case MENU_INDEX: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
	} else
	Tcl_SetObjResult(interp, TkNewIndexObj(index));

	break;
    }
    case MENU_INSERT:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index type ?-option value ...?");
	    goto error;
	}
	if (MenuAddOrInsert(interp,menuPtr,objv[2],objc-3,objv+3) != TCL_OK) {
	    goto error;
	}
	break;
    case MENU_INVOKE: {
	TkSizeT index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (GetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index == TCL_INDEX_NONE) {
	    goto done;
	}
	result = TkInvokeMenu(interp, menuPtr, index);
	break;
    }
    case MENU_POST: {
	int x, y;
	TkSizeT index = TCL_INDEX_NONE;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?index?");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    goto error;
	}
	if (objc == 5) {
            if (GetMenuIndex(interp, menuPtr, objv[4], 0, &index) != TCL_OK) {
                goto error;
            }
	}

	/*
	 * Tearoff menus are the same as ordinary menus on the Mac and are
	 * posted differently on Windows than non-tearoffs. TkpPostMenu







|



















|









|

















|
<












|
<



|




|











|






|






|


|




|









|






|


|





|








|















|





|


|

|
|
>













|





|


|







|










|







660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715

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

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
    case MENU_CGET: {
	Tcl_Obj *resultPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    goto error;
	}
	resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr,
		tsdPtr->menuOptionTable, objv[2],
		menuPtr->tkwin);
	if (resultPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case MENU_CLONE:
	if ((objc < 3) || (objc > 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "newMenuName ?menuType?");
	    goto error;
	}
	result = CloneMenu(menuPtr, objv[2], (objc == 3) ? NULL : objv[3]);
	break;
    case MENU_CONFIGURE: {
	Tcl_Obj *resultPtr;

	if (objc == 2) {
	    resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
		    tsdPtr->menuOptionTable, NULL,
		    menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr,
		    tsdPtr->menuOptionTable, objv[2],
		    menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenu(interp, menuPtr, objc - 2, objv + 2);
	}
	if (result != TCL_OK) {
	    goto error;
	}
	break;
    }
    case MENU_DELETE: {
	int first, last;


	if ((objc != 3) && (objc != 4)) {
	    Tcl_WrongNumArgs(interp, 2, objv, "first ?last?");
	    goto error;
	}

	/*
	 * If 'first' explicitly refers to past the end of the menu, we don't
	 * do anything. [Bug 220950]
	 */

	if (isdigit(UCHAR(Tcl_GetString(objv[2])[0]))
		&& Tcl_GetIntFromObj(NULL, objv[2], &first) == TCL_OK) {

	    if (first >= menuPtr->numEntries) {
		goto done;
	    }
	} else if (TkGetMenuIndex(interp,menuPtr,objv[2],0,&first) != TCL_OK){
	    goto error;
	}
	if (objc == 3) {
	    last = first;
	} else if (TkGetMenuIndex(interp,menuPtr,objv[3],0,&last) != TCL_OK) {
	    goto error;
	}

	if (menuPtr->tearoff && (first == 0)) {
	    /*
	     * Sorry, can't delete the tearoff entry; must reconfigure the
	     * menu.
	     */

	    first = 1;
	}
	if ((first == -1) || (last < first)) {
	    goto done;
	}
	DeleteMenuCloneEntries(menuPtr, first, last);
	break;
    }
    case MENU_ENTRYCGET: {
	int index;
	Tcl_Obj *resultPtr;

	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index option");
	    goto error;
	}
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	resultPtr = Tk_GetOptionValue(interp, (char *) mePtr,
		mePtr->optionTable, objv[3], menuPtr->tkwin);
	Tcl_Release(mePtr);
	if (resultPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, resultPtr);
	break;
    }
    case MENU_ENTRYCONFIGURE: {
	int index;
	Tcl_Obj *resultPtr;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index ?-option value ...?");
	    goto error;
	}
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	mePtr = menuPtr->entries[index];
	Tcl_Preserve(mePtr);
	if (objc == 3) {
	    resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr,
		    mePtr->optionTable, NULL, menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else if (objc == 4) {
	    resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr,
		    mePtr->optionTable, objv[3], menuPtr->tkwin);
	    if (resultPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		result = TCL_OK;
		Tcl_SetObjResult(interp, resultPtr);
	    }
	} else {
	    result = ConfigureMenuCloneEntries(interp, menuPtr, index,
		    objc-3, objv+3);
	}
	Tcl_Release(mePtr);
	break;
    }
    case MENU_INDEX: {
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "string");
	    goto error;
	}
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    Tcl_SetObjResult(interp, Tcl_NewStringObj("none", -1));
	} else {
	    Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
	}
	break;
    }
    case MENU_INSERT:
	if (objc < 4) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "index type ?-option value ...?");
	    goto error;
	}
	if (MenuAddOrInsert(interp,menuPtr,objv[2],objc-3,objv+3) != TCL_OK) {
	    goto error;
	}
	break;
    case MENU_INVOKE: {
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	result = TkInvokeMenu(interp, menuPtr, index);
	break;
    }
    case MENU_POST: {
	int x, y;
	int index = -1;

	if (objc != 4 && objc != 5) {
	    Tcl_WrongNumArgs(interp, 2, objv, "x y ?index?");
	    goto error;
	}
	if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK)
		|| (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) {
	    goto error;
	}
	if (objc == 5) {
            if (TkGetMenuIndex(interp, menuPtr, objv[4], 0, &index) != TCL_OK) {
                goto error;
            }
	}

	/*
	 * Tearoff menus are the same as ordinary menus on the Mac and are
	 * posted differently on Windows than non-tearoffs. TkpPostMenu
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
	    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];
	}







|






|


|







|






|


|







894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
	    result = TkpPostMenu(interp, menuPtr, x, y, index);
	} else {
	    result = TkpPostTearoffMenu(interp, menuPtr, x, y, index);
	}
	break;
    }
    case MENU_POSTCASCADE: {
	int index;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}

	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if ((index < 0) || (menuPtr->entries[index]->type != CASCADE_ENTRY)) {
	    result = TkPostSubmenu(interp, menuPtr, NULL);
	} else {
	    result = TkPostSubmenu(interp, menuPtr, menuPtr->entries[index]);
	}
	break;
    }
    case MENU_TYPE: {
	int index;
	const char *typeStr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "index");
	    goto error;
	}
	if (TkGetMenuIndex(interp, menuPtr, objv[2], 0, &index) != TCL_OK) {
	    goto error;
	}
	if (index < 0) {
	    goto done;
	}
	if (menuPtr->entries[index]->type == TEAROFF_ENTRY) {
	    typeStr = "tearoff";
	} else {
	    typeStr = menuEntryTypeStrings[menuPtr->entries[index]->type];
	}
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007




1008
1009
1010
1011
1012

1013
1014
1015
1016
1017
1018
1019
1020
1021











1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077

1078

1079
1080
1081
1082
1083
1084
1085
 *	associated with that index.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Commands may get excecuted; variables may get set; sub-menus may get
 *	posted.
 *
 *----------------------------------------------------------------------
 */

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;
	} else {
	    valuePtr = mePtr->onValuePtr;
	}
	if (valuePtr == NULL) {
	    valuePtr = Tcl_NewObj();
	}
	Tcl_IncrRefCount(valuePtr);
	if (Tcl_ObjSetVar2(interp, mePtr->namePtr, NULL, valuePtr,
		TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(valuePtr);
    } else if ((mePtr->type == RADIO_BUTTON_ENTRY)
	    && (mePtr->namePtr != NULL)) {
	Tcl_Obj *valuePtr = mePtr->onValuePtr;

	if (valuePtr == NULL) {
	    valuePtr = Tcl_NewObj();
	}
	Tcl_IncrRefCount(valuePtr);
	if (Tcl_ObjSetVar2(interp, mePtr->namePtr, NULL, valuePtr,
		TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(valuePtr);
    }

    /*
     * We check numEntries in addition to whether the menu entry has a command
     * because that goes to zero if the menu gets deleted (e.g., during
     * command evaluation).
     */

    if ((menuPtr->numEntries != 0) && (result == TCL_OK)
	    && (mePtr->commandPtr != NULL)) {
	Tcl_Obj *commandPtr = mePtr->commandPtr;

	Tcl_IncrRefCount(commandPtr);
	result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL);
	Tcl_DecrRefCount(commandPtr);
    }

    Tcl_Release(mePtr);


  done:
    return result;
}

/*
 *----------------------------------------------------------------------







|








>
>
>
>
|




>

|







>
>
>
>
>
>
>
>
>
>
>
|









|











|





|






|













|
|
|
|
<


>
|
>







978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
 *	associated with that index.
 *
 * Results:
 *	Standard Tcl result.
 *
 * Side effects:
 *	Commands may get excecuted; variables may get set; sub-menus may get
 *	posted, the passed menu may be destroyed.
 *
 *----------------------------------------------------------------------
 */

int
TkInvokeMenu(
    Tcl_Interp *interp,		/* The interp that the menu lives in. */
    TkMenu *menuPtr,		/* The menu we are invoking. */
				/* Must be protected by Tcl_Preserve
				 * against freeing by the caller.
				 * Tk Bug [2d3a81c0].
				 */
    int index)			/* The zero based index of the item we are
    				 * invoking. */
{
    int result = TCL_OK;
    TkMenuEntry *mePtr;
    Tcl_Obj *commandPtr = NULL, *namePtr = NULL;

    if (index < 0) {
    	goto done;
    }
    mePtr = menuPtr->entries[index];
    if (mePtr->state == ENTRY_DISABLED) {
	goto done;
    }

    if (mePtr->commandPtr != NULL) {
	commandPtr = mePtr->commandPtr;
	Tcl_IncrRefCount(commandPtr);
    }
    if ((mePtr->type == CHECK_BUTTON_ENTRY) ||
	    (mePtr->type == RADIO_BUTTON_ENTRY)) {
	if (mePtr->namePtr != NULL) {
	    namePtr = mePtr->namePtr;
	    Tcl_IncrRefCount(namePtr);
	}
    }

    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)
	    && (namePtr != NULL)) {
	Tcl_Obj *valuePtr;

	if (mePtr->entryFlags & ENTRY_SELECTED) {
	    valuePtr = mePtr->offValuePtr;
	} else {
	    valuePtr = mePtr->onValuePtr;
	}
	if (valuePtr == NULL) {
	    valuePtr = Tcl_NewObj();
	}
	Tcl_IncrRefCount(valuePtr);
	if (Tcl_ObjSetVar2(interp, namePtr, NULL, valuePtr,
		TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(valuePtr);
    } else if ((mePtr->type == RADIO_BUTTON_ENTRY)
	    && (namePtr != NULL)) {
	Tcl_Obj *valuePtr = mePtr->onValuePtr;

	if (valuePtr == NULL) {
	    valuePtr = Tcl_NewObj();
	}
	Tcl_IncrRefCount(valuePtr);
	if (Tcl_ObjSetVar2(interp, namePtr, NULL, valuePtr,
		TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) == NULL) {
	    result = TCL_ERROR;
	}
	Tcl_DecrRefCount(valuePtr);
    }

    /*
     * We check numEntries in addition to whether the menu entry has a command
     * because that goes to zero if the menu gets deleted (e.g., during
     * command evaluation).
     */

    if ((menuPtr->numEntries != 0) && (result == TCL_OK)
	    && (commandPtr != NULL)) {
	result = Tcl_EvalObjEx(interp, commandPtr, TCL_EVAL_GLOBAL);
    }
    if (commandPtr != NULL) {

	Tcl_DecrRefCount(commandPtr);
    }
    if (namePtr != NULL) {
	Tcl_DecrRefCount(namePtr);
    }

  done:
    return result;
}

/*
 *----------------------------------------------------------------------
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
    if (TkFreeMenuReferences(menuPtr->menuRefPtr)) {
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->mainMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);

	    parentMainMenuPtr = cascadePtr->menuPtr->mainMenuPtr;
	    parentMainEntryPtr =
		    parentMainMenuPtr->entries[cascadePtr->index];
	    newObjv[0] = menuNamePtr;
	    newObjv[1] = parentMainEntryPtr->namePtr;

	    /*
	     * It is possible that the menu info is out of sync, and these







|


|







1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
    if (TkFreeMenuReferences(menuPtr->menuRefPtr)) {
	menuPtr->menuRefPtr = NULL;
    }

    for (; cascadePtr != NULL; cascadePtr = nextCascadePtr) {
    	nextCascadePtr = cascadePtr->nextCascadePtr;

    	if (menuPtr->masterMenuPtr != menuPtr) {
	    Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);

	    parentMainMenuPtr = cascadePtr->menuPtr->masterMenuPtr;
	    parentMainEntryPtr =
		    parentMainMenuPtr->entries[cascadePtr->index];
	    newObjv[0] = menuNamePtr;
	    newObjv[1] = parentMainEntryPtr->namePtr;

	    /*
	     * It is possible that the menu info is out of sync, and these
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
		Tcl_DecrRefCount(newObjv[1]);
	    }
    	} else {
    	    ConfigureMenuEntry(cascadePtr, 0, NULL);
    	}
    }

    if (menuPtr->mainMenuPtr != menuPtr) {
	for (menuInstancePtr = menuPtr->mainMenuPtr;
		menuInstancePtr != NULL;
		menuInstancePtr = menuInstancePtr->nextInstancePtr) {
	    if (menuInstancePtr->nextInstancePtr == menuPtr) {
		menuInstancePtr->nextInstancePtr =
			menuInstancePtr->nextInstancePtr->nextInstancePtr;
		break;
	    }







|
|







1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
		Tcl_DecrRefCount(newObjv[1]);
	    }
    	} else {
    	    ConfigureMenuEntry(cascadePtr, 0, NULL);
    	}
    }

    if (menuPtr->masterMenuPtr != menuPtr) {
	for (menuInstancePtr = menuPtr->masterMenuPtr;
		menuInstancePtr != NULL;
		menuInstancePtr = menuInstancePtr->nextInstancePtr) {
	    if (menuInstancePtr->nextInstancePtr == menuPtr) {
		menuInstancePtr->nextInstancePtr =
			menuInstancePtr->nextInstancePtr->nextInstancePtr;
		break;
	    }
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197

1198
1199

1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
	/*
	 * 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.
 *







|


>


>

















<
|
|
|
|







1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221

1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
	/*
	 * As each menu entry is deleted from the end of the array of entries,
	 * decrement menuPtr->numEntries. Otherwise, the act of deleting menu
	 * entry i will dereference freed memory attempting to queue a redraw
	 * for menu entries (i+1)...numEntries.
	 */

	Tcl_EventuallyFree(menuPtr->entries[i], DestroyMenuEntry);
	menuPtr->numEntries = i;
    }
    menuPtr->active = -1;
    if (menuPtr->entries != NULL) {
	ckfree(menuPtr->entries);
	menuPtr->entries = NULL;
    }
    TkMenuFreeDrawOptions(menuPtr);
    Tk_FreeConfigOptions((char *) menuPtr,
	    tsdPtr->menuOptionTable, menuPtr->tkwin);
    if (menuPtr->tkwin != NULL) {
	Tk_Window tkwin = menuPtr->tkwin;

	menuPtr->tkwin = NULL;
	Tk_DestroyWindow(tkwin);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkDestroyMenu --
 *

 *	This function is invoked to clean up the internal structure of a menu
 *	at a safe time (when no-one is using it anymore). If called on a main
 *	instance, destroys all of the instances. If called on a non-main
 *	instance, just destroys that instance.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Everything associated with the menu is freed up.
 *
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
	topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;
	while (topLevelListPtr != NULL) {
	    nextTopLevelPtr = topLevelListPtr->nextPtr;
	    TkpSetWindowMenuBar(topLevelListPtr->tkwin, NULL);
	    topLevelListPtr = nextTopLevelPtr;
	}
    }
    if (menuPtr->mainMenuPtr == menuPtr) {
	while (menuPtr->nextInstancePtr != NULL) {
	    menuInstancePtr = menuPtr->nextInstancePtr;
	    menuPtr->nextInstancePtr = menuInstancePtr->nextInstancePtr;
    	    if (menuInstancePtr->tkwin != NULL) {
		Tk_Window tkwin = menuInstancePtr->tkwin;

		/*







|







1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
	topLevelListPtr = menuPtr->menuRefPtr->topLevelListPtr;
	while (topLevelListPtr != NULL) {
	    nextTopLevelPtr = topLevelListPtr->nextPtr;
	    TkpSetWindowMenuBar(topLevelListPtr->tkwin, NULL);
	    topLevelListPtr = nextTopLevelPtr;
	}
    }
    if (menuPtr->masterMenuPtr == menuPtr) {
	while (menuPtr->nextInstancePtr != NULL) {
	    menuInstancePtr = menuPtr->nextInstancePtr;
	    menuPtr->nextInstancePtr = menuInstancePtr->nextInstancePtr;
    	    if (menuInstancePtr->tkwin != NULL) {
		Tk_Window tkwin = menuInstancePtr->tkwin;

		/*
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
 *	Everything associated with the menu entry is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuEntry(
    void *memPtr)		/* Pointer to entry to be freed. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)memPtr;
    TkMenu *menuPtr = mePtr->menuPtr;

    if (menuPtr->postedCascade == mePtr) {
    	/*
	 * Ignore errors while unposting the menu, since it's possible that
	 * the menu has already been deleted and the unpost will generate an
	 * error.
	 */

	TkPostSubmenu(menuPtr->interp, menuPtr, NULL);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeConfigOptions handle all the standard option-related stuff.
     */

    if (mePtr->type == CASCADE_ENTRY) {
	if (menuPtr->mainMenuPtr != menuPtr) {
	    TkMenu *destroyThis = NULL;
	    TkMenuReferences *menuRefPtr = mePtr->childMenuRefPtr;

	    /*
	     * The menu as a whole is a clone. We must delete the clone of the
	     * cascaded menu for the particular entry we are destroying.
	     */

	    if (menuRefPtr != NULL) {
		destroyThis = menuRefPtr->menuPtr;

		/*
		 * But only if it is a clone. What can happen is that we are
		 * in the middle of deleting a menu and this menu pointer has
		 * already been reset to point to the original menu. In that
		 * case we have nothing special to do.
		 */

		if ((destroyThis != NULL)
			&& (destroyThis->mainMenuPtr == destroyThis)) {
		    destroyThis = NULL;
		}
	    }
	    UnhookCascadeEntry(mePtr);
	    menuRefPtr = mePtr->childMenuRefPtr;
	    if (menuRefPtr != NULL) {
		if (menuRefPtr->menuPtr == destroyThis) {







|




















|



















|







1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
 *	Everything associated with the menu entry is freed.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuEntry(
    char *memPtr)		/* Pointer to entry to be freed. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)memPtr;
    TkMenu *menuPtr = mePtr->menuPtr;

    if (menuPtr->postedCascade == mePtr) {
    	/*
	 * Ignore errors while unposting the menu, since it's possible that
	 * the menu has already been deleted and the unpost will generate an
	 * error.
	 */

	TkPostSubmenu(menuPtr->interp, menuPtr, NULL);
    }

    /*
     * Free up all the stuff that requires special handling, then let
     * Tk_FreeConfigOptions handle all the standard option-related stuff.
     */

    if (mePtr->type == CASCADE_ENTRY) {
	if (menuPtr->masterMenuPtr != menuPtr) {
	    TkMenu *destroyThis = NULL;
	    TkMenuReferences *menuRefPtr = mePtr->childMenuRefPtr;

	    /*
	     * The menu as a whole is a clone. We must delete the clone of the
	     * cascaded menu for the particular entry we are destroying.
	     */

	    if (menuRefPtr != NULL) {
		destroyThis = menuRefPtr->menuPtr;

		/*
		 * But only if it is a clone. What can happen is that we are
		 * in the middle of deleting a menu and this menu pointer has
		 * already been reset to point to the original menu. In that
		 * case we have nothing special to do.
		 */

		if ((destroyThis != NULL)
			&& (destroyThis->masterMenuPtr == destroyThis)) {
		    destroyThis = NULL;
		}
	    }
	    UnhookCascadeEntry(mePtr);
	    menuRefPtr = mePtr->childMenuRefPtr;
	    if (menuRefPtr != NULL) {
		if (menuRefPtr->menuPtr == destroyThis) {
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
 */

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







|







1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
 */

static void
MenuWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    TkMenu *menuPtr = (TkMenu *)instanceData;
    int i;

    TkMenuConfigureDrawOptions(menuPtr);
    for (i = 0; i < menuPtr->numEntries; i++) {
    	TkMenuConfigureEntryDrawOptions(menuPtr->entries[i],
		menuPtr->entries[i]->index);
	TkpConfigureMenuEntry(menuPtr->entries[i]);
    }
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
{
    int i;
    TkMenu *menuListPtr, *cleanupPtr;
    int result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	menuListPtr->errorStructPtr = (Tk_SavedOptions *)ckalloc(sizeof(Tk_SavedOptions));
	result = Tk_SetOptions(interp, menuListPtr,
		tsdPtr->menuOptionTable, objc, objv,
		menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
	if (result != TCL_OK) {
	    for (cleanupPtr = menuPtr->mainMenuPtr;
		    cleanupPtr != menuListPtr;
		    cleanupPtr = cleanupPtr->nextInstancePtr) {
		Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
		ckfree(cleanupPtr->errorStructPtr);
		cleanupPtr->errorStructPtr = NULL;
	    }
	    if (menuListPtr->errorStructPtr != NULL) {







|


|



|







1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
{
    int i;
    TkMenu *menuListPtr, *cleanupPtr;
    int result;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	menuListPtr->errorStructPtr = (Tk_SavedOptions *)ckalloc(sizeof(Tk_SavedOptions));
	result = Tk_SetOptions(interp, (char *) menuListPtr,
		tsdPtr->menuOptionTable, objc, objv,
		menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL);
	if (result != TCL_OK) {
	    for (cleanupPtr = menuPtr->masterMenuPtr;
		    cleanupPtr != menuListPtr;
		    cleanupPtr = cleanupPtr->nextInstancePtr) {
		Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
		ckfree(cleanupPtr->errorStructPtr);
		cleanupPtr->errorStructPtr = NULL;
	    }
	    if (menuListPtr->errorStructPtr != NULL) {
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
	 * an initial tear-off entry at the beginning of the menu.
	 */

	if (menuListPtr->tearoff) {
	    if ((menuListPtr->numEntries == 0)
		    || (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) {
		if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) {
		    for (cleanupPtr = menuPtr->mainMenuPtr;
			    cleanupPtr != menuListPtr;
			    cleanupPtr = cleanupPtr->nextInstancePtr) {
			Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
			ckfree(cleanupPtr->errorStructPtr);
			cleanupPtr->errorStructPtr = NULL;
		    }
		    if (menuListPtr->errorStructPtr != NULL) {
			Tk_RestoreSavedOptions(menuListPtr->errorStructPtr);
			ckfree(menuListPtr->errorStructPtr);
			menuListPtr->errorStructPtr = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	} else if ((menuListPtr->numEntries > 0)
		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {

	    Tcl_EventuallyFree(menuListPtr->entries[0], (Tcl_FreeProc *) DestroyMenuEntry);

	    for (i = 0; i < (int)menuListPtr->numEntries - 1; i++) {
		menuListPtr->entries[i] = menuListPtr->entries[i + 1];
		menuListPtr->entries[i]->index = i;
	    }
	    if (--menuListPtr->numEntries == 0) {
		ckfree(menuListPtr->entries);
		menuListPtr->entries = NULL;
	    }
	}

	TkMenuConfigureDrawOptions(menuListPtr);

	/*
	 * After reconfiguring a menu, we need to reconfigure all of the
	 * entries in the menu, since some of the things in the children (such
	 * as graphics contexts) may have to change to reflect changes in the
	 * parent.
	 */

	for (i = 0; i < (int)menuListPtr->numEntries; i++) {
	    TkMenuEntry *mePtr;

	    mePtr = menuListPtr->entries[i];
	    ConfigureMenuEntry(mePtr, 0, NULL);
	}

	TkEventuallyRecomputeMenu(menuListPtr);
    }

    for (cleanupPtr = menuPtr->mainMenuPtr; cleanupPtr != NULL;
	    cleanupPtr = cleanupPtr->nextInstancePtr) {
	Tk_FreeSavedOptions(cleanupPtr->errorStructPtr);
	ckfree(cleanupPtr->errorStructPtr);
	cleanupPtr->errorStructPtr = NULL;
    }

    return TCL_OK;







|

















|

|


















|









|







1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
	 * an initial tear-off entry at the beginning of the menu.
	 */

	if (menuListPtr->tearoff) {
	    if ((menuListPtr->numEntries == 0)
		    || (menuListPtr->entries[0]->type != TEAROFF_ENTRY)) {
		if (MenuNewEntry(menuListPtr, 0, TEAROFF_ENTRY) == NULL) {
		    for (cleanupPtr = menuPtr->masterMenuPtr;
			    cleanupPtr != menuListPtr;
			    cleanupPtr = cleanupPtr->nextInstancePtr) {
			Tk_RestoreSavedOptions(cleanupPtr->errorStructPtr);
			ckfree(cleanupPtr->errorStructPtr);
			cleanupPtr->errorStructPtr = NULL;
		    }
		    if (menuListPtr->errorStructPtr != NULL) {
			Tk_RestoreSavedOptions(menuListPtr->errorStructPtr);
			ckfree(menuListPtr->errorStructPtr);
			menuListPtr->errorStructPtr = NULL;
		    }
		    return TCL_ERROR;
		}
	    }
	} else if ((menuListPtr->numEntries > 0)
		&& (menuListPtr->entries[0]->type == TEAROFF_ENTRY)) {

	    Tcl_EventuallyFree(menuListPtr->entries[0], 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);
    }

    for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != NULL;
	    cleanupPtr = cleanupPtr->nextInstancePtr) {
	Tk_FreeSavedOptions(cleanupPtr->errorStructPtr);
	ckfree(cleanupPtr->errorStructPtr);
	cleanupPtr->errorStructPtr = NULL;
    }

    return TCL_OK;
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
     * 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.
     */







|




|







1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
     * Tk_ConfigureWidget, such as special processing for defaults, sizing
     * strings, graphics contexts, etc.
     */

    if (mePtr->labelPtr == NULL) {
	mePtr->labelLength = 0;
    } else {
	Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
    }

    /*
     * If this is a cascade entry, the platform-specific data of the child
     * menu has to be updated. Also, the links that point to parents and
     * cascades have to be updated.
     */
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
	Tcl_UntraceVar2(menuPtr->interp, name, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, mePtr);
    }

    result = TCL_OK;
    if (menuPtr->tkwin != NULL) {
	if (Tk_SetOptions(menuPtr->interp, mePtr,
		mePtr->optionTable, objc, objv, menuPtr->tkwin,
		&errorStruct, NULL) != TCL_OK) {
	    return TCL_ERROR;
	}
	result = PostProcessEntry(mePtr);
	if (result != TCL_OK) {
	    Tk_RestoreSavedOptions(&errorStruct);







|







1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
	Tcl_UntraceVar2(menuPtr->interp, name, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuVarProc, mePtr);
    }

    result = TCL_OK;
    if (menuPtr->tkwin != NULL) {
	if (Tk_SetOptions(menuPtr->interp, (char *) mePtr,
		mePtr->optionTable, objc, objv, menuPtr->tkwin,
		&errorStruct, NULL) != TCL_OK) {
	    return TCL_ERROR;
	}
	result = PostProcessEntry(mePtr);
	if (result != TCL_OK) {
	    Tk_RestoreSavedOptions(&errorStruct);
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuCloneEntries(
    Tcl_Interp *dummy,		/* Used for error reporting. */
    TkMenu *menuPtr,		/* Information about whole menu. */
    int index,			/* Index of mePtr within menuPtr's entries. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;
    int cascadeEntryChanged = 0;
    TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL;
    Tcl_Obj *oldCascadePtr = NULL;
    const char *newCascadeName;
    (void)dummy;

    /*
     * Cascades are kind of tricky here. This is special case #3 in the
     * comment at the top of this file. Basically, if a menu is the main
     * menu of a clone chain, and has an entry with a cascade menu, the clones
     * of the menu will point to clones of the cascade menu. We have to
     * destroy the clones of the cascades, clone the new cascade menu, and
     * configure the entry to point to the new clone.
     */

    mePtr = menuPtr->mainMenuPtr->entries[index];
    if (mePtr->type == CASCADE_ENTRY) {
	oldCascadePtr = mePtr->namePtr;
	if (oldCascadePtr != NULL) {
	    Tcl_IncrRefCount(oldCascadePtr);
	}
    }








|











<










|







1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989

1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
 *	mePtr; old resources get freed, if there were any.
 *
 *----------------------------------------------------------------------
 */

static int
ConfigureMenuCloneEntries(
    Tcl_Interp *interp,		/* Used for error reporting. */
    TkMenu *menuPtr,		/* Information about whole menu. */
    int index,			/* Index of mePtr within menuPtr's entries. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[])	/* Arguments. */
{
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;
    int cascadeEntryChanged = 0;
    TkMenuReferences *oldCascadeMenuRefPtr, *cascadeMenuRefPtr = NULL;
    Tcl_Obj *oldCascadePtr = NULL;
    const char *newCascadeName;


    /*
     * Cascades are kind of tricky here. This is special case #3 in the
     * comment at the top of this file. Basically, if a menu is the main
     * menu of a clone chain, and has an entry with a cascade menu, the clones
     * of the menu will point to clones of the cascade menu. We have to
     * destroy the clones of the cascades, clone the new cascade menu, and
     * configure the entry to point to the new clone.
     */

    mePtr = menuPtr->masterMenuPtr->entries[index];
    if (mePtr->type == CASCADE_ENTRY) {
	oldCascadePtr = mePtr->namePtr;
	if (oldCascadePtr != NULL) {
	    Tcl_IncrRefCount(oldCascadePtr);
	}
    }

2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	    cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    newCascadeName);
	}
    }

    for (menuListPtr = menuPtr->mainMenuPtr->nextInstancePtr;
    	    menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = menuListPtr->entries[index];

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,







|







2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
	if (mePtr->namePtr != NULL) {
	    newCascadeName = Tcl_GetString(mePtr->namePtr);
	    cascadeMenuRefPtr = TkFindMenuReferences(menuPtr->interp,
		    newCascadeName);
	}
    }

    for (menuListPtr = menuPtr->masterMenuPtr->nextInstancePtr;
    	    menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = menuListPtr->entries[index];

	if (cascadeEntryChanged && (mePtr->namePtr != NULL)) {
	    oldCascadeMenuRefPtr = TkFindMenuReferencesObj(menuPtr->interp,
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145

2146
2147

2148
2149

2150
2151
2152

2153
2154
2155
2156
2157



2158







2159


2160


2161



2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * GetMenuIndex --
 *
 *	Parse a textual index into a menu and return the numerical index of
 *	the indicated entry.
 *
 * Results:
 *	A standard Tcl result. If all went well, then *indexPtr is filled in
 *	with the entry index corresponding to string (ranges from -1 to the
 *	number of entries in the menu minus one). Otherwise an error message
 *	is left in the interp's result.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
GetMenuIndex(
    Tcl_Interp *interp,		/* For error messages. */
    TkMenu *menuPtr,		/* Menu for which the index is being
				 * specified. */
    Tcl_Obj *objPtr,		/* Specification of an entry in menu. See
				 * manual entry for valid .*/
    int lastOK,			/* Non-zero means its OK to return index just
				 * *after* last entry. */
    TkSizeT *indexPtr)		/* Where to store converted index. */
{
    int i;
    const char *string;

    if (TkGetIntForIndex(objPtr, menuPtr->numEntries - 1, lastOK, indexPtr) == TCL_OK) {
	/* TCL_INDEX_NONE is only accepted if it does not result from a negative number */
	if (*indexPtr != TCL_INDEX_NONE || Tcl_GetString(objPtr)[0] != '-') {
	    if (*indexPtr >= menuPtr->numEntries) {
		*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	    }
	    return TCL_OK;
	}
    }

    string = Tcl_GetString(objPtr);

    if ((string[0] == 'a') && (strcmp(string, "active") == 0)) {
	*indexPtr = menuPtr->active;
	goto success;
    }

    if ((string[0] == 'l') && (strcmp(string, "last") == 0)) {

	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);
	goto success;

    }


    if ((string[0] == 'n') && (strcmp(string, "none") == 0)) {
	*indexPtr = TCL_INDEX_NONE;
	goto success;

    }

    if (string[0] == '@') {
	if (GetIndexFromCoords(NULL, menuPtr, string, indexPtr)
		== TCL_OK) {



	    goto success;







	}


    }






    for (i = 0; i < (int)menuPtr->numEntries; i++) {
	Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr;
	const char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr);

	if ((label != NULL) && (Tcl_StringCaseMatch(label, string, 0))) {
	    *indexPtr = i;
	    goto success;
	}
    }

    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
	    "bad menu entry index \"%s\"", string));
    Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
    return TCL_ERROR;

  success:
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * MenuCmdDeletedProc --
 *







|

















|







|


|
<
<
<
<
<
<
<
<
<
<
<
<



|


|
>

<
>


>
|
|
<
>



|

>
>
>
|
>
>
>
>
>
>
>
|
>
>
|
>
>
|
>
>
>
|





|







<
<
<







2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129












2130
2131
2132
2133
2134
2135
2136
2137
2138

2139
2140
2141
2142
2143
2144

2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185



2186
2187
2188
2189
2190
2191
2192
    }
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * TkGetMenuIndex --
 *
 *	Parse a textual index into a menu and return the numerical index of
 *	the indicated entry.
 *
 * Results:
 *	A standard Tcl result. If all went well, then *indexPtr is filled in
 *	with the entry index corresponding to string (ranges from -1 to the
 *	number of entries in the menu minus one). Otherwise an error message
 *	is left in the interp's result.
 *
 * Side effects:
 *	None.
 *
 *--------------------------------------------------------------
 */

int
TkGetMenuIndex(
    Tcl_Interp *interp,		/* For error messages. */
    TkMenu *menuPtr,		/* Menu for which the index is being
				 * specified. */
    Tcl_Obj *objPtr,		/* Specification of an entry in menu. See
				 * manual entry for valid .*/
    int lastOK,			/* Non-zero means its OK to return index just
				 * *after* last entry. */
    int *indexPtr)		/* Where to store converted index. */
{
    int i;
    const char *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))
	    || ((string[0] == 'e') && (strcmp(string, "end") == 0))) {
	*indexPtr = menuPtr->numEntries - ((lastOK) ? 0 : 1);

	return TCL_OK;
    }

    if ((string[0] == '\0') ||
	    ((string[0] == 'n') && (strcmp(string, "none") == 0))) {
	*indexPtr = -1;

	return TCL_OK;
    }

    if (string[0] == '@') {
	if (GetIndexFromCoords(interp, menuPtr, string, indexPtr)
		== TCL_OK) {
	    return TCL_OK;
	}
    }

    if (isdigit(UCHAR(string[0]))) {
	if (Tcl_GetIntFromObj(interp, objPtr, &i) == TCL_OK) {
	    if (i >= menuPtr->numEntries) {
		if (lastOK) {
		    i = menuPtr->numEntries;
		} else {
		    i = menuPtr->numEntries-1;
		}
	    } else if (i < 0) {
		i = -1;
	    }
	    *indexPtr = i;
	    return TCL_OK;
	}
	Tcl_ResetResult(interp);
    }

    for (i = 0; i < menuPtr->numEntries; i++) {
	Tcl_Obj *labelPtr = menuPtr->entries[i]->labelPtr;
	const char *label = (labelPtr == NULL) ? NULL : Tcl_GetString(labelPtr);

	if ((label != NULL) && (Tcl_StringCaseMatch(label, string, 0))) {
	    *indexPtr = i;
	    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 --
 *
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.
     */








|





|







2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
 *
 *----------------------------------------------------------------------
 */

static TkMenuEntry *
MenuNewEntry(
    TkMenu *menuPtr,		/* Menu that will hold the new entry. */
    int index,			/* Where in the menu the new entry is to
				 * go. */
    int type)			/* The type of the new entry. */
{
    TkMenuEntry *mePtr;
    TkMenuEntry **newEntries;
    int i;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    /*
     * Create a new array of entries with an empty slot for the new entry.
     */

2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
    mePtr->namePtr = NULL;
    mePtr->childMenuRefPtr = NULL;
    mePtr->onValuePtr = NULL;
    mePtr->offValuePtr = NULL;
    mePtr->entryFlags = 0;
    mePtr->index = index;
    mePtr->nextCascadePtr = NULL;
    if (Tk_InitOptions(menuPtr->interp, mePtr,
	    mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
	ckfree(mePtr);
	return NULL;
    }
    TkMenuInitializeEntryDrawingFields(mePtr);
    if (TkpMenuNewEntry(mePtr) != TCL_OK) {
	Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable,







|







2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
    mePtr->namePtr = NULL;
    mePtr->childMenuRefPtr = NULL;
    mePtr->onValuePtr = NULL;
    mePtr->offValuePtr = NULL;
    mePtr->entryFlags = 0;
    mePtr->index = index;
    mePtr->nextCascadePtr = NULL;
    if (Tk_InitOptions(menuPtr->interp, (char *) mePtr,
	    mePtr->optionTable, menuPtr->tkwin) != TCL_OK) {
	ckfree(mePtr);
	return NULL;
    }
    TkMenuInitializeEntryDrawingFields(mePtr);
    if (TkpMenuNewEntry(mePtr) != TCL_OK) {
	Tk_FreeConfigOptions((char *) mePtr, mePtr->optionTable,
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
    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;







|




|





|

|




















|








|

|


|
<







2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404

2405
2406
2407
2408
2409
2410
2411
    Tcl_Obj *indexPtr,		/* Object describing index at which to insert.
				 * NULL means insert at end. */
    int objc,			/* Number of elements in objv. */
    Tcl_Obj *const objv[])	/* Arguments to command: first arg is type of
				 * entry, others are config options. */
{
    int type;
    int index;
    TkMenuEntry *mePtr;
    TkMenu *menuListPtr;

    if (indexPtr != NULL) {
	if (TkGetMenuIndex(interp, menuPtr, indexPtr, 1, &index) != TCL_OK) {
	    return TCL_ERROR;
	}
    } else {
	index = menuPtr->numEntries;
    }
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"bad index \"%s\"", Tcl_GetString(indexPtr)));
	Tcl_SetErrorCode(interp, "TK", "MENU", "INDEX", NULL);
	return TCL_ERROR;
    }
    if (menuPtr->tearoff && (index == 0)) {
	index = 1;
    }

    /*
     * Figure out the type of the new entry.
     */

    if (Tcl_GetIndexFromObjStruct(interp, objv[0], menuEntryTypeStrings,
	    sizeof(char *), "menu entry type", 0, &type) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * Now we have to add an entry for every instance related to this menu.
     */

    for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL;
    	    menuListPtr = menuListPtr->nextInstancePtr) {

    	mePtr = MenuNewEntry(menuListPtr, index, type);
    	if (mePtr == NULL) {
    	    return TCL_ERROR;
    	}
    	if (ConfigureMenuEntry(mePtr, objc - 1, objv + 1) != TCL_OK) {
	    TkMenu *errorMenuPtr;
	    int i;

	    for (errorMenuPtr = menuPtr->masterMenuPtr;
		    errorMenuPtr != NULL;
		    errorMenuPtr = errorMenuPtr->nextInstancePtr) {
    		Tcl_EventuallyFree(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;
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
    	 */

    	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;








|







2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
    	 */

    	if ((menuPtr != menuListPtr) && (type == CASCADE_ENTRY)) {
    	    if ((mePtr->namePtr != NULL)
		    && (mePtr->childMenuRefPtr != NULL)
    	    	    && (mePtr->childMenuRefPtr->menuPtr != NULL)) {
		TkMenu *cascadeMenuPtr =
			mePtr->childMenuRefPtr->menuPtr->masterMenuPtr;
		Tcl_Obj *newCascadePtr, *newObjv[2];
		Tcl_Obj *menuNamePtr = Tcl_NewStringObj("-menu", -1);
		Tcl_Obj *windowNamePtr =
			Tcl_NewStringObj(Tk_PathName(menuListPtr->tkwin), -1);
		Tcl_Obj *normalPtr = Tcl_NewStringObj("normal", -1);
		TkMenuReferences *menuRefPtr;

2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
    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.
	 */








<
<







2491
2492
2493
2494
2495
2496
2497


2498
2499
2500
2501
2502
2503
2504
    const char *name2,		/* Second part of variable's name. */
    int flags)			/* Describes what just happened. */
{
    TkMenuEntry *mePtr = (TkMenuEntry *)clientData;
    TkMenu *menuPtr;
    const char *value;
    const char *name, *onValue;



    if (Tcl_InterpDeleted(interp) || (mePtr->namePtr == NULL)) {
	/*
	 * Do nothing if the interpreter is going away or we have
	 * no variable name.
	 */

2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
 *
 *----------------------------------------------------------------------
 */

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







|
|




|













|







2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
 *
 *----------------------------------------------------------------------
 */

int
TkActivateMenuEntry(
    TkMenu *menuPtr,	/* Menu in which to activate. */
    int index)			/* Index of entry to activate, or -1 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
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,







|
>







2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
CloneMenu(
    TkMenu *menuPtr,		/* The menu we are going to clone. */
    Tcl_Obj *newMenuNamePtr,	/* The name to give the new menu. */
    Tcl_Obj *newMenuTypePtr)	/* What kind of menu is this, a normal menu a
    				 * menubar, or a tearoff? */
{
    int returnResult;
    int menuType;
    int i;
    TkMenuReferences *menuRefPtr;
    Tcl_Obj *menuDupCommandArray[4];

    if (newMenuTypePtr == NULL) {
	menuType = MAIN_MENU;
    } else {
	if (Tcl_GetIndexFromObjStruct(menuPtr->interp, newMenuTypePtr,
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {
	    menuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->mainMenuPtr = menuPtr->mainMenuPtr;
	} else {
	    TkMenu *mainMenuPtr;

	    mainMenuPtr = menuPtr->mainMenuPtr;
	    newMenuPtr->nextInstancePtr = mainMenuPtr->nextInstancePtr;
	    mainMenuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->mainMenuPtr = mainMenuPtr;
	}

	/*
	 * Add the main menu's window to the bind tags for this window after
	 * this window's tag. This is so the user can bind to either this
	 * clone (which may not be easy to do) or the entire menu clone
	 * structure.







|

|

|
|
|
|







2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
	/*
	 * Now put this newly created menu into the parent menu's instance
	 * chain.
	 */

	if (menuPtr->nextInstancePtr == NULL) {
	    menuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->masterMenuPtr = menuPtr->masterMenuPtr;
	} else {
	    TkMenu *masterMenuPtr;

	    masterMenuPtr = menuPtr->masterMenuPtr;
	    newMenuPtr->nextInstancePtr = masterMenuPtr->nextInstancePtr;
	    masterMenuPtr->nextInstancePtr = newMenuPtr;
	    newMenuPtr->masterMenuPtr = masterMenuPtr;
	}

	/*
	 * Add the main menu's window to the bind tags for this window after
	 * this window's tag. This is so the user can bind to either this
	 * clone (which may not be easy to do) or the entire menu clone
	 * structure.
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
	    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,







|







2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
	    for (i = 0; i < numElements; i++) {
		Tcl_ListObjIndex(newMenuPtr->interp, bindingsPtr, i,
			&elementPtr);
		windowName = Tcl_GetString(elementPtr);
		if (strcmp(windowName, Tk_PathName(newMenuPtr->tkwin))
			== 0) {
		    Tcl_Obj *newElementPtr = Tcl_NewStringObj(
			    Tk_PathName(newMenuPtr->masterMenuPtr->tkwin), -1);

		    /*
		     * The newElementPtr will have its refCount incremented
		     * here, so we don't need to worry about it any more.
		     */

		    Tcl_ListObjReplace(menuPtr->interp, bindingsPtr,
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
	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,







|







2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
	Tcl_DecrRefCount(newObjv[1]);
	Tcl_ResetResult(menuPtr->interp);

	/*
	 * Clone all of the cascade menus that this menu points to.
	 */

	for (i = 0; i < menuPtr->numEntries; i++) {
	    TkMenuReferences *cascadeRefPtr;
	    TkMenu *oldCascadePtr;

	    if ((menuPtr->entries[i]->type == CASCADE_ENTRY)
		&& (menuPtr->entries[i]->namePtr != NULL)) {
		cascadeRefPtr =
			TkFindMenuReferencesObj(menuPtr->interp,
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888

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







|


|



|
|

|







2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893

static int
MenuDoXPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    int index;

    TkRecomputeMenu(menuPtr);
    if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
    Tcl_ResetResult(interp);
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(menuPtr->entries[index]->x));
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925

static int
MenuDoYPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    TkSizeT index;

    TkRecomputeMenu(menuPtr);
    if (GetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	goto error;
    }
    Tcl_ResetResult(interp);
    if (index == TCL_INDEX_NONE) {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(menuPtr->entries[index]->y));
    }

    return TCL_OK;

  error:
    return TCL_ERROR;
}







|


|



|
|

|







2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930

static int
MenuDoYPosition(
    Tcl_Interp *interp,
    TkMenu *menuPtr,
    Tcl_Obj *objPtr)
{
    int index;

    TkRecomputeMenu(menuPtr);
    if (TkGetMenuIndex(interp, menuPtr, objPtr, 0, &index) != TCL_OK) {
	goto error;
    }
    Tcl_ResetResult(interp);
    if (index < 0) {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(0));
    } else {
	Tcl_SetObjResult(interp, Tcl_NewIntObj(menuPtr->entries[index]->y));
    }

    return TCL_OK;

  error:
    return TCL_ERROR;
}
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953

2954
2955
2956
2957
2958
2959
2960
2961
2962
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)







|




|

|
>
















|



>
>
>












|







2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
 *
 * Side effects:
 *	If int is invalid, interp's result will be set to NULL.
 *
 *----------------------------------------------------------------------
 */

static int
GetIndexFromCoords(
    Tcl_Interp *interp,		/* Interpreter of menu. */
    TkMenu *menuPtr,		/* The menu we are searching. */
    const char *string,		/* The @string we are parsing. */
    int *indexPtr)		/* The index of the item that matches. */
{
    int x, y;
    int i;
    const char *p;
    char *end;
    int x2, borderwidth, max;

    TkRecomputeMenu(menuPtr);
    p = string + 1;
    y = strtol(p, &end, 0);
    if (end == p) {
	goto error;
    }
    Tk_GetPixelsFromObj(interp, menuPtr->tkwin,
	menuPtr->borderWidthPtr, &borderwidth);
    if (*end == ',') {
	x = y;
	p = end + 1;
	y = strtol(p, &end, 0);
	if ((end == p) || (*end != '\0')) {
	    goto error;
	}
    } else {
	if (*end != '\0') {
	    goto error;
	}
	x = borderwidth;
    }

    *indexPtr = -1;

    /* set the width of the final column to the remainder of the window
     * being aware of windows that may not be mapped yet.
     */
    max = Tk_IsMapped(menuPtr->tkwin)
      ? Tk_Width(menuPtr->tkwin) : Tk_ReqWidth(menuPtr->tkwin);
    max -= borderwidth;

    for (i = 0; i < 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.
     */








|







3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
3041
3042
3043
3044
3045
 *----------------------------------------------------------------------
 */

static void
RecursivelyDeleteMenu(
    TkMenu *menuPtr)		/* The menubar instance we are deleting. */
{
    int i;
    TkMenuEntry *mePtr;

    /*
     * It is not 100% clear that this preserve/release pair is required, but
     * we have added them for safety in this very complex code.
     */

3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123

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







|







3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130
3131
3132

	    Tcl_DecrRefCount(resultPtr);
	    resultPtr = Tcl_DuplicateObj(parentPtr);
	    if (doDot) {
		Tcl_AppendToObj(resultPtr, ".", -1);
	    }
	    Tcl_AppendObjToObj(resultPtr, childPtr);
	    intPtr = Tcl_NewIntObj(i);
	    Tcl_AppendObjToObj(resultPtr, intPtr);
	    Tcl_DecrRefCount(intPtr);
    	}
	destString = Tcl_GetString(resultPtr);
    	if ((Tcl_FindCommand(interp, destString, NULL, 0) == NULL)
		&& ((nameTablePtr == NULL)
		|| (Tcl_FindHashEntry(nameTablePtr, destString) == NULL))) {
3175
3176
3177
3178
3179
3180
3181
3182
3183
3184
3185
3186
3187
3188
3189
	     */

	    if (menuRefPtr->menuPtr != NULL) {
		TkMenu *instancePtr;

		menuPtr = menuRefPtr->menuPtr;

		for (instancePtr = menuPtr->mainMenuPtr;
			instancePtr != NULL;
			instancePtr = instancePtr->nextInstancePtr) {
		    if (instancePtr->menuType == MENUBAR
			    && instancePtr->parentTopLevelPtr == tkwin) {
			RecursivelyDeleteMenu(instancePtr);
			break;
		    }







|







3184
3185
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196
3197
3198
	     */

	    if (menuRefPtr->menuPtr != NULL) {
		TkMenu *instancePtr;

		menuPtr = menuRefPtr->menuPtr;

		for (instancePtr = menuPtr->masterMenuPtr;
			instancePtr != NULL;
			instancePtr = instancePtr->nextInstancePtr) {
		    if (instancePtr->menuType == MENUBAR
			    && instancePtr->parentTopLevelPtr == tkwin) {
			RecursivelyDeleteMenu(instancePtr);
			break;
		    }
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
3321
3322
3323
3324
3325
 *
 *----------------------------------------------------------------------
 */

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







|

<
<







3317
3318
3319
3320
3321
3322
3323
3324
3325


3326
3327
3328
3329
3330
3331
3332
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMenuHashTable(
    ClientData clientData,	/* The menu hash table we are destroying. */
    Tcl_Interp *interp)		/* The interpreter we are destroying. */
{


    Tcl_DeleteHashTable((Tcl_HashTable *)clientData);
    ckfree(clientData);
}

/*
 *----------------------------------------------------------------------
 *
3523
3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
				 * entries to delete. */
    int last)			/* The zero-based last entry. */
{
    TkMenu *menuListPtr;
    int numDeleted, i, j;

    numDeleted = last + 1 - first;
    for (menuListPtr = menuPtr->mainMenuPtr; menuListPtr != NULL;
	    menuListPtr = menuListPtr->nextInstancePtr) {
	for (i = last; i >= first; i--) {
	    Tcl_EventuallyFree(menuListPtr->entries[i], (Tcl_FreeProc *) DestroyMenuEntry);
	}
	for (i = last + 1; i < (int)menuListPtr->numEntries; i++) {
	    j = i - numDeleted;
	    menuListPtr->entries[j] = menuListPtr->entries[i];
	    menuListPtr->entries[j]->index = j;
	}
	menuListPtr->numEntries -= numDeleted;
	if (menuListPtr->numEntries == 0) {
	    ckfree(menuListPtr->entries);
	    menuListPtr->entries = NULL;
	}
	if (((int)menuListPtr->active >= first)
		&& ((int)menuListPtr->active <= last)) {
	    menuListPtr->active = -1;
	} else if ((int)menuListPtr->active > last) {
	    menuListPtr->active -= numDeleted;
	}
	TkEventuallyRecomputeMenu(menuListPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * MenuCleanup --
 *
 *	Resets menusInitialized to allow Tk to be finalized and reused without
 *	the DLL being unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
MenuCleanup(
    ClientData dummy)
{
    (void)dummy;

    menusInitialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInit --







|


|

|









|
|

|









|














|
|

<
<







3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582


3583
3584
3585
3586
3587
3588
3589
				 * entries to delete. */
    int last)			/* The zero-based last entry. */
{
    TkMenu *menuListPtr;
    int numDeleted, i, j;

    numDeleted = last + 1 - first;
    for (menuListPtr = menuPtr->masterMenuPtr; 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);
	    menuListPtr->entries = NULL;
	}
	if ((menuListPtr->active >= first)
		&& (menuListPtr->active <= last)) {
	    menuListPtr->active = -1;
	} else if (menuListPtr->active > last) {
	    menuListPtr->active -= numDeleted;
	}
	TkEventuallyRecomputeMenu(menuListPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuCleanup --
 *
 *	Resets menusInitialized to allow Tk to be finalized and reused without
 *	the DLL being unloaded.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void
TkMenuCleanup(
    ClientData unused)
{


    menusInitialized = 0;
}

/*
 *----------------------------------------------------------------------
 *
 * TkMenuInit --
3608
3609
3610
3611
3612
3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
	    menusInitialized = 1;
	}

	/*
	 * Make sure we cleanup on finalize.
	 */

	TkCreateExitHandler((Tcl_ExitProc *) MenuCleanup, NULL);
	Tcl_MutexUnlock(&menuMutex);
    }
    if (!tsdPtr->menusInitialized) {
	TkpMenuThreadInit();
	tsdPtr->menuOptionTable =
		Tk_CreateOptionTable(NULL, tkMenuConfigSpecs);
	tsdPtr->entryOptionTables[TEAROFF_ENTRY] =







|







3613
3614
3615
3616
3617
3618
3619
3620
3621
3622
3623
3624
3625
3626
3627
	    menusInitialized = 1;
	}

	/*
	 * Make sure we cleanup on finalize.
	 */

	TkCreateExitHandler((Tcl_ExitProc *) TkMenuCleanup, NULL);
	Tcl_MutexUnlock(&menuMutex);
    }
    if (!tsdPtr->menusInitialized) {
	TkpMenuThreadInit();
	tsdPtr->menuOptionTable =
		Tk_CreateOptionTable(NULL, tkMenuConfigSpecs);
	tsdPtr->entryOptionTables[TEAROFF_ENTRY] =
Changes to generic/tkMenu.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * 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 (c) 1996-1998 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMENU
#define _TKMENU
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
    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). */
    int labelLength;		/* Number of non-NULL characters in label. */
    int state;			/* State of button for display purposes:
				 * normal, active, or disabled. */
    int underline;		/* Value of -underline option: specifies index
				 * of character to underline (<0 means don't
				 * underline anything). */
    Tcl_Obj *underlinePtr;	/* Index of character to underline. */
    Tcl_Obj *bitmapPtr;		/* Bitmap to display in menu entry, or NULL.
				 * If not NULL then label is ignored. */
    Tcl_Obj *imagePtr;		/* Name of image to display, or NULL. If not
				 * NULL, bitmap, text, and textVarName are
				 * ignored. */
    Tk_Image image;		/* Image to display in menu entry, or NULL if
				 * none. */
    Tcl_Obj *selectImagePtr;	/* Name of image to display when selected, or
				 * NULL. */
    Tk_Image selectImage;	/* Image to display in entry when selected, or
				 * NULL if none. Ignored if image is NULL. */
    Tcl_Obj *accelPtr;		/* Accelerator string displayed at right of
				 * menu entry. NULL means no such accelerator.
				 * Malloc'ed. */
    int accelLength;		/* Number of non-NULL characters in
				 * accelerator. */
    int indicatorOn;		/* True means draw indicator, false means
				 * don't draw it. This field is ignored unless
				 * the entry is a radio or check button. */
    /*
     * Display attributes
     */
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
    Display *display;		/* Display containing widget. Needed, among
				 * other things, so that resources can be
				 * freed up even after tkwin has gone away. */
    Tcl_Interp *interp;		/* Interpreter associated with menu. */
    Tcl_Command widgetCmd;	/* Token for menu's widget command. */
    TkMenuEntry **entries;	/* Array of pointers to all the entries in the
				 * menu. NULL means no entries. */
    TkSizeT numEntries;		/* Number of elements in entries. */
    TkSizeT active;			/* Index of active entry. TCL_INDEX_NONE means
				 * nothing active. */
    int 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" */

    /*







|
|
|







259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
    Display *display;		/* Display containing widget. Needed, among
				 * other things, so that resources can be
				 * freed up even after tkwin has gone away. */
    Tcl_Interp *interp;		/* Interpreter associated with menu. */
    Tcl_Command widgetCmd;	/* Token for menu's widget command. */
    TkMenuEntry **entries;	/* Array of pointers to all the entries in the
				 * menu. NULL means no entries. */
    int numEntries;		/* Number of elements in entries. */
    int active;			/* Index of active entry. -1 means nothing
				 * active. */
    int menuType;		/* MAIN_MENU, TEAROFF_MENU, or MENUBAR. See
    				 * below for definitions. */
    Tcl_Obj *menuTypePtr;	/* Used to control whether created tkwin is a
				 * toplevel or not. "normal", "menubar", or
				 * "toplevel" */

    /*
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
				 * definition. */
    TkMenuEntry *postedCascade;	/* Points to menu entry for cascaded submenu
				 * that is currently posted or NULL if no
				 * submenu posted. */
    struct TkMenu *nextInstancePtr;
    				/* The next instance of this menu in the
    				 * chain. */
    struct TkMenu *mainMenuPtr;
    				/* A pointer to the original menu for this
    				 * clone chain. Points back to this structure
    				 * if this menu is a main menu. */
    void *reserved1; /* not used any more. */
    Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the
    				 * toplevel that owns the menu. Only
    				 * applicable for menubar clones. */







|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
				 * definition. */
    TkMenuEntry *postedCascade;	/* Points to menu entry for cascaded submenu
				 * that is currently posted or NULL if no
				 * submenu posted. */
    struct TkMenu *nextInstancePtr;
    				/* The next instance of this menu in the
    				 * chain. */
    struct TkMenu *masterMenuPtr;
    				/* A pointer to the original menu for this
    				 * clone chain. Points back to this structure
    				 * if this menu is a main menu. */
    void *reserved1; /* not used any more. */
    Tk_Window parentTopLevelPtr;/* If this menu is a menubar, this is the
    				 * toplevel that owns the menu. Only
    				 * applicable for menubar clones. */
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
				 * of options are in this structure. */
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */
    Tcl_Obj *activeReliefPtr;	/* 3-d effect for active element. */
} TkMenu;

/*
 * When the toplevel configure -menu command is executed, the menu may not
 * exist yet. We need to keep a linked list of windows that reference a
 * particular menu.
 */







<







374
375
376
377
378
379
380

381
382
383
384
385
386
387
				 * of options are in this structure. */
    Tk_OptionSpec *extensionPtr;/* Needed by the configuration package for
				 * this widget to be extended. */
    Tk_SavedOptions *errorStructPtr;
				/* We actually have to allocate these because
				 * multiple menus get changed during one
				 * ConfigureMenu call. */

} TkMenu;

/*
 * When the toplevel configure -menu command is executed, the menu may not
 * exist yet. We need to keep a linked list of windows that reference a
 * particular menu.
 */
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493


494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
 * 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.
 */







>
















|












>
>



|


|

















|







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
 * configuration information. If the main instance is deleted, all instances
 * are deleted. If one of the other instances is deleted, only that instance
 * is deleted.
 */

#define UNKNOWN_TYPE		-1
#define MAIN_MENU 		0
#define MASTER_MENU 		0
#define TEAROFF_MENU 		1
#define MENUBAR 		2

/*
 * Various geometry definitions:
 */

#define CASCADE_ARROW_HEIGHT	10
#define CASCADE_ARROW_WIDTH	8
#define DECORATION_BORDER_WIDTH	2

/*
 * Menu-related functions that are shared among Tk modules but not exported to
 * the outside world:
 */

MODULE_SCOPE int	TkActivateMenuEntry(TkMenu *menuPtr, int index);
MODULE_SCOPE void	TkBindMenu(Tk_Window tkwin, TkMenu *menuPtr);
MODULE_SCOPE TkMenuReferences*TkCreateMenuReferences(Tcl_Interp *interp,
			    const char *name);
MODULE_SCOPE void	TkDestroyMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkEventuallyRecomputeMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkEventuallyRedrawMenu(TkMenu *menuPtr,
			    TkMenuEntry *mePtr);
MODULE_SCOPE TkMenuReferences*TkFindMenuReferences(Tcl_Interp *interp, const char *name);
MODULE_SCOPE TkMenuReferences*TkFindMenuReferencesObj(Tcl_Interp *interp,
			    Tcl_Obj *namePtr);
MODULE_SCOPE int	TkFreeMenuReferences(TkMenuReferences *menuRefPtr);
MODULE_SCOPE Tcl_HashTable *TkGetMenuHashTable(Tcl_Interp *interp);
MODULE_SCOPE int	TkGetMenuIndex(Tcl_Interp *interp, TkMenu *menuPtr,
			    Tcl_Obj *objPtr, int lastOK, int *indexPtr);
MODULE_SCOPE void	TkMenuInitializeDrawingFields(TkMenu *menuPtr);
MODULE_SCOPE void	TkMenuInitializeEntryDrawingFields(TkMenuEntry *mePtr);
MODULE_SCOPE int	TkInvokeMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int index);
MODULE_SCOPE void	TkMenuConfigureDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE int	TkMenuConfigureEntryDrawOptions(
			    TkMenuEntry *mePtr, int index);
MODULE_SCOPE void	TkMenuFreeDrawOptions(TkMenu *menuPtr);
MODULE_SCOPE void	TkMenuEntryFreeDrawOptions(TkMenuEntry *mePtr);
MODULE_SCOPE void	TkMenuEventProc(ClientData clientData,
    			    XEvent *eventPtr);
MODULE_SCOPE void	TkMenuImageProc(ClientData clientData, int x, int y,
			    int width, int height, int imgWidth,
			    int imgHeight);
MODULE_SCOPE void	TkMenuInit(void);
MODULE_SCOPE void	TkMenuSelectImageProc(ClientData clientData, int x,
			    int y, int width, int height, int imgWidth,
			    int imgHeight);
MODULE_SCOPE Tcl_Obj *	TkNewMenuName(Tcl_Interp *interp,
			    Tcl_Obj *parentNamePtr, TkMenu *menuPtr);
MODULE_SCOPE int	TkPostCommand(TkMenu *menuPtr);
MODULE_SCOPE int	TkPostSubmenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    TkMenuEntry *mePtr);
MODULE_SCOPE int	TkPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int x, int y);
MODULE_SCOPE int	TkPreprocessMenu(TkMenu *menuPtr);
MODULE_SCOPE void	TkRecomputeMenu(TkMenu *menuPtr);

/*
 * These routines are the platform-dependent routines called by the common
 * code.
 */
536
537
538
539
540
541
542
543
544
545
546
			    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 */







|



538
539
540
541
542
543
544
545
546
547
548
			    int drawingParameters);
MODULE_SCOPE void	TkpMenuInit(void);
MODULE_SCOPE int	TkpMenuNewEntry(TkMenuEntry *mePtr);
MODULE_SCOPE int	TkpNewMenu(TkMenu *menuPtr);
MODULE_SCOPE int	TkpPostMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int x, int y, int index);
MODULE_SCOPE int	TkpPostTearoffMenu(Tcl_Interp *interp, TkMenu *menuPtr,
			    int x, int y, int index);
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
/*
 * 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"






|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * tkMenuDraw.c --
 *
 *	This module implements the platform-independent drawing and geometry
 *	calculations of menu widgets.
 *
 * Copyright (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenu.h"
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
 *
 *----------------------------------------------------------------------
 */

int
TkMenuConfigureEntryDrawOptions(
    TkMenuEntry *mePtr,
    TkSizeT index)
{
    XGCValues gcValues;
    GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
    unsigned long mask;
    Tk_Font tkfont;
    TkMenu *menuPtr = mePtr->menuPtr;








|







294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
 *
 *----------------------------------------------------------------------
 */

int
TkMenuConfigureEntryDrawOptions(
    TkMenuEntry *mePtr,
    int index)
{
    XGCValues gcValues;
    GC newGC, newActiveGC, newDisabledGC, newIndicatorGC;
    unsigned long mask;
    Tk_Font tkfont;
    TkMenu *menuPtr = mePtr->menuPtr;

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

    if (menuPtr->tkwin == NULL) {
	return;
    }
    if (mePtr != NULL) {
	mePtr->entryFlags |= ENTRY_NEEDS_REDISPLAY;
    } else {
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
 *--------------------------------------------------------------
 */

static void
ComputeMenuGeometry(
    ClientData clientData)	/* Structure describing menu. */
{
    TkMenu *menuPtr = (TkMenu *)clientData;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    if (menuPtr->menuType == MENUBAR) {
	TkpComputeMenubarGeometry(menuPtr);







|







526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
 *--------------------------------------------------------------
 */

static void
ComputeMenuGeometry(
    ClientData clientData)	/* Structure describing menu. */
{
    TkMenu *menuPtr = clientData;

    if (menuPtr->tkwin == NULL) {
	return;
    }

    if (menuPtr->menuType == MENUBAR) {
	TkpComputeMenubarGeometry(menuPtr);
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
    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);
    }
}







|
<
<
<
<
<
<







582
583
584
585
586
587
588
589






590
591
592
593
594
595
596
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be
				 * <=0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkMenuEntry *mePtr = clientData;







    if ((mePtr->entryFlags & ENTRY_SELECTED)
	    && !(mePtr->menuPtr->menuFlags & REDRAW_PENDING)) {
	mePtr->menuPtr->menuFlags |= REDRAW_PENDING;
	Tcl_DoWhenIdle(DisplayMenu, mePtr->menuPtr);
    }
}
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
 *----------------------------------------------------------------------
 */

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;








|


<
|







611
612
613
614
615
616
617
618
619
620

621
622
623
624
625
626
627
628
 *----------------------------------------------------------------------
 */

static void
DisplayMenu(
    ClientData clientData)	/* Information about widget. */
{
    TkMenu *menuPtr = clientData;
    TkMenuEntry *mePtr;
    Tk_Window tkwin = menuPtr->tkwin;

    int index, strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;
    int relief;

762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
 */

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







|







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
 */

void
TkMenuEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenu *menuPtr = clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ConfigureNotify) {
	TkEventuallyRecomputeMenu(menuPtr);
	TkEventuallyRedrawMenu(menuPtr, NULL);
    } else if (eventPtr->type == ActivateNotify) {
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
    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);
    }
}








|
<
<
<
<
<
<







820
821
822
823
824
825
826
827






828
829
830
831
832
833
834
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be
				 * <=0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkMenu *menuPtr = ((TkMenuEntry *) clientData)->menuPtr;







    if ((menuPtr->tkwin != NULL) && !(menuPtr->menuFlags & RESIZE_PENDING)) {
	menuPtr->menuFlags |= RESIZE_PENDING;
	Tcl_DoWhenIdle(ComputeMenuGeometry, menuPtr);
    }
}

950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965

	Tk_GetRootCoords(menuPtr->tkwin, &x, &y);
	AdjustMenuCoords(menuPtr, mePtr, &x, &y);

	menuPtr->postedCascade = mePtr;
	subary[0] = mePtr->namePtr;
	subary[1] = Tcl_NewStringObj("post", -1);
	subary[2] = Tcl_NewWideIntObj(x);
	subary[3] = Tcl_NewWideIntObj(y);
	Tcl_IncrRefCount(subary[1]);
	Tcl_IncrRefCount(subary[2]);
	Tcl_IncrRefCount(subary[3]);
	result = Tcl_EvalObjv(interp, 4, subary, 0);
	Tcl_DecrRefCount(subary[1]);
	Tcl_DecrRefCount(subary[2]);
	Tcl_DecrRefCount(subary[3]);







|
|







937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952

	Tk_GetRootCoords(menuPtr->tkwin, &x, &y);
	AdjustMenuCoords(menuPtr, mePtr, &x, &y);

	menuPtr->postedCascade = mePtr;
	subary[0] = mePtr->namePtr;
	subary[1] = Tcl_NewStringObj("post", -1);
	subary[2] = Tcl_NewIntObj(x);
	subary[3] = Tcl_NewIntObj(y);
	Tcl_IncrRefCount(subary[1]);
	Tcl_IncrRefCount(subary[2]);
	Tcl_IncrRefCount(subary[3]);
	result = Tcl_EvalObjv(interp, 4, subary, 0);
	Tcl_DecrRefCount(subary[1]);
	Tcl_DecrRefCount(subary[2]);
	Tcl_DecrRefCount(subary[3]);
Changes to generic/tkMenubutton.c.
9
10
11
12
13
14
15

16
17
18
19
20
21
22
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenubutton.h"


/*
 * The structure below defines menubutton class behavior by means of
 * procedures that can be invoked from generic window code.
 */

static const Tk_ClassProcs menubuttonClass = {







>







9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkMenubutton.h"
#include "default.h"

/*
 * The structure below defines menubutton class behavior by means of
 * procedures that can be invoked from generic window code.
 */

static const Tk_ClassProcs menubuttonClass = {
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
 * 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},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR,
	TCL_INDEX_NONE, offsetof(TkMenuButton, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_MENUBUTTON_HIGHLIGHT, TCL_INDEX_NONE,
	offsetof(TkMenuButton, highlightColorPtr),	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH,
	TCL_INDEX_NONE, offsetof(TkMenuButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_MENUBUTTON_IMAGE, TCL_INDEX_NONE, offsetof(TkMenuButton, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_MENUBUTTON_INDICATOR, TCL_INDEX_NONE, offsetof(TkMenuButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MENUBUTTON_JUSTIFY, TCL_INDEX_NONE, offsetof(TkMenuButton, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_MENUBUTTON_MENU, TCL_INDEX_NONE, offsetof(TkMenuButton, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_MENUBUTTON_PADX, TCL_INDEX_NONE, offsetof(TkMenuButton, padX),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_MENUBUTTON_PADY, TCL_INDEX_NONE, offsetof(TkMenuButton, padY),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENUBUTTON_RELIEF, TCL_INDEX_NONE, offsetof(TkMenuButton, relief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	 DEF_BUTTON_COMPOUND, TCL_INDEX_NONE, offsetof(TkMenuButton, compound), 0,
	 compoundStrings, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_MENUBUTTON_STATE, TCL_INDEX_NONE, offsetof(TkMenuButton, state),
	0, stateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENUBUTTON_TAKE_FOCUS, TCL_INDEX_NONE,
	offsetof(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MENUBUTTON_TEXT, TCL_INDEX_NONE, offsetof(TkMenuButton, text), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MENUBUTTON_TEXT_VARIABLE, TCL_INDEX_NONE,
	offsetof(TkMenuButton, textVarName), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_MENUBUTTON_UNDERLINE, TCL_INDEX_NONE, offsetof(TkMenuButton, underline),
	 0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_MENUBUTTON_WIDTH, TCL_INDEX_NONE, offsetof(TkMenuButton, widthString),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_MENUBUTTON_WRAP_LENGTH, TCL_INDEX_NONE, offsetof(TkMenuButton, wrapLength),
	0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
};

/*
 * The following tables define the menubutton widget commands and map the
 * indexes into the string tables into a single enumerated type used to







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<






|
|


|
|
|

|
|

|

|
|
|
|

|


|
|

|


|
|


|

|
|

|

|

|



|

|
|


|

|


|


|

|


|


|


|


|
|

|
|

|
|

|

|
|

|
|

|


|







32
33
34
35
36
37
38


















39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
 * is used together with the "enum direction" declaration in tkMenubutton.h.
 */

static const char *const directionStrings[] = {
    "above", "below", "flush", "left", "right", NULL
};



















/*
 * Information used for parsing configuration specs:
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_BORDER, "-activebackground", "activeBackground", "Foreground",
	DEF_MENUBUTTON_ACTIVE_BG_COLOR, -1,
	Tk_Offset(TkMenuButton, activeBorder), 0,
	(ClientData) DEF_MENUBUTTON_ACTIVE_BG_MONO, 0},
    {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background",
	DEF_MENUBUTTON_ACTIVE_FG_COLOR, -1,
	Tk_Offset(TkMenuButton, activeFg),
	0, DEF_MENUBUTTON_ACTIVE_FG_MONO, 0},
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor",
	DEF_MENUBUTTON_ANCHOR, -1,
	Tk_Offset(TkMenuButton, anchor), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	DEF_MENUBUTTON_BG_COLOR, -1, Tk_Offset(TkMenuButton, normalBorder),
	0, DEF_MENUBUTTON_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1,
	0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL, 0, -1,
	0, "-background", 0},
    {TK_OPTION_BITMAP, "-bitmap", "bitmap", "Bitmap",
	DEF_MENUBUTTON_BITMAP, -1, Tk_Offset(TkMenuButton, bitmap),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_MENUBUTTON_BORDER_WIDTH, -1,
	Tk_Offset(TkMenuButton, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_MENUBUTTON_CURSOR, -1, Tk_Offset(TkMenuButton, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING_TABLE, "-direction", "direction", "Direction",
	DEF_MENUBUTTON_DIRECTION, -1, Tk_Offset(TkMenuButton, direction),
	TK_OPTION_ENUM_VAR, directionStrings, 0},
    {TK_OPTION_COLOR, "-disabledforeground", "disabledForeground",
	"DisabledForeground", DEF_MENUBUTTON_DISABLED_FG_COLOR,
	-1, Tk_Offset(TkMenuButton, disabledFg), TK_OPTION_NULL_OK,
	(ClientData) DEF_MENUBUTTON_DISABLED_FG_MONO, 0},
    {TK_OPTION_SYNONYM, "-fg", "foreground", NULL, NULL, 0, -1,
	0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MENUBUTTON_FONT, -1, Tk_Offset(TkMenuButton, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MENUBUTTON_FG, -1, Tk_Offset(TkMenuButton, normalFg), 0, 0, 0},
    {TK_OPTION_STRING, "-height", "height", "Height",
	DEF_MENUBUTTON_HEIGHT, -1, Tk_Offset(TkMenuButton, heightString),
	0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	"HighlightBackground", DEF_MENUBUTTON_HIGHLIGHT_BG_COLOR,
	-1, Tk_Offset(TkMenuButton, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	DEF_MENUBUTTON_HIGHLIGHT, -1,
	Tk_Offset(TkMenuButton, highlightColorPtr),	0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MENUBUTTON_HIGHLIGHT_WIDTH,
	-1, Tk_Offset(TkMenuButton, highlightWidth), 0, 0, 0},
    {TK_OPTION_STRING, "-image", "image", "Image",
	DEF_MENUBUTTON_IMAGE, -1, Tk_Offset(TkMenuButton, imageString),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-indicatoron", "indicatorOn", "IndicatorOn",
	DEF_MENUBUTTON_INDICATOR, -1, Tk_Offset(TkMenuButton, indicatorOn),
	0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MENUBUTTON_JUSTIFY, -1, Tk_Offset(TkMenuButton, justify), 0, 0, 0},
    {TK_OPTION_STRING, "-menu", "menu", "Menu",
	DEF_MENUBUTTON_MENU, -1, Tk_Offset(TkMenuButton, menuName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	DEF_MENUBUTTON_PADX, -1, Tk_Offset(TkMenuButton, padX),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	DEF_MENUBUTTON_PADY, -1, Tk_Offset(TkMenuButton, padY),
	0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MENUBUTTON_RELIEF, -1, Tk_Offset(TkMenuButton, relief),
	0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-compound", "compound", "Compound",
	DEF_BUTTON_COMPOUND, -1, Tk_Offset(TkMenuButton, compound),
	0, tkCompoundStrings, 0},
    {TK_OPTION_STRING_TABLE, "-state", "state", "State",
	DEF_MENUBUTTON_STATE, -1, Tk_Offset(TkMenuButton, state),
	TK_OPTION_ENUM_VAR, tkStateStrings, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MENUBUTTON_TAKE_FOCUS, -1,
	Tk_Offset(TkMenuButton, takeFocus), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MENUBUTTON_TEXT, -1, Tk_Offset(TkMenuButton, text), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MENUBUTTON_TEXT_VARIABLE, -1,
	Tk_Offset(TkMenuButton, textVarName), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_INT, "-underline", "underline", "Underline",
	DEF_MENUBUTTON_UNDERLINE, -1, Tk_Offset(TkMenuButton, underline),
	0, 0, 0},
    {TK_OPTION_STRING, "-width", "width", "Width",
	DEF_MENUBUTTON_WIDTH, -1, Tk_Offset(TkMenuButton, widthString),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength",
	DEF_MENUBUTTON_WRAP_LENGTH, -1, Tk_Offset(TkMenuButton, wrapLength),
	0, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, NULL, 0}
};

/*
 * The following tables define the menubutton widget commands and map the
 * indexes into the string tables into a single enumerated type used to
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenubuttonObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*







|







<







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

205
206
207
208
209
210
211
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MenubuttonObjCmd(
    ClientData clientData,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    /*
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
    mbPtr->takeFocus = NULL;
    mbPtr->flags = 0;

    Tk_CreateEventHandler(mbPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MenuButtonEventProc, mbPtr);

    if (Tk_InitOptions(interp, mbPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMenuButton(interp, mbPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(mbPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonWidgetObjCmd --







|









|







286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    mbPtr->takeFocus = NULL;
    mbPtr->flags = 0;

    Tk_CreateEventHandler(mbPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MenuButtonEventProc, mbPtr);

    if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMenuButton(interp, mbPtr, objc-2, objv+2) != TCL_OK) {
	Tk_DestroyWindow(mbPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(mbPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MenuButtonWidgetObjCmd --
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
static int
MenuButtonWidgetObjCmd(
    ClientData clientData,	/* Information about button widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    int result, index;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }







|







325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
static int
MenuButtonWidgetObjCmd(
    ClientData clientData,	/* Information about button widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    TkMenuButton *mbPtr = clientData;
    int result, index;
    Tcl_Obj *objPtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
    switch (index) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, mbPtr,
		mbPtr->optionTable, objv[2], mbPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, mbPtr,
		    mbPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    mbPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {







|









|







347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
    switch (index) {
    case COMMAND_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 1, objv, "cget option");
	    goto error;
	}

	objPtr = Tk_GetOptionValue(interp, (char *) mbPtr,
		mbPtr->optionTable, objv[2], mbPtr->tkwin);
	if (objPtr == NULL) {
	    goto error;
	}
	Tcl_SetObjResult(interp, objPtr);
	break;

    case COMMAND_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) mbPtr,
		    mbPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    mbPtr->tkwin);
	    if (objPtr == NULL) {
		goto error;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	} else {
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, mbPtr,
		    mbPtr->optionTable, objc, objv,
		    mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.







|







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

    for (error = 0; error <= 1; error++) {
	if (!error) {
	    /*
	     * First pass: set options to new values.
	     */

	    if (Tk_SetOptions(interp, (char *) mbPtr,
		    mbPtr->optionTable, objc, objv,
		    mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
		continue;
	    }
	} else {
	    /*
	     * Second pass: restore options to old values.
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
	if (value == NULL) {
	    Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (mbPtr->text != NULL) {
		ckfree(mbPtr->text);
	    }
	    mbPtr->text = (char *)ckalloc(strlen(value) + 1);
	    strcpy(mbPtr->text, value);
	}
	Tcl_TraceVar2(interp, mbPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuButtonTextVarProc, mbPtr);
    }








|







611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
	if (value == NULL) {
	    Tcl_SetVar2(interp, mbPtr->textVarName, NULL, mbPtr->text,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (mbPtr->text != NULL) {
		ckfree(mbPtr->text);
	    }
	    mbPtr->text = ckalloc(strlen(value) + 1);
	    strcpy(mbPtr->text, value);
	}
	Tcl_TraceVar2(interp, mbPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MenuButtonTextVarProc, mbPtr);
    }

671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
void
TkMenuButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    TkMenuButton *mbPtr = (TkMenuButton *)instanceData;

    gcValues.font = Tk_FontId(mbPtr->tkfont);
    gcValues.foreground = mbPtr->normalFg->pixel;
    gcValues.background = Tk_3DBorderColor(mbPtr->normalBorder)->pixel;

    /*
     * Note: GraphicsExpose events are disabled in GC's because they're used







|







653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
void
TkMenuButtonWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc;
    unsigned long mask;
    TkMenuButton *mbPtr = instanceData;

    gcValues.font = Tk_FontId(mbPtr->tkfont);
    gcValues.foreground = mbPtr->normalFg->pixel;
    gcValues.background = Tk_3DBorderColor(mbPtr->normalBorder)->pixel;

    /*
     * Note: GraphicsExpose events are disabled in GC's because they're used
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
 */

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.







|







754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
 */

static void
MenuButtonEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    TkMenuButton *mbPtr = clientData;

    if ((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0)) {
	goto redraw;
    } else if (eventPtr->type == ConfigureNotify) {
	/*
	 * Must redraw after size changes, since layout could have changed and
	 * borders will need to be redrawn.
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
 *----------------------------------------------------------------------
 */

static void
MenuButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    Tk_Window tkwin = mbPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the
     * widget.







|







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
 *----------------------------------------------------------------------
 */

static void
MenuButtonCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    TkMenuButton *mbPtr = clientData;
    Tk_Window tkwin = mbPtr->tkwin;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the
     * widget.
864
865
866
867
868
869
870

871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
 * Side effects:
 *	The text displayed in the menu button will change to match the
 *	variable.
 *
 *--------------------------------------------------------------
 */


static char *
MenuButtonTextVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    const char *value;
    size_t len;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {







>








|

|
<
<







846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864


865
866
867
868
869
870
871
 * Side effects:
 *	The text displayed in the menu button will change to match the
 *	variable.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
MenuButtonTextVarProc(
    ClientData clientData,	/* Information about button. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    TkMenuButton *mbPtr = clientData;
    const char *value;
    unsigned len;



    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
    value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (mbPtr->text != NULL) {
	ckfree(mbPtr->text);
    }
    len = 1 + strlen(value);
    mbPtr->text = (char *)ckalloc(len);
    memcpy(mbPtr->text, value, len);
    TkpComputeMenuButtonGeometry(mbPtr);

    if ((mbPtr->tkwin != NULL) && Tk_IsMapped(mbPtr->tkwin)
	    && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	mbPtr->flags |= REDRAW_PENDING;







|
|







902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
    value = Tcl_GetVar2(interp, mbPtr->textVarName, NULL, TCL_GLOBAL_ONLY);
    if (value == NULL) {
	value = "";
    }
    if (mbPtr->text != NULL) {
	ckfree(mbPtr->text);
    }
    len = 1 + (unsigned) strlen(value);
    mbPtr->text = ckalloc(len);
    memcpy(mbPtr->text, value, len);
    TkpComputeMenuButtonGeometry(mbPtr);

    if ((mbPtr->tkwin != NULL) && Tk_IsMapped(mbPtr->tkwin)
	    && !(mbPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	mbPtr->flags |= REDRAW_PENDING;
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkMenuButton *mbPtr = (TkMenuButton *)clientData;
    (void)x;
    (void)y;
    (void)width;
    (void)height;
    (void)imgWidth;
    (void)imgHeight;

    if (mbPtr->tkwin != NULL) {
	TkpComputeMenuButtonGeometry(mbPtr);
	if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	    mbPtr->flags |= REDRAW_PENDING;
	}







|
<
<
<
<
<
<







942
943
944
945
946
947
948
949






950
951
952
953
954
955
956
    ClientData clientData,	/* Pointer to widget record. */
    int x, int y,		/* Upper left pixel (within image) that must
				 * be redisplayed. */
    int width, int height,	/* Dimensions of area to redisplay (may be <=
				 * 0). */
    int imgWidth, int imgHeight)/* New dimensions of image. */
{
    TkMenuButton *mbPtr = clientData;







    if (mbPtr->tkwin != NULL) {
	TkpComputeMenuButtonGeometry(mbPtr);
	if (Tk_IsMapped(mbPtr->tkwin) && !(mbPtr->flags & REDRAW_PENDING)) {
	    Tcl_DoWhenIdle(TkpDisplayMenuButton, mbPtr);
	    mbPtr->flags |= REDRAW_PENDING;
	}
Changes to generic/tkMenubutton.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*
 * 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 (c) 1996-1997 Sun Microsystems, Inc.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMENUBUTTON
#define _TKMENUBUTTON
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
				 * 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







|







161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
				 * whether the menubutton should show both an
				 * image and text, and, if so, how. */
    enum direction direction;	/* Direction for where to pop the menu. Valid
    				 * directions are "above", "below", "left",
    				 * "right", and "flush". "flush" means that
    				 * the upper left corner of the menubutton is
    				 * where the menu pops up. "above" and "below"
    				 * will attempt to pop the menu completely
    				 * above or below the menu respectively.
    				 * "left" and "right" will pop the menu left
    				 * or right, and the active item will be next
    				 * to the button. */
    Tk_Cursor cursor;		/* Current cursor for window, or NULL. */
    char *takeFocus;		/* Value of -takefocus option; not used in the
				 * C code, but used by keyboard traversal
Changes to generic/tkMessage.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/*
 * 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"

/*
 * A data structure of the following type is kept for each message 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
/*
 * 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 Ajuba Solutions.
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "default.h"
#include "tkInt.h"

/*
 * A data structure of the following type is kept for each message widget
 * managed by this file:
 */

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

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








|

|

|


|

|

|
|

|


|

|

|

|
|

|


|
|

|

|
|

|
|

|

|


|

|


|




















|







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

/*
 * Information used for argv parsing.
 */

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", DEF_MESSAGE_ANCHOR,
	 -1, Tk_Offset(Message, anchor), 0, 0, 0},
    {TK_OPTION_INT, "-aspect", "aspect", "Aspect", DEF_MESSAGE_ASPECT,
	 -1, Tk_Offset(Message, aspect), 0, 0, 0},
    {TK_OPTION_BORDER, "-background", "background", "Background",
	 DEF_MESSAGE_BG_COLOR, -1, Tk_Offset(Message, border), 0,
	 DEF_MESSAGE_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL,
	 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL, NULL,
	 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	 DEF_MESSAGE_BORDER_WIDTH, -1,
	 Tk_Offset(Message, borderWidth), 0, 0, 0},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	 DEF_MESSAGE_CURSOR, -1, Tk_Offset(Message, cursor),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_SYNONYM, "-fg", NULL, NULL, NULL,
	 0, -1, 0, "-foreground", 0},
    {TK_OPTION_FONT, "-font", "font", "Font",
	DEF_MESSAGE_FONT, -1, Tk_Offset(Message, tkfont), 0, 0, 0},
    {TK_OPTION_COLOR, "-foreground", "foreground", "Foreground",
	DEF_MESSAGE_FG, -1, Tk_Offset(Message, fgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightbackground", "highlightBackground",
	 "HighlightBackground", DEF_MESSAGE_HIGHLIGHT_BG, -1,
	 Tk_Offset(Message, highlightBgColorPtr), 0, 0, 0},
    {TK_OPTION_COLOR, "-highlightcolor", "highlightColor", "HighlightColor",
	 DEF_MESSAGE_HIGHLIGHT, -1, Tk_Offset(Message, highlightColorPtr),
	 0, 0, 0},
    {TK_OPTION_PIXELS, "-highlightthickness", "highlightThickness",
	"HighlightThickness", DEF_MESSAGE_HIGHLIGHT_WIDTH, -1,
	 Tk_Offset(Message, highlightWidth), 0, 0, 0},
    {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify",
	DEF_MESSAGE_JUSTIFY, -1, Tk_Offset(Message, justify), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", "padX", "Pad",
	 DEF_MESSAGE_PADX, Tk_Offset(Message, padXPtr),
	 Tk_Offset(Message, padX), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", "padY", "Pad",
	 DEF_MESSAGE_PADY, Tk_Offset(Message, padYPtr),
	 Tk_Offset(Message, padY), 0, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_MESSAGE_RELIEF, -1, Tk_Offset(Message, relief), 0, 0, 0},
    {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus",
	DEF_MESSAGE_TAKE_FOCUS, -1, Tk_Offset(Message, takeFocus),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_STRING, "-text", "text", "Text",
	DEF_MESSAGE_TEXT, -1, Tk_Offset(Message, string), 0, 0, 0},
    {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable",
	DEF_MESSAGE_TEXT_VARIABLE, -1, Tk_Offset(Message, textVarName),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_MESSAGE_WIDTH, -1, Tk_Offset(Message, width), 0, 0 ,0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 * Forward declarations for functions defined later in this file:
 */

static void		MessageCmdDeletedProc(ClientData clientData);
static void		MessageEventProc(ClientData clientData,
			    XEvent *eventPtr);
static char *		MessageTextVarProc(ClientData clientData,
			    Tcl_Interp *interp, const char *name1,
			    const char *name2, int flags);
static int		MessageWidgetObjCmd(ClientData clientData,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
static void		MessageWorldChanged(ClientData instanceData);
static void		ComputeMessageGeometry(Message *msgPtr);
static int		ConfigureMessage(Tcl_Interp *interp, Message *msgPtr,
			    int objc, Tcl_Obj *const objv[], int flags);
static void		DestroyMessage(char *memPtr);
static void		DisplayMessage(ClientData clientData);

/*
 * The structure below defines message class behavior by means of functions
 * that can be invoked from generic window code.
 */

210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MessageObjCmd(
    ClientData dummy,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;
    (void)dummy;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    /*
     * Create the option table for this widget class. If it has already been
     * created, the cached pointer will be returned.
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    msgPtr = (Message *)ckalloc(sizeof(Message));
    memset(msgPtr, 0, sizeof(Message));

    /*
     * Set values for those fields that don't take a 0 or NULL value.
     */

    msgPtr->tkwin = tkwin;
    msgPtr->display = Tk_Display(tkwin);







|







<



















|
|







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

225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
 *	See the user documentation.
 *
 *--------------------------------------------------------------
 */

int
Tk_MessageObjCmd(
    ClientData clientData,	/* NULL. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr;
    Tk_OptionTable optionTable;
    Tk_Window tkwin;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "pathName ?-option value ...?");
	return TCL_ERROR;
    }

    tkwin = Tk_CreateWindowFromPath(interp, Tk_MainWindow(interp),
	    Tcl_GetString(objv[1]), NULL);
    if (tkwin == NULL) {
	return TCL_ERROR;
    }

    /*
     * Create the option table for this widget class. If it has already been
     * created, the cached pointer will be returned.
     */

    optionTable = Tk_CreateOptionTable(interp, optionSpecs);

    msgPtr = ckalloc(sizeof(Message));
    memset(msgPtr, 0, (size_t) sizeof(Message));

    /*
     * Set values for those fields that don't take a 0 or NULL value.
     */

    msgPtr->tkwin = tkwin;
    msgPtr->display = Tk_Display(tkwin);
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
    msgPtr->cursor = NULL;

    Tk_SetClass(msgPtr->tkwin, "Message");
    Tk_SetClassProcs(msgPtr->tkwin, &messageClass, msgPtr);
    Tk_CreateEventHandler(msgPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MessageEventProc, msgPtr);
    if (Tk_InitOptions(interp, msgPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(msgPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MessageWidgetObjCmd --







|









|







263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
    msgPtr->cursor = NULL;

    Tk_SetClass(msgPtr->tkwin, "Message");
    Tk_SetClassProcs(msgPtr->tkwin, &messageClass, msgPtr);
    Tk_CreateEventHandler(msgPtr->tkwin,
	    ExposureMask|StructureNotifyMask|FocusChangeMask,
	    MessageEventProc, msgPtr);
    if (Tk_InitOptions(interp, (char *)msgPtr, optionTable, tkwin) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    if (ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0) != TCL_OK) {
	Tk_DestroyWindow(msgPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(msgPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * MessageWidgetObjCmd --
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
static int
MessageWidgetObjCmd(
    ClientData clientData,	/* Information about message widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr = (Message *)clientData;
    static const char *const optionStrings[] = { "cget", "configure", NULL };
    enum options { MESSAGE_CGET, MESSAGE_CONFIGURE };
    int index;
    int result = TCL_OK;
    Tcl_Obj *objPtr;

    if (objc < 2) {







|







302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
static int
MessageWidgetObjCmd(
    ClientData clientData,	/* Information about message widget. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument strings. */
{
    Message *msgPtr = clientData;
    static const char *const optionStrings[] = { "cget", "configure", NULL };
    enum options { MESSAGE_CGET, MESSAGE_CONFIGURE };
    int index;
    int result = TCL_OK;
    Tcl_Obj *objPtr;

    if (objc < 2) {
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354

    switch ((enum options) index) {
    case MESSAGE_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	} else {
	    objPtr = Tk_GetOptionValue(interp, msgPtr,
		    msgPtr->optionTable, objv[2], msgPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
		result = TCL_OK;
	    }
	}
	break;
    case MESSAGE_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, msgPtr,
		    msgPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    msgPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
		result = TCL_OK;







|











|







327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353

    switch ((enum options) index) {
    case MESSAGE_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	} else {
	    objPtr = Tk_GetOptionValue(interp, (char *) msgPtr,
		    msgPtr->optionTable, objv[2], msgPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
		result = TCL_OK;
	    }
	}
	break;
    case MESSAGE_CONFIGURE:
	if (objc <= 3) {
	    objPtr = Tk_GetOptionInfo(interp, (char *) msgPtr,
		    msgPtr->optionTable, (objc == 3) ? objv[2] : NULL,
		    msgPtr->tkwin);
	    if (objPtr == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, objPtr);
		result = TCL_OK;
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
 *	Everything associated with the message is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMessage(
    void *memPtr)		/* Info about message widget. */
{
    Message *msgPtr = (Message *) memPtr;

    msgPtr->flags |= MESSAGE_DELETED;

    Tcl_DeleteCommandFromToken(msgPtr->interp, msgPtr->widgetCmd);
    if (msgPtr->flags & REDRAW_PENDING) {







|







378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
 *	Everything associated with the message is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyMessage(
    char *memPtr)		/* Info about message widget. */
{
    Message *msgPtr = (Message *) memPtr;

    msgPtr->flags |= MESSAGE_DELETED;

    Tcl_DeleteCommandFromToken(msgPtr->interp, msgPtr->widgetCmd);
    if (msgPtr->flags & REDRAW_PENDING) {
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
    Message *msgPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    Tk_SavedOptions savedOptions;
    (void)flags;

    /*
     * Eliminate any existing trace on a variable monitored by the message.
     */

    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }

    if (Tk_SetOptions(interp, msgPtr, msgPtr->optionTable, objc, objv,
	    msgPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }

    /*
     * If the message is to display the value of a variable, then set up a







<











|







440
441
442
443
444
445
446

447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
    Message *msgPtr,	/* Information about widget; may or may not
				 * already have values for some fields. */
    int objc,			/* Number of valid entries in argv. */
    Tcl_Obj *const objv[],	/* Arguments. */
    int flags)			/* Flags to pass to Tk_ConfigureWidget. */
{
    Tk_SavedOptions savedOptions;


    /*
     * Eliminate any existing trace on a variable monitored by the message.
     */

    if (msgPtr->textVarName != NULL) {
	Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }

    if (Tk_SetOptions(interp, (char *) msgPtr, msgPtr->optionTable, objc, objv,
	    msgPtr->tkwin, &savedOptions, NULL) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }

    /*
     * If the message is to display the value of a variable, then set up a
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
	if (value == NULL) {
	    Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (msgPtr->string != NULL) {
		ckfree(msgPtr->string);
	    }
	    msgPtr->string = strcpy((char *)ckalloc(strlen(value) + 1), value);
	}
	Tcl_TraceVar2(interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }

    /*







|







474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
	if (value == NULL) {
	    Tcl_SetVar2(interp, msgPtr->textVarName, NULL, msgPtr->string,
		    TCL_GLOBAL_ONLY);
	} else {
	    if (msgPtr->string != NULL) {
		ckfree(msgPtr->string);
	    }
	    msgPtr->string = strcpy(ckalloc(strlen(value) + 1), value);
	}
	Tcl_TraceVar2(interp, msgPtr->textVarName, NULL,
		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		MessageTextVarProc, msgPtr);
    }

    /*
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
static void
MessageWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    Tk_FontMetrics fm;
    Message *msgPtr = (Message *)instanceData;

    if (msgPtr->border != NULL) {
	Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border);
    }

    gcValues.font = Tk_FontId(msgPtr->tkfont);
    gcValues.foreground = msgPtr->fgColorPtr->pixel;







|







523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
static void
MessageWorldChanged(
    ClientData instanceData)	/* Information about widget. */
{
    XGCValues gcValues;
    GC gc = NULL;
    Tk_FontMetrics fm;
    Message *msgPtr = instanceData;

    if (msgPtr->border != NULL) {
	Tk_SetBackgroundFromBorder(msgPtr->tkwin, msgPtr->border);
    }

    gcValues.font = Tk_FontId(msgPtr->tkfont);
    gcValues.foreground = msgPtr->fgColorPtr->pixel;
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
 *--------------------------------------------------------------
 */

static void
DisplayMessage(
    ClientData clientData)	/* Information about window. */
{
    Message *msgPtr = (Message *)clientData;
    Tk_Window tkwin = msgPtr->tkwin;
    int x, y;
    int borderWidth = msgPtr->highlightWidth;

    msgPtr->flags &= ~REDRAW_PENDING;
    if ((msgPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;







|







662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
 *--------------------------------------------------------------
 */

static void
DisplayMessage(
    ClientData clientData)	/* Information about window. */
{
    Message *msgPtr = clientData;
    Tk_Window tkwin = msgPtr->tkwin;
    int x, y;
    int borderWidth = msgPtr->highlightWidth;

    msgPtr->flags &= ~REDRAW_PENDING;
    if ((msgPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
 */

static void
MessageEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Message *msgPtr = (Message *)clientData;

    if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))
	    || (eventPtr->type == ConfigureNotify)) {
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	DestroyMessage(clientData);
    } else if (eventPtr->type == FocusIn) {







|







738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
 */

static void
MessageEventProc(
    ClientData clientData,	/* Information about window. */
    XEvent *eventPtr)		/* Information about event. */
{
    Message *msgPtr = clientData;

    if (((eventPtr->type == Expose) && (eventPtr->xexpose.count == 0))
	    || (eventPtr->type == ConfigureNotify)) {
	goto redraw;
    } else if (eventPtr->type == DestroyNotify) {
	DestroyMessage(clientData);
    } else if (eventPtr->type == FocusIn) {
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
 *----------------------------------------------------------------------
 */

static void
MessageCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Message *msgPtr = (Message *)clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the
     * widget.
     */







|







791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
 *----------------------------------------------------------------------
 */

static void
MessageCmdDeletedProc(
    ClientData clientData)	/* Pointer to widget record for widget. */
{
    Message *msgPtr = clientData;

    /*
     * This function could be invoked either because the window was destroyed
     * and the command was then deleted (in which case tkwin is NULL) or
     * because the command was deleted, and then this function destroys the
     * widget.
     */
824
825
826
827
828
829
830

831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
 *
 * Side effects:
 *	The text displayed in the message will change to match the variable.
 *
 *--------------------------------------------------------------
 */


static char *
MessageTextVarProc(
    ClientData clientData,	/* Information about message. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    Message *msgPtr = (Message *)clientData;
    const char *value;
    (void)name1;
    (void)name2;

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {







>








|

<
<







822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839


840
841
842
843
844
845
846
 *
 * Side effects:
 *	The text displayed in the message will change to match the variable.
 *
 *--------------------------------------------------------------
 */

	/* ARGSUSED */
static char *
MessageTextVarProc(
    ClientData clientData,	/* Information about message. */
    Tcl_Interp *interp,		/* Interpreter containing variable. */
    const char *name1,		/* Name of variable. */
    const char *name2,		/* Second part of variable name. */
    int flags)			/* Information about what happened. */
{
    Message *msgPtr = 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) {
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
    if (value == NULL) {
	value = "";
    }
    if (msgPtr->string != NULL) {
	ckfree(msgPtr->string);
    }
    msgPtr->numChars = Tcl_NumUtfChars(value, -1);
    msgPtr->string = (char *)ckalloc(strlen(value) + 1);
    strcpy(msgPtr->string, value);
    ComputeMessageGeometry(msgPtr);

    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, msgPtr);
	msgPtr->flags |= REDRAW_PENDING;







|







878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
    if (value == NULL) {
	value = "";
    }
    if (msgPtr->string != NULL) {
	ckfree(msgPtr->string);
    }
    msgPtr->numChars = Tcl_NumUtfChars(value, -1);
    msgPtr->string = ckalloc(strlen(value) + 1);
    strcpy(msgPtr->string, value);
    ComputeMessageGeometry(msgPtr);

    if ((msgPtr->tkwin != NULL) && Tk_IsMapped(msgPtr->tkwin)
	    && !(msgPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayMessage, msgPtr);
	msgPtr->flags |= REDRAW_PENDING;
Changes to generic/tkObj.c.
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
 * 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.
 */

70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
 * A WindowRep caches name-to-window lookups. The cache is invalid if tkwin is
 * NULL or if mainPtr->deletionEpoch does not match epoch.
 */

typedef struct WindowRep {
    Tk_Window tkwin;		/* Cached window; NULL if not found. */
    TkMainInfo *mainPtr;	/* MainWindow associated with tkwin. */
#if TCL_MAJOR_VERSION > 8
    size_t epoch;			/* Value of mainPtr->deletionEpoch at last
				 * successful lookup. */
#else
    long epoch;
#endif
} WindowRep;

/*
 * Prototypes for functions defined later in this file:
 */

static void		DupMMInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void		DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj*copyPtr);
static void		DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj*copyPtr);
static void		FreeMMInternalRep(Tcl_Obj *objPtr);
static void		FreePixelInternalRep(Tcl_Obj *objPtr);
static void		FreeWindowInternalRep(Tcl_Obj *objPtr);
static ThreadSpecificData *GetTypeCache(void);
static void		UpdateStringOfMM(Tcl_Obj *objPtr);
static int		SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);

#if TCL_MAJOR_VERSION < 9
#if defined(USE_TCL_STUBS)
/*  Little hack to eliminate the need for "tclInt.h" here:
    Just copy a small portion of TclIntStubs, just
    enough to make it work */
typedef struct TclIntStubs {
    int magic;
    void *hooks;
    void (*dummy[34]) (void); /* dummy entries 0-33, not used */
    int (*tclGetIntForIndex) (Tcl_Interp *interp, Tcl_Obj *objPtr, int endValue, int *indexPtr); /* 34 */
} TclIntStubs;
extern const struct TclIntStubs *tclIntStubsPtr;

# undef Tcl_GetIntForIndex
# define Tcl_GetIntForIndex(interp, obj, max, ptr) ((tclIntStubsPtr->tclGetIntForIndex == NULL)? \
    ((int (*)(Tcl_Interp*,  Tcl_Obj *, int, int*))(void *)((&(tclStubsPtr->tcl_PkgProvideEx))[645]))((interp), (obj), (max), (ptr)): \
	tclIntStubsPtr->tclGetIntForIndex((interp), (obj), (max), (ptr)))
#elif TCL_MINOR_VERSION < 7
extern int TclGetIntForIndex(Tcl_Interp*,  Tcl_Obj *, int, int*);
# define Tcl_GetIntForIndex(interp, obj, max, ptr) TclGetIntForIndex(interp, obj, max, ptr)
#endif
#endif

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType pixelObjType = {
    "pixel",			/* name */
    FreePixelInternalRep,	/* freeIntRepProc */
    DupPixelInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType mmObjType = {
    "mm",			/* name */
    FreeMMInternalRep,		/* freeIntRepProc */
    DupMMInternalRep,		/* dupIntRepProc */
    UpdateStringOfMM,		/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "window"
 * Tcl object.
 */

static const Tcl_ObjType windowObjType = {
    "window",			/* name */
    FreeWindowInternalRep,	/* freeIntRepProc */
    DupWindowInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    NULL			/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * GetTypeCache --
 *







<
|

<
<
<


















<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<











|













|












|







68
69
70
71
72
73
74

75
76



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























95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
 * A WindowRep caches name-to-window lookups. The cache is invalid if tkwin is
 * NULL or if mainPtr->deletionEpoch does not match epoch.
 */

typedef struct WindowRep {
    Tk_Window tkwin;		/* Cached window; NULL if not found. */
    TkMainInfo *mainPtr;	/* MainWindow associated with tkwin. */

    long epoch;			/* Value of mainPtr->deletionEpoch at last
				 * successful lookup. */



} WindowRep;

/*
 * Prototypes for functions defined later in this file:
 */

static void		DupMMInternalRep(Tcl_Obj *srcPtr, Tcl_Obj *copyPtr);
static void		DupPixelInternalRep(Tcl_Obj *srcPtr, Tcl_Obj*copyPtr);
static void		DupWindowInternalRep(Tcl_Obj *srcPtr,Tcl_Obj*copyPtr);
static void		FreeMMInternalRep(Tcl_Obj *objPtr);
static void		FreePixelInternalRep(Tcl_Obj *objPtr);
static void		FreeWindowInternalRep(Tcl_Obj *objPtr);
static ThreadSpecificData *GetTypeCache(void);
static void		UpdateStringOfMM(Tcl_Obj *objPtr);
static int		SetMMFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetPixelFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
static int		SetWindowFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
























/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType pixelObjType = {
    "pixel",			/* name */
    FreePixelInternalRep,	/* freeIntRepProc */
    DupPixelInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    SetPixelFromAny		/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "pixel" Tcl
 * object, used for measuring distances. The pixel object remembers its
 * initial display-independent settings.
 */

static const Tcl_ObjType mmObjType = {
    "mm",			/* name */
    FreeMMInternalRep,		/* freeIntRepProc */
    DupMMInternalRep,		/* dupIntRepProc */
    UpdateStringOfMM,		/* updateStringProc */
    SetMMFromAny		/* setFromAnyProc */
};

/*
 * The following structure defines the implementation of the "window"
 * Tcl object.
 */

static const Tcl_ObjType windowObjType = {
    "window",			/* name */
    FreeWindowInternalRep,	/* freeIntRepProc */
    DupWindowInternalRep,	/* dupIntRepProc */
    NULL,			/* updateStringProc */
    SetWindowFromAny		/* setFromAnyProc */
};

/*
 *----------------------------------------------------------------------
 *
 * GetTypeCache --
 *
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
static ThreadSpecificData *
GetTypeCache(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->doubleTypePtr == NULL) {
	/* Smart initialization of doubleTypePtr/intTypePtr without
	 * hash-table lookup or creating complete Tcl_Obj's */
	Tcl_Obj obj;
	obj.bytes = (char *)"end";
	obj.length = 3;
	obj.typePtr = NULL;
	Tcl_GetIntForIndex(NULL, &obj, TCL_INDEX_NONE, (TkSizeT *)&obj.internalRep.doubleValue);
	tsdPtr->endTypePtr = obj.typePtr;
	obj.bytes = (char *)"0.0";
	obj.length = 3;
	obj.typePtr = NULL;
	Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue);
	tsdPtr->doubleTypePtr = obj.typePtr;
	obj.bytes = (char *)"0";
	obj.length = 1;
	obj.typePtr = NULL;
	Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue);
	tsdPtr->intTypePtr = obj.typePtr;
    }
    return tsdPtr;
}

/*
 *----------------------------------------------------------------------
 *
 * TkGetIntForIndex --
 *
 *	Almost the same as Tcl_GetIntForIndex, but it return an int, and it is
 *	more restricted. For example it only accepts "end", not "end-1", and
 *	only "2", not "1+1"
 *
 * Results:
 *	The return value is a standard Tcl object result.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */

int
TkGetIntForIndex(
    Tcl_Obj *indexObj,
    TkSizeT end,
    int lastOK,
    TkSizeT *indexPtr)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (Tcl_GetIntForIndex(NULL, indexObj, end + lastOK, indexPtr) != TCL_OK) {
	return TCL_ERROR;
    }
    if (indexObj->typePtr == tsdPtr->endTypePtr) {
	/* check for "end", but not "end-??" or "end+??" */
	return (*indexPtr == (end + lastOK)) ? TCL_OK :  TCL_ERROR;
    }
    if (indexObj->typePtr != tsdPtr->intTypePtr) {
	/* Neither do we accept "??-??" or "??+??" */
	return TCL_ERROR;
    }
#if TCL_MAJOR_VERSION < 9
    if ((*indexPtr < -1) || (end < -1)) {
	return TCL_ERROR;
    }
#endif
    if ((*indexPtr + 1) > (end + 1)) {
	*indexPtr = end + 1;
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * GetPixelsFromObjEx --
 *
 *	Attempt to return a pixel value from the Tcl object "objPtr". If the
 *	object is not already a pixel value, an attempt will be made to







|


<

<
<
<

<



<
<
<
<
<




<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







148
149
150
151
152
153
154
155
156
157

158



159

160
161
162





163
164
165
166


















































167
168
169
170
171
172
173
static ThreadSpecificData *
GetTypeCache(void)
{
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

    if (tsdPtr->doubleTypePtr == NULL) {
	/* Smart initialization of doubleTypePtr 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;
}



















































/*
 *----------------------------------------------------------------------
 *
 * GetPixelsFromObjEx --
 *
 *	Attempt to return a pixel value from the Tcl object "objPtr". If the
 *	object is not already a pixel value, an attempt will be made to
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
    int *intPtr,
    double *dblPtr)		/* Places to store resulting pixels. */
{
    int result, fresh;
    double d;
    PixelRep *pixelPtr;
    static const double bias[] = {
	1.0,	10.0,	25.4,	0.35278 /*25.4 / 72.0*/
    };

    /*
     * Special hacks where the type of the object is known to be something
     * that is just numeric and cannot require distance conversion. This pokes
     * holes in Tcl's abstractions, but they are just for optimization, not
     * 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) {







|


<
<
<
<
<
<
<

<

<
|




<
<
<
<
<
<







194
195
196
197
198
199
200
201
202
203







204

205

206
207
208
209
210






211
212
213
214
215
216
217
    int *intPtr,
    double *dblPtr)		/* Places to store resulting pixels. */
{
    int result, fresh;
    double d;
    PixelRep *pixelPtr;
    static const double bias[] = {
	1.0,	10.0,	25.4,	0.35277777777777775 /*25.4 / 72.0*/
    };








    if (objPtr->typePtr != &pixelObjType) {



	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);
    if (fresh) {
531
532
533
534
535
536
537

538
539
540
541
542
543
544
545
546
547
548
549

550

551

552
553
554
555

556














557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
 */

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







>






|
|
|
|
<
|
>
|
>
|
>
|
|
<
<
>

>
>
>
>
>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444

445
446
447
448
449
450
451
452


453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
 */

static int
SetPixelFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *typeCache = GetTypeCache();
    const Tcl_ObjType *typePtr;
    const char *string;
    char *rest;
    double d;
    int i, units;

    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 {
	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);
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
    Tcl_Obj *objPtr,		/* The object from which to get mms. */
    double *doublePtr)		/* Place to store resulting millimeters. */
{
    int result;
    double d;
    MMRep *mmPtr;
    static const double bias[] = {
	10.0,	25.4,	1.0,	0.35278 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}







|







545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
    Tcl_Obj *objPtr,		/* The object from which to get mms. */
    double *doublePtr)		/* Place to store resulting millimeters. */
{
    int result;
    double d;
    MMRep *mmPtr;
    static const double bias[] = {
	10.0,	25.4,	1.0,	0.35277777777777775 /*25.4 / 72.0*/
    };

    if (objPtr->typePtr != &mmObjType) {
	result = SetMMFromAny(interp, objPtr);
	if (result != TCL_OK) {
	    return result;
	}
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761

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








|







659
660
661
662
663
664
665
666
667
668
669
670
671
672
673

static void
UpdateStringOfMM(
    Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    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
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))) {







|





|
<
<
<
|










>
>









<
<
<
<
<







701
702
703
704
705
706
707
708
709
710
711
712
713
714



715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736





737
738
739
740
741
742
743
static int
SetMMFromAny(
    Tcl_Interp *interp,		/* Used for error reporting if not NULL. */
    Tcl_Obj *objPtr)		/* The object to convert. */
{
    ThreadSpecificData *typeCache = GetTypeCache();
    const Tcl_ObjType *typePtr;
    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 {
	/*
	 * It wasn't a known int or double, so parse it.
	 */

	string = Tcl_GetString(objPtr);

	d = strtod(string, &rest);
	if (rest == string) {





	error:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad screen distance \"%s\"", string));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "DISTANCE", NULL);
	    return TCL_ERROR;
	}
	while ((*rest != '\0') && isspace(UCHAR(*rest))) {
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * Tk_NewWindowObj --
 *
 *	This function allocates a new Tcl_Obj that refers to a particular to a
 *	particular Tk window.
 *
 * Results:
 *	A standard Tcl object reference, with refcount 0.
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Tcl_Obj *
Tk_NewWindowObj(
    Tk_Window tkwin)
{
    Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    SetWindowFromAny(NULL, objPtr);







|

|
|











|







958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
    objPtr->internalRep.twoPtrValue.ptr1 = NULL;
    objPtr->typePtr = NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkNewWindowObj --
 *
 *	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 *
TkNewWindowObj(
    Tk_Window tkwin)
{
    Tcl_Obj *objPtr = Tcl_NewStringObj(Tk_PathName(tkwin), -1);
    TkMainInfo *mainPtr = ((TkWindow *) tkwin)->mainPtr;
    WindowRep *winPtr;

    SetWindowFromAny(NULL, objPtr);
Changes to generic/tkOldConfig.c.
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
 *
 * 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);

/*







<
<
<
<
<
<
<
<
|
<
|
<
<








|




|

|







10
11
12
13
14
15
16








17

18


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"









#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, char *widgRec);
static Tk_ConfigSpec *	FindConfigSpec(Tcl_Interp *interp,
			    Tk_ConfigSpec *specs, const char *argvName,
			    int needFlags, int hateFlags);
static char *		FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, char *widgRec);
static const char *	FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin,
			    const Tk_ConfigSpec *specPtr, char *widgRec,
			    char *buffer, Tcl_FreeProc **freeProcPtr);
static Tk_ConfigSpec *	GetCachedSpecs(Tcl_Interp *interp,
			    const Tk_ConfigSpec *staticSpecs);
static void		DeleteSpecCacheTable(ClientData clientData,
			    Tcl_Interp *interp);

/*
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
    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 {







|







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
    if (tkwin == NULL) {
	/*
	 * Either we're not really in Tk, or the main window was destroyed and
	 * we're on our way out of the application
	 */

	Tcl_SetObjResult(interp, Tcl_NewStringObj("NULL main window", -1));
	Tcl_SetErrorCode(interp, "TK", "NO_MAIN_WINDOW", (char *)NULL);
	return TCL_ERROR;
    }

    needFlags = flags & ~(TK_CONFIG_USER_BIT - 1);
    if (Tk_Depth(tkwin) <= 1) {
	hateFlags = TK_CONFIG_COLOR_ONLY;
    } else {
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
	/*
	 * 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];
	}







|







131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
	/*
	 * Process the entry.
	 */

	if (argc < 2) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "value for \"%s\" missing", arg));
	    Tcl_SetErrorCode(interp, "TK", "VALUE_MISSING", (char *)NULL);
	    return TCL_ERROR;
	}
	if (flags & TK_CONFIG_OBJS) {
	    arg = Tcl_GetString((Tcl_Obj *) argv[1]);
	} else {
	    arg = argv[1];
	}
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
	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;







|








|

















|







261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
	if (specPtr->argvName[length] == 0) {
	    matchPtr = specPtr;
	    goto gotMatch;
	}
	if (matchPtr != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "ambiguous option \"%s\"", argvName));
	    Tcl_SetErrorCode(interp, "TK", "LOOKUP", "OPTION", argvName, (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;
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358





359



360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window containing widget (needed to set up
				 * X resources). */
    Tk_ConfigSpec *specPtr,	/* Specifier to apply. */
    Tk_Uid value,		/* Value to use to fill in widgRec. */
    int valueIsUid,		/* Non-zero means value is a Tk_Uid; zero
				 * means it's an ordinary string. */
    void *widgRec)		/* Record whose fields are to be modified.
				 * Values must be properly initialized. */
{
    void *ptr;
    Tk_Uid uid;
    int nullValue;

    nullValue = 0;
    if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) {
	nullValue = 1;
    }






    do {



	ptr = (char *)widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_INT:
	    if (Tcl_GetInt(interp, value, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_DOUBLE:
	    if (Tcl_GetDouble(interp, value, (double *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_STRING: {
	    char *oldStr, *newStr;

	    if (nullValue) {
		newStr = NULL;
	    } else {
		newStr = (char *)ckalloc(strlen(value) + 1);
		strcpy(newStr, value);
	    }
	    oldStr = *((char **) ptr);
	    if (oldStr != NULL) {
		ckfree(oldStr);
	    }
	    *((char **) ptr) = newStr;
	    break;
	}
	case TK_CONFIG_UID:
	    if (nullValue) {
		*((Tk_Uid *) ptr) = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		*((Tk_Uid *) ptr) = uid;
	    }
	    break;
	case TK_CONFIG_COLOR: {
	    XColor *newPtr, *oldPtr;

	    if (nullValue) {
		newPtr = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newPtr = Tk_GetColor(interp, tkwin, uid);
		if (newPtr == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldPtr = *((XColor **) ptr);
	    if (oldPtr != NULL) {
		Tk_FreeColor(oldPtr);
	    }
	    *((XColor **) ptr) = newPtr;
	    break;
	}
	case TK_CONFIG_FONT: {
	    Tk_Font newFont;

	    if (nullValue) {
		newFont = NULL;
	    } else {
		newFont = Tk_GetFont(interp, tkwin, value);
		if (newFont == NULL) {
		    return TCL_ERROR;
		}
	    }
	    Tk_FreeFont(*((Tk_Font *) ptr));
	    *((Tk_Font *) ptr) = newFont;
	    break;
	}
	case TK_CONFIG_BITMAP: {
	    Pixmap newBmp, oldBmp;

	    if (nullValue) {
		newBmp = None;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newBmp = Tk_GetBitmap(interp, tkwin, uid);
		if (newBmp == None) {
		    return TCL_ERROR;
		}
	    }
	    oldBmp = *((Pixmap *) ptr);
	    if (oldBmp != None) {
		Tk_FreeBitmap(Tk_Display(tkwin), oldBmp);
	    }
	    *((Pixmap *) ptr) = newBmp;
	    break;
	}
	case TK_CONFIG_BORDER: {
	    Tk_3DBorder newBorder, oldBorder;

	    if (nullValue) {
		newBorder = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newBorder = Tk_Get3DBorder(interp, tkwin, uid);
		if (newBorder == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldBorder = *((Tk_3DBorder *) ptr);
	    if (oldBorder != NULL) {
		Tk_Free3DBorder(oldBorder);
	    }
	    *((Tk_3DBorder *) ptr) = newBorder;
	    break;
	}
	case TK_CONFIG_RELIEF:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetRelief(interp, uid, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_CURSOR:
	case TK_CONFIG_ACTIVE_CURSOR: {
	    Tk_Cursor newCursor, oldCursor;

	    if (nullValue) {
		newCursor = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newCursor = Tk_GetCursor(interp, tkwin, uid);
		if (newCursor == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldCursor = *((Tk_Cursor *) ptr);
	    if (oldCursor != NULL) {
		Tk_FreeCursor(Tk_Display(tkwin), oldCursor);
	    }
	    *((Tk_Cursor *) ptr) = newCursor;
	    if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) {
		Tk_DefineCursor(tkwin, newCursor);
	    }
	    break;
	}
	case TK_CONFIG_JUSTIFY:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetJustify(interp, uid, (Tk_Justify *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_ANCHOR:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetAnchor(interp, uid, (Tk_Anchor *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_CAP_STYLE:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetCapStyle(interp, uid, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_JOIN_STYLE:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetJoinStyle(interp, uid, (int *) ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_PIXELS:
	    if (Tk_GetPixels(interp, tkwin, value, (int *) ptr)
		!= TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_MM:
	    if (Tk_GetScreenMM(interp, tkwin, value, (double*)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_WINDOW: {
	    Tk_Window tkwin2;

	    if (nullValue) {
		tkwin2 = NULL;
	    } else {
		tkwin2 = Tk_NameToWindow(interp, value, tkwin);
		if (tkwin2 == NULL) {
		    return TCL_ERROR;
		}
	    }
	    *((Tk_Window *) ptr) = tkwin2;
	    break;
	}
	case TK_CONFIG_CUSTOM:
	    if (specPtr->customPtr->parseProc(specPtr->customPtr->clientData,
		    interp, tkwin, value, (char *)widgRec, specPtr->offset)!=TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	default:
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad config table: unknown type %d", specPtr->type));
	    Tcl_SetErrorCode(interp, "TK", "BAD_CONFIG", NULL);
	    return TCL_ERROR;
	}
	specPtr++;
    } while ((specPtr->argvName == NULL) && (specPtr->type != TK_CONFIG_END));
    return TCL_OK;
}








|


|




|



>
>
>
>
>

>
>
>
|


|




|




|












|



|




|

|
|














|



|













|
|














|



|














|



|




|
















|



|







|





|





|





|




|





|














|




|






|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Tk_Window tkwin,		/* Window containing widget (needed to set up
				 * X resources). */
    Tk_ConfigSpec *specPtr,	/* Specifier to apply. */
    Tk_Uid value,		/* Value to use to fill in widgRec. */
    int valueIsUid,		/* Non-zero means value is a Tk_Uid; zero
				 * means it's an ordinary string. */
    char *widgRec)		/* Record whose fields are to be modified.
				 * Values must be properly initialized. */
{
    char *ptr;
    Tk_Uid uid;
    int nullValue;

    nullValue = 0;
    if ((*value == 0) && (specPtr->specFlags & (TK_CONFIG_NULL_OK|32 /* TCL_NULL_OK */))) {
	nullValue = 1;
    }

    if (specPtr->specFlags & TK_CONFIG_OBJS) {
	/* Prevent surprises, TK_CONFIG_OBJS is not supported here in 8.6 */
	Tcl_AppendResult(interp, "TK_CONFIG_OBJS not supported", (char *)NULL);
	return TCL_ERROR;
    }
    do {
	if (specPtr->offset < 0) {
	    break;
	}
	ptr = widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_BOOLEAN:
	    if (Tcl_GetBoolean(interp, value, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_INT:
	    if (Tcl_GetInt(interp, value, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_DOUBLE:
	    if (Tcl_GetDouble(interp, value, (double *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_STRING: {
	    char *oldStr, *newStr;

	    if (nullValue) {
		newStr = NULL;
	    } else {
		newStr = (char *)ckalloc(strlen(value) + 1);
		strcpy(newStr, value);
	    }
	    oldStr = *((char **)ptr);
	    if (oldStr != NULL) {
		ckfree(oldStr);
	    }
	    *((char **)ptr) = newStr;
	    break;
	}
	case TK_CONFIG_UID:
	    if (nullValue) {
		*((Tk_Uid *)ptr) = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid)value : Tk_GetUid(value);
		*((Tk_Uid *)ptr) = uid;
	    }
	    break;
	case TK_CONFIG_COLOR: {
	    XColor *newPtr, *oldPtr;

	    if (nullValue) {
		newPtr = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newPtr = Tk_GetColor(interp, tkwin, uid);
		if (newPtr == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldPtr = *((XColor **)ptr);
	    if (oldPtr != NULL) {
		Tk_FreeColor(oldPtr);
	    }
	    *((XColor **)ptr) = newPtr;
	    break;
	}
	case TK_CONFIG_FONT: {
	    Tk_Font newFont;

	    if (nullValue) {
		newFont = NULL;
	    } else {
		newFont = Tk_GetFont(interp, tkwin, value);
		if (newFont == NULL) {
		    return TCL_ERROR;
		}
	    }
	    Tk_FreeFont(*((Tk_Font *)ptr));
	    *((Tk_Font *)ptr) = newFont;
	    break;
	}
	case TK_CONFIG_BITMAP: {
	    Pixmap newBmp, oldBmp;

	    if (nullValue) {
		newBmp = None;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newBmp = Tk_GetBitmap(interp, tkwin, uid);
		if (newBmp == None) {
		    return TCL_ERROR;
		}
	    }
	    oldBmp = *((Pixmap *)ptr);
	    if (oldBmp != None) {
		Tk_FreeBitmap(Tk_Display(tkwin), oldBmp);
	    }
	    *((Pixmap *)ptr) = newBmp;
	    break;
	}
	case TK_CONFIG_BORDER: {
	    Tk_3DBorder newBorder, oldBorder;

	    if (nullValue) {
		newBorder = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newBorder = Tk_Get3DBorder(interp, tkwin, uid);
		if (newBorder == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldBorder = *((Tk_3DBorder *)ptr);
	    if (oldBorder != NULL) {
		Tk_Free3DBorder(oldBorder);
	    }
	    *((Tk_3DBorder *)ptr) = newBorder;
	    break;
	}
	case TK_CONFIG_RELIEF:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetRelief(interp, uid, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_CURSOR:
	case TK_CONFIG_ACTIVE_CURSOR: {
	    Tk_Cursor newCursor, oldCursor;

	    if (nullValue) {
		newCursor = NULL;
	    } else {
		uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
		newCursor = Tk_GetCursor(interp, tkwin, uid);
		if (newCursor == NULL) {
		    return TCL_ERROR;
		}
	    }
	    oldCursor = *((Tk_Cursor *)ptr);
	    if (oldCursor != NULL) {
		Tk_FreeCursor(Tk_Display(tkwin), oldCursor);
	    }
	    *((Tk_Cursor *)ptr) = newCursor;
	    if (specPtr->type == TK_CONFIG_ACTIVE_CURSOR) {
		Tk_DefineCursor(tkwin, newCursor);
	    }
	    break;
	}
	case TK_CONFIG_JUSTIFY:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetJustify(interp, uid, (Tk_Justify *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_ANCHOR:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetAnchor(interp, uid, (Tk_Anchor *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_CAP_STYLE:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetCapStyle(interp, uid, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_JOIN_STYLE:
	    uid = valueIsUid ? (Tk_Uid) value : Tk_GetUid(value);
	    if (Tk_GetJoinStyle(interp, uid, (int *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_PIXELS:
	    if (Tk_GetPixels(interp, tkwin, value, (int *)ptr)
		!= TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_MM:
	    if (Tk_GetScreenMM(interp, tkwin, value, (double *)ptr) != TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	case TK_CONFIG_WINDOW: {
	    Tk_Window tkwin2;

	    if (nullValue) {
		tkwin2 = NULL;
	    } else {
		tkwin2 = Tk_NameToWindow(interp, value, tkwin);
		if (tkwin2 == NULL) {
		    return TCL_ERROR;
		}
	    }
	    *((Tk_Window *)ptr) = tkwin2;
	    break;
	}
	case TK_CONFIG_CUSTOM:
	    if (specPtr->customPtr->parseProc(specPtr->customPtr->clientData,
		    interp, tkwin, value, widgRec, specPtr->offset)!=TCL_OK) {
		return TCL_ERROR;
	    }
	    break;
	default:
	    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;
}

652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
	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;
}

/*







|



|







649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
	if ((argvName != NULL) && (specPtr->argvName != argvName)) {
	    continue;
	}
	if (((specPtr->specFlags & needFlags) != needFlags)
		|| (specPtr->specFlags & hateFlags)) {
	    continue;
	}
	if ((specPtr->argvName == NULL) || (specPtr->offset < 0)) {
	    continue;
	}
	list = FormatConfigInfo(interp, tkwin, specPtr, widgRec);
	Tcl_AppendResult(interp, leader, list, "}", (char *)NULL);
	ckfree(list);
	leader = " {";
    }
    return TCL_OK;
}

/*
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
FormatConfigInfo(
    Tcl_Interp *interp,		/* Interpreter to use for things like
				 * floating-point precision. */
    Tk_Window tkwin,		/* Window corresponding to widget. */
    const Tk_ConfigSpec *specPtr,
				/* Pointer to information describing
				 * option. */
    void *widgRec)		/* Pointer to record holding current values of
				 * info for widget. */
{
    const char *argv[6];
    char *result;
    char buffer[200];
    Tcl_FreeProc *freeProc = NULL;








|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
FormatConfigInfo(
    Tcl_Interp *interp,		/* Interpreter to use for things like
				 * floating-point precision. */
    Tk_Window tkwin,		/* Window corresponding to widget. */
    const Tk_ConfigSpec *specPtr,
				/* Pointer to information describing
				 * option. */
    char *widgRec)		/* Pointer to record holding current values of
				 * info for widget. */
{
    const char *argv[6];
    char *result;
    char buffer[200];
    Tcl_FreeProc *freeProc = NULL;

720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
	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;
}

/*
 *----------------------------------------------------------------------







|
|

|







717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
	argv[3] = "";
    }
    if (argv[4] == NULL) {
	argv[4] = "";
    }
    result = Tcl_Merge(5, argv);
    if (freeProc != NULL) {
	if (freeProc == TCL_DYNAMIC) {
	    ckfree((char *)argv[4]);
	} else {
	    freeProc((char *)argv[4]);
	}
    }
    return result;
}

/*
 *----------------------------------------------------------------------
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773



774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

static const char *
FormatConfigValue(
    Tcl_Interp *interp,		/* Interpreter for use in real conversions. */
    Tk_Window tkwin,		/* Window corresponding to widget. */
    const Tk_ConfigSpec *specPtr, /* Pointer to information describing option.
				 * Must not point to a synonym option. */
    void *widgRec,		/* Pointer to record holding current values of
				 * info for widget. */
    char *buffer,		/* Static buffer to use for small values.
				 * Must have at least 200 bytes of storage. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to word to fill in with address of
				 * function to free the result, or NULL if
				 * result is static. */
{
    void *ptr;
    const char *result;

    *freeProcPtr = NULL;



    ptr = (char *)widgRec + specPtr->offset;
    result = "";
    switch (specPtr->type) {
    case TK_CONFIG_BOOLEAN:
	if (*((int *)ptr) == 0) {
	    result = "0";
	} else {
	    result = "1";
	}
	break;
    case TK_CONFIG_INT:
	sprintf(buffer, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_DOUBLE:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_STRING:







|











>
>
>
|










|







752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

static const char *
FormatConfigValue(
    Tcl_Interp *interp,		/* Interpreter for use in real conversions. */
    Tk_Window tkwin,		/* Window corresponding to widget. */
    const Tk_ConfigSpec *specPtr, /* Pointer to information describing option.
				 * Must not point to a synonym option. */
    char *widgRec,		/* Pointer to record holding current values of
				 * info for widget. */
    char *buffer,		/* Static buffer to use for small values.
				 * Must have at least 200 bytes of storage. */
    Tcl_FreeProc **freeProcPtr)	/* Pointer to word to fill in with address of
				 * function to free the result, or NULL if
				 * result is static. */
{
    void *ptr;
    const char *result;

    *freeProcPtr = NULL;
    if (specPtr->offset < 0) {
	return NULL;
    }
    ptr = 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
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
    case TK_CONFIG_CAP_STYLE:
	result = Tk_NameOfCapStyle(*((int *)ptr));
	break;
    case TK_CONFIG_JOIN_STYLE:
	result = Tk_NameOfJoinStyle(*((int *)ptr));
	break;
    case TK_CONFIG_PIXELS:
	sprintf(buffer, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_MM:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_WINDOW: {
	tkwin = *((Tk_Window *)ptr);
	if (tkwin != NULL) {
	    result = Tk_PathName(tkwin);
	}
	break;
    }
    case TK_CONFIG_CUSTOM:
	result = specPtr->customPtr->printProc(specPtr->customPtr->clientData,
		tkwin, (char *)widgRec, specPtr->offset, freeProcPtr);
	break;
    default:
	result = "?? unknown type ??";
    }
    return result;
}








|















|







856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
    case TK_CONFIG_CAP_STYLE:
	result = Tk_NameOfCapStyle(*((int *)ptr));
	break;
    case TK_CONFIG_JOIN_STYLE:
	result = Tk_NameOfJoinStyle(*((int *)ptr));
	break;
    case TK_CONFIG_PIXELS:
	snprintf(buffer, 200, "%d", *((int *)ptr));
	result = buffer;
	break;
    case TK_CONFIG_MM:
	Tcl_PrintDouble(interp, *((double *)ptr), buffer);
	result = buffer;
	break;
    case TK_CONFIG_WINDOW: {
	tkwin = *((Tk_Window *)ptr);
	if (tkwin != NULL) {
	    result = Tk_PathName(tkwin);
	}
	break;
    }
    case TK_CONFIG_CUSTOM:
	result = specPtr->customPtr->printProc(specPtr->customPtr->clientData,
		tkwin, widgRec, specPtr->offset, freeProcPtr);
	break;
    default:
	result = "?? unknown type ??";
    }
    return result;
}

940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
    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;
}

/*
 *----------------------------------------------------------------------







|
|

|







940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
    if (specPtr == NULL) {
	return TCL_ERROR;
    }
    result = FormatConfigValue(interp, tkwin, specPtr, widgRec, buffer,
	    &freeProc);
    Tcl_SetObjResult(interp, Tcl_NewStringObj(result, -1));
    if (freeProc != NULL) {
	if (freeProc == TCL_DYNAMIC) {
	    ckfree((char *)result);
	} else {
	    freeProc((char *)result);
	}
    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
987
988
989
990
991
992
993



994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
{
    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;
	case TK_CONFIG_COLOR:
	    if (*((XColor **) ptr) != NULL) {
		Tk_FreeColor(*((XColor **) ptr));
		*((XColor **) ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_FONT:
	    Tk_FreeFont(*((Tk_Font *) ptr));
	    *((Tk_Font *) ptr) = NULL;
	    break;
	case TK_CONFIG_BITMAP:
	    if (*((Pixmap *) ptr) != None) {
		Tk_FreeBitmap(display, *((Pixmap *) ptr));
		*((Pixmap *) ptr) = None;
	    }
	    break;
	case TK_CONFIG_BORDER:
	    if (*((Tk_3DBorder *) ptr) != NULL) {
		Tk_Free3DBorder(*((Tk_3DBorder *) ptr));
		*((Tk_3DBorder *) ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_CURSOR:
	case TK_CONFIG_ACTIVE_CURSOR:
	    if (*((Tk_Cursor *) ptr) != NULL) {
		Tk_FreeCursor(display, *((Tk_Cursor *) ptr));
		*((Tk_Cursor *) ptr) = NULL;
	    }
	}
    }
}

/*
 *--------------------------------------------------------------







>
>
>




|
|
|



|
|
|



|
|


|
|
|



|
|
|




|
|
|







987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
{
    const Tk_ConfigSpec *specPtr;
    char *ptr;

    for (specPtr = specs; specPtr->type != TK_CONFIG_END; specPtr++) {
	if ((specPtr->specFlags & needFlags) != needFlags) {
	    continue;
	}
	if (specPtr->offset < 0) {
	    continue;
	}
	ptr = widgRec + specPtr->offset;
	switch (specPtr->type) {
	case TK_CONFIG_STRING:
	    if (*((char **)ptr) != NULL) {
		ckfree(*((char **)ptr));
		*((char **)ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_COLOR:
	    if (*((XColor **)ptr) != NULL) {
		Tk_FreeColor(*((XColor **)ptr));
		*((XColor **)ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_FONT:
	    Tk_FreeFont(*((Tk_Font *)ptr));
	    *((Tk_Font *)ptr) = NULL;
	    break;
	case TK_CONFIG_BITMAP:
	    if (*((Pixmap *)ptr) != None) {
		Tk_FreeBitmap(display, *((Pixmap *)ptr));
		*((Pixmap *)ptr) = None;
	    }
	    break;
	case TK_CONFIG_BORDER:
	    if (*((Tk_3DBorder *)ptr) != NULL) {
		Tk_Free3DBorder(*((Tk_3DBorder *)ptr));
		*((Tk_3DBorder *)ptr) = NULL;
	    }
	    break;
	case TK_CONFIG_CURSOR:
	case TK_CONFIG_ACTIVE_CURSOR:
	    if (*((Tk_Cursor *)ptr) != NULL) {
		Tk_FreeCursor(display, *((Tk_Cursor *)ptr));
		*((Tk_Cursor *)ptr) = NULL;
	    }
	}
    }
}

/*
 *--------------------------------------------------------------
Changes to generic/tkOldTest.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26



27
28
29
30
31
32
33
34
/*
 * 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. */










|















>
>
>
|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
/*
 * tkOldTest.c --
 *
 *	This file contains C command functions for additional Tcl
 *	commands that are used to test Tk's support for legacy
 *	interfaces.  These commands are not normally included in Tcl/Tk
 *	applications; they're only used for testing.
 *
 * Copyright (c) 1993-1994 The Regents of the University of California.
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
 * Copyright (c) 1998-1999 Scriptics Corporation.
 * Contributions by Don Porter, NIST, 2007.  (not subject to US copyright)
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#define USE_OLD_IMAGE
#ifndef USE_TCL_STUBS
#   define USE_TCL_STUBS
#endif
#ifndef USE_TK_STUBS
#   define USE_TK_STUBS
#endif
#include "tkInt.h"

#ifdef _WIN32
#include "tkWinInt.h"
#endif

/*
 * The following data structure represents the model for a test image:
 */

typedef struct TImageModel {
    Tk_ImageModel model;        /* Tk's token for image model. */
    Tcl_Interp *interp;         /* Interpreter for application. */
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
/*
 * 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







|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
 * Forward declarations for functions defined later in this file:
 */

static int              ImageObjCmd(ClientData dummy,
                            Tcl_Interp *interp, int objc,
            			    Tcl_Obj * const objv[]);


/*
 *----------------------------------------------------------------------
 *
 * TkOldTestInit --
 *
 *	This function performs initialization for the Tk test suite
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 *	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;
}








|


<



<

<



















|
>

















<
















|




|

|







106
107
108
109
110
111
112
113
114
115

116
117
118

119

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

158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
 *	Creates several test commands.
 *
 *----------------------------------------------------------------------
 */

int
TkOldTestInit(
    Tcl_Interp *interp)
{
    static int initialized = 0;


    if (!initialized) {
	initialized = 1;

	Tk_CreateImageType(&imageType);

    }
    return TCL_OK;
}

/*
 *----------------------------------------------------------------------
 *
 * ImageCreate --
 *
 *	This function is called by the Tk image code to create "oldtest" images.
 *
 * Results:
 *	A standard Tcl result.
 *
 * Side effects:
 *	The data structure for a new image is allocated.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
ImageCreate(
    Tcl_Interp *interp,		/* Interpreter for application containing
				 * image. */
    char *name,			/* Name to use for image. */
    int argc,			/* Number of arguments. */
    char **argv,		/* Argument strings for options (doesn't
				 * include image name or type). */
    Tk_ImageType *typePtr,	/* Pointer to our type record (not used). */
    Tk_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 < 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 = ckalloc(sizeof(TImageModel));
    timPtr->model = model;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = ckalloc(strlen(name) + 1);
    strcpy(timPtr->imageName, name);
    timPtr->varName = ckalloc(strlen(varName) + 1);
    strcpy(timPtr->varName, varName);
    Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
    *clientDataPtr = timPtr;
    Tk_ImageChanged(model, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}

199
200
201
202
203
204
205

206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
 *
 * 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) {







>







|







199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
 *
 * Side effects:
 *	Forces windows to be created.
 *
 *----------------------------------------------------------------------
 */

	/* ARGSUSED */
static int
ImageObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    TImageModel *timPtr = clientData;
    int x, y, width, height;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
    if (strcmp(Tcl_GetString(objv[1]), "changed") == 0) {
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284

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







|




|



|







262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285

static ClientData
ImageGet(
    Tk_Window tkwin,		/* Token for window in which image will be
				 * used. */
    ClientData clientData)	/* Pointer to TImageModel for image. */
{
    TImageModel *timPtr = 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 = ckalloc(sizeof(TImageInstance));
    instPtr->modelPtr = timPtr;
    instPtr->fg = Tk_GetColor(timPtr->interp, tkwin, "#ff0000");
    gcValues.foreground = instPtr->fg->pixel;
    instPtr->gc = Tk_GetGC(tkwin, GCForeground, &gcValues);
    return instPtr;
}

308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
    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;
    }







|


|







309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
    int imageX, int imageY,	/* Origin of area to redraw, relative to
				 * origin of image. */
    int width, int height,	/* Dimensions of area to redraw. */
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];

    snprintf(buffer, sizeof(buffer), "%s display %d %d %d %d %d %d",
	    instPtr->modelPtr->imageName, imageX, imageY, width, height,
	    drawableX, drawableY);
    Tcl_SetVar2(instPtr->modelPtr->interp, instPtr->modelPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->modelPtr->width - imageX)) {
	width = instPtr->modelPtr->width - imageX;
    }
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
 */

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







|


|







354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
 */

static void
ImageFree(
    ClientData clientData,	/* Pointer to TImageInstance for instance. */
    Display *display)		/* Display where image was to be drawn. */
{
    TImageInstance *instPtr = 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);
}

387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = (TImageModel *)clientData;
    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:
 */







|


|








<








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

407
408
409
410
411
412
413
414

static void
ImageDelete(
    ClientData clientData)	/* Pointer to TImageModel for image. When
				 * this function is called, no more instances
				 * exist. */
{
    TImageModel *timPtr = 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);
}


/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkOption.c.
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
     * option database is densely populated, or if the widget has many
     * masquerading options.
     */

    if (masqName != NULL) {
	char *masqClass;
	Tk_Uid nodeId, winClassId, winNameId;
	TkSizeT classNameLength;
	Element *nodePtr, *leafPtr;
	static const int searchOrder[] = {
	    EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS,
	    WILDCARD_NODE_CLASS, -1
	};
	const int *currentPtr;
	int currentStack, leafCount;

	/*
	 * Extract the masquerade class name from the name field.
	 */

	classNameLength	= masqName - name;
	masqClass = (char *)ckalloc(classNameLength + 1);
	strncpy(masqClass, name, classNameLength);
	masqClass[classNameLength] = '\0';

	winClassId = Tk_GetUid(masqClass);
	ckfree(masqClass);
	winNameId = ((TkWindow *) tkwin)->nameUid;







|












|







517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
     * option database is densely populated, or if the widget has many
     * masquerading options.
     */

    if (masqName != NULL) {
	char *masqClass;
	Tk_Uid nodeId, winClassId, winNameId;
	size_t classNameLength;
	Element *nodePtr, *leafPtr;
	static const int searchOrder[] = {
	    EXACT_NODE_NAME, WILDCARD_NODE_NAME, EXACT_NODE_CLASS,
	    WILDCARD_NODE_CLASS, -1
	};
	const int *currentPtr;
	int currentStack, leafCount;

	/*
	 * Extract the masquerade class name from the name field.
	 */

	classNameLength	= (size_t) (masqName - name);
	masqClass = (char *)ckalloc(classNameLength + 1);
	strncpy(masqClass, name, classNameLength);
	masqClass[classNameLength] = '\0';

	winClassId = Tk_GetUid(masqClass);
	ckfree(masqClass);
	winNameId = ((TkWindow *) tkwin)->nameUid;
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
    int priority)		/* Priority level to use for options in this
				 * file, such as TK_USER_DEFAULT_PRIO or
				 * TK_INTERACTIVE_PRIO. Must be between 0 and
				 * TK_MAX_PRIO. */
{
    const char *realName;
    Tcl_Obj *buffer;
    int result;
    TkSizeT bufferSize;
    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * Prevent file system access in a safe interpreter.
     */








|
<







1080
1081
1082
1083
1084
1085
1086
1087

1088
1089
1090
1091
1092
1093
1094
    int priority)		/* Priority level to use for options in this
				 * file, such as TK_USER_DEFAULT_PRIO or
				 * TK_INTERACTIVE_PRIO. Must be between 0 and
				 * TK_MAX_PRIO. */
{
    const char *realName;
    Tcl_Obj *buffer;
    int result, bufferSize;

    Tcl_Channel chan;
    Tcl_DString newName;

    /*
     * Prevent file system access in a safe interpreter.
     */

1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
	return TCL_ERROR;
    }

    buffer = Tcl_NewObj();
    Tcl_IncrRefCount(buffer);
    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
    bufferSize = Tcl_ReadChars(chan, buffer, -1, 0);
    if (bufferSize == TCL_IO_FAILURE) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading file \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    Tcl_Close(NULL, chan);







|







1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
	return TCL_ERROR;
    }

    buffer = Tcl_NewObj();
    Tcl_IncrRefCount(buffer);
    Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8");
    bufferSize = Tcl_ReadChars(chan, buffer, -1, 0);
    if (bufferSize == -1) {
	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		"error reading file \"%s\": %s",
		fileName, Tcl_PosixError(interp)));
	Tcl_Close(NULL, chan);
	return TCL_ERROR;
    }
    Tcl_Close(NULL, chan);
Changes to generic/tkPack.c.
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
/*
 * 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);

/*







|

<


<







116
117
118
119
120
121
122
123
124

125
126

127
128
129
130
131
132
133
/*
 * Forward declarations for functions defined later in this file:
 */

static void		ArrangePacking(ClientData clientData);
static int		ConfigureContent(Tcl_Interp *interp, Tk_Window tkwin,
			    int objc, Tcl_Obj *const objv[]);
static Tcl_FreeProc	DestroyPacker;
static Packer *		GetPacker(Tk_Window tkwin);

static int		PackAfter(Tcl_Interp *interp, Packer *prevPtr,
			    Packer *containerPtr, int objc,Tcl_Obj *const objv[]);

static void		PackStructureProc(ClientData clientData,
			    XEvent *eventPtr);
static void		Unlink(Packer *packPtr);
static int		XExpansion(Packer *contentPtr, int cavityWidth);
static int		YExpansion(Packer *contentPtr, int cavityHeight);

/*
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
    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));
    }
}

/*
 *------------------------------------------------------------------------







|

|
|







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    int halfSpace,		/* The left or top padding amount */
    int allSpace)		/* The total amount of padding */
{
    Tcl_Obj *padding[2];

    if (halfSpace*2 == allSpace) {
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1),
		Tcl_NewIntObj(halfSpace));
    } else {
	padding[0] = Tcl_NewIntObj(halfSpace);
	padding[1] = Tcl_NewIntObj(allSpace - halfSpace);
	Tcl_DictObjPut(NULL, bufferObj, Tcl_NewStringObj(switchName, -1),
		Tcl_NewListObj(2, padding));
    }
}

/*
 *------------------------------------------------------------------------
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250


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


268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284


285
286
287
288
289
290
291
    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;







|
|
<
|
<
<

<
|
<
|














|
|






|
|





<







|
>
>
















|
>
>
















|
>
>







193
194
195
196
197
198
199
200
201

202


203

204

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

235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    Tk_Window tkwin = (Tk_Window)clientData;
    const char *argv2;
    static const char *const optionStrings[] = {
	/* after, append, before and unpack are deprecated */
	"after", "append", "before", "unpack", "configure",

	"content", "forget", "info", "propagate", "slaves", NULL };


    enum options {

	PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK, 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], &optionStrings[4],
		"option", 0, &index);
	return TCL_ERROR;
    }

    argv2 = Tcl_GetString(objv[2]);
    switch ((enum options) index) {

    case PACK_AFTER: {
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!(prevPtr = GetPacker(tkwin2))) {
	    return TCL_OK;
	}
	if (prevPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}
	return PackAfter(interp, prevPtr, prevPtr->containerPtr, objc-3, objv+3);
    }
    case PACK_APPEND: {
	Packer *containerPtr;
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!(containerPtr = GetPacker(tkwin2))) {
	    return TCL_OK;
	}
	prevPtr = containerPtr->contentPtr;
	if (prevPtr != NULL) {
	    while (prevPtr->nextPtr != NULL) {
		prevPtr = prevPtr->nextPtr;
	    }
	}
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }
    case PACK_BEFORE: {
	Packer *packPtr, *containerPtr;
	Packer *prevPtr;
	Tk_Window tkwin2;

	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!(packPtr = GetPacker(tkwin2))) {
	    return TCL_OK;
	}
	if (packPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}
	containerPtr = packPtr->containerPtr;
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325


326
327
328
329
330
331
332
		if (prevPtr->nextPtr == packPtr) {
		    break;
		}
	    }
	}
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }
#endif /* !TK_NO_DEPRECATED */
    case PACK_CONFIGURE:
	if (argv2[0] != '.') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad argument \"%s\": must be name of window", argv2));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
	    return TCL_ERROR;
	}
	return ConfigureContent(interp, tkwin, objc-2, objv+2);
    case PACK_FORGET: {
	Tk_Window content;
	Packer *contentPtr;
	int i;

	for (i = 2; i < objc; i++) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		continue;
	    }
	    contentPtr = GetPacker(content);


	    if ((contentPtr != NULL) && (contentPtr->containerPtr != NULL)) {
		Tk_ManageGeometry(content, NULL, NULL);
		if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		    Tk_UnmaintainGeometry(contentPtr->tkwin,
			    contentPtr->containerPtr->tkwin);
		}
		Unlink(contentPtr);







<

















|
>
>







298
299
300
301
302
303
304

305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
		if (prevPtr->nextPtr == packPtr) {
		    break;
		}
	    }
	}
	return PackAfter(interp, prevPtr, containerPtr, objc-3, objv+3);
    }

    case PACK_CONFIGURE:
	if (argv2[0] != '.') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "bad argument \"%s\": must be name of window", argv2));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL);
	    return TCL_ERROR;
	}
	return ConfigureContent(interp, tkwin, objc-2, objv+2);
    case PACK_FORGET: {
	Tk_Window content;
	Packer *contentPtr;
	int i;

	for (i = 2; i < objc; i++) {
	    if (TkGetWindowFromObj(interp, tkwin, objv[i], &content) != TCL_OK) {
		continue;
	    }
	    if (!(contentPtr = GetPacker(content))) {
		continue;
	    }
	    if ((contentPtr != NULL) && (contentPtr->containerPtr != NULL)) {
		Tk_ManageGeometry(content, NULL, NULL);
		if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
		    Tk_UnmaintainGeometry(contentPtr->tkwin,
			    contentPtr->containerPtr->tkwin);
		}
		Unlink(contentPtr);
343
344
345
346
347
348
349
350


351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	    return TCL_ERROR;
	}
	contentPtr = GetPacker(content);


	if (contentPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}

	infoObj = Tcl_NewObj();
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
		Tk_NewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-anchor", -1),
		Tcl_NewStringObj(Tk_NameOfAnchor(contentPtr->anchor), -1));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-expand", -1),
		Tcl_NewBooleanObj(contentPtr->flags & EXPAND));
	switch (contentPtr->flags & (FILLX|FILLY)) {
	case 0:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),







|
>
>









|







342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &content) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!(contentPtr = GetPacker(content))) {
	    return TCL_OK;
	}
	if (contentPtr->containerPtr == NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "window \"%s\" isn't packed", argv2));
	    Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED", NULL);
	    return TCL_ERROR;
	}

	infoObj = Tcl_NewObj();
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-in", -1),
		TkNewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-anchor", -1),
		Tcl_NewStringObj(Tk_NameOfAnchor(contentPtr->anchor), -1));
	Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-expand", -1),
		Tcl_NewBooleanObj(contentPtr->flags & EXPAND));
	switch (contentPtr->flags & (FILLX|FILLY)) {
	case 0:
	    Tcl_DictObjPut(NULL, infoObj, Tcl_NewStringObj("-fill", -1),
397
398
399
400
401
402
403
404


405
406
407
408
409
410
411
	if (objc > 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	containerPtr = GetPacker(container);


	if (objc == 3) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	    return TCL_ERROR;







|
>
>







398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
	if (objc > 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window ?boolean?");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	if (!(containerPtr = GetPacker(container))) {
	    return TCL_OK;
	}
	if (objc == 3) {
	    Tcl_SetObjResult(interp,
		    Tcl_NewBooleanObj(!(containerPtr->flags & DONT_PROPAGATE)));
	    return TCL_OK;
	}
	if (Tcl_GetBooleanFromObj(interp, objv[3], &propagate) != TCL_OK) {
	    return TCL_ERROR;
454
455
456
457
458
459
460
461


462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	containerPtr = GetPacker(container);


	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj(contentPtr->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }
#ifndef TK_NO_DEPRECATED
    case PACK_UNPACK: {
	Tk_Window tkwin2;
	Packer *packPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if ((packPtr != NULL) && (packPtr->containerPtr != NULL)) {
	    Tk_ManageGeometry(tkwin2, NULL, NULL);
	    if (packPtr->containerPtr->tkwin != Tk_Parent(packPtr->tkwin)) {
		Tk_UnmaintainGeometry(packPtr->tkwin,
			packPtr->containerPtr->tkwin);
	    }
	    Unlink(packPtr);
	    Tk_UnmapWindow(packPtr->tkwin);
	}
	break;
    }
#endif /* !TK_NO_DEPRECATED */
    }

    return TCL_OK;
}

/*
 *------------------------------------------------------------------------







|
>
>



|




<












|










<







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474

475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497

498
499
500
501
502
503
504
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &container) != TCL_OK) {
	    return TCL_ERROR;
	}
	resultObj = Tcl_NewObj();
	if (!(containerPtr = GetPacker(container))) {
	    return TCL_OK;
	}
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = contentPtr->nextPtr) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    TkNewWindowObj(contentPtr->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;
    }

    case PACK_UNPACK: {
	Tk_Window tkwin2;
	Packer *packPtr;

	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "window");
	    return TCL_ERROR;
	}
	if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr = GetPacker(tkwin2);
	if (packPtr && (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;
    }

    }

    return TCL_OK;
}

/*
 *------------------------------------------------------------------------
1018
1019
1020
1021
1022
1023
1024
1025

1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046




1047
1048
1049
1050
1051
1052
1053

/*
 *------------------------------------------------------------------------
 *
 * GetPacker --
 *
 *	This internal function is used to locate a Packer structure for a
 *	given window, creating one if one doesn't exist already.

 *
 * Results:
 *	The return value is a pointer to the Packer structure corresponding to
 *	tkwin.
 *
 * Side effects:
 *	A new packer structure may be created. If so, then a callback is set
 *	up to clean things up when the window is deleted.
 *
 *------------------------------------------------------------------------
 */

static Packer *
GetPacker(
    Tk_Window tkwin)		/* Token for window for which packer structure
				 * is desired. */
{
    Packer *packPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;





    if (!dispPtr->packInit) {
	dispPtr->packInit = 1;
	Tcl_InitHashTable(&dispPtr->packerHashTable, TCL_ONE_WORD_KEYS);
    }

    /*







|
>



|

















>
>
>
>







1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061

/*
 *------------------------------------------------------------------------
 *
 * GetPacker --
 *
 *	This internal function is used to locate a Packer structure for a
 *	window, creating one if one doesn't exist already, except if the window
 *	is already dead.
 *
 * Results:
 *	The return value is a pointer to the Packer structure corresponding to
 *	tkwin, or NULL when tkwin is already dead.
 *
 * Side effects:
 *	A new packer structure may be created. If so, then a callback is set
 *	up to clean things up when the window is deleted.
 *
 *------------------------------------------------------------------------
 */

static Packer *
GetPacker(
    Tk_Window tkwin)		/* Token for window for which packer structure
				 * is desired. */
{
    Packer *packPtr;
    Tcl_HashEntry *hPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    if (((TkWindow *) tkwin)->flags & TK_ALREADY_DEAD) {
	return NULL;
    }

    if (!dispPtr->packInit) {
	dispPtr->packInit = 1;
	Tcl_InitHashTable(&dispPtr->packerHashTable, TCL_ONE_WORD_KEYS);
    }

    /*
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
 * 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. */







<







1101
1102
1103
1104
1105
1106
1107

1108
1109
1110
1111
1112
1113
1114
 * Side effects:
 *	The geometry of the specified windows may change, both now and again
 *	in the future.
 *
 *------------------------------------------------------------------------
 */


static int
PackAfter(
    Tcl_Interp *interp,		/* Interpreter for error reporting. */
    Packer *prevPtr,		/* Pack windows in argv just after this
				 * window; NULL means pack as first child of
				 * containerPtr. */
    Packer *containerPtr,		/* Container in which to pack windows. */
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164


1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
	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')







|











|
>
>


















|
|







1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (((Tk_FakeWin *) (ancestor))->flags & TK_TOP_HIERARCHY) {
	    badWindow:
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack %s inside %s", Tcl_GetString(objv[0]),
			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;
	}
	if (!(packPtr = GetPacker(tkwin))) {
	    return TCL_OK;
	}

	/*
	 * Process options for this window.
	 */

	if (Tcl_ListObjGetElements(interp, objv[1], &optionCount, &options)
		!= TCL_OK) {
	    return TCL_ERROR;
	}
	packPtr->side = TOP;
	packPtr->anchor = TK_ANCHOR_CENTER;
	packPtr->padX = packPtr->padY = 0;
	packPtr->padLeft = packPtr->padTop = 0;
	packPtr->iPadX = packPtr->iPadY = 0;
	packPtr->flags &= ~(FILLX|FILLY|EXPAND);
	packPtr->flags |= OLD_STYLE;
	for (index = 0 ; index < optionCount; index++) {
	    Tcl_Obj *curOptPtr = options[index];
	    int length;
	    const char *curOpt = Tcl_GetStringFromObj(curOptPtr, &length);

	    c = curOpt[0];

	    if ((c == 't')
		    && (strncmp(curOpt, "top", length)) == 0) {
		packPtr->side = TOP;
	    } else if ((c == 'b')
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
		    && (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;
		}







|

















|












|







1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
		    && (strcmp(curOpt, "fill")) == 0) {
		packPtr->flags |= FILLX|FILLY;
	    } else if ((length == 5) && (strcmp(curOpt, "fillx")) == 0) {
		packPtr->flags |= FILLX;
	    } else if ((length == 5) && (strcmp(curOpt, "filly")) == 0) {
		packPtr->flags |= FILLY;
	    } else if ((c == 'p') && (strcmp(curOpt, "padx")) == 0) {
		if (optionCount <= (index+1)) {
		missingPad:
		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			    "wrong # args: \"%s\" option must be"
			    " followed by screen distance", curOpt));
		    Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			    NULL);
		    return TCL_ERROR;
		}
		if (TkParsePadAmount(interp, tkwin, options[index+1],
			&packPtr->padLeft, &packPtr->padX) != TCL_OK) {
		    return TCL_ERROR;
		}
		packPtr->padX /= 2;
		packPtr->padLeft /= 2;
		packPtr->iPadX = 0;
		index++;
	    } else if ((c == 'p') && (strcmp(curOpt, "pady")) == 0) {
		if (optionCount <= (index+1)) {
		    goto missingPad;
		}
		if (TkParsePadAmount(interp, tkwin, options[index+1],
			&packPtr->padTop, &packPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		packPtr->padY /= 2;
		packPtr->padTop /= 2;
		packPtr->iPadY = 0;
		index++;
	    } else if ((c == 'f') && (length > 1)
		    && (strncmp(curOpt, "frame", length) == 0)) {
		if (optionCount <= (index+1)) {
		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
			    "wrong # args: \"frame\""
			    " option must be followed by anchor point", -1));
		    Tcl_SetErrorCode(interp, "TK", "OLDPACK", "BAD_PARAMETER",
			    NULL);
		    return TCL_ERROR;
		}
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
    }
    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.







<







1323
1324
1325
1326
1327
1328
1329

1330
1331
1332
1333
1334
1335
1336
    }
    if (!(containerPtr->flags & REQUESTED_REPACK)) {
	containerPtr->flags |= REQUESTED_REPACK;
	Tcl_DoWhenIdle(ArrangePacking, containerPtr);
    }
    return TCL_OK;
}


/*
 *----------------------------------------------------------------------
 *
 * Unlink --
 *
 *	Remove a packer from its container's list of content.
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
    }

    packPtr->containerPtr = NULL;

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.
     *
     * Send the event "NoManagedChild" to the container to inform it about there
     * being no managed children inside it.
     */

    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "pack");
	containerPtr->flags &= ~ALLOCED_CONTAINER;
	Tk_SendVirtualEvent(containerPtr->tkwin, "NoManagedChild", NULL);
    }

}

/*
 *----------------------------------------------------------------------
 *







<
<
<





<







1376
1377
1378
1379
1380
1381
1382



1383
1384
1385
1386
1387

1388
1389
1390
1391
1392
1393
1394
    }

    packPtr->containerPtr = NULL;

    /*
     * If we have emptied this container from content it means we are no longer
     * handling it and should mark it as free.



     */

    if ((containerPtr->contentPtr == NULL) && (containerPtr->flags & ALLOCED_CONTAINER)) {
	TkFreeGeometryContainer(containerPtr->tkwin, "pack");
	containerPtr->flags &= ~ALLOCED_CONTAINER;

    }

}

/*
 *----------------------------------------------------------------------
 *
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 --







|




>
>
>







1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
 *	Everything associated with the packer is freed up.
 *
 *----------------------------------------------------------------------
 */

static void
DestroyPacker(
    char *memPtr)		/* Info about packed window that is now
				 * dead. */
{
    Packer *packPtr = (Packer *)memPtr;

    if (packPtr->flags & REQUESTED_REPACK) {
	Tcl_CancelIdleCall(ArrangePacking, packPtr);
    }
    ckfree(packPtr);
}

/*
 *----------------------------------------------------------------------
 *
 * PackStructureProc --
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}

	if (packPtr->tkwin != NULL) {
	    TkDisplay *dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr;
            Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable,
		    packPtr->tkwin));
	}

	if (packPtr->flags & REQUESTED_REPACK) {
	    Tcl_CancelIdleCall(ArrangePacking, packPtr);
	}
	packPtr->tkwin = NULL;
	Tcl_EventuallyFree(packPtr, (Tcl_FreeProc *) DestroyPacker);
    } else if (eventPtr->type == MapNotify) {
	/*
	 * When a container gets mapped, must redo the geometry computation so
	 * that all of its content get remapped.
	 */

	if ((packPtr->contentPtr != NULL)







|






|







1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}

	if (packPtr->tkwin != NULL) {
	    TkDisplay *dispPtr = ((TkWindow *) packPtr->tkwin)->dispPtr;
            Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->packerHashTable,
		    (void *)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)
1580
1581
1582
1583
1584
1585
1586
1587



1588
1589
1590
1591
1592
1593
1594
	if (Tk_TopWinHierarchy(content)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't pack \"%s\": it's a top-level window",
		    Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}
	contentPtr = GetPacker(content);



	contentPtr->flags &= ~OLD_STYLE;

	/*
	 * If the content isn't currently packed, reset all of its configuration
	 * information to default values (there could be old values left from
	 * a previous packing).
	 */







|
>
>
>







1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
	if (Tk_TopWinHierarchy(content)) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't pack \"%s\": it's a top-level window",
		    Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	    return TCL_ERROR;
	}
	if (!(contentPtr = GetPacker(content))) {
	    continue;
	}

	contentPtr->flags &= ~OLD_STYLE;

	/*
	 * If the content isn't currently packed, reset all of its configuration
	 * information to default values (there could be old values left from
	 * a previous packing).
	 */
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625


1626
1627
1628
1629
1630
1631
1632
	    if ((i+2) > objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"extra option \"%s\" (option with no value?)",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TK", "PACK", "BAD_PARAMETER", NULL);
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i], optionStrings,
		    sizeof(char *), "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }

	    switch ((enum options) index) {
	    case CONF_AFTER:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    prevPtr = GetPacker(other);


		    if (prevPtr->containerPtr == NULL) {
		    notPacked:
			Tcl_SetObjResult(interp, Tcl_ObjPrintf(
				"window \"%s\" isn't packed",
				Tcl_GetString(objv[i+1])));
			Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED",
				NULL);







|
|










|
>
>







1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
	    if ((i+2) > objc) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"extra option \"%s\" (option with no value?)",
			Tcl_GetString(objv[i])));
		Tcl_SetErrorCode(interp, "TK", "PACK", "BAD_PARAMETER", NULL);
		return TCL_ERROR;
	    }
	    if (Tcl_GetIndexFromObj(interp, objv[i], optionStrings,
		    "option", 0, &index) != TCL_OK) {
		return TCL_ERROR;
	    }

	    switch ((enum options) index) {
	    case CONF_AFTER:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    if (!(prevPtr = GetPacker(other))) {
			continue;
		    }
		    if (prevPtr->containerPtr == NULL) {
		    notPacked:
			Tcl_SetObjResult(interp, Tcl_ObjPrintf(
				"window \"%s\" isn't packed",
				Tcl_GetString(objv[i+1])));
			Tcl_SetErrorCode(interp, "TK", "PACK", "NOT_PACKED",
				NULL);
1644
1645
1646
1647
1648
1649
1650
1651


1652
1653
1654
1655
1656
1657
1658
		break;
	    case CONF_BEFORE:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    otherPtr = GetPacker(other);


		    if (otherPtr->containerPtr == NULL) {
			goto notPacked;
		    }
		    containerPtr = otherPtr->containerPtr;
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr == otherPtr) {
			prevPtr = NULL;







|
>
>







1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
		break;
	    case CONF_BEFORE:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    if (!(otherPtr = GetPacker(other))) {
			continue;
		    }
		    if (otherPtr->containerPtr == NULL) {
			goto notPacked;
		    }
		    containerPtr = otherPtr->containerPtr;
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr == otherPtr) {
			prevPtr = NULL;
1693
1694
1695
1696
1697
1698
1699
1700


1701
1702
1703
1704
1705
1706
1707
		break;
	    case CONF_IN:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    containerPtr = GetPacker(other);


		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr != NULL) {
			while (prevPtr->nextPtr != NULL) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;







|
>
>







1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
		break;
	    case CONF_IN:
		if (j == 0) {
		    if (TkGetWindowFromObj(interp, tkwin, objv[i+1], &other)
			    != TCL_OK) {
			return TCL_ERROR;
		    }
		    if (!(containerPtr = GetPacker(other))) {
			continue;
		    }
		    prevPtr = containerPtr->contentPtr;
		    if (prevPtr != NULL) {
			while (prevPtr->nextPtr != NULL) {
			    prevPtr = prevPtr->nextPtr;
			}
		    }
		    positionGiven = 1;
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
	    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;
	    }
	}








|
|







1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
	    case CONF_PADY:
		if (TkParsePadAmount(interp, content, objv[i+1],
			&contentPtr->padTop, &contentPtr->padY) != TCL_OK) {
		    return TCL_ERROR;
		}
		break;
	    case CONF_SIDE:
		if (Tcl_GetIndexFromObj(interp, objv[i+1], sideNames,
			"side", TCL_EXACT, &side) != TCL_OK) {
		    return TCL_ERROR;
		}
		contentPtr->side = (Side) side;
		break;
	    }
	}

1776
1777
1778
1779
1780
1781
1782
1783


1784
1785
1786
1787
1788
1789
1790
	/*
	 * If none of the "-in", "-before", or "-after" options has been
	 * specified, arrange for the content to go at the end of the order for
	 * its parent.
	 */

	if (!positionGiven) {
	    containerPtr = GetPacker(Tk_Parent(content));


	    prevPtr = containerPtr->contentPtr;
	    if (prevPtr != NULL) {
		while (prevPtr->nextPtr != NULL) {
		    prevPtr = prevPtr->nextPtr;
		}
	    }
	}







|
>
>







1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
	/*
	 * If none of the "-in", "-before", or "-after" options has been
	 * specified, arrange for the content to go at the end of the order for
	 * its parent.
	 */

	if (!positionGiven) {
	    if (!(containerPtr = GetPacker(Tk_Parent(content)))) {
		continue;
	    }
	    prevPtr = containerPtr->contentPtr;
	    if (prevPtr != NULL) {
		while (prevPtr->nextPtr != NULL) {
		    prevPtr = prevPtr->nextPtr;
		}
	    }
	}
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
	parent = Tk_Parent(content);
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack \"%s\" inside \"%s\"", Tcl_GetString(objv[j]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		return TCL_ERROR;
	    }
	}
	if (content == containerPtr->tkwin) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't pack \"%s\" inside itself", Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put \"%s\" inside \"%s\": would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		return TCL_ERROR;
	    }
	}
	if (containerPtr->tkwin != Tk_Parent(content)) {
	    ((TkWindow *)content)->maintainerPtr = (TkWindow *)containerPtr->tkwin;







|







|












|







1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
	parent = Tk_Parent(content);
	for (ancestor = containerPtr->tkwin; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == parent) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't pack %s inside %s", Tcl_GetString(objv[j]),
			Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		return TCL_ERROR;
	    }
	}
	if (content == containerPtr->tkwin) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't pack %s inside itself", Tcl_GetString(objv[j])));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "SELF", NULL);
	    return TCL_ERROR;
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)containerPtr->tkwin; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)content) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put %s inside %s, would cause management loop",
	            Tcl_GetString(objv[j]), Tk_PathName(containerPtr->tkwin)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		return TCL_ERROR;
	    }
	}
	if (containerPtr->tkwin != Tk_Parent(content)) {
	    ((TkWindow *)content)->maintainerPtr = (TkWindow *)containerPtr->tkwin;
Changes to generic/tkPanedWindow.c.
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
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
 */








|


|







|







221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
static int		ConfigurePanes(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
static void		DestroyOptionTables(ClientData clientData,
			    Tcl_Interp *interp);
static int		SetSticky(ClientData clientData, Tcl_Interp *interp,
			    Tk_Window tkwin, Tcl_Obj **value, char *recordPtr,
			    int internalOffset, char *oldInternalPtr,
			    int flags);
static Tcl_Obj *	GetSticky(ClientData clientData, Tk_Window tkwin,
			    char *recordPtr, int internalOffset);
static void		RestoreSticky(ClientData clientData, Tk_Window tkwin,
			    char *internalPtr, char *oldInternalPtr);
static void		AdjustForSticky(int sticky, int cavityWidth,
			    int cavityHeight, int *xPtr, int *yPtr,
			    int *paneWidthPtr, int *paneHeightPtr);
static void		MoveSash(PanedWindow *pwPtr, int sash, int diff);
static int		ObjectIsEmpty(Tcl_Obj *objPtr);
static char *		ComputeSlotAddress(char *recordPtr, int offset);
static int		PanedWindowIdentifyCoords(PanedWindow *pwPtr,
			    Tcl_Interp *interp, int x, int y);

/*
 * Sashes are between panes only, so there is one less sash than 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 --







|
|

|

|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|
|

|

|
|

|
|

|
|

|
|

|
|

|
|





|
|

|
|

|
|

|

|

|

|

|
|

|
|

|
|







271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
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, -1, Tk_Offset(PanedWindow, background), 0,
	DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_SYNONYM, "-bd", NULL, NULL,
	NULL, 0, -1, 0, "-borderwidth", 0},
    {TK_OPTION_SYNONYM, "-bg", NULL, NULL,
	NULL, 0, -1, 0, "-background", 0},
    {TK_OPTION_PIXELS, "-borderwidth", "borderWidth", "BorderWidth",
	DEF_PANEDWINDOW_BORDERWIDTH, -1, Tk_Offset(PanedWindow, borderWidth),
	0, 0, GEOMETRY},
    {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
	DEF_PANEDWINDOW_CURSOR, -1, Tk_Offset(PanedWindow, cursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-handlepad", "handlePad", "HandlePad",
	DEF_PANEDWINDOW_HANDLEPAD, -1, Tk_Offset(PanedWindow, handlePad),
	0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-handlesize", "handleSize", "HandleSize",
	DEF_PANEDWINDOW_HANDLESIZE, Tk_Offset(PanedWindow, handleSizePtr),
	Tk_Offset(PanedWindow, handleSize), 0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-height", "height", "Height",
	DEF_PANEDWINDOW_HEIGHT, Tk_Offset(PanedWindow, heightPtr),
	Tk_Offset(PanedWindow, height), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-opaqueresize", "opaqueResize", "OpaqueResize",
	DEF_PANEDWINDOW_OPAQUERESIZE, -1,
	Tk_Offset(PanedWindow, resizeOpaque), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient",
	DEF_PANEDWINDOW_ORIENT, -1, Tk_Offset(PanedWindow, orient),
	TK_OPTION_ENUM_VAR, orientStrings, GEOMETRY},
    {TK_OPTION_BORDER, "-proxybackground", "proxyBackground", "ProxyBackground",
	0, -1, Tk_Offset(PanedWindow, proxyBackground),
	TK_OPTION_NULL_OK, (ClientData) DEF_PANEDWINDOW_BG_MONO, 0},
    {TK_OPTION_PIXELS, "-proxyborderwidth", "proxyBorderWidth", "ProxyBorderWidth",
	DEF_PANEDWINDOW_PROXYBORDER, Tk_Offset(PanedWindow, proxyBorderWidthPtr),
	Tk_Offset(PanedWindow, proxyBorderWidth), 0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-proxyrelief", "proxyRelief", "Relief",
	0, -1, Tk_Offset(PanedWindow, proxyRelief),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_RELIEF, "-relief", "relief", "Relief",
	DEF_PANEDWINDOW_RELIEF, -1, Tk_Offset(PanedWindow, relief), 0, 0, 0},
    {TK_OPTION_CURSOR, "-sashcursor", "sashCursor", "Cursor",
	DEF_PANEDWINDOW_SASHCURSOR, -1, Tk_Offset(PanedWindow, sashCursor),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-sashpad", "sashPad", "SashPad",
	DEF_PANEDWINDOW_SASHPAD, -1, Tk_Offset(PanedWindow, sashPad),
	0, 0, GEOMETRY},
    {TK_OPTION_RELIEF, "-sashrelief", "sashRelief", "Relief",
	DEF_PANEDWINDOW_SASHRELIEF, -1, Tk_Offset(PanedWindow, sashRelief),
	0, 0, 0},
    {TK_OPTION_PIXELS, "-sashwidth", "sashWidth", "Width",
	DEF_PANEDWINDOW_SASHWIDTH, Tk_Offset(PanedWindow, sashWidthPtr),
	Tk_Offset(PanedWindow, sashWidth), 0, 0, GEOMETRY},
    {TK_OPTION_BOOLEAN, "-showhandle", "showHandle", "ShowHandle",
	DEF_PANEDWINDOW_SHOWHANDLE, -1, Tk_Offset(PanedWindow, showHandle),
	0, 0, GEOMETRY},
    {TK_OPTION_PIXELS, "-width", "width", "Width",
	DEF_PANEDWINDOW_WIDTH, Tk_Offset(PanedWindow, widthPtr),
	Tk_Offset(PanedWindow, width), TK_OPTION_NULL_OK, 0, GEOMETRY},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

static const Tk_OptionSpec paneOptionSpecs[] = {
    {TK_OPTION_WINDOW, "-after", NULL, NULL,
	DEF_PANEDWINDOW_PANE_AFTER, -1, Tk_Offset(Pane, after),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-before", NULL, NULL,
	DEF_PANEDWINDOW_PANE_BEFORE, -1, Tk_Offset(Pane, before),
	TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL,
	DEF_PANEDWINDOW_PANE_HEIGHT, Tk_Offset(Pane, heightPtr),
	Tk_Offset(Pane, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_BOOLEAN, "-hide", "hide", "Hide",
	DEF_PANEDWINDOW_PANE_HIDE, -1, Tk_Offset(Pane, hide), 0,0,GEOMETRY},
    {TK_OPTION_PIXELS, "-minsize", NULL, NULL,
	DEF_PANEDWINDOW_PANE_MINSIZE, -1, Tk_Offset(Pane, minSize), 0, 0, 0},
    {TK_OPTION_PIXELS, "-padx", NULL, NULL,
	DEF_PANEDWINDOW_PANE_PADX, -1, Tk_Offset(Pane, padx), 0, 0, 0},
    {TK_OPTION_PIXELS, "-pady", NULL, NULL,
	DEF_PANEDWINDOW_PANE_PADY, -1, Tk_Offset(Pane, pady), 0, 0, 0},
    {TK_OPTION_CUSTOM, "-sticky", NULL, NULL,
	DEF_PANEDWINDOW_PANE_STICKY, -1, Tk_Offset(Pane, sticky),
	0, &stickyOption, 0},
    {TK_OPTION_STRING_TABLE, "-stretch", "stretch", "Stretch",
	DEF_PANEDWINDOW_PANE_STRETCH, -1, Tk_Offset(Pane, stretch),
	TK_OPTION_ENUM_VAR, stretchStrings, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL,
	DEF_PANEDWINDOW_PANE_WIDTH, Tk_Offset(Pane, widthPtr),
	Tk_Offset(Pane, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
};

/*
 *--------------------------------------------------------------
 *
 * Tk_PanedWindowObjCmd --
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424

    pwOpts = (OptionTables *)
	    Tcl_GetAssocData(interp, "PanedWindowOptionTables", NULL);
    if (pwOpts == NULL) {
	/*
	 * The first time this function is invoked, the option tables will be
	 * NULL. We then create the option tables from the templates and store
	 * a pointer to the tables as the command's clinical so we'll have
	 * easy access to it in the future.
	 */

	pwOpts = (OptionTables *)ckalloc(sizeof(OptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
	 */

	Tcl_SetAssocData(interp, "PanedWindowOptionTables",
		DestroyOptionTables, pwOpts);







|



|







406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424

    pwOpts = (OptionTables *)
	    Tcl_GetAssocData(interp, "PanedWindowOptionTables", NULL);
    if (pwOpts == NULL) {
	/*
	 * The first time this function is invoked, the option tables will be
	 * NULL. We then create the option tables from the templates and store
	 * a pointer to the tables as the command's clientData so we'll have
	 * easy access to it in the future.
	 */

	pwOpts = ckalloc(sizeof(OptionTables));

	/*
	 * Set up an exit handler to free the optionTables struct.
	 */

	Tcl_SetAssocData(interp, "PanedWindowOptionTables",
		DestroyOptionTables, pwOpts);
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
    /*
     * Keep a hold of the associated tkwin until we destroy the widget,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(pwPtr->tkwin);

    if (Tk_InitOptions(interp, pwPtr, pwOpts->pwOptions,
	    tkwin) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tk_CreateEventHandler(pwPtr->tkwin, ExposureMask|StructureNotifyMask,
	    PanedWindowEventProc, pwPtr);







|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
    /*
     * Keep a hold of the associated tkwin until we destroy the widget,
     * otherwise Tk might free it while we still need it.
     */

    Tcl_Preserve(pwPtr->tkwin);

    if (Tk_InitOptions(interp, (char *) pwPtr, pwOpts->pwOptions,
	    tkwin) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tk_CreateEventHandler(pwPtr->tkwin, ExposureMask|StructureNotifyMask,
	    PanedWindowEventProc, pwPtr);
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

    if (ConfigurePanedWindow(interp, pwPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->proxywin);
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, Tk_NewWindowObj(pwPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowWidgetObjCmd --







|







502
503
504
505
506
507
508
509
510
511
512
513
514
515
516

    if (ConfigurePanedWindow(interp, pwPtr, objc - 2, objv + 2) != TCL_OK) {
	Tk_DestroyWindow(pwPtr->proxywin);
	Tk_DestroyWindow(pwPtr->tkwin);
	return TCL_ERROR;
    }

    Tcl_SetObjResult(interp, TkNewWindowObj(pwPtr->tkwin));
    return TCL_OK;
}

/*
 *--------------------------------------------------------------
 *
 * PanedWindowWidgetObjCmd --
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
    };
    Tcl_Obj *resultObj;
    int index, count, i, x, y;
    Tk_Window tkwin;
    Pane *panePtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "command",
	    0, &index) != TCL_OK) {
	return TCL_ERROR;
    }







|







547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
    };
    Tcl_Obj *resultObj;
    int index, count, i, x, y;
    Tk_Window tkwin;
    Pane *panePtr;

    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg arg...?");
	return TCL_ERROR;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings, "command",
	    0, &index) != TCL_OK) {
	return TCL_ERROR;
    }
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

    case PW_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
	}
	resultObj = Tk_GetOptionValue(interp, pwPtr,
		pwPtr->optionTable, objv[2], pwPtr->tkwin);
	if (resultObj == NULL) {
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;

    case PW_CONFIGURE:
	resultObj = NULL;
	if (objc <= 3) {
	    resultObj = Tk_GetOptionInfo(interp, pwPtr,
		    pwPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, pwPtr->tkwin);
	    if (resultObj == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, resultObj);
	    }







|











|







574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600

    case PW_CGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 2, objv, "option");
	    result = TCL_ERROR;
	    break;
	}
	resultObj = Tk_GetOptionValue(interp, (char *) pwPtr,
		pwPtr->optionTable, objv[2], pwPtr->tkwin);
	if (resultObj == NULL) {
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;

    case PW_CONFIGURE:
	resultObj = NULL;
	if (objc <= 3) {
	    resultObj = Tk_GetOptionInfo(interp, (char *) pwPtr,
		    pwPtr->optionTable,
		    (objc == 3) ? objv[2] : NULL, pwPtr->tkwin);
	    if (resultObj == NULL) {
		result = TCL_ERROR;
	    } else {
		Tcl_SetObjResult(interp, resultObj);
	    }
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i]->tkwin == tkwin) {
		resultObj = Tk_GetOptionValue(interp,
			pwPtr->panes[i], pwPtr->paneOpts,
			objv[3], tkwin);
	    }
	}
	if (resultObj == NULL) {
	    if (i == pwPtr->numPanes) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"not managed by this window", -1));
		Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED",
			NULL);
	    }
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;

    case PW_PANECONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "pane ?-option value ...?");
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	if (objc <= 4) {
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    pwPtr->tkwin);
            if (tkwin == NULL) {
                /*
                 * Just a plain old bad window; Tk_NameToWindow filled in an
                 * error message for us.
                 */

                result = TCL_ERROR;
                break;
            }
	    for (i = 0; i < pwPtr->numPanes; i++) {
		if (pwPtr->panes[i]->tkwin == tkwin) {
		    resultObj = Tk_GetOptionInfo(interp,
			    pwPtr->panes[i], pwPtr->paneOpts,
			    (objc == 4) ? objv[3] : NULL,
			    pwPtr->tkwin);
		    if (resultObj == NULL) {
			result = TCL_ERROR;
		    } else {
			Tcl_SetObjResult(interp, resultObj);
		    }
		    break;
		}
	    }
	} else {
	    result = ConfigurePanes(pwPtr, interp, objc, objv);
	}
	break;

    case PW_PANES:
	resultObj = Tcl_NewObj();
	for (i = 0; i < pwPtr->numPanes; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    Tk_NewWindowObj(pwPtr->panes[i]->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case PW_PROXY:
	result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
	break;







|



















|



















|



















|







664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	for (i = 0; i < pwPtr->numPanes; i++) {
	    if (pwPtr->panes[i]->tkwin == tkwin) {
		resultObj = Tk_GetOptionValue(interp,
			(char *) pwPtr->panes[i], pwPtr->paneOpts,
			objv[3], tkwin);
	    }
	}
	if (resultObj == NULL) {
	    if (i == pwPtr->numPanes) {
		Tcl_SetObjResult(interp, Tcl_NewStringObj(
			"not managed by this window", -1));
		Tcl_SetErrorCode(interp, "TK", "PANEDWINDOW", "UNMANAGED",
			NULL);
	    }
	    result = TCL_ERROR;
	} else {
	    Tcl_SetObjResult(interp, resultObj);
	}
	break;

    case PW_PANECONFIGURE:
	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "pane ?option? ?value option value ...?");
	    result = TCL_ERROR;
	    break;
	}
	resultObj = NULL;
	if (objc <= 4) {
	    tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[2]),
		    pwPtr->tkwin);
            if (tkwin == NULL) {
                /*
                 * Just a plain old bad window; Tk_NameToWindow filled in an
                 * error message for us.
                 */

                result = TCL_ERROR;
                break;
            }
	    for (i = 0; i < pwPtr->numPanes; i++) {
		if (pwPtr->panes[i]->tkwin == tkwin) {
		    resultObj = Tk_GetOptionInfo(interp,
			    (char *) pwPtr->panes[i], pwPtr->paneOpts,
			    (objc == 4) ? objv[3] : NULL,
			    pwPtr->tkwin);
		    if (resultObj == NULL) {
			result = TCL_ERROR;
		    } else {
			Tcl_SetObjResult(interp, resultObj);
		    }
		    break;
		}
	    }
	} else {
	    result = ConfigurePanes(pwPtr, interp, objc, objv);
	}
	break;

    case PW_PANES:
	resultObj = Tcl_NewObj();
	for (i = 0; i < pwPtr->numPanes; i++) {
	    Tcl_ListObjAppendElement(NULL, resultObj,
		    TkNewWindowObj(pwPtr->panes[i]->tkwin));
	}
	Tcl_SetObjResult(interp, resultObj);
	break;

    case PW_PROXY:
	result = PanedWindowProxyCommand(pwPtr, interp, objc, objv);
	break;
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
     * Pre-parse the configuration options, to get the before/after specifiers
     * into an easy-to-find location (a local variable). Also, check the
     * return from Tk_SetOptions once, here, so we can save a little bit of
     * extra testing in the for loop below.
     */

    memset((void *)&options, 0, sizeof(Pane));
    if (Tk_SetOptions(interp, &options, pwPtr->paneOpts,
	    objc - firstOptionArg, objv + firstOptionArg,
	    pwPtr->tkwin, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * If either -after or -before was given, find the numerical index that







|







843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
     * Pre-parse the configuration options, to get the before/after specifiers
     * into an easy-to-find location (a local variable). Also, check the
     * return from Tk_SetOptions once, here, so we can save a little bit of
     * extra testing in the for loop below.
     */

    memset((void *)&options, 0, sizeof(Pane));
    if (Tk_SetOptions(interp, (char *) &options, pwPtr->paneOpts,
	    objc - firstOptionArg, objv + firstOptionArg,
	    pwPtr->tkwin, NULL, NULL) != TCL_OK) {
	return TCL_ERROR;
    }

    /*
     * If either -after or -before was given, find the numerical index that
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934

	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i + 2]),
		pwPtr->tkwin);

	found = 0;
	for (j = 0; j < pwPtr->numPanes; j++) {
	    if (pwPtr->panes[j] != NULL && pwPtr->panes[j]->tkwin == tkwin) {
		Tk_SetOptions(interp, pwPtr->panes[j],
			pwPtr->paneOpts, objc - firstOptionArg,
			objv + firstOptionArg, pwPtr->tkwin, NULL, NULL);
		if (pwPtr->panes[j]->minSize < 0) {
		    pwPtr->panes[j]->minSize = 0;
		}
		found = 1;








|







920
921
922
923
924
925
926
927
928
929
930
931
932
933
934

	tkwin = Tk_NameToWindow(interp, Tcl_GetString(objv[i + 2]),
		pwPtr->tkwin);

	found = 0;
	for (j = 0; j < pwPtr->numPanes; j++) {
	    if (pwPtr->panes[j] != NULL && pwPtr->panes[j]->tkwin == tkwin) {
		Tk_SetOptions(interp, (char *) pwPtr->panes[j],
			pwPtr->paneOpts, objc - firstOptionArg,
			objv + firstOptionArg, pwPtr->tkwin, NULL, NULL);
		if (pwPtr->panes[j]->minSize < 0) {
		    pwPtr->panes[j]->minSize = 0;
		}
		found = 1;

967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
	/*
	 * Create a new pane structure and initialize it. All panes start
	 * out with their "natural" dimensions.
	 */

	panePtr = (Pane *)ckalloc(sizeof(Pane));
	memset(panePtr, 0, sizeof(Pane));
	Tk_InitOptions(interp, panePtr, pwPtr->paneOpts,
		pwPtr->tkwin);
	Tk_SetOptions(interp, panePtr, pwPtr->paneOpts,
		objc - firstOptionArg, objv + firstOptionArg,
		pwPtr->tkwin, NULL, NULL);
	panePtr->tkwin = tkwin;
	panePtr->containerPtr = pwPtr;
	doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
	if (panePtr->width > 0) {
	    panePtr->paneWidth = panePtr->width;







|

|







967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
	/*
	 * Create a new pane structure and initialize it. All panes start
	 * out with their "natural" dimensions.
	 */

	panePtr = (Pane *)ckalloc(sizeof(Pane));
	memset(panePtr, 0, sizeof(Pane));
	Tk_InitOptions(interp, (char *)panePtr, pwPtr->paneOpts,
		pwPtr->tkwin);
	Tk_SetOptions(interp, (char *)panePtr, pwPtr->paneOpts,
		objc - firstOptionArg, objv + firstOptionArg,
		pwPtr->tkwin, NULL, NULL);
	panePtr->tkwin = tkwin;
	panePtr->containerPtr = pwPtr;
	doubleBw = 2 * Tk_Changes(panePtr->tkwin)->border_width;
	if (panePtr->width > 0) {
	    panePtr->paneWidth = panePtr->width;
1011
1012
1013
1014
1015
1016
1017


1018

1019
1020

1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
    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++;
	    }







>
>

>
|
|
>
|


















|







1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
    i = sizeof(Pane *) * (pwPtr->numPanes + numNewPanes);
    newPanes = (Pane **)ckalloc(i);
    memset(newPanes, 0, i);
    if (index == -1) {
	/*
	 * If none of the existing panes have to be moved, just copy the old
	 * and append the new.
	 * Be careful about the case pwPtr->numPanes == 0 since in this case
	 * pwPtr->panes is NULL, and the memcpy would have undefined behavior.
	 */
	if (pwPtr->numPanes) {
	    memcpy(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++;
	    }
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}
	panePtr = pwPtr->panes[sash];

	coords[0] = Tcl_NewWideIntObj(panePtr->sashx);
	coords[1] = Tcl_NewWideIntObj(panePtr->sashy);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;

    case SASH_MARK:
	if (objc != 6 && objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?x y?");
	    return TCL_ERROR;







|
|







1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "invalid sash index", -1));
	    Tcl_SetErrorCode(interp, "TK", "VALUE", "SASH_INDEX", NULL);
	    return TCL_ERROR;
	}
	panePtr = pwPtr->panes[sash];

	coords[0] = Tcl_NewIntObj(panePtr->sashx);
	coords[1] = Tcl_NewIntObj(panePtr->sashy);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;

    case SASH_MARK:
	if (objc != 6 && objc != 4) {
	    Tcl_WrongNumArgs(interp, 3, objv, "index ?x y?");
	    return TCL_ERROR;
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
	    if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
		return TCL_ERROR;
	    }

	    pwPtr->panes[sash]->markx = x;
	    pwPtr->panes[sash]->marky = y;
	} else {
	    coords[0] = Tcl_NewWideIntObj(pwPtr->panes[sash]->markx);
	    coords[1] = Tcl_NewWideIntObj(pwPtr->panes[sash]->marky);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	}
	break;

    case SASH_DRAGTO:
    case SASH_PLACE:
	if (objc != 6) {







|
|







1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
	    if (Tcl_GetIntFromObj(interp, objv[5], &y) != TCL_OK) {
		return TCL_ERROR;
	    }

	    pwPtr->panes[sash]->markx = x;
	    pwPtr->panes[sash]->marky = y;
	} else {
	    coords[0] = Tcl_NewIntObj(pwPtr->panes[sash]->markx);
	    coords[1] = Tcl_NewIntObj(pwPtr->panes[sash]->marky);
	    Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	}
	break;

    case SASH_DRAGTO:
    case SASH_PLACE:
	if (objc != 6) {
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
    PanedWindow *pwPtr,		/* Information about widget. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    Tk_SavedOptions savedOptions;
    int typemask = 0;

    if (Tk_SetOptions(interp, pwPtr, pwPtr->optionTable, objc, objv,
	    pwPtr->tkwin, &savedOptions, &typemask) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }

    Tk_FreeSavedOptions(&savedOptions);








|







1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
    PanedWindow *pwPtr,		/* Information about widget. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument values. */
{
    Tk_SavedOptions savedOptions;
    int typemask = 0;

    if (Tk_SetOptions(interp, (char *)pwPtr, pwPtr->optionTable, objc, objv,
	    pwPtr->tkwin, &savedOptions, &typemask) != TCL_OK) {
	Tk_RestoreSavedOptions(&savedOptions);
	return TCL_ERROR;
    }

    Tk_FreeSavedOptions(&savedOptions);

2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
 */

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







|







2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
 */

static Tcl_Obj *
GetSticky(
    TCL_UNUSED(void *),
    TCL_UNUSED(Tk_Window),
    char *recordPtr,		/* Pointer to widget record. */
    int internalOffset)		/* Offset within *recordPtr containing the
				 * sticky value. */
{
    int sticky = *(int *)(recordPtr + internalOffset);
    char buffer[5];
    char *p = &buffer[0];

    if (sticky & STICK_NORTH) {
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    TCL_UNUSED(Tk_Window),	/* Window for which option is being set. */
    Tcl_Obj **value,		/* Pointer to the pointer to the value object.
				 * We use a pointer to the pointer because we
				 * may need to return a value (NULL). */
    char *recordPtr,		/* Pointer to storage for the widget record. */
    TkSizeT internalOffset,		/* Offset within *recordPtr at which the
				 * internal value is to be stored. */
    char *oldInternalPtr,	/* Pointer to storage for the old value. */
    int flags)			/* Flags for the option, set Tk_SetOptions. */
{
    int sticky = 0;
    char c;
    void *internalPtr;
    const char *string;

    internalPtr = ComputeSlotAddress(recordPtr, internalOffset);

    if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
	*value = NULL;
    } else {







|





<
|







2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460

2461
2462
2463
2464
2465
2466
2467
2468
    TCL_UNUSED(void *),
    Tcl_Interp *interp,		/* Current interp; may be used for errors. */
    TCL_UNUSED(Tk_Window),	/* Window for which option is being set. */
    Tcl_Obj **value,		/* Pointer to the pointer to the value object.
				 * We use a pointer to the pointer because we
				 * may need to return a value (NULL). */
    char *recordPtr,		/* Pointer to storage for the widget record. */
    int internalOffset,		/* Offset within *recordPtr at which the
				 * internal value is to be stored. */
    char *oldInternalPtr,	/* Pointer to storage for the old value. */
    int flags)			/* Flags for the option, set Tk_SetOptions. */
{
    int sticky = 0;

    char c, *internalPtr;
    const char *string;

    internalPtr = ComputeSlotAddress(recordPtr, internalOffset);

    if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) {
	*value = NULL;
    } else {
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
    switch ((enum options) index) {
    case PROXY_COORD:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}

	coords[0] = Tcl_NewWideIntObj(pwPtr->proxyx);
	coords[1] = Tcl_NewWideIntObj(pwPtr->proxyy);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;

    case PROXY_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;







|
|







2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
    switch ((enum options) index) {
    case PROXY_COORD:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
	}

	coords[0] = Tcl_NewIntObj(pwPtr->proxyx);
	coords[1] = Tcl_NewIntObj(pwPtr->proxyy);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, coords));
	break;

    case PROXY_FORGET:
	if (objc != 3) {
	    Tcl_WrongNumArgs(interp, 3, objv, NULL);
	    return TCL_ERROR;
3015
3016
3017
3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static void *
ComputeSlotAddress(
    void *recordPtr,	/* Pointer to the start of a record. */
    TkSizeT offset)		/* Offset of a slot within that record; may be TCL_INDEX_NONE. */
{
    if (offset != TCL_INDEX_NONE) {
	return (char *)recordPtr + offset;
    } else {
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------







|

|
|

|
|







3018
3019
3020
3021
3022
3023
3024
3025
3026
3027
3028
3029
3030
3031
3032
3033
3034
3035
3036
3037
3038
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static char *
ComputeSlotAddress(
    char *recordPtr,	/* Pointer to the start of a record. */
    int offset)		/* Offset of a slot within that record; may be < 0. */
{
    if (offset >= 0) {
	return recordPtr + offset;
    } else {
	return NULL;
    }
}

/*
 *----------------------------------------------------------------------
3137
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
     * Set results. Note that the empty string is the default (this function
     * is called inside the implementation of a command).
     */

    if (found != -1) {
	Tcl_Obj *list[2];

	list[0] = Tcl_NewWideIntObj(found);
	list[1] = Tcl_NewStringObj((isHandle ? "handle" : "sash"), -1);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, list));
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|













3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153
3154
3155
3156
3157
3158
3159
3160
     * Set results. Note that the empty string is the default (this function
     * is called inside the implementation of a command).
     */

    if (found != -1) {
	Tcl_Obj *list[2];

	list[0] = Tcl_NewIntObj(found);
	list[1] = Tcl_NewStringObj((isHandle ? "handle" : "sash"), -1);
	Tcl_SetObjResult(interp, Tcl_NewListObj(2, list));
    }
    return TCL_OK;
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Deleted generic/tkPkgConfig.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
 * tkPkgConfig.c --
 *
 *	This file contains the configuration information to embed into the tcl
 *	binary library.
 *
 * Copyright (c) 2002 Andreas Kupries <andreas_kupries@users.sourceforge.net>
 * Copyright (c) 2017 Stuart Cassoff <stwo@users.sourceforge.net>
 *
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

/* Note, the definitions in this module are influenced by the following C
 * preprocessor macros:
 *
 * OSCMa  = shortcut for "old style configuration macro activates"
 * NSCMdt = shortcut for "new style configuration macro declares that"
 *
 * - TCL_THREADS		OSCMa compilation as threaded.
 * - TCL_MEM_DEBUG		OSCMa memory debugging.
 *
 * - TCL_CFG_DO64BIT		NSCMdt tk is compiled for a 64bit system.
 * - NDEBUG			NSCMdt tk is compiled with symbol info off.
 * - TCL_CFG_OPTIMIZED		NSCMdt tk is compiled with cc optimizations on
 * - TCL_CFG_PROFILED		NSCMdt tk is compiled with profiling info.
 *
 * - _WIN32 || __CYGWIN__	The value for the fontsytem key will be
 *   MAC_OSX_TK			chosen based on these macros/defines.
 *   HAVE_XFT			NSCMdt xft font support was requested.
 *
 * - CFG_RUNTIME_*		Paths to various stuff at runtime.
 * - CFG_INSTALL_*		Paths to various stuff at installation time.
 *
 * - TCL_CFGVAL_ENCODING	string containing the encoding used for the
 *				configuration values.
 */

#include "tkInt.h"


#ifndef TCL_CFGVAL_ENCODING
#define TCL_CFGVAL_ENCODING "utf-8"
#endif

/*
 * Use C preprocessor statements to define the various values for the embedded
 * configuration information.
 */

#ifdef TCL_THREADS
#  define  CFG_THREADED		"1"
#else
#  define  CFG_THREADED		"0"
#endif

#ifdef TCL_MEM_DEBUG
#  define CFG_MEMDEBUG		"1"
#else
#  define CFG_MEMDEBUG		"0"
#endif

#ifdef TCL_CFG_DO64BIT
#  define CFG_64		"1"
#else
#  define CFG_64		"0"
#endif

#ifndef NDEBUG
#  define CFG_DEBUG		"1"
#else
#  define CFG_DEBUG		"0"
#endif

#ifdef TCL_CFG_OPTIMIZED
#  define CFG_OPTIMIZED		"1"
#else
#  define CFG_OPTIMIZED		"0"
#endif

#ifdef TCL_CFG_PROFILED
#  define CFG_PROFILED		"1"
#else
#  define CFG_PROFILED		"0"
#endif

#if defined(_WIN32)
#  define CFG_FONTSYSTEM	"gdi"
#elif defined(MAC_OSX_TK)
#  define CFG_FONTSYSTEM	"cocoa"
#elif defined(HAVE_XFT)
#  define CFG_FONTSYSTEM	"xft"
#else
#  define CFG_FONTSYSTEM	"x11"
#endif

static const Tcl_Config cfg[] = {
    {"debug",			CFG_DEBUG},
    {"threaded",		CFG_THREADED},
    {"profiled",		CFG_PROFILED},
    {"64bit",			CFG_64},
    {"optimized",		CFG_OPTIMIZED},
#ifdef TK_NO_DEPRECATED
    {"nodeprecated",	"1"},
#endif
    {"mem_debug",		CFG_MEMDEBUG},
    {"fontsystem",		CFG_FONTSYSTEM},

    /* Runtime paths to various stuff */

#ifdef CFG_RUNTIME_LIBDIR
    {"libdir,runtime",		CFG_RUNTIME_LIBDIR},
#endif
#ifdef CFG_RUNTIME_BINDIR
    {"bindir,runtime",		CFG_RUNTIME_BINDIR},
#endif
#ifdef CFG_RUNTIME_SCRDIR
    {"scriptdir,runtime",	CFG_RUNTIME_SCRDIR},
#endif
#ifdef CFG_RUNTIME_INCDIR
    {"includedir,runtime",	CFG_RUNTIME_INCDIR},
#endif
#ifdef CFG_RUNTIME_DOCDIR
    {"docdir,runtime",		CFG_RUNTIME_DOCDIR},
#endif
#ifdef CFG_RUNTIME_DEMODIR
    {"demodir,runtime",		CFG_RUNTIME_DEMODIR},
#endif

    /* Installation paths to various stuff */

#ifdef CFG_INSTALL_LIBDIR
    {"libdir,install",		CFG_INSTALL_LIBDIR},
#endif
#ifdef CFG_INSTALL_BINDIR
    {"bindir,install",		CFG_INSTALL_BINDIR},
#endif
#ifdef CFG_INSTALL_SCRDIR
    {"scriptdir,install",	CFG_INSTALL_SCRDIR},
#endif
#ifdef CFG_INSTALL_INCDIR
    {"includedir,install",	CFG_INSTALL_INCDIR},
#endif
#ifdef CFG_INSTALL_DOCDIR
    {"docdir,install",		CFG_INSTALL_DOCDIR},
#endif
#ifdef CFG_INSTALL_DEMODIR
    {"demodir,install",		CFG_INSTALL_DEMODIR},
#endif

    /* Last entry, closes the array */
    {NULL, NULL}
};

void
TkInitEmbeddedConfigurationInformation(
    Tcl_Interp *interp)		/* Interpreter the configuration command is
				 * registered in. */
{
    Tcl_RegisterConfig(interp, "tk", cfg, TCL_CFGVAL_ENCODING);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<


















































































































































































































































































































































Changes to generic/tkPlace.c.
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * 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.







|
|
|
|
|
|
|


|


|

|
|
|
|
|
|
|
|
|
|
|







77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/*
 * Type masks for options:
 */

#define IN_MASK		1

static const Tk_OptionSpec optionSpecs[] = {
    {TK_OPTION_ANCHOR, "-anchor", NULL, NULL, "nw", -1,
	 Tk_Offset(Content, anchor), 0, 0, 0},
    {TK_OPTION_STRING_TABLE, "-bordermode", NULL, NULL, "inside", -1,
	 Tk_Offset(Content, borderMode), TK_OPTION_ENUM_VAR, borderModeStrings, 0},
    {TK_OPTION_PIXELS, "-height", NULL, NULL, "", Tk_Offset(Content, heightPtr),
	 Tk_Offset(Content, height), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_WINDOW, "-in", NULL, NULL, "", -1, Tk_Offset(Content, inTkwin),
	 0, 0, IN_MASK},
    {TK_OPTION_DOUBLE, "-relheight", NULL, NULL, "",
	 Tk_Offset(Content, relHeightPtr), Tk_Offset(Content, relHeight),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relwidth", NULL, NULL, "",
	 Tk_Offset(Content, relWidthPtr), Tk_Offset(Content, relWidth),
	 TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_DOUBLE, "-relx", NULL, NULL, "0", -1,
	 Tk_Offset(Content, relX), 0, 0, 0},
    {TK_OPTION_DOUBLE, "-rely", NULL, NULL, "0", -1,
	 Tk_Offset(Content, relY), 0, 0, 0},
    {TK_OPTION_PIXELS, "-width", NULL, NULL, "", Tk_Offset(Content, widthPtr),
	 Tk_Offset(Content, width), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-x", NULL, NULL, "0", Tk_Offset(Content, xPtr),
	 Tk_Offset(Content, x), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_PIXELS, "-y", NULL, NULL, "0", Tk_Offset(Content, yPtr),
	 Tk_Offset(Content, y), TK_OPTION_NULL_OK, 0, 0},
    {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, -1, 0, 0, 0}
};

/*
 * Flag definitions for Content structures:
 *
 * CHILD_WIDTH -		1 means -width was specified;
 * CHILD_REL_WIDTH -		1 means -relwidth was specified.
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * For each container window that has a content managed by the placer there is a
 * structure of the following form:
 */

typedef struct Container {
    Tk_Window tkwin;		/* Tk's token for container window. */
    struct Content *contentPtr;	/* First in linked list of content windowslaced
				 * relative to this container. */
    int *abortPtr;		/* If non-NULL, it means that there is a nested
				 * call to RecomputePlacement already working on
				 * this window.  *abortPtr may be set to 1 to
				 * abort that nested call.  This happens, for
				 * example, if tkwin or any of its content
				 * is deleted. */







|







125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/*
 * For each container window that has a content managed by the placer there is a
 * structure of the following form:
 */

typedef struct Container {
    Tk_Window tkwin;		/* Tk's token for container window. */
    struct Content *contentPtr;	/* First in linked list of content placed
				 * relative to this container. */
    int *abortPtr;		/* If non-NULL, it means that there is a nested
				 * call to RecomputePlacement already working on
				 * this window.  *abortPtr may be set to 1 to
				 * abort that nested call.  This happens, for
				 * example, if tkwin or any of its content
				 * is deleted. */
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
    Tk_Window tkwin;
    Content *contentPtr;
    TkDisplay *dispPtr;
    Tk_OptionTable optionTable;
    static const char *const optionStrings[] = {
	"configure", "content", "forget", "info", "slaves", NULL
    };
    static const char *const optionStringsNoDep[] = {
	"configure", "content", "forget", "info", NULL
    };
    enum options { PLACE_CONFIGURE, PLACE_CONTENT, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES };
    int index;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option|pathName args");
	return TCL_ERROR;
    }







<
<
<







212
213
214
215
216
217
218



219
220
221
222
223
224
225
    Tk_Window tkwin;
    Content *contentPtr;
    TkDisplay *dispPtr;
    Tk_OptionTable optionTable;
    static const char *const optionStrings[] = {
	"configure", "content", "forget", "info", "slaves", NULL
    };



    enum options { PLACE_CONFIGURE, PLACE_CONTENT, PLACE_FORGET, PLACE_INFO, PLACE_SLAVES };
    int index;

    if (objc < 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option|pathName args");
	return TCL_ERROR;
    }
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261

	/*
	 * Initialize, if that hasn't been done yet.
	 */

	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (!dispPtr->placeInit) {
	    Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	    dispPtr->placeInit = 1;
	}

	return ConfigureContent(interp, tkwin, optionTable, objc-2, objv+2);
    }

    /*







|
|







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

	/*
	 * Initialize, if that hasn't been done yet.
	 */

	dispPtr = ((TkWindow *) tkwin)->dispPtr;
	if (!dispPtr->placeInit) {
	    Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	    Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	    dispPtr->placeInit = 1;
	}

	return ConfigureContent(interp, tkwin, optionTable, objc-2, objv+2);
    }

    /*
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311

    /*
     * Initialize, if that hasn't been done yet.
     */

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->placeInit) {
	Tcl_InitHashTable(&dispPtr->containerTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->contentTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings,
	    sizeof(char *), "option", 0, &index) != TCL_OK) {
	/*
	 * Call it again without the deprecated ones to get a proper error
	 * message. This works well since there can't be any ambiguity between
	 * deprecated and new options.
	 */

	Tcl_GetIndexFromObjStruct(interp, objv[1], optionStringsNoDep,
		sizeof(char *), "option", 0, &index);
	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case PLACE_CONFIGURE:
	if (objc == 3 || objc == 4) {
	    Tcl_Obj *objPtr;

	    contentPtr = FindContent(tkwin);
	    if (contentPtr == NULL) {
		return TCL_OK;
	    }
	    objPtr = Tk_GetOptionInfo(interp, contentPtr, optionTable,
		    (objc == 4) ? objv[3] : NULL, tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}







|
|



|
|
<
<
<
<
<
<
<
<












|







267
268
269
270
271
272
273
274
275
276
277
278
279
280








281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300

    /*
     * Initialize, if that hasn't been done yet.
     */

    dispPtr = ((TkWindow *) tkwin)->dispPtr;
    if (!dispPtr->placeInit) {
	Tcl_InitHashTable(&dispPtr->masterTable, TCL_ONE_WORD_KEYS);
	Tcl_InitHashTable(&dispPtr->slaveTable, TCL_ONE_WORD_KEYS);
	dispPtr->placeInit = 1;
    }

    if (Tcl_GetIndexFromObj(interp, objv[1], optionStrings,
	    "option", 0, &index) != TCL_OK) {








	return TCL_ERROR;
    }

    switch ((enum options) index) {
    case PLACE_CONFIGURE:
	if (objc == 3 || objc == 4) {
	    Tcl_Obj *objPtr;

	    contentPtr = FindContent(tkwin);
	    if (contentPtr == NULL) {
		return TCL_OK;
	    }
	    objPtr = Tk_GetOptionInfo(interp, (char *)contentPtr, optionTable,
		    (objc == 4) ? objv[3] : NULL, tkwin);
	    if (objPtr == NULL) {
		return TCL_ERROR;
	    }
	    Tcl_SetObjResult(interp, objPtr);
	    return TCL_OK;
	}
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
	    return TCL_OK;
	}
	if ((contentPtr->containerPtr != NULL) &&
		(contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin))) {
	    Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
	}
	UnlinkContent(contentPtr);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
		tkwin));
	Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
		contentPtr);
	Tk_ManageGeometry(tkwin, NULL, NULL);
	Tk_UnmapWindow(tkwin);
	FreeContent(contentPtr);
	break;








|
|







310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
	    return TCL_OK;
	}
	if ((contentPtr->containerPtr != NULL) &&
		(contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin))) {
	    Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
	}
	UnlinkContent(contentPtr);
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
		(void *)tkwin));
	Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
		contentPtr);
	Tk_ManageGeometry(tkwin, NULL, NULL);
	Tk_UnmapWindow(tkwin);
	FreeContent(contentPtr);
	break;

352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
	containerPtr = FindContainer(tkwin);
	if (containerPtr != NULL) {
	    Tcl_Obj *listPtr = Tcl_NewObj();

	    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		    contentPtr = contentPtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			Tk_NewWindowObj(contentPtr->tkwin));
	    }
	    Tcl_SetObjResult(interp, listPtr);
	}
	break;
    }
    }








|







341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
	containerPtr = FindContainer(tkwin);
	if (containerPtr != NULL) {
	    Tcl_Obj *listPtr = Tcl_NewObj();

	    for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		    contentPtr = contentPtr->nextPtr) {
		Tcl_ListObjAppendElement(NULL, listPtr,
			TkNewWindowObj(contentPtr->tkwin));
	    }
	    Tcl_SetObjResult(interp, listPtr);
	}
	break;
    }
    }

390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
    Tk_OptionTable table)
{
    Tcl_HashEntry *hPtr;
    Content *contentPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->contentTable, (char *) tkwin, &isNew);
    if (!isNew) {
	return (Content *)Tcl_GetHashValue(hPtr);
    }

    /*
     * No preexisting content structure for that window, so make a new one and
     * populate it with some default values.







|







379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
    Tk_OptionTable table)
{
    Tcl_HashEntry *hPtr;
    Content *contentPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->slaveTable, (char *) tkwin, &isNew);
    if (!isNew) {
	return (Content *)Tcl_GetHashValue(hPtr);
    }

    /*
     * No preexisting content structure for that window, so make a new one and
     * populate it with some default values.
433
434
435
436
437
438
439



440
441
442
443
444
445
446
 *----------------------------------------------------------------------
 */

static void
FreeContent(
    Content *contentPtr)
{



    Tk_FreeConfigOptions((char *) contentPtr, contentPtr->optionTable,
	    contentPtr->tkwin);
    ckfree(contentPtr);
}

/*
 *----------------------------------------------------------------------







>
>
>







422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
 *----------------------------------------------------------------------
 */

static void
FreeContent(
    Content *contentPtr)
{
    if (contentPtr->containerPtr && (contentPtr->containerPtr->flags & PARENT_RECONFIG_PENDING)) {
	Tcl_CancelIdleCall(RecomputePlacement, contentPtr->containerPtr);
    }
    Tk_FreeConfigOptions((char *) contentPtr, contentPtr->optionTable,
	    contentPtr->tkwin);
    ckfree(contentPtr);
}

/*
 *----------------------------------------------------------------------
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
static Content *
FindContent(
    Tk_Window tkwin)		/* Token for desired content. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->contentTable, tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Content *)Tcl_GetHashValue(hPtr);
}

/*







|







455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
static Content *
FindContent(
    Tk_Window tkwin)		/* Token for desired content. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->slaveTable, (char *) tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Content *)Tcl_GetHashValue(hPtr);
}

/*
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
	return;
    }
    if (containerPtr->contentPtr == contentPtr) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (prevPtr = containerPtr->contentPtr; ; prevPtr = prevPtr->nextPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("UnlinkContent couldn't find content to unlink");
	    }
	    if (prevPtr->nextPtr == contentPtr) {
		prevPtr->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }







|







495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
	return;
    }
    if (containerPtr->contentPtr == contentPtr) {
	containerPtr->contentPtr = contentPtr->nextPtr;
    } else {
	for (prevPtr = containerPtr->contentPtr; ; prevPtr = prevPtr->nextPtr) {
	    if (prevPtr == NULL) {
		Tcl_Panic("UnlinkContent couldn't find slave to unlink");
	    }
	    if (prevPtr->nextPtr == contentPtr) {
		prevPtr->nextPtr = contentPtr->nextPtr;
		break;
	    }
	}
    }
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    Container *containerPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->containerTable, (char *)tkwin, &isNew);
    if (isNew) {
	containerPtr = (Container *)ckalloc(sizeof(Container));
	containerPtr->tkwin = tkwin;
	containerPtr->contentPtr = NULL;
	containerPtr->abortPtr = NULL;
	containerPtr->flags = 0;
	Tcl_SetHashValue(hPtr, containerPtr);







|







536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    Container *containerPtr;
    int isNew;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_CreateHashEntry(&dispPtr->masterTable, (char *)tkwin, &isNew);
    if (isNew) {
	containerPtr = (Container *)ckalloc(sizeof(Container));
	containerPtr->tkwin = tkwin;
	containerPtr->contentPtr = NULL;
	containerPtr->abortPtr = NULL;
	containerPtr->flags = 0;
	Tcl_SetHashValue(hPtr, containerPtr);
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
static Container *
FindContainer(
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->containerTable, tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Container *)Tcl_GetHashValue(hPtr);
}

/*







|







578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
static Container *
FindContainer(
    Tk_Window tkwin)		/* Token for desired container. */
{
    Tcl_HashEntry *hPtr;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    hPtr = Tcl_FindHashEntry(&dispPtr->masterTable, (char *) tkwin);
    if (hPtr == NULL) {
	return NULL;
    }
    return (Container *)Tcl_GetHashValue(hPtr);
}

/*
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
		"wm command instead", Tk_PathName(tkwin)));
	Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	return TCL_ERROR;
    }

    contentPtr = CreateContent(tkwin, table);

    if (Tk_SetOptions(interp, contentPtr, table, objc, objv,
	    contentPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }

    /*
     * Set content flags. First clear the field, then add bits as needed.
     */







|







629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
		"wm command instead", Tk_PathName(tkwin)));
	Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "TOPLEVEL", NULL);
	return TCL_ERROR;
    }

    contentPtr = CreateContent(tkwin, table);

    if (Tk_SetOptions(interp, (char *)contentPtr, table, objc, objv,
	    contentPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
	goto error;
    }

    /*
     * Set content flags. First clear the field, then add bits as needed.
     */
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726

	for (ancestor = win; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(contentPtr->tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't place \"%s\" relative to \"%s\"",
			Tk_PathName(contentPtr->tkwin), Tk_PathName(win)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		goto error;
	    }
	}
	if (contentPtr->tkwin == win) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't place \"%s\" relative to itself",
		    Tk_PathName(contentPtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
	    goto error;
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)win; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)contentPtr->tkwin) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put \"%s\" inside \"%s\": would cause management loop",
	            Tk_PathName(contentPtr->tkwin), Tk_PathName(win)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		goto error;
	    }
	}
	if (win != Tk_Parent(contentPtr->tkwin)) {
	    ((TkWindow *)contentPtr->tkwin)->maintainerPtr = (TkWindow *)win;







|







|













|







682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718

	for (ancestor = win; ; ancestor = Tk_Parent(ancestor)) {
	    if (ancestor == Tk_Parent(contentPtr->tkwin)) {
		break;
	    }
	    if (Tk_TopWinHierarchy(ancestor)) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't place %s relative to %s",
			Tk_PathName(contentPtr->tkwin), Tk_PathName(win)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "HIERARCHY", NULL);
		goto error;
	    }
	}
	if (contentPtr->tkwin == win) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't place %s relative to itself",
		    Tk_PathName(contentPtr->tkwin)));
	    Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
	    goto error;
	}

	/*
	 * Check for management loops.
	 */

	for (container = (TkWindow *)win; container != NULL;
	     container = (TkWindow *)TkGetContainer(container)) {
	    if (container == (TkWindow *)contentPtr->tkwin) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't put %s inside %s, would cause management loop",
	            Tk_PathName(contentPtr->tkwin), Tk_PathName(win)));
		Tcl_SetErrorCode(interp, "TK", "GEOMETRY", "LOOP", NULL);
		goto error;
	    }
	}
	if (win != Tk_Parent(contentPtr->tkwin)) {
	    ((TkWindow *)contentPtr->tkwin)->maintainerPtr = (TkWindow *)win;
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
    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);







|







806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
    if (contentPtr == NULL) {
	return TCL_OK;
    }
    infoObj = Tcl_NewObj();
    if (contentPtr->containerPtr != NULL) {
	Tcl_AppendToObj(infoObj, "-in", -1);
	Tcl_ListObjAppendElement(NULL, infoObj,
		TkNewWindowObj(contentPtr->containerPtr->tkwin));
	Tcl_AppendToObj(infoObj, " ", -1);
    }
    Tcl_AppendPrintfToObj(infoObj,
	    "-x %d -relx %.4g -y %d -rely %.4g",
	    contentPtr->x, contentPtr->relX, contentPtr->y, contentPtr->relY);
    if (contentPtr->flags & CHILD_WIDTH) {
	Tcl_AppendPrintfToObj(infoObj, " -width %d", contentPtr->width);
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
    case DestroyNotify:
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->containerTable,
		containerPtr->tkwin));
	if (containerPtr->flags & PARENT_RECONFIG_PENDING) {
	    Tcl_CancelIdleCall(RecomputePlacement, containerPtr);
	}
	containerPtr->tkwin = NULL;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}







|
|







1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
    case DestroyNotify:
	for (contentPtr = containerPtr->contentPtr; contentPtr != NULL;
		contentPtr = nextPtr) {
	    contentPtr->containerPtr = NULL;
	    nextPtr = contentPtr->nextPtr;
	    contentPtr->nextPtr = NULL;
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->masterTable,
		(char *) containerPtr->tkwin));
	if (containerPtr->flags & PARENT_RECONFIG_PENDING) {
	    Tcl_CancelIdleCall(RecomputePlacement, containerPtr);
	}
	containerPtr->tkwin = NULL;
	if (containerPtr->abortPtr != NULL) {
	    *containerPtr->abortPtr = 1;
	}
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (eventPtr->type == DestroyNotify) {
	if (contentPtr->containerPtr != NULL) {
	    UnlinkContent(contentPtr);
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
		contentPtr->tkwin));
	FreeContent(contentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *







|
|







1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
    Content *contentPtr = (Content *)clientData;
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (eventPtr->type == DestroyNotify) {
	if (contentPtr->containerPtr != NULL) {
	    UnlinkContent(contentPtr);
	}
	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
		(char *) contentPtr->tkwin));
	FreeContent(contentPtr);
    }
}

/*
 *----------------------------------------------------------------------
 *
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Tk_UnmapWindow(tkwin);
    UnlinkContent(contentPtr);
    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->contentTable,
	    tkwin));
    Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
	    contentPtr);
    FreeContent(contentPtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */







|
|












1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
    TkDisplay *dispPtr = ((TkWindow *) contentPtr->tkwin)->dispPtr;

    if (contentPtr->containerPtr->tkwin != Tk_Parent(contentPtr->tkwin)) {
	Tk_UnmaintainGeometry(contentPtr->tkwin, contentPtr->containerPtr->tkwin);
    }
    Tk_UnmapWindow(tkwin);
    UnlinkContent(contentPtr);
    Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->slaveTable,
	    (char *) tkwin));
    Tk_DeleteEventHandler(tkwin, StructureNotifyMask, ContentStructureProc,
	    contentPtr);
    FreeContent(contentPtr);
}

/*
 * Local Variables:
 * mode: c
 * c-basic-offset: 4
 * fill-column: 78
 * End:
 */
Changes to generic/tkPlatDecls.h.
1
2
3
4
5
6
7
8
9
10
11
12
13
/*
 * 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
50
51
52
53
54
55
56
57






58

59

60

61
62
63
64
65
66
67
68

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
EXTERN void		Tk_PointerEvent(HWND hwnd, int x, int y);
/* 5 */
EXTERN int		Tk_TranslateWinEvent(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam,
				LRESULT *result);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */






/* Slot 1 is reserved */

/* Slot 2 is reserved */

/* Slot 3 is reserved */

/* 4 */
EXTERN void		TkMacOSXInitAppleEvents(Tcl_Interp *interp);
/* 5 */
EXTERN void		TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y,
				int width, int height, int flags);
/* 6 */
EXTERN void		TkMacOSXInvalClipRgns(Tk_Window tkwin);
/* Slot 7 is reserved */

/* 8 */
EXTERN void *		TkMacOSXGetRootControl(Drawable drawable);
/* 9 */
EXTERN void		Tk_MacOSXSetupTkNotifier(void);
/* 10 */
EXTERN int		Tk_MacOSXIsAppInFront(void);
/* 11 */
EXTERN Tk_Window	Tk_MacOSXGetTkWindow(void *w);
/* 12 */
EXTERN void *		Tk_MacOSXGetCGContextForDrawable(Drawable drawable);
/* 13 */
EXTERN void *		Tk_MacOSXGetNSWindowForDrawable(Drawable drawable);
/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* 16 */
EXTERN void		TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y,
				int width, int height, int flags);
#endif /* AQUA */

typedef struct TkPlatStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    Window (*tk_AttachHWND) (Tk_Window tkwin, HWND hwnd); /* 0 */
    HINSTANCE (*tk_GetHINSTANCE) (void); /* 1 */
    HWND (*tk_GetHWND) (Window window); /* 2 */
    Tk_Window (*tk_HWNDToWindow) (HWND hwnd); /* 3 */
    void (*tk_PointerEvent) (HWND hwnd, int x, int y); /* 4 */
    int (*tk_TranslateWinEvent) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*reserved0)(void);
    void (*reserved1)(void);
    void (*reserved2)(void);
    void (*reserved3)(void);
    void (*tkMacOSXInitAppleEvents) (Tcl_Interp *interp); /* 4 */
    void (*tkGenWMConfigureEvent_) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 5 */
    void (*tkMacOSXInvalClipRgns) (Tk_Window tkwin); /* 6 */
    void (*reserved7)(void);
    void * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */
    void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */
    int (*tk_MacOSXIsAppInFront) (void); /* 10 */
    Tk_Window (*tk_MacOSXGetTkWindow) (void *w); /* 11 */
    void * (*tk_MacOSXGetCGContextForDrawable) (Drawable drawable); /* 12 */
    void * (*tk_MacOSXGetNSWindowForDrawable) (Drawable drawable); /* 13 */
    void (*reserved14)(void);
    void (*reserved15)(void);
    void (*tkGenWMConfigureEvent) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 16 */
#endif /* AQUA */
} TkPlatStubs;

extern const TkPlatStubs *tkPlatStubsPtr;

#ifdef __cplusplus
}







|
>
>
>
>
>
>
|
>
|
>
|
>



|



|
>















|
















|
|
|
|

|

|








|







50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
EXTERN void		Tk_PointerEvent(HWND hwnd, int x, int y);
/* 5 */
EXTERN int		Tk_TranslateWinEvent(HWND hwnd, UINT message,
				WPARAM wParam, LPARAM lParam,
				LRESULT *result);
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* 0 */
EXTERN void		Tk_MacOSXSetEmbedHandler(
				Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr,
				Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr,
				Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr,
				Tk_MacOSXEmbedGetClipProc *getClipProc,
				Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc);
/* 1 */
EXTERN void		Tk_MacOSXTurnOffMenus(void);
/* 2 */
EXTERN void		Tk_MacOSXTkOwnsCursor(int tkOwnsIt);
/* 3 */
EXTERN void		TkMacOSXInitMenus(Tcl_Interp *interp);
/* 4 */
EXTERN void		TkMacOSXInitAppleEvents(Tcl_Interp *interp);
/* 5 */
EXTERN void		TkGenWMConfigureEvent(Tk_Window tkwin, int x, int y,
				int width, int height, int flags);
/* 6 */
EXTERN void		TkMacOSXInvalClipRgns(Tk_Window tkwin);
/* 7 */
EXTERN void *		TkMacOSXGetDrawablePort(Drawable drawable);
/* 8 */
EXTERN void *		TkMacOSXGetRootControl(Drawable drawable);
/* 9 */
EXTERN void		Tk_MacOSXSetupTkNotifier(void);
/* 10 */
EXTERN int		Tk_MacOSXIsAppInFront(void);
/* 11 */
EXTERN Tk_Window	Tk_MacOSXGetTkWindow(void *w);
/* 12 */
EXTERN void *		Tk_MacOSXGetCGContextForDrawable(Drawable drawable);
/* 13 */
EXTERN void *		Tk_MacOSXGetNSWindowForDrawable(Drawable drawable);
/* Slot 14 is reserved */
/* Slot 15 is reserved */
/* 16 */
EXTERN void		TkGenWMConfigureEvent_(Tk_Window tkwin, int x, int y,
				int width, int height, int flags);
#endif /* AQUA */

typedef struct TkPlatStubs {
    int magic;
    void *hooks;

#if defined(_WIN32) || defined(__CYGWIN__) /* WIN */
    Window (*tk_AttachHWND) (Tk_Window tkwin, HWND hwnd); /* 0 */
    HINSTANCE (*tk_GetHINSTANCE) (void); /* 1 */
    HWND (*tk_GetHWND) (Window window); /* 2 */
    Tk_Window (*tk_HWNDToWindow) (HWND hwnd); /* 3 */
    void (*tk_PointerEvent) (HWND hwnd, int x, int y); /* 4 */
    int (*tk_TranslateWinEvent) (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam, LRESULT *result); /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
    void (*tk_MacOSXSetEmbedHandler) (Tk_MacOSXEmbedRegisterWinProc *registerWinProcPtr, Tk_MacOSXEmbedGetGrafPortProc *getPortProcPtr, Tk_MacOSXEmbedMakeContainerExistProc *containerExistProcPtr, Tk_MacOSXEmbedGetClipProc *getClipProc, Tk_MacOSXEmbedGetOffsetInParentProc *getOffsetProc); /* 0 */
    void (*tk_MacOSXTurnOffMenus) (void); /* 1 */
    void (*tk_MacOSXTkOwnsCursor) (int tkOwnsIt); /* 2 */
    void (*tkMacOSXInitMenus) (Tcl_Interp *interp); /* 3 */
    void (*tkMacOSXInitAppleEvents) (Tcl_Interp *interp); /* 4 */
    void (*tkGenWMConfigureEvent) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 5 */
    void (*tkMacOSXInvalClipRgns) (Tk_Window tkwin); /* 6 */
    void * (*tkMacOSXGetDrawablePort) (Drawable drawable); /* 7 */
    void * (*tkMacOSXGetRootControl) (Drawable drawable); /* 8 */
    void (*tk_MacOSXSetupTkNotifier) (void); /* 9 */
    int (*tk_MacOSXIsAppInFront) (void); /* 10 */
    Tk_Window (*tk_MacOSXGetTkWindow) (void *w); /* 11 */
    void * (*tk_MacOSXGetCGContextForDrawable) (Drawable drawable); /* 12 */
    void * (*tk_MacOSXGetNSWindowForDrawable) (Drawable drawable); /* 13 */
    void (*reserved14)(void);
    void (*reserved15)(void);
    void (*tkGenWMConfigureEvent_) (Tk_Window tkwin, int x, int y, int width, int height, int flags); /* 16 */
#endif /* AQUA */
} TkPlatStubs;

extern const TkPlatStubs *tkPlatStubsPtr;

#ifdef __cplusplus
}
141
142
143
144
145
146
147
148
149
150
151




152
153
154
155
156
157
158


159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
	(tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */
#define Tk_PointerEvent \
	(tkPlatStubsPtr->tk_PointerEvent) /* 4 */
#define Tk_TranslateWinEvent \
	(tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
/* Slot 0 is reserved */
/* Slot 1 is reserved */
/* Slot 2 is reserved */
/* Slot 3 is reserved */




#define TkMacOSXInitAppleEvents \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */
#define TkGenWMConfigureEvent_ \
	(tkPlatStubsPtr->tkGenWMConfigureEvent_) /* 5 */
#define TkMacOSXInvalClipRgns \
	(tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */
/* Slot 7 is reserved */


#define TkMacOSXGetRootControl \
	(tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */
#define Tk_MacOSXSetupTkNotifier \
	(tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */
#define Tk_MacOSXIsAppInFront \
	(tkPlatStubsPtr->tk_MacOSXIsAppInFront) /* 10 */
#define Tk_MacOSXGetTkWindow \
	(tkPlatStubsPtr->tk_MacOSXGetTkWindow) /* 11 */
#define Tk_MacOSXGetCGContextForDrawable \
	(tkPlatStubsPtr->tk_MacOSXGetCGContextForDrawable) /* 12 */
#define Tk_MacOSXGetNSWindowForDrawable \
	(tkPlatStubsPtr->tk_MacOSXGetNSWindowForDrawable) /* 13 */
/* Slot 14 is reserved */
/* Slot 15 is reserved */
#define TkGenWMConfigureEvent \
	(tkPlatStubsPtr->tkGenWMConfigureEvent) /* 16 */
#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#ifdef __cplusplus







|
|
|
|
>
>
>
>


|
|


<
>
>














|
|







151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171

172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
	(tkPlatStubsPtr->tk_HWNDToWindow) /* 3 */
#define Tk_PointerEvent \
	(tkPlatStubsPtr->tk_PointerEvent) /* 4 */
#define Tk_TranslateWinEvent \
	(tkPlatStubsPtr->tk_TranslateWinEvent) /* 5 */
#endif /* WIN */
#ifdef MAC_OSX_TK /* AQUA */
#define Tk_MacOSXSetEmbedHandler \
	(tkPlatStubsPtr->tk_MacOSXSetEmbedHandler) /* 0 */
#define Tk_MacOSXTurnOffMenus \
	(tkPlatStubsPtr->tk_MacOSXTurnOffMenus) /* 1 */
#define Tk_MacOSXTkOwnsCursor \
	(tkPlatStubsPtr->tk_MacOSXTkOwnsCursor) /* 2 */
#define TkMacOSXInitMenus \
	(tkPlatStubsPtr->tkMacOSXInitMenus) /* 3 */
#define TkMacOSXInitAppleEvents \
	(tkPlatStubsPtr->tkMacOSXInitAppleEvents) /* 4 */
#define TkGenWMConfigureEvent \
	(tkPlatStubsPtr->tkGenWMConfigureEvent) /* 5 */
#define TkMacOSXInvalClipRgns \
	(tkPlatStubsPtr->tkMacOSXInvalClipRgns) /* 6 */

#define TkMacOSXGetDrawablePort \
	(tkPlatStubsPtr->tkMacOSXGetDrawablePort) /* 7 */
#define TkMacOSXGetRootControl \
	(tkPlatStubsPtr->tkMacOSXGetRootControl) /* 8 */
#define Tk_MacOSXSetupTkNotifier \
	(tkPlatStubsPtr->tk_MacOSXSetupTkNotifier) /* 9 */
#define Tk_MacOSXIsAppInFront \
	(tkPlatStubsPtr->tk_MacOSXIsAppInFront) /* 10 */
#define Tk_MacOSXGetTkWindow \
	(tkPlatStubsPtr->tk_MacOSXGetTkWindow) /* 11 */
#define Tk_MacOSXGetCGContextForDrawable \
	(tkPlatStubsPtr->tk_MacOSXGetCGContextForDrawable) /* 12 */
#define Tk_MacOSXGetNSWindowForDrawable \
	(tkPlatStubsPtr->tk_MacOSXGetNSWindowForDrawable) /* 13 */
/* Slot 14 is reserved */
/* Slot 15 is reserved */
#define TkGenWMConfigureEvent_ \
	(tkPlatStubsPtr->tkGenWMConfigureEvent_) /* 16 */
#endif /* AQUA */

#endif /* defined(USE_TK_STUBS) */

/* !END!: Do not edit above this line. */

#ifdef __cplusplus
Changes to generic/tkPointer.c.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

23
24
25
26
27
28
29
/*
 * 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"

#ifdef _WIN32
#include "