Tk Source Code

Check-in [0ebf4c5a]
Login

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

Overview
Comment:Merge updates from 8.6 branch.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | irontcl
Files: files | file ages | folders
SHA3-256:0ebf4c5ae1d29ee086a3f21544d1c6f519520c5275dcec96f510bcb70fdc91dc
User & Date: mistachkin 2018-11-10 19:50:22
Context
2018-11-10
19:50
Merge updates from 8.6 branch. Leaf check-in: 0ebf4c5a user: mistachkin tags: irontcl
19:37
The 'option readfile' sub-command should maintain existing list structure for values. Fix for [766ef52f31]. check-in: 5550a138 user: mistachkin tags: core-8-6-branch
2018-02-12
23:58
Merge updates from 8.6 branch. check-in: 45295241 user: mistachkin tags: irontcl
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to doc/Inactive.3.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
.SH SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
long
\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR
.sp
\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR
.SH ARGUMENTS
.AS Display *display
.AP Display *display in
The display on which the user inactivity timer is to be queried or
reset.
.BE
.SH DESCRIPTION
.PP
\fBTk_GetUserInactiveTime\fR returns the number of milliseconds that
have passed since the last user interaction (usually via keyboard or
mouse) with the respective display. On systems and displays that do not
support querying the user inactiviy time, \fB\-1\fR is returned.
\fBTk_GetUserInactiveTime\fR resets the user inactivity timer of the
given display to zero.  On windowing systems that do not support
multiple displays \fIdisplay\fR can be passed as \fBNULL\fR.
.SH KEYWORDS
idle, inactive







|











|
|




10
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 SYNOPSIS
.nf
\fB#include <tk.h>\fR
.sp
long
\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR
.sp
\fBTk_ResetUserInactiveTime(\fIdisplay\fB)\fR
.SH ARGUMENTS
.AS Display *display
.AP Display *display in
The display on which the user inactivity timer is to be queried or
reset.
.BE
.SH DESCRIPTION
.PP
\fBTk_GetUserInactiveTime\fR returns the number of milliseconds that
have passed since the last user interaction (usually via keyboard or
mouse) with the respective display. On systems and displays that do not
support querying the user inactivity time, \fB\-1\fR is returned.
\fBTk_ResetUserInactiveTime\fR resets the user inactivity timer of the
given display to zero.  On windowing systems that do not support
multiple displays \fIdisplay\fR can be passed as \fBNULL\fR.
.SH KEYWORDS
idle, inactive

Changes to doc/chooseDirectory.n.

13
14
15
16
17
18
19







20
21
22
23
24
25
26
27
28
29




30
31
32
33
34
35
36
.BE
.SH DESCRIPTION
.PP
The procedure \fBtk_chooseDirectory\fR pops up a dialog box for the
user to select a directory. The following \fIoption\-value\fR pairs are
possible as command line arguments:
.TP







\fB\-initialdir\fR \fIdirname\fR
Specifies that the directories in \fIdirectory\fR should be displayed
when the dialog pops up. If this parameter is not specified,
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\-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







>
>
>
>
>
>
>










>
>
>
>







13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.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

Changes to doc/event.n.

334
335
336
337
338
339
340
341


342
343
344
345
346
347
348
changed.
.TP
\fB<<Selection>>\fR
This is sent to a text widget when the selection in the widget is
changed.
.TP
\fB<<ThemeChanged>>\fR
This is sent to a text widget when the ttk (Tile) theme changed.


.TP
\fB<<TraverseIn>>\fR
This is sent to a widget when the focus enters the widget because of a
user-driven
.QW "tab to widget"
action.
.TP







|
>
>







334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
changed.
.TP
\fB<<Selection>>\fR
This is sent to a text widget when the selection in the widget is
changed.
.TP
\fB<<ThemeChanged>>\fR
This is sent to all widgets when the ttk theme changed. The ttk
widgets listen to this event and redisplay themselves when it fires.
The legacy widgets ignore this event.
.TP
\fB<<TraverseIn>>\fR
This is sent to a widget when the focus enters the widget because of a
user-driven
.QW "tab to widget"
action.
.TP

Changes to doc/getOpenFile.n.

31
32
33
34
35
36
37







38
39
40
41
42
43
44
as\fR command in the \fBFile\fR menu. If the user enters a file that
already exists, the dialog box prompts the user for confirmation
whether the existing file should be overwritten or not.
.PP
The following \fIoption\-value\fR pairs are possible as command line
arguments to these two commands:
.TP







\fB\-confirmoverwrite\fR \fIboolean\fR
Configures how the Save dialog reacts when the selected file already
exists, and saving would overwrite it.  A true value requests a
confirmation dialog be presented to the user.  A false value requests
that the overwrite take place without confirmation.  Default value is true.
.TP
\fB\-defaultextension\fR \fIextension\fR







>
>
>
>
>
>
>







31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
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

Changes to doc/messageBox.n.

20
21
22
23
24
25
26






27
28
29
30
31
32
33
the buttons in the message window is identified by a unique symbolic
name (see the \fB\-type\fR options).  After the message window is
popped up, \fBtk_messageBox\fR waits for the user to select one of the
buttons. Then it returns the symbolic name of the selected button.
.PP
The following option-value pairs are supported:
.TP






\fB\-default\fR \fIname\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
and so on). See \fB\-type\fR







>
>
>
>
>
>







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
the buttons in the message window is identified by a unique symbolic
name (see the \fB\-type\fR options).  After the message window is
popped up, \fBtk_messageBox\fR waits for the user to select one of the
buttons. Then it returns the symbolic name of the selected button.
.PP
The following option-value pairs are supported:
.TP
\fB\-command\fR \fIstring\fR
Specifies the prefix of a Tcl command to invoke when the user closes the
dialog. The actual command consists of \fIstring\fR followed by a space
and the name of the button clicked by the user to close the dialog. This
is only available on Mac OS X.
.TP
\fB\-default\fR \fIname\fR
.
\fIName\fR gives the symbolic name of the default button for
this message window (
.QW ok ,
.QW cancel ,
and so on). See \fB\-type\fR

Changes to doc/panedwindow.n.

25
26
27
28
29
30
31











32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
306
307
308
309
310
311
312


















































313
314
315
316
317
318
319
.OP \-handlesize handleSize HandleSize
Specifies the side length of a sash handle.  Handles are always
drawn as squares.  May be any value accepted by \fBTk_GetPixels\fR.
.OP \-height height Height
Specifies a desired height for the overall panedwindow widget. May be any
value accepted by \fBTk_GetPixels\fR. If an empty string, the widget will be
made high enough to allow all contained widgets to have their natural height.











.OP \-proxybackground proxyBackground ProxyBackground
Background color to use when drawing the proxy. If an empty string, the
value of the \fB-background\fR option will be used.
.OP \-proxyborderwidth proxyBorderWidth ProxyBorderWidth
Specifies the borderwidth of the proxy. May be any value accepted by
\fBTk_GetPixels\fR.
.OP \-proxyrelief proxyRelief ProxyRelief
Relief to use when drawing the proxy. May be any of the standard Tk
relief values. If an empty string, the value of the \fB-sashrelief\fR
option will be used.
.OP \-opaqueresize opaqueResize OpaqueResize
Specifies whether panes should be resized as a sash is moved (true),
or if resizing should be deferred until the sash is placed (false).
.OP \-sashcursor sashCursor SashCursor
Mouse cursor to use when over a sash.  If null,
\fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and
\fBsb_v_double_arrow\fR will be used for vertical panedwindows.
.OP \-sashpad sashPad SashPad
Specifies the amount of padding to leave of each side of a sash.  May
be any value accepted by \fBTk_GetPixels\fR.
................................................................................
.
Identify the panedwindow component underneath the point given by
\fIx\fR and \fIy\fR, in window coordinates.  If the point is over a
sash or a sash handle, the result is a two element list containing the
index of the sash or handle, and a word indicating whether it is over
a sash or a handle, such as {0 sash} or {2 handle}.  If the point is
over any other part of the panedwindow, the result is an empty list.
.TP
\fIpathName \fBproxy \fR?\fIargs\fR?
.
This command is used to query and change the position of the sash
proxy, used for rubberband-style pane resizing. It can take any of
the following forms:
.RS
.TP
\fIpathName \fBproxy coord\fR
.
Return a list containing the x and y coordinates of the most recent
proxy location.
.TP
\fIpathName \fBproxy forget\fR
.
Remove the proxy from the display.
.TP
\fIpathName \fBproxy place \fIx y\fR
.
Place the proxy at the given \fIx\fR and \fIy\fR coordinates.
.RE
.TP
\fIpathName \fBsash \fR?\fIargs\fR?
This command is used to query and change the position of sashes in the
panedwindow.  It can take any of the following forms:
.RS
.TP
\fIpathName \fBsash coord \fIindex\fR
.
Return the current x and y coordinate pair for the sash given by
\fIindex\fR.  \fIIndex\fR must be an integer between 0 and 1 less than
the number of panes in the panedwindow.  The coordinates given are
those of the top left corner of the region containing the sash.
.TP
\fIpathName \fBsash dragto \fIindex x y\fR
.
This command computes the difference between the given coordinates and the
coordinates given to the last \fBsash mark\fR command for the given
sash.  It then moves that sash the computed difference.  The return
value is the empty string.
.TP
\fIpathName \fBsash mark \fIindex x y\fR
.
Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in
conjunction with later \fBsash dragto\fR commands to move the sash.
.TP
\fIpathName \fBsash place \fIindex x y\fR
.
Place the sash given by \fIindex\fR at the given coordinates.
.RE
.TP
\fIpathName \fBpanecget \fIwindow option\fR
.
Query a management option for \fIwindow\fR.  \fIOption\fR may be any
value allowed by the \fBpaneconfigure\fR subcommand.
.TP
\fIpathName \fBpaneconfigure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
................................................................................
width may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.RE
.TP
\fIpathName \fBpanes\fR
.
Returns an ordered list of the widgets managed by \fIpathName\fR.


















































.SH "RESIZING PANES"
.PP
A pane is resized by grabbing the sash (or sash handle if present) and
dragging with the mouse.  This is accomplished via mouse motion
bindings on the widget.  When a sash is moved, the sizes of the panes
on each side of the sash, and thus the widgets in those panes, are
adjusted.







>
>
>
>
>
>
>
>
>
>
>










<
<
<







 







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







 







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







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52



53
54
55
56
57
58
59
...
136
137
138
139
140
141
142


















































143
144
145
146
147
148
149
...
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
.OP \-handlesize handleSize HandleSize
Specifies the side length of a sash handle.  Handles are always
drawn as squares.  May be any value accepted by \fBTk_GetPixels\fR.
.OP \-height height Height
Specifies a desired height for the overall panedwindow widget. May be any
value accepted by \fBTk_GetPixels\fR. If an empty string, the widget will be
made high enough to allow all contained widgets to have their natural height.
.OP \-opaqueresize opaqueResize OpaqueResize
Specifies whether panes should be resized as a sash is moved (true),
or if resizing should be deferred until the sash is placed (false).
In the latter case, a
.QW ghost
version of the sash is displayed during the resizing to show where the
panes will be resized to when releasing the mouse button. This
.QW ghost
version of the sash is the proxy. It's rendering can be configured
using the \fB-proxybackground\fR, \fB-proxyborderwidth\fR and
\fB-proxyrelief\fR options.
.OP \-proxybackground proxyBackground ProxyBackground
Background color to use when drawing the proxy. If an empty string, the
value of the \fB-background\fR option will be used.
.OP \-proxyborderwidth proxyBorderWidth ProxyBorderWidth
Specifies the borderwidth of the proxy. May be any value accepted by
\fBTk_GetPixels\fR.
.OP \-proxyrelief proxyRelief ProxyRelief
Relief to use when drawing the proxy. May be any of the standard Tk
relief values. If an empty string, the value of the \fB-sashrelief\fR
option will be used.



.OP \-sashcursor sashCursor SashCursor
Mouse cursor to use when over a sash.  If null,
\fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and
\fBsb_v_double_arrow\fR will be used for vertical panedwindows.
.OP \-sashpad sashPad SashPad
Specifies the amount of padding to leave of each side of a sash.  May
be any value accepted by \fBTk_GetPixels\fR.
................................................................................
.
Identify the panedwindow component underneath the point given by
\fIx\fR and \fIy\fR, in window coordinates.  If the point is over a
sash or a sash handle, the result is a two element list containing the
index of the sash or handle, and a word indicating whether it is over
a sash or a handle, such as {0 sash} or {2 handle}.  If the point is
over any other part of the panedwindow, the result is an empty list.


















































.TP
\fIpathName \fBpanecget \fIwindow option\fR
.
Query a management option for \fIwindow\fR.  \fIOption\fR may be any
value allowed by the \fBpaneconfigure\fR subcommand.
.TP
\fIpathName \fBpaneconfigure \fIwindow \fR?\fIoption\fR? ?\fIvalue option value ...\fR?
................................................................................
width may later be adjusted by the movement of sashes in the
panedwindow.  \fISize\fR may be any value accepted by \fBTk_GetPixels\fR.
.RE
.TP
\fIpathName \fBpanes\fR
.
Returns an ordered list of the widgets managed by \fIpathName\fR.
.TP
\fIpathName \fBproxy \fR?\fIargs\fR?
.
This command is used to query and change the position of the sash
proxy, used for rubberband-style pane resizing. It can take any of
the following forms:
.RS
.TP
\fIpathName \fBproxy coord\fR
.
Return a list containing the x and y coordinates of the most recent
proxy location.
.TP
\fIpathName \fBproxy forget\fR
.
Remove the proxy from the display.
.TP
\fIpathName \fBproxy place \fIx y\fR
.
Place the proxy at the given \fIx\fR and \fIy\fR coordinates.
.RE
.TP
\fIpathName \fBsash \fR?\fIargs\fR?
This command is used to query and change the position of sashes in the
panedwindow.  It can take any of the following forms:
.RS
.TP
\fIpathName \fBsash coord \fIindex\fR
.
Return the current x and y coordinate pair for the sash given by
\fIindex\fR.  \fIIndex\fR must be an integer between 0 and 1 less than
the number of panes in the panedwindow.  The coordinates given are
those of the top left corner of the region containing the sash.
.TP
\fIpathName \fBsash dragto \fIindex x y\fR
.
This command computes the difference between the given coordinates and the
coordinates given to the last \fBsash mark\fR command for the given
sash.  It then moves that sash the computed difference.  The return
value is the empty string.
.TP
\fIpathName \fBsash mark \fIindex x y\fR
.
Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in
conjunction with later \fBsash dragto\fR commands to move the sash.
.TP
\fIpathName \fBsash place \fIindex x y\fR
.
Place the sash given by \fIindex\fR at the given coordinates.
.RE
.SH "RESIZING PANES"
.PP
A pane is resized by grabbing the sash (or sash handle if present) and
dragging with the mouse.  This is accomplished via mouse motion
bindings on the widget.  When a sash is moved, the sizes of the panes
on each side of the sash, and thus the widgets in those panes, are
adjusted.

Changes to doc/radiobutton.n.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
mouse cursor is over the widget.  This option can be used to make
toolbar buttons, by configuring \fB\-relief flat \-overrelief
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the radiobutton.
The empty string is the default value.
.OP \-selectcolor selectColor Background
Specifies a background color to use when the button is selected.
If \fB\-indicatoron\fR is true then the color applies to the indicator.
Under Windows, this color is used as the background for the indicator
regardless of the select state.
If \fB\-indicatoron\fR is false, this color is used as the background
for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fB\-image\fR option)







<
|
|







59
60
61
62
63
64
65

66
67
68
69
70
71
72
73
74
mouse cursor is over the widget.  This option can be used to make
toolbar buttons, by configuring \fB\-relief flat \-overrelief
raised\fR.  If the value of this option is the empty string, then no
alternative relief is used when the mouse cursor is over the radiobutton.
The empty string is the default value.
.OP \-selectcolor selectColor Background
Specifies a background color to use when the button is selected.

If \fBindicatorOn\fR is true then the color is used as the background for
the indicator regardless of the select state.
If \fB\-indicatoron\fR is false, this color is used as the background
for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR,
whenever the widget is selected.
If specified as an empty string then no special color is used for
displaying when the widget is selected.
.OP \-selectimage selectImage SelectImage
Specifies an image to display (in place of the \fB\-image\fR option)

Changes to doc/ttk_button.n.

53
54
55
56
57
58
59











































60
61
62
63
64
65
66
.TP
\fIpathName \fBinvoke\fR
Invokes the command associated with the button.
.SH "STANDARD STYLES"
.PP
\fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard
themes, which is useful for creating widgets for toolbars.











































.SH "SEE ALSO"
ttk::widget(n), button(n)
.SH "KEYWORDS"
widget, button, default, command
'\" Local Variables:
'\" mode: nroff
'\" End:







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







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
.TP
\fIpathName \fBinvoke\fR
Invokes the command associated with the button.
.SH "STANDARD STYLES"
.PP
\fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard
themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::button\fP is \fBTButton\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBpressed\fP, \fBreadonly\fP.
.PP
\fBTButton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-anchor\fP \fIanchor\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-highlightcolor\fP \fIcolor\fP
.br
\fB\-highlightthickness\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-shiftrelief\fP \fIamount\fP
.RS
\fB\-shiftrelief\fP specifies how far the button contents are
shifted down and right in the \fIpressed\fP state.
This action provides additional skeumorphic feedback.
.RE
\fB\-width\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), button(n)
.SH "KEYWORDS"
widget, button, default, command
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_checkbutton.n.

64
65
66
67
68
69
70




























71
72
73
74
75
76
77
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::checkbutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.




























.SH "SEE ALSO"
ttk::widget(n), ttk::radiobutton(n), checkbutton(n)
.SH "KEYWORDS"
widget, button, toggle, check, option
'\" Local Variables:
'\" mode: nroff
'\" End:







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







64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::checkbutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::checkbutton\fP is \fBTCheckbutton\fP.
.PP
Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP,
\fBpressed\fP, \fBselected\fP, \fBreadonly\fP.
.PP
\fBTCheckbutton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indicatorbackground\fP \fIcolor\fP
.br
\fB\-indicatorcolor\fP \fIcolor\fP
.br
\fB\-indicatormargin\fP \fIpadding\fP
.br
\fB\-indicatorrelief\fP \fIrelief\fP
.br
\fB\-padding\fP \fIpadding\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::radiobutton(n), checkbutton(n)
.SH "KEYWORDS"
widget, button, toggle, check, option
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_combobox.n.

106
107
108
109
110
111
112













































































113
114
115
116
117
118
119
.DE
.SH "VIRTUAL EVENTS"
.PP
The combobox widget generates a \fB<<ComboboxSelected>>\fR virtual event
when the user selects an element from the list of values.
If the selection action unposts the listbox,
this event is delivered after the listbox is unposted.













































































.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n)
.SH KEYWORDS
choice, entry, list box, text box, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







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







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
.DE
.SH "VIRTUAL EVENTS"
.PP
The combobox widget generates a \fB<<ComboboxSelected>>\fR virtual event
when the user selects an element from the list of values.
If the selection action unposts the listbox,
this event is delivered after the listbox is unposted.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::combobox\fP is \fBTCombobox\fP.
The \fBttk::combobox\fP uses the \fBentry\fP and
\fBlistbox\fP widgets internally.
The listbox frame has a class name of \fBComboboxPopdownFrame\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBpressed\fP, \fBreadonly\fP.
.PP
\fBTCombobox\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-arrowcolor\fP \fIcolor\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-focusfill\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Can only be changed when using non-native and non-graphical themes.
.RE
\fB\-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
.RS
Text entry select foreground.
.RE
.PP
The \fBttk::combobox\fP popdown listbox cannot be configured using
\fBttk::style\fP nor via the widget \fBconfigure\fP command.  The listbox
can be configured using the option database.
.PP
option add *TCombobox*Listbox.background \fIcolor\fP
.br
option add *TCombobox*Listbox.font \fIfont\fP
.br
option add *TCombobox*Listbox.foreground \fIcolor\fP
.br
option add *TCombobox*Listbox.selectBackground \fIcolor\fP
.br
option add *TCombobox*Listbox.selectForeground \fIcolor\fP
.PP
To configure a specific listbox (subject to future change):
.CS
set popdown [ttk::combobox::PopdownWindow .mycombobox]
$popdown.f.l configure \-font \fIfont\fP
.CE
.PP
\fBComboboxPopdownFrame\fP
styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-relief\fP \fIrelief\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n)
.SH KEYWORDS
choice, entry, list box, text box, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_entry.n.

457
458
459
460
461
462
463









































464
465
466
467
468
469
470
Typically, the text is
.QW grayed-out
in the \fBdisabled\fR state,
and a different background is used in the \fBreadonly\fR state.
.PP
The entry widget sets the \fBinvalid\fR state if revalidation fails,
and clears it whenever validation succeeds.









































.SH "SEE ALSO"
ttk::widget(n), entry(n)
.SH KEYWORDS
entry, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:







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







457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
Typically, the text is
.QW grayed-out
in the \fBdisabled\fR state,
and a different background is used in the \fBreadonly\fR state.
.PP
The entry widget sets the \fBinvalid\fR state if revalidation fails,
and clears it whenever validation succeeds.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::entry\fP is \fBTEntry\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP.
.PP
\fBTEntry\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.RS
When using the aqua theme (Mac OS X), changes the \fB\-fieldbackground\fP.
.RE
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Does not work with the aqua theme (Mac OS X).
.br
Some themes use a graphical background and their field background colors cannot be changed.
.RE
\fB\-foreground\fP \fIcolor\fP
.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
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), entry(n)
.SH KEYWORDS
entry, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_frame.n.

41
42
43
44
45
46
47













48
49
50
51
52
53
54
.PP
Note that if the \fBpack\fR, \fBgrid\fR, or other geometry managers
are used to manage the children of the \fBframe\fR,
by the GM's requested size will normally take precedence
over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options.
\fBpack propagate\fR and \fBgrid propagate\fR can be used
to change this.













.SH "SEE ALSO"
ttk::widget(n), ttk::labelframe(n), frame(n)
.SH "KEYWORDS"
widget, frame, container
'\" Local Variables:
'\" mode: nroff
'\" End:







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







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
.PP
Note that if the \fBpack\fR, \fBgrid\fR, or other geometry managers
are used to manage the children of the \fBframe\fR,
by the GM's requested size will normally take precedence
over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options.
\fBpack propagate\fR and \fBgrid propagate\fR can be used
to change this.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::frame\fP is \fBTFrame\fP.
.PP
\fBTFrame\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::labelframe(n), frame(n)
.SH "KEYWORDS"
widget, frame, container
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_label.n.

59
60
61
62
63
64
65



















66
67
68
69
70
the text is split into lines such that no line is longer
than the specified value.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.



















.SH "SEE ALSO"
ttk::widget(n), label(n)
'\" Local Variables:
'\" mode: nroff
'\" End:







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





59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
the text is split into lines such that no line is longer
than the specified value.
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::label\fP is \fBTLabel\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTLabel\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), label(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_labelframe.n.

61
62
63
64
65
66
67








































68
69
70
71
72
73
74
(See \fIttk::frame(n)\fR for further notes on \fB\-width\fR and
\fB\-height\fR).
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.








































.SH "SEE ALSO"
ttk::widget(n), ttk::frame(n), labelframe(n)
.SH "KEYWORDS"
widget, frame, container, label, groupbox
'\" Local Variables:
'\" mode: nroff
'\" End:







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







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
(See \fIttk::frame(n)\fR for further notes on \fB\-width\fR and
\fB\-height\fR).
.SH "WIDGET COMMAND"
.PP
Supports the standard widget commands
\fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR;
see \fIttk::widget(n)\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::labelframe\fP is \fBTLabelframe\fP.
The text label
has a class of \fBTLabelframe.Label\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTLabelframe\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-labelmargins\fP \fIamount\fP
.br
\fB\-labeloutside\fP \fIboolean\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-relief\fP \fIrelief\fP
.PP
\fBTLabelframe.Label\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::frame(n), labelframe(n)
.SH "KEYWORDS"
widget, frame, container, label, groupbox
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_menubutton.n.

41
42
43
44
45
46
47



























48
49
50
51
52
53
54
Menubutton widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
.SH "STANDARD STYLES"
.PP
\fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.



























.SH "SEE ALSO"
ttk::widget(n), menu(n), menubutton(n)
.SH "KEYWORDS"
widget, button, menu
'\" Local Variables:
'\" mode: nroff
'\" End:







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







41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
Menubutton widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
.SH "STANDARD STYLES"
.PP
\fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::menubutton\fP is \fBTMenubutton\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBreadonly\fP.
.PP
\fBTMenubutton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-arrowsize\fP \fIamount\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-relief\fP \fIrelief\fP
.br
\fB\-width\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), menu(n), menubutton(n)
.SH "KEYWORDS"
widget, button, menu
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_notebook.n.

204
205
206
207
208
209
210


















































211
212
213
214
215
216
217
.CS
pack [\fBttk::notebook\fR .nb]
\&.nb add [frame .nb.f1] \-text "First tab"
\&.nb add [frame .nb.f2] \-text "Second tab"
\&.nb select .nb.f2
ttk::notebook::enableTraversal .nb
.CE


















































.SH "SEE ALSO"
ttk::widget(n), grid(n)
.SH "KEYWORDS"
pane, tab
'\" Local Variables:
'\" mode: nroff
'\" End:







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







204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
.CS
pack [\fBttk::notebook\fR .nb]
\&.nb add [frame .nb.f1] \-text "First tab"
\&.nb add [frame .nb.f2] \-text "Second tab"
\&.nb select .nb.f2
ttk::notebook::enableTraversal .nb
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::notebook\fP is \fBTNotebook\fP.  The tab has
a class name of \fBTNotebook.Tab\fP
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBselected\fP.
.PP
\fBTNotebook\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-padding\fP \fIpadding\fP
.br
\fB\-tabmargins\fP \fIpadding\fP
.br
\fB\-tabposition\fP \fIside\fP
.br
.PP
\fBTNotebook.Tab\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-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:

Changes to doc/ttk_panedwindow.n.

116
117
118
119
120
121
122



































123
124
125
126
127
.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 "SEE ALSO"
ttk::widget(n), ttk::notebook(n), panedwindow(n)
'\" Local Variables:
'\" mode: nroff
'\" End:







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





116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
.DE
.SH "VIRTUAL EVENTS"
.PP
The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts
for <Leave> events when the pointer crosses from a parent to a child. The
panedwindow widget needs to know when that happens.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::panedwindow\fP is \fBTPanedwindow\fP.  The
sash has a class name of \fBSash\fP.
.PP
\fBTPanedwindow\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
\fBSash\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-gripcount\fP \fIcount\fP
.br
\fB\-handlepad\fP \fIamount\fP
.br
\fB\-handlesize\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-sashpad\fP \fIamount\fP
.br
\fB\-sashrelief\fP \fIrelief\fP
.br
\fB\-sashthickness\fP \fIamount\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::notebook(n), panedwindow(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_progressbar.n.

82
83
84
85
86
87
88





























89
90
91
92
93
\fIpathName \fBstep\fR ?\fIamount\fR?
Increments the \fB\-value\fR by \fIamount\fR.
\fIamount\fR defaults to 1.0 if omitted.
.TP
\fIpathName \fBstop\fR
Stop autoincrement mode:
cancels any recurring timer event initiated by \fIpathName \fBstart\fR.





























.SH "SEE ALSO"
ttk::widget(n)
'\" Local Variables:
'\" mode: nroff
'\" End:







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





82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
\fIpathName \fBstep\fR ?\fIamount\fR?
Increments the \fB\-value\fR by \fIamount\fR.
\fIamount\fR defaults to 1.0 if omitted.
.TP
\fIpathName \fBstop\fR
Stop autoincrement mode:
cancels any recurring timer event initiated by \fIpathName \fBstart\fR.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::progressbar\fP is \fBTProgressbar\fP.
.PP
\fBTProgressbar\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-maxphase\fP
.RS
For the aqua theme.
.RE
\fB\-period\fP
.RS
For the aqua theme.
.RE
\fB\-troughcolor\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_radiobutton.n.

61
62
63
64
65
66
67




























68
69
70
71
72
73
74
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::radiobutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.




























.SH "SEE ALSO"
ttk::widget(n), ttk::checkbutton(n), radiobutton(n)
.SH "KEYWORDS"
widget, button, option
'\" Local Variables:
'\" mode: nroff
'\" End:







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







61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
or
.QW indeterminate
selection.)
.SH "STANDARD STYLES"
.PP
\fBTtk::radiobutton\fR widgets support the \fBToolbutton\fR style in all
standard themes, which is useful for creating widgets for toolbars.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::radiobutton\fP is \fBTRadiobutton\fP.
.PP
Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP,
\fBpressed\fP, \fBreadonly\fP, \fBselected\fP.
.PP
\fBTRadiobutton\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indicatorbackground\fP \fIcolor\fP
.br
\fB\-indicatorcolor\fP \fIcolor\fP
.br
\fB\-indicatormargin\fP \fIpadding\fP
.br
\fB\-indicatorrelief\fP \fIrelief\fP
.br
\fB\-padding\fP \fIpadding\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::checkbutton(n), radiobutton(n)
.SH "KEYWORDS"
widget, button, option
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_scale.n.

87
88
89
90
91
92
93





























94
95
96
97
98
99
100
101
.PP
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Get the coordinates corresponding to \fIvalue\fR, or the coordinates
corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR
is omitted.





























.SH "SEE ALSO"
ttk::widget(n), scale(n)
.SH KEYWORDS
scale, slider, trough, widget
.\" Local Variables:
.\" mode: nroff
.\" fill-column: 78
.\" End:







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








87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
.PP
.TP
\fIpathName \fBcoords \fR?\fIvalue\fR?
.
Get the coordinates corresponding to \fIvalue\fR, or the coordinates
corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR
is omitted.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scale\fP is \fBTProgressbar\fP.
.PP
Dynamic states: \fBactive\fP.
.PP
\fBTProgressbar\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-borderwidth\fP \fIamount\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-groovewidth\fP \fIamount\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-sliderwidth\fP \fIamount\fP
.br
\fB\-troughcolor\fP \fIcolor\fP
.br
\fB\-troughrelief\fP \fIrelief\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), scale(n)
.SH KEYWORDS
scale, slider, trough, widget
.\" Local Variables:
.\" mode: nroff
.\" fill-column: 78
.\" End:

Changes to doc/ttk_scrollbar.n.

150
151
152
153
154
155
156



























157
158
159
160
161
162
163
text $f.t \-xscrollcommand [list $f.hsb set] \-yscrollcommand [list $f.vsb set]
grid $f.t \-row 0 \-column 0 \-sticky nsew
grid $f.vsb \-row 0 \-column 1 \-sticky nsew
grid $f.hsb \-row 1 \-column 0 \-sticky nsew
grid columnconfigure $f 0 \-weight 1
grid rowconfigure $f 0 \-weight 1
.CE



























.SH "SEE ALSO"
ttk::widget(n), scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:







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







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
text $f.t \-xscrollcommand [list $f.hsb set] \-yscrollcommand [list $f.vsb set]
grid $f.t \-row 0 \-column 0 \-sticky nsew
grid $f.vsb \-row 0 \-column 1 \-sticky nsew
grid $f.hsb \-row 1 \-column 0 \-sticky nsew
grid columnconfigure $f 0 \-weight 1
grid rowconfigure $f 0 \-weight 1
.CE
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::scrollbar\fP is \fBTScrollbar\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP.
.PP
\fBTScrollbar\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-arrowcolor\fP \fIcolor\fP
.br
\fB\-background\fP \fIcolor\fP
.br
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-lightcolor\fP \fIcolor\fP
.br
\fB\-troughcolor\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), scrollbar(n)
.SH KEYWORDS
scrollbar, widget
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_separator.n.

26
27
28
29
30
31
32













33
34
35
36
37
38
39
Specifies the orientation of the separator.
.SH "WIDGET COMMAND"
.PP
Separator widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
.PP













.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, separator
'\" Local Variables:
'\" mode: nroff
'\" End:







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







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
Specifies the orientation of the separator.
.SH "WIDGET COMMAND"
.PP
Separator widgets support the standard
\fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
methods.  No other widget methods are used.
.PP
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::separator\fP is \fBTSeparator\fP.
.PP
\fBTSeparator\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, separator
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_sizegrip.n.

1
2
3
4
5
6
7
8
9
10
11
12
13
..
56
57
58
59
60
61
62













63
64
65
66
67
68
69
'\"
'\" Copyright (c) 2006 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\" 
.TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::sizegrip \- Bottom-right corner resize widget
.SH SYNOPSIS
\fBttk::sizegrip\fR \fIpathName \fR?\fIoptions\fR?
................................................................................
instead of
.QW "\fBwm geometry ... \fIw\fBx\fIh\fB+\fIx\fB+\fIy\fR" ),
the sizegrip widget will not resize the window.
.PP
\fBttk::sizegrip\fR widgets only support
.QW southeast
resizing.













.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, sizegrip, grow box
'\" Local Variables:
'\" mode: nroff
'\" End:





|







 







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







1
2
3
4
5
6
7
8
9
10
11
12
13
..
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
'\"
'\" Copyright (c) 2006 Joe English
'\"
'\" See the file "license.terms" for information on usage and redistribution
'\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
'\"
.TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget"
.so man.macros
.BS
.SH NAME
ttk::sizegrip \- Bottom-right corner resize widget
.SH SYNOPSIS
\fBttk::sizegrip\fR \fIpathName \fR?\fIoptions\fR?
................................................................................
instead of
.QW "\fBwm geometry ... \fIw\fBx\fIh\fB+\fIx\fB+\fIy\fR" ),
the sizegrip widget will not resize the window.
.PP
\fBttk::sizegrip\fR widgets only support
.QW southeast
resizing.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::sizegrip\fP is \fBTSizegrip\fP.
.PP
\fBTSizegrip\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n)
.SH "KEYWORDS"
widget, sizegrip, grow box
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_spinbox.n.

76
77
78
79
80
81
82







































83
84
85
86
87
88
89
or is not set or the \fB\-values\fR option has been used then the value
is set directly.
.SH "VIRTUAL EVENTS"
.PP
The spinbox widget generates a \fB<<Increment>>\fR virtual event when
the user presses <Up>, and a \fB<<Decrement>>\fR virtual event when the
user presses <Down>.







































.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n), spinbox(n)
.SH KEYWORDS
entry, spinbox, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:







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







76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
or is not set or the \fB\-values\fR option has been used then the value
is set directly.
.SH "VIRTUAL EVENTS"
.PP
The spinbox widget generates a \fB<<Increment>>\fR virtual event when
the user presses <Up>, and a \fB<<Decrement>>\fR virtual event when the
user presses <Down>.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::spinbox\fP is \fBTSpinbox\fP.
.PP
Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP.
.PP
\fBTSpinbox\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-arrowcolor\fP \fIcolor\fP
.br
\fB\-arrowsize\fP \fIamount\fP
.br
\fB\-background\fP \fIcolor\fP
.RS
When using the aqua theme (Mac OS X), changes the \fB\-fieldbackground\fP.
.RE
\fB\-bordercolor\fP \fIcolor\fP
.br
\fB\-darkcolor\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.RS
Does not work with the aqua theme (Mac OS X).
.RE
\fB\-foreground\fP \fIcolor\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
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), ttk::entry(n), spinbox(n)
.SH KEYWORDS
entry, spinbox, widget, text field
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to doc/ttk_treeview.n.

470
471
472
473
474
475
476


































































477
478
479
480
481
Generated just after setting the focus item to \fB\-open false\fR.
.PP
The \fBfocus\fR and \fBselection\fR widget commands can be used
to determine the affected item or items.
'\" Not yet:
'\" In Tk 8.5, the affected item is also passed as the \fB\-detail\fR field
'\" of the virtual event.


































































.SH "SEE ALSO"
ttk::widget(n), listbox(n), image(n), bind(n)
'\" Local Variables:
'\" mode: nroff
'\" End:







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





470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
Generated just after setting the focus item to \fB\-open false\fR.
.PP
The \fBfocus\fR and \fBselection\fR widget commands can be used
to determine the affected item or items.
'\" Not yet:
'\" In Tk 8.5, the affected item is also passed as the \fB\-detail\fR field
'\" of the virtual event.
.SH "STYLING OPTIONS"
.PP
The class name for a \fBttk::treeview\fP is \fBTreeview\fP.
The treeview header class name is \fBHeading\fP.
The treeview item class name is \fBItem\fP.
The treeview cell class name is \fBCell\fP.
.PP
Dynamic states: \fBdisabled\fP, \fBselected\fP.
.PP
\fBTreeview\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-fieldbackground\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-rowheight\fP \fIamount\fP
.RS
The \fB\-rowheight\fP value is not corrected by the \fBtk scaling\fP
value or by the configured font size and must always be set.  Also make
sure that the \fB\-rowheight\fP is large enough to contain any images.
.PP
To adjust the \fB\-rowheight\fP for the Treeview style, use the following code
after \fBtk scaling\fP has been applied.
Note that even if you do not support or change \fBtk scaling\fP
in your program, your users may have it set in their .wishrc.
.RE
.PP
.CS
ttk::style configure Treeview \\
     \-rowheight [expr {[font metrics \fIfont\fP \-linespace] + 2}]
.CE
.PP
\fBHeading\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-background\fP \fIcolor\fP
.br
\fB\-font\fP \fIfont\fP
.br
\fB\-relief\fP \fIrelief\fP
.PP
\fBItem\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-foreground\fP \fIcolor\fP
.br
\fB\-indicatormargins\fP \fIpadding\fP
.br
\fB\-indicatorsize\fP \fIamount\fP
.br
\fB\-padding\fP \fIpadding\fP
.PP
\fBCell\fP styling options configurable with \fBttk::style\fP
are:
.PP
\fB\-padding\fP \fIpadding\fP
.PP
Some options are only available for specific themes.
.PP
See the \fBttk::style\fP manual page for information on how to configure
ttk styles.
.SH "SEE ALSO"
ttk::widget(n), listbox(n), image(n), bind(n)
'\" Local Variables:
'\" mode: nroff
'\" End:

Changes to generic/tk.h.

1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
typedef struct Tk_TSOffset {
    int flags;			/* Flags; see below for possible values */
    int xoffset;		/* x offset */
    int yoffset;		/* y offset */
} Tk_TSOffset;

/*
 * Bit fields in Tk_Offset->flags:
 */

#define TK_OFFSET_INDEX		1
#define TK_OFFSET_RELATIVE	2
#define TK_OFFSET_LEFT		4
#define TK_OFFSET_CENTER	8
#define TK_OFFSET_RIGHT		16







|







1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
typedef struct Tk_TSOffset {
    int flags;			/* Flags; see below for possible values */
    int xoffset;		/* x offset */
    int yoffset;		/* y offset */
} Tk_TSOffset;

/*
 * Bit fields in Tk_TSOffset->flags:
 */

#define TK_OFFSET_INDEX		1
#define TK_OFFSET_RELATIVE	2
#define TK_OFFSET_LEFT		4
#define TK_OFFSET_CENTER	8
#define TK_OFFSET_RIGHT		16

Changes to generic/tkBind.c.

71
72
73
74
75
76
77











78


79
80
81
82
83
84
85
 * down (and auto-repeating). There may be as many as 3 auto-repeat events
 * after each mouse button press or release (see the first large comment block
 * within Tk_BindEvent for more on this), for a total of 20 events to cover
 * the three button presses and two intervening releases. If you reduce
 * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost.
 */












#define EVENT_BUFFER_SIZE 30


typedef struct Tk_BindingTable_ {
    XEvent eventRing[EVENT_BUFFER_SIZE];
				/* Circular queue of recent events (higher
				 * indices are for more recent events). */
    Detail detailRing[EVENT_BUFFER_SIZE];
				/* "Detail" information (keySym, button,
				 * Tk_Uid, or 0) for each entry in







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







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
 * down (and auto-repeating). There may be as many as 3 auto-repeat events
 * after each mouse button press or release (see the first large comment block
 * within Tk_BindEvent for more on this), for a total of 20 events to cover
 * the three button presses and two intervening releases. If you reduce
 * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost.
 */

/*
 * NOTE: The changes which were needed to make Tk work on OSX 10.14 (Mojave)
 * also demand that the event ring be a bit bigger.  It might be wise to
 * augment the current double-click pattern matching by adding a new
 * DoubleClick modifier bit which could be set based on the clickCount of the
 * Apple NSEvent object.
 */

#ifndef TK_MAC_OSX
  #define EVENT_BUFFER_SIZE 45
#else
  #define EVENT_BUFFER_SIZE 30
#endif

typedef struct Tk_BindingTable_ {
    XEvent eventRing[EVENT_BUFFER_SIZE];
				/* Circular queue of recent events (higher
				 * indices are for more recent events). */
    Detail detailRing[EVENT_BUFFER_SIZE];
				/* "Detail" information (keySym, button,
				 * Tk_Uid, or 0) for each entry in

Changes to generic/tkButton.c.

875
876
877
878
879
880
881





882

883
884
885
886
887
888
889
....
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
		 * Special note: must cancel any existing idle handler for
		 * TkpDisplayButton; it's no longer needed, and
		 * TkpDisplayButton cleared the REDRAW_PENDING flag.
		 */

		Tcl_CancelIdleCall(TkpDisplayButton, butPtr);
		XFlush(butPtr->display);





		Tcl_Sleep(50);

	    }
	}
	break;

    case COMMAND_INVOKE:
	if (objc > 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "invoke");
................................................................................
	if (!(flags & TCL_INTERP_DESTROYED)) {
	    Tcl_UntraceVar2(interp, name1, name2,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ButtonTextVarProc, clientData);
	}
 	return NULL;
     }
 
    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
	if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {







>
>
>
>
>

>







 







|







875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
....
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
		 * Special note: must cancel any existing idle handler for
		 * TkpDisplayButton; it's no longer needed, and
		 * TkpDisplayButton cleared the REDRAW_PENDING flag.
		 */

		Tcl_CancelIdleCall(TkpDisplayButton, butPtr);
		XFlush(butPtr->display);
		#ifndef MAC_OSX_TK
		/*
		 * On the mac you can not sleep in a display proc, and the
		 * flash command doesn't do anything anyway.
		 */
		Tcl_Sleep(50);
		#endif
	    }
	}
	break;

    case COMMAND_INVOKE:
	if (objc > 2) {
	    Tcl_WrongNumArgs(interp, 1, objv, "invoke");
................................................................................
	if (!(flags & TCL_INTERP_DESTROYED)) {
	    Tcl_UntraceVar2(interp, name1, name2,
		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
		    ButtonTextVarProc, clientData);
	}
 	return NULL;
     }

    /*
     * If the variable is unset, then immediately recreate it unless the whole
     * interpreter is going away.
     */

    if (flags & TCL_TRACE_UNSETS) {
	if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {

Changes to generic/tkConfig.c.

933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
 *----------------------------------------------------------------------
 */

static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{
    int length;

    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes != NULL) {
	return (objPtr->length == 0);
    }
    (void)Tcl_GetStringFromObj(objPtr, &length);
    return (length == 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * GetOption --
 *







<
<



|
|

<
|







933
934
935
936
937
938
939


940
941
942
943
944
945

946
947
948
949
950
951
952
953
 *----------------------------------------------------------------------
 */

static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{


    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes == NULL) {
	Tcl_GetString(objPtr);
    }

    return (objPtr->length == 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * GetOption --
 *

Changes to generic/tkEntry.h.

217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
				 * 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[10];	/* 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 */







|







217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
				 * 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 */

Changes to generic/tkImgGIF.c.

1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193

1194
1195




1196
1197
1198
1199
1200

1201
1202
1203
1204
1205
1206
1207
		}

		if (oldCode == -1) {
		    /*
		     * Last pass reset the decoder, so the first code we see
		     * must be a singleton. Seed the stack with it, and set up
		     * the old/first code pointers for insertion into the
		     * string table. We can't just roll this into the
		     * clearCode test above, because at that point we have not
		     * yet read the next code.
		     */

		    *top++ = append[code];
		    oldCode = code;
		    firstCode = code;
		    continue;
		}

		inCode = code;

		if (code == maxCode) {
		    /*
		     * maxCode is always one bigger than our highest assigned
		     * code. If the code we see is equal to maxCode, then we
		     * are about to add a new string to the table. ???
		     */

		    *top++ = firstCode;
		    code = oldCode;
		}

		while (code > clearCode) {
		    /*
		     * Populate the stack by tracing the string in the string
		     * table from its tail to its head
		     */

		    *top++ = append[code];
		    code = prefix[code];
		}
		firstCode = append[code];

		/*
		 * If there's no more room in our string table, quit.
		 * Otherwise, add a new string to the table
		 */

		if (maxCode >= (1 << MAX_LWZ_BITS)) {
		    return TCL_OK;
		}

		/*
		 * Push the head of the string onto the stack.
		 */

		*top++ = firstCode;


		/*
		 * Add a new string to the string table




		 */

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







|
|
|










|



|








|








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

|

>
|
<
>
>
>
>
|

|
|
|
>







1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179









1180
1181
1182
1183
1184
1185
1186

1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
		}

		if (oldCode == -1) {
		    /*
		     * Last pass reset the decoder, so the first code we see
		     * must be a singleton. Seed the stack with it, and set up
		     * the old/first code pointers for insertion into the
		     * codes table. We can't just roll this into the clearCode
		     * test above, because at that point we have not yet read
		     * the next code.
		     */

		    *top++ = append[code];
		    oldCode = code;
		    firstCode = code;
		    continue;
		}

		inCode = code;

		if ((code == maxCode) && (maxCode < (1 << MAX_LWZ_BITS))) {
		    /*
		     * maxCode is always one bigger than our highest assigned
		     * code. If the code we see is equal to maxCode, then we
		     * are about to add a new entry to the codes table.
		     */

		    *top++ = firstCode;
		    code = oldCode;
		}

		while (code > clearCode) {
		    /*
		     * Populate the stack by tracing the code in the codes
		     * table from its tail to its head
		     */

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

Changes to generic/tkImgPhInstance.c.

26
27
28
29
30
31
32

33
34

35
36
37
38
39
40
41
...
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
...
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455

456
457
458
459
460
461
462
...
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
...
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
...
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611

612
613
614
615
616
617
618
...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653




















654
655
656
657
658
659
660
...
705
706
707
708
709
710
711

712
713
714
715
716
717
718

extern int		_XInitImageFuncPtrs(XImage *image);

/*
 * Forward declarations
 */


static void		BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr,
			    int xOffset, int yOffset, int width, int height);

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);
................................................................................
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *	Note that on MacOS, if the background comes from a Retina display
 *	then it will be twice as wide and twice as high as the photoimage.
 *
 *----------------------------------------------------------------------
 */

#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
#define RGB(r, g, b)	((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
	(UCHAR(b) << blue_shift)  ))
#ifdef MAC_OSX_TK
#define RGBA(r, g, b, a) ((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
	(UCHAR(b) << blue_shift)  | \
	(UCHAR(a) << alpha_shift) ))
#endif
#define RGB15(r, g, b)	((unsigned)( \
	(((r) * red_mask / 255)   & red_mask)   | \
	(((g) * green_mask / 255) & green_mask) | \
	(((b) * blue_mask / 255)  & blue_mask)  ))
#endif /* !_WIN32 */

static void
................................................................................
				 * draw. */
    int width, int height)	/* Width & height of image to draw. */
{
    int x, y, line;
    unsigned long pixel;
    unsigned char r, g, b, alpha, unalpha, *masterPtr;
    unsigned char *alphaAr = iPtr->masterPtr->pix32;
#if defined(MAC_OSX_TK)
    /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels.  Each
     * block gets blended with the color of one image pixel.  Since we iterate
     * over the background subpixels, we reset the width and height to the
     * subpixel dimensions of the background image we are using.
     */
    int pp = bgImg->pixelpower;
    width = width << pp;
    height = height << pp;
#endif

    /*
     * This blending is an integer version of the Source-Over compositing rule
     * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
     * 1984) that has been hard-coded (for speed) to work with targetting a
     * solid surface.
     *
     * The 'unalpha' field must be 255-alpha; it is separated out to encourage
................................................................................
    }
    while ((0x0001 & (green_mask >> green_shift)) == 0) {
	green_shift++;
    }
    while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
	blue_shift++;
    }
#ifdef MAC_OSX_TK
    unsigned long alpha_mask = visual->alpha_mask;
    unsigned long alpha_shift = 0;
    while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) {
	alpha_shift++;
    }
#endif
#endif /* !_WIN32 */

    /*
     * Only UNIX requires the special case for <24bpp. It varies with 3 extra
     * shifts and uses RGB15. The 24+bpp version could also then be further
     * optimized.
     */
................................................................................
	    }
	}
	return;
    }
#endif /* !_WIN32 && !MAC_OSX_TK */

    for (y = 0; y < height; y++) {
# if !defined(MAC_OSX_TK)
	line = (y + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    masterPtr = alphaAr + ((line + x + xOffset) * 4);
#else
	/* Repeat each image row and column 2^pp times. */
	line = ((y>>pp) + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4);
#endif
	    alpha = masterPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */

	    if (alpha) {
................................................................................
		    ga = GetGValue(pixel);
		    ba = GetBValue(pixel);
		    unalpha = 255 - alpha;	/* Calculate once. */
		    r = ALPHA_BLEND(ra, r, alpha, unalpha);
		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
		}
#ifndef MAC_OSX_TK
		XPutPixel(bgImg, x, y, RGB(r, g, b));
#else
		XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha));
#endif
	    }
	}
    }
#undef ALPHA_BLEND
}

 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
................................................................................
				 * 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;
    XVisualInfo visInfo = instancePtr->visualInfo;

    /*
     * If there's no pixmap, it means that an error occurred while creating
     * the image instance so it can't be displayed.
     */

    if (instancePtr->pixels == None) {
	return;
    }





















    if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

	/*
................................................................................
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
    }
    XFlush(display);

}
 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoFree --
 *







>


>







 







|








<
<
<
<
<
<
<







 







<
<
<
<
<
<
<
<
<
<
>







 







<
<
<
<
<
<
<







 







<



<
<
<
<
<
<







 







<

<
<
<





>







 







<










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







 







>







26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422







423
424
425
426
427
428
429
...
434
435
436
437
438
439
440










441
442
443
444
445
446
447
448
...
474
475
476
477
478
479
480







481
482
483
484
485
486
487
...
533
534
535
536
537
538
539

540
541
542






543
544
545
546
547
548
549
...
567
568
569
570
571
572
573

574



575
576
577
578
579
580
581
582
583
584
585
586
587
...
605
606
607
608
609
610
611

612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
...
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707

extern int		_XInitImageFuncPtrs(XImage *image);

/*
 * Forward declarations
 */

#ifndef MAC_OSX_TK
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);
................................................................................
 *	Note that Win32 pre-defines those operations that we really need.
 *
 *	Note that on MacOS, if the background comes from a Retina display
 *	then it will be twice as wide and twice as high as the photoimage.
 *
 *----------------------------------------------------------------------
 */
#ifndef MAC_OSX_TK
#ifndef _WIN32
#define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
#define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
#define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
#define RGB(r, g, b)	((unsigned)( \
	(UCHAR(r) << red_shift)   | \
	(UCHAR(g) << green_shift) | \
	(UCHAR(b) << blue_shift)  ))







#define RGB15(r, g, b)	((unsigned)( \
	(((r) * red_mask / 255)   & red_mask)   | \
	(((g) * green_mask / 255) & green_mask) | \
	(((b) * blue_mask / 255)  & blue_mask)  ))
#endif /* !_WIN32 */

static void
................................................................................
				 * draw. */
    int width, int height)	/* Width & height of image to draw. */
{
    int x, y, line;
    unsigned long pixel;
    unsigned char r, g, b, alpha, unalpha, *masterPtr;
    unsigned char *alphaAr = iPtr->masterPtr->pix32;











    /*
     * This blending is an integer version of the Source-Over compositing rule
     * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH
     * 1984) that has been hard-coded (for speed) to work with targetting a
     * solid surface.
     *
     * The 'unalpha' field must be 255-alpha; it is separated out to encourage
................................................................................
    }
    while ((0x0001 & (green_mask >> green_shift)) == 0) {
	green_shift++;
    }
    while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
	blue_shift++;
    }







#endif /* !_WIN32 */

    /*
     * Only UNIX requires the special case for <24bpp. It varies with 3 extra
     * shifts and uses RGB15. The 24+bpp version could also then be further
     * optimized.
     */
................................................................................
	    }
	}
	return;
    }
#endif /* !_WIN32 && !MAC_OSX_TK */

    for (y = 0; y < height; y++) {

	line = (y + yOffset) * iPtr->masterPtr->width;
	for (x = 0; x < width; x++) {
	    masterPtr = alphaAr + ((line + x + xOffset) * 4);






	    alpha = masterPtr[3];

	    /*
	     * Ignore pixels that are fully transparent
	     */

	    if (alpha) {
................................................................................
		    ga = GetGValue(pixel);
		    ba = GetBValue(pixel);
		    unalpha = 255 - alpha;	/* Calculate once. */
		    r = ALPHA_BLEND(ra, r, alpha, unalpha);
		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
		}

		XPutPixel(bgImg, x, y, RGB(r, g, b));



	    }
	}
    }
#undef ALPHA_BLEND
}
#endif /* MAC_OSX_TK */
 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoDisplay --
 *
 *	This function is invoked to draw a photo image.
................................................................................
				 * 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;


    /*
     * 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 MAC_OSX_TK
    /*
     * The Mac version of TkPutImage handles RGBA images directly.  There is
     * no need to call XGetImage or to do the Porter-Duff compositing by hand.
     * We just let the CG graphics library do it, using the graphics hardware.
     */
    unsigned char *rgbaPixels = instancePtr->masterPtr->pix32;

    XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels,
				 (unsigned int)instancePtr->width,
				 (unsigned int)instancePtr->height,
				 0, (unsigned int)(4 * instancePtr->width));
    TkPutImage(NULL, 0, display, drawable, instancePtr->gc,
	       photo, imageX, imageY, drawableX, drawableY,
	       (unsigned int) width, (unsigned int) height);
    photo->data = NULL;
    XDestroyImage(photo);
#else
    XVisualInfo visInfo = instancePtr->visualInfo;
    
    if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA)
	    && visInfo.depth >= 15
	    && (visInfo.class == DirectColor || visInfo.class == TrueColor)) {
	Tk_ErrorHandler handler;
	XImage *bgImg = NULL;

	/*
................................................................................
	XCopyArea(display, instancePtr->pixels, drawable, instancePtr->gc,
		imageX, imageY, (unsigned) width, (unsigned) height,
		drawableX, drawableY);
	XSetClipMask(display, instancePtr->gc, None);
	XSetClipOrigin(display, instancePtr->gc, 0, 0);
    }
    XFlush(display);
#endif
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkImgPhotoFree --
 *

Changes to generic/tkInt.decls.

979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
}
declare 38 aqua {
    int TkSetMacColor(unsigned long pixel, void *macColor)
}
declare 39 aqua {
    void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid)
}
declare 40 aqua {
    void TkSuspendClipboard(void)
}
declare 41 aqua {
    int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart)
}
declare 42 aqua {
    Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, int rootY,
	    int *newX, int *newY)
}







|
|
|







979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
}
declare 38 aqua {
    int TkSetMacColor(unsigned long pixel, void *macColor)
}
declare 39 aqua {
    void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid)
}
#
# Slot 40 unused (WAS: TkSuspendClipboard)
#
declare 41 aqua {
    int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart)
}
declare 42 aqua {
    Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, int rootY,
	    int *newX, int *newY)
}

Changes to generic/tkIntPlatDecls.h.

220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
...
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
...
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
/* 37 */
EXTERN void		TkMacOSXWindowOffset(void *wRef, int *xOffset,
				int *yOffset);
/* 38 */
EXTERN int		TkSetMacColor(unsigned long pixel, void *macColor);
/* 39 */
EXTERN void		TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid);
/* 40 */
EXTERN void		TkSuspendClipboard(void);
/* 41 */
EXTERN int		TkMacOSXZoomToplevel(void *whichWindow,
				short zoomPart);
/* 42 */
EXTERN Tk_Window	Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX,
				int rootY, int *newX, int *newY);
/* 43 */
................................................................................
    void (*tkMacOSXUnregisterMacWindow) (void *portPtr); /* 33 */
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    TkRegion (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
    void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
    void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */
    int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */
    void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */
    void (*tkSuspendClipboard) (void); /* 40 */
    int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */
    Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */
    MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */
    MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */
    void (*tkMacOSXPreprocessMenu) (void); /* 45 */
    int (*tkpIsWindowFloating) (void *window); /* 46 */
    Tk_Window (*tkMacOSXGetCapture) (void); /* 47 */
................................................................................
	(tkIntPlatStubsPtr->tkMacOSXWinBounds) /* 36 */
#define TkMacOSXWindowOffset \
	(tkIntPlatStubsPtr->tkMacOSXWindowOffset) /* 37 */
#define TkSetMacColor \
	(tkIntPlatStubsPtr->tkSetMacColor) /* 38 */
#define TkSetWMName \
	(tkIntPlatStubsPtr->tkSetWMName) /* 39 */
#define TkSuspendClipboard \
	(tkIntPlatStubsPtr->tkSuspendClipboard) /* 40 */
#define TkMacOSXZoomToplevel \
	(tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */
#define Tk_TopCoordsToWindow \
	(tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 42 */
#define TkMacOSXContainerId \
	(tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */
#define TkMacOSXGetHostToplevel \







|
<







 







|







 







|
<







220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
...
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
...
594
595
596
597
598
599
600
601

602
603
604
605
606
607
608
/* 37 */
EXTERN void		TkMacOSXWindowOffset(void *wRef, int *xOffset,
				int *yOffset);
/* 38 */
EXTERN int		TkSetMacColor(unsigned long pixel, void *macColor);
/* 39 */
EXTERN void		TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid);
/* Slot 40 is reserved */

/* 41 */
EXTERN int		TkMacOSXZoomToplevel(void *whichWindow,
				short zoomPart);
/* 42 */
EXTERN Tk_Window	Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX,
				int rootY, int *newX, int *newY);
/* 43 */
................................................................................
    void (*tkMacOSXUnregisterMacWindow) (void *portPtr); /* 33 */
    int (*tkMacOSXUseMenuID) (short macID); /* 34 */
    TkRegion (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */
    void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */
    void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */
    int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */
    void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */
    void (*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 */
................................................................................
	(tkIntPlatStubsPtr->tkMacOSXWinBounds) /* 36 */
#define TkMacOSXWindowOffset \
	(tkIntPlatStubsPtr->tkMacOSXWindowOffset) /* 37 */
#define TkSetMacColor \
	(tkIntPlatStubsPtr->tkSetMacColor) /* 38 */
#define TkSetWMName \
	(tkIntPlatStubsPtr->tkSetWMName) /* 39 */
/* Slot 40 is reserved */

#define TkMacOSXZoomToplevel \
	(tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */
#define Tk_TopCoordsToWindow \
	(tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 42 */
#define TkMacOSXContainerId \
	(tkIntPlatStubsPtr->tkMacOSXContainerId) /* 43 */
#define TkMacOSXGetHostToplevel \

Changes to generic/tkMain.c.

232
233
234
235
236
237
238




239
240
241
242
243
244
245
    Tcl_InitMemory(interp);

    is.interp = interp;
    is.gotPartial = 0;
    Tcl_Preserve(interp);

#if defined(_WIN32) && !defined(__CYGWIN__)




    Tk_InitConsoleChannels(interp);
#endif

#ifdef MAC_OSX_TK
    if (Tcl_GetStartupScript(NULL) == NULL) {
	TkMacOSXDefaultStartupScript();
    }







>
>
>
>







232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
    Tcl_InitMemory(interp);

    is.interp = interp;
    is.gotPartial = 0;
    Tcl_Preserve(interp);

#if defined(_WIN32) && !defined(__CYGWIN__)
#if !defined(STATIC_BUILD)
    /* If compiled for Win32 but running on Cygwin, don't use console */
    if (!tclStubsPtr->reserved9)
#endif
    Tk_InitConsoleChannels(interp);
#endif

#ifdef MAC_OSX_TK
    if (Tcl_GetStartupScript(NULL) == NULL) {
	TkMacOSXDefaultStartupScript();
    }

Changes to generic/tkMenu.c.

1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
     * Tk_ConfigureWidget, such as special processing for defaults, sizing
     * strings, graphics contexts, etc.
     */

    if (mePtr->labelPtr == NULL) {
	mePtr->labelLength = 0;
    } else {
	(void)Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength);
    }
    if (mePtr->accelPtr == NULL) {
	mePtr->accelLength = 0;
    } else {
	(void)Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength);
    }

    /*
     * If this is a cascade entry, the platform-specific data of the child
     * menu has to be updated. Also, the links that point to parents and
     * cascades have to be updated.
     */







|




|







1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
     * 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.
     */

Changes to generic/tkMenuDraw.c.

620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
...
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
    register Tk_Window tkwin = menuPtr->tkwin;
    int index, strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;
    int activeBorderWidth;
    int relief;


    menuPtr->menuFlags &= ~REDRAW_PENDING;
    if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin,
	    menuPtr->activeBorderWidthPtr, &activeBorderWidth);

    if (menuPtr->menuType == MENUBAR) {
	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
		borderWidth, Tk_Width(tkwin) - 2 * borderWidth,
		Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT);
    }

................................................................................
	if (menuPtr->menuType != MENUBAR) {
	    if (!(mePtr->entryFlags & ENTRY_NEEDS_REDISPLAY)) {
		continue;
	    }
	}
	mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY;

	if (menuPtr->menuType == MENUBAR) {
	    width = mePtr->width;
	} else {
	    if (mePtr->entryFlags & ENTRY_LAST_COLUMN) {
		width = Tk_Width(menuPtr->tkwin) - mePtr->x
			- activeBorderWidth;
	    } else {
		width = mePtr->width + borderWidth;
	    }
	}
	TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,
		&menuMetrics, mePtr->x, mePtr->y, width,
		mePtr->height, strictMotif, 1);
	if ((index > 0) && (menuPtr->menuType != MENUBAR)
		&& mePtr->columnBreak) {
	    mePtr = menuPtr->entries[index - 1];
	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,
		mePtr->x, mePtr->y + mePtr->height,
		mePtr->width,
		Tk_Height(tkwin) - mePtr->y - mePtr->height -
		activeBorderWidth, 0,
		TK_RELIEF_FLAT);
	}
    }

    if (menuPtr->menuType != MENUBAR) {
	int x, y, height;

	if (menuPtr->numEntries == 0) {
	    x = y = borderWidth;
	    width = Tk_Width(tkwin) - 2 * activeBorderWidth;
	    height = Tk_Height(tkwin) - 2 * activeBorderWidth;
	} else {
	    mePtr = menuPtr->entries[menuPtr->numEntries - 1];
	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
		border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
		Tk_Height(tkwin) - mePtr->y - mePtr->height
		- activeBorderWidth, 0,
		TK_RELIEF_FLAT);
	    x = mePtr->x + mePtr->width;
	    y = mePtr->y + mePtr->height;
	    width = Tk_Width(tkwin) - x - activeBorderWidth;
	    height = Tk_Height(tkwin) - y - activeBorderWidth;
	}
	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y,
		width, height, 0, TK_RELIEF_FLAT);
    }

    Tk_GetReliefFromObj(NULL, menuPtr->reliefPtr, &relief);
    Tk_Draw3DRectangle(menuPtr->tkwin, Tk_WindowId(tkwin),







<











<
<







 







<
<
<
<
<
<
<
<
<
<

|





|
<
|
<
|








|
|




|
<
|


|
|







620
621
622
623
624
625
626

627
628
629
630
631
632
633
634
635
636
637


638
639
640
641
642
643
644
...
661
662
663
664
665
666
667










668
669
670
671
672
673
674
675

676

677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692

693
694
695
696
697
698
699
700
701
702
703
704
    register Tk_Window tkwin = menuPtr->tkwin;
    int index, strictMotif;
    Tk_Font tkfont;
    Tk_FontMetrics menuMetrics;
    int width;
    int borderWidth;
    Tk_3DBorder border;

    int relief;


    menuPtr->menuFlags &= ~REDRAW_PENDING;
    if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) {
	return;
    }

    Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr,
	    &borderWidth);
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);



    if (menuPtr->menuType == MENUBAR) {
	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth,
		borderWidth, Tk_Width(tkwin) - 2 * borderWidth,
		Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT);
    }

................................................................................
	if (menuPtr->menuType != MENUBAR) {
	    if (!(mePtr->entryFlags & ENTRY_NEEDS_REDISPLAY)) {
		continue;
	    }
	}
	mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY;











	TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont,
		&menuMetrics, mePtr->x, mePtr->y, mePtr->width,
		mePtr->height, strictMotif, 1);
	if ((index > 0) && (menuPtr->menuType != MENUBAR)
		&& mePtr->columnBreak) {
	    mePtr = menuPtr->entries[index - 1];
	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border,
		mePtr->x, mePtr->y + mePtr->height, mePtr->width,

		Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,

		0, TK_RELIEF_FLAT);
	}
    }

    if (menuPtr->menuType != MENUBAR) {
	int x, y, height;

	if (menuPtr->numEntries == 0) {
	    x = y = borderWidth;
	    width = Tk_Width(tkwin) - 2 * borderWidth;
	    height = Tk_Height(tkwin) - 2 * borderWidth;
	} else {
	    mePtr = menuPtr->entries[menuPtr->numEntries - 1];
	    Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin),
		border, mePtr->x, mePtr->y + mePtr->height, mePtr->width,
		Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth,

		0, TK_RELIEF_FLAT);
	    x = mePtr->x + mePtr->width;
	    y = mePtr->y + mePtr->height;
	    width = Tk_Width(tkwin) - x - borderWidth;
	    height = Tk_Height(tkwin) - y - borderWidth;
	}
	Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y,
		width, height, 0, TK_RELIEF_FLAT);
    }

    Tk_GetReliefFromObj(NULL, menuPtr->reliefPtr, &relief);
    Tk_Draw3DRectangle(menuPtr->tkwin, Tk_WindowId(tkwin),

Changes to generic/tkObj.c.

664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
...
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

static void
UpdateStringOfMM(
    register Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    register int len;

    mmPtr = objPtr->internalRep.twoPtrValue.ptr1;
    /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
    if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
	Tcl_Panic("UpdateStringOfMM: false precondition");
    }

    Tcl_PrintDouble(NULL, mmPtr->value, buffer);
    len = (int)strlen(buffer);

    objPtr->bytes = ckalloc(len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
}
 
/*
................................................................................
    const Tcl_ObjType *typePtr;
    WindowRep *winPtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    (void)Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    winPtr = ckalloc(sizeof(WindowRep));
    winPtr->tkwin = NULL;







|








|







 







|







664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
...
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902

static void
UpdateStringOfMM(
    register Tcl_Obj *objPtr)   /* pixel obj with string rep to update. */
{
    MMRep *mmPtr;
    char buffer[TCL_DOUBLE_SPACE];
    size_t len;

    mmPtr = objPtr->internalRep.twoPtrValue.ptr1;
    /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */
    if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) {
	Tcl_Panic("UpdateStringOfMM: false precondition");
    }

    Tcl_PrintDouble(NULL, mmPtr->value, buffer);
    len = strlen(buffer);

    objPtr->bytes = ckalloc(len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
}
 
/*
................................................................................
    const Tcl_ObjType *typePtr;
    WindowRep *winPtr;

    /*
     * Free the old internalRep before setting the new one.
     */

    Tcl_GetString(objPtr);
    typePtr = objPtr->typePtr;
    if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) {
	typePtr->freeIntRepProc(objPtr);
    }

    winPtr = ckalloc(sizeof(WindowRep));
    winPtr->tkwin = NULL;

Changes to generic/tkOldTest.c.

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

    timPtr = ckalloc(sizeof(TImageMaster));
    timPtr->master = master;
    timPtr->interp = interp;
    timPtr->width = 30;
    timPtr->height = 15;
    timPtr->imageName = ckalloc((unsigned) (strlen(name) + 1));
    strcpy(timPtr->imageName, name);
    timPtr->varName = ckalloc((unsigned) (strlen(varName) + 1));
    strcpy(timPtr->varName, varName);
    Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL);
    *clientDataPtr = timPtr;
    Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}
 







|

|







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

    timPtr = ckalloc(sizeof(TImageMaster));
    timPtr->master = master;
    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(master, 0, 0, 30, 15, 30, 15);
    return TCL_OK;
}
 

Changes to generic/tkOption.c.

991
992
993
994
995
996
997



998
999
1000
1001
1002
1003
1004
....
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
	/*
	 * Skip white space between the name and the value.
	 */

	src++;
	while ((*src == ' ') || (*src == '\t')) {
	    src++;



	}
	if (*src == '\0') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "missing value on line %d", lineNum));
	    Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "VALUE", NULL);
	    return TCL_ERROR;
	}
................................................................................
		    src += 2;
		    lineNum++;
		    continue;
		} else if (src[1] == 'n') {
		    src += 2;
		    *dst++ = '\n';
		    continue;
		} else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') {
		    ++src;
		} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
			src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
		    *dst++ = ((src[1]&7)<<6) | ((src[2]&7)<<3) | (src[3]&7);
		    src += 4;
		    continue;
		}







>
>
>







 







|







991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
....
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
	/*
	 * Skip white space between the name and the value.
	 */

	src++;
	while ((*src == ' ') || (*src == '\t')) {
	    src++;
	}
	if (*src == '\\' && (src[1] == '\t' || src[1] == ' ')) {
	    src++;
	}
	if (*src == '\0') {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "missing value on line %d", lineNum));
	    Tcl_SetErrorCode(interp, "TK", "OPTIONDB", "VALUE", NULL);
	    return TCL_ERROR;
	}
................................................................................
		    src += 2;
		    lineNum++;
		    continue;
		} else if (src[1] == 'n') {
		    src += 2;
		    *dst++ = '\n';
		    continue;
		} else if (src[1] == '\\') {
		    ++src;
		} else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' &&
			src[2] <= '9' && src[3] >= '0' && src[3] <= '9') {
		    *dst++ = ((src[1]&7)<<6) | ((src[2]&7)<<3) | (src[3]&7);
		    src += 4;
		    continue;
		}

Changes to generic/tkPanedWindow.c.

2988
2989
2990
2991
2992
2993
2994
2995
2996
2997
2998
2999
3000
3001
3002
3003
3004
3005
3006
3007
3008
3009
3010
3011
 *----------------------------------------------------------------------
 */

static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{
    int length;

    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes != NULL) {
	return (objPtr->length == 0);
    }
    (void)Tcl_GetStringFromObj(objPtr, &length);
    return (length == 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * ComputeInternalPointer --
 *







<
<



|
|

<
|







2988
2989
2990
2991
2992
2993
2994


2995
2996
2997
2998
2999
3000

3001
3002
3003
3004
3005
3006
3007
3008
 *----------------------------------------------------------------------
 */

static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{


    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes == NULL) {
	Tcl_GetString(objPtr);
    }

    return (objPtr->length == 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * ComputeInternalPointer --
 *

Changes to generic/tkScale.h.

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
				 * display any tick marks. */
    double resolution;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    int digits;			/* Number of significant digits to print in
				 * values. 0 means we get to choose the number
				 * based on resolution and/or the range of the
				 * scale. */
    char format[10];		/* Sprintf conversion specifier computed from
				 * digits and other information. */
    double bigIncrement;	/* Amount to use for large increments to scale
				 * value. (0 means we pick a value). */
    char *command;		/* Command prefix to use when invoking Tcl
				 * commands because the scale value changed.
				 * NULL means don't invoke commands. */
    int repeatDelay;		/* How long to wait before auto-repeating on







|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
				 * display any tick marks. */
    double resolution;		/* If > 0, all values are rounded to an even
				 * multiple of this value. */
    int digits;			/* Number of significant digits to print in
				 * values. 0 means we get to choose the number
				 * based on resolution and/or the range of the
				 * scale. */
    char format[16];		/* Sprintf conversion specifier computed from
				 * digits and other information. */
    double bigIncrement;	/* Amount to use for large increments to scale
				 * value. (0 means we pick a value). */
    char *command;		/* Command prefix to use when invoking Tcl
				 * commands because the scale value changed.
				 * NULL means don't invoke commands. */
    int repeatDelay;		/* How long to wait before auto-repeating on

Changes to generic/tkStubInit.c.

543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    TkMacOSXUnregisterMacWindow, /* 33 */
    TkMacOSXUseMenuID, /* 34 */
    TkMacOSXVisableClipRgn, /* 35 */
    TkMacOSXWinBounds, /* 36 */
    TkMacOSXWindowOffset, /* 37 */
    TkSetMacColor, /* 38 */
    TkSetWMName, /* 39 */
    TkSuspendClipboard, /* 40 */
    TkMacOSXZoomToplevel, /* 41 */
    Tk_TopCoordsToWindow, /* 42 */
    TkMacOSXContainerId, /* 43 */
    TkMacOSXGetHostToplevel, /* 44 */
    TkMacOSXPreprocessMenu, /* 45 */
    TkpIsWindowFloating, /* 46 */
    TkMacOSXGetCapture, /* 47 */







|







543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    TkMacOSXUnregisterMacWindow, /* 33 */
    TkMacOSXUseMenuID, /* 34 */
    TkMacOSXVisableClipRgn, /* 35 */
    TkMacOSXWinBounds, /* 36 */
    TkMacOSXWindowOffset, /* 37 */
    TkSetMacColor, /* 38 */
    TkSetWMName, /* 39 */
    0, /* 40 */
    TkMacOSXZoomToplevel, /* 41 */
    Tk_TopCoordsToWindow, /* 42 */
    TkMacOSXContainerId, /* 43 */
    TkMacOSXGetHostToplevel, /* 44 */
    TkMacOSXPreprocessMenu, /* 45 */
    TkpIsWindowFloating, /* 46 */
    TkMacOSXGetCapture, /* 47 */

Changes to generic/tkTest.c.

27
28
29
30
31
32
33



34
35
36
37
38
39
40
...
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
...
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
....
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
....
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
#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"



#endif

#ifdef __UNIX__
#include "tkUnixInt.h"
#endif

/*
................................................................................
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int		TestmenubarObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#endif
#if defined(_WIN32) || defined(MAC_OSX_TK)
static int		TestmetricsObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#endif
static int		TestobjconfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
................................................................................
    Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);

#if defined(_WIN32) || defined(MAC_OSX_TK)
    Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#elif !defined(__CYGWIN__)
    Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#endif /* _WIN32 || MAC_OSX_TK */

    /*
     * Create test image type.
     */

    if (!initialized) {
	initialized = 1;
................................................................................
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = (TImageInstance *) clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];


















    sprintf(buffer, "%s display %d %d %d %d %d %d",
	    instPtr->masterPtr->imageName, imageX, imageY, width, height,
	    drawableX, drawableY);
    Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
	    buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->masterPtr->width - imageX)) {
	width = instPtr->masterPtr->width - imageX;
    }
    if (height > (instPtr->masterPtr->height - imageY)) {
	height = instPtr->masterPtr->height - imageY;
    }


    XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
	    (unsigned) (width-1), (unsigned) (height-1));
    XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
	    (int) (drawableX + width - 1), (int) (drawableY + height - 1));
    XDrawLine(display, drawable, instPtr->gc, drawableX,
	    (int) (drawableY + height - 1),
	    (int) (drawableX + width - 1), drawableY);
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if defined(_WIN32) || defined(MAC_OSX_TK)
static int
TestmetricsObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    char buf[TCL_INTEGER_SPACE];
    int val;

#ifdef _WIN32
    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }
#else
    Tk_Window tkwin = (Tk_Window) clientData;
    TkWindow *winPtr;

    if (objc != 3) {
	Tcl_WrongNumArgs(interp, 1, objv, "option window");
	return TCL_ERROR;
    }

    winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
    if (winPtr == NULL) {
	return TCL_ERROR;
    }
#endif

    if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) {
#ifdef _WIN32
	val = GetSystemMetrics(SM_CYVSCROLL);
#else
	val = ((TkScrollbar *) winPtr->instanceData)->width;
#endif
    } else  if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) {
#ifdef _WIN32
	val = GetSystemMetrics(SM_CXHSCROLL);
#else
	val = ((TkScrollbar *) winPtr->instanceData)->width;
#endif
    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be cxhscroll or cyvscroll", NULL);
	return TCL_ERROR;
    }
    sprintf(buf, "%d", val);
    Tcl_AppendResult(interp, buf, NULL);







>
>
>







 







|







 







|


|






|







 







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

|






>
>







 







|










<




<
<
<

<
<
<
<
<
<
<
<
<
<
<

<

<
<
<

<

<
<
<







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
...
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
....
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
....
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
#ifdef _WIN32
#include "tkWinInt.h"
#endif

#if defined(MAC_OSX_TK)
#include "tkMacOSXInt.h"
#include "tkScrollbar.h"
#define SIMULATE_DRAWING TkTestSimulateDrawing(true);
#else
#define SIMULATE_DRAWING
#endif

#ifdef __UNIX__
#include "tkUnixInt.h"
#endif

/*
................................................................................
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__))
static int		TestmenubarObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj *const objv[]);
#endif
#if defined(_WIN32)
static int		TestmetricsObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
#endif
static int		TestobjconfigObjCmd(ClientData dummy,
			    Tcl_Interp *interp, int objc,
			    Tcl_Obj * const objv[]);
................................................................................
    Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);

#if defined(_WIN32)
    Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK)
    Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
    Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd,
	    (ClientData) Tk_MainWindow(interp), NULL);
#endif /* _WIN32 */

    /*
     * Create test image type.
     */

    if (!initialized) {
	initialized = 1;
................................................................................
    int drawableX, int drawableY)
				/* Coordinates in drawable corresponding to
				 * imageX and imageY. */
{
    TImageInstance *instPtr = (TImageInstance *) clientData;
    char buffer[200 + TCL_INTEGER_SPACE * 6];

    /*
     * The purpose of the test image type is to track the calls to an image
     * display proc and record the parameters passed in each call.  On macOS
     * these tests will fail because of the asynchronous drawing.  The low
     * level graphics calls below which are supposed to draw a rectangle will
     * not draw anything to the screen because the idle task will not be
     * processed inside of the drawRect method and hence will not be able to
     * obtain a valid graphics context. Instead, the window will be marked as
     * needing display, and will be redrawn during a future asynchronous call
     * to drawRect.  This will generate an other call to this display proc,
     * and the recorded data will show extra calls, causing the test to fail.
     * To avoid this, we can set the [NSApp simulateDrawing] flag, which will
     * cause all low level drawing routines to return immediately and not
     * schedule the window for drawing later.  This flag is cleared by the
     * next call to XSync, which is called by the update command.
     */

    sprintf(buffer, "%s display %d %d %d %d",
	    instPtr->masterPtr->imageName, imageX, imageY, width, height);

    Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL,
		buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT);
    if (width > (instPtr->masterPtr->width - imageX)) {
	width = instPtr->masterPtr->width - imageX;
    }
    if (height > (instPtr->masterPtr->height - imageY)) {
	height = instPtr->masterPtr->height - imageY;
    }

    SIMULATE_DRAWING
    XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY,
	    (unsigned) (width-1), (unsigned) (height-1));
    XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY,
	    (int) (drawableX + width - 1), (int) (drawableY + height - 1));
    XDrawLine(display, drawable, instPtr->gc, drawableX,
	    (int) (drawableY + height - 1),
	    (int) (drawableX + width - 1), drawableY);
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

#if defined(_WIN32)
static int
TestmetricsObjCmd(
    ClientData clientData,	/* Main window for application. */
    Tcl_Interp *interp,		/* Current interpreter. */
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])		/* Argument strings. */
{
    char buf[TCL_INTEGER_SPACE];
    int val;


    if (objc < 2) {
	Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?");
	return TCL_ERROR;
    }















    if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) {

	val = GetSystemMetrics(SM_CYVSCROLL);



    } else  if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) {

	val = GetSystemMetrics(SM_CXHSCROLL);



    } else {
	Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]),
		"\": must be cxhscroll or cyvscroll", NULL);
	return TCL_ERROR;
    }
    sprintf(buf, "%d", val);
    Tcl_AppendResult(interp, buf, NULL);

Changes to generic/tkText.c.

860
861
862
863
864
865
866
867

868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
...
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
....
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
....
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
....
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
....
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
....
1479
1480
1481
1482
1483
1484
1485



1486
1487
1488
1489
1490
1491
1492
1493
1494



1495
1496
1497
1498
1499
1500
1501
1502
....
2623
2624
2625
2626
2627
2628
2629
2630

2631
2632
2633
2634
2635
2636
2637
....
4172
4173
4174
4175
4176
4177
4178
4179
4180
4181
4182
4183
4184
4185
4186
....
4697
4698
4699
4700
4701
4702
4703
4704
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
....
5811
5812
5813
5814
5815
5816
5817
5818
5819
5820
5821
5822
5823
5824
5825
....
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
....
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
....
6073
6074
6075
6076
6077
6078
6079

6080

6081

6082
6083

6084
6085
6086
6087
6088
6089
6090
....
6812
6813
6814
6815
6816
6817
6818
6819
6820
6821
6822
6823
6824
6825
6826
6827
6828
6829
	indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-1]);
	if (indexToPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}

	for (i = 2; i < objc-2; i++) {
	    int value, length;

	    const char *option = Tcl_GetString(objv[i]);
	    char c;

	    length = objv[i]->length;
	    if (length < 2 || option[0] != '-') {
		goto badOption;
	    }
	    c = option[1];
	    if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_CHARS);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displaychars", option, (unsigned) length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_DISPLAY_CHARS);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displayindices", option,(unsigned)length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_DISPLAY_INDICES);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displaylines", option, (unsigned) length)) {
		TkTextLine *fromPtr, *lastPtr;
		TkTextIndex index, index2;

		int compare = TkTextIndexCmp(indexFromPtr, indexToPtr);
		value = 0;

		if (compare == 0) {
................................................................................
		    }
		}

		if (compare > 0) {
		    value = -value;
		}
	    } else if (c == 'i'
		    && !strncmp("-indices", option, (unsigned) length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_INDICES);
	    } else if (c == 'l'
		    && !strncmp("-lines", option, (unsigned) length)) {
		value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr)
			- TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
	    } else if (c == 'u'
		    && !strncmp("-update", option, (unsigned) length)) {
		update = 1;
		continue;
	    } else if (c == 'x'
		    && !strncmp("-xpixels", option, (unsigned) length)) {
		int x1, x2;
		TkTextIndex index;

		index = *indexFromPtr;
		TkTextFindDisplayLineEnd(textPtr, &index, 0, &x1);
		index = *indexToPtr;
		TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2);
		value = x2 - x1;
	    } else if (c == 'y'
		    && !strncmp("-ypixels", option, (unsigned) length)) {
		if (update) {
		    TkTextUpdateLineMetrics(textPtr,
			    TkBTreeLinesTo(textPtr, indexFromPtr->linePtr),
			    TkBTreeLinesTo(textPtr, indexToPtr->linePtr), -1);
		}
		value = TkTextIndexYPixels(textPtr, indexToPtr)
			- TkTextIndexYPixels(textPtr, indexFromPtr);
................................................................................
		if (objc & 1) {
		    indices[i] = indices[i-1];
		    TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i],
			    COUNT_INDICES);
		    objc++;
		}
		useIdx = ckalloc(objc);
		memset(useIdx, 0, (unsigned) objc);

		/*
		 * Do a decreasing order sort so that we delete the end ranges
		 * first to maintain index consistency.
		 */

		qsort(indices, (unsigned) objc / 2,
			2 * sizeof(TkTextIndex), TextIndexSortProc);
		lastStart = NULL;

		/*
		 * Second pass will handle bogus ranges (end < start) and
		 * overlapping ranges.
		 */
................................................................................
    case TEXT_EDIT:
	result = TextEditCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_GET: {
	Tcl_Obj *objPtr = NULL;
	int i, found = 0, visible = 0;
	const char *name;
	int length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "?-displaychars? ?--? index1 ?index2 ...?");
	    result = TCL_ERROR;
	    goto done;
	}
................................................................................
	 */

	i = 2;
	if (objc > 3) {
	    name = Tcl_GetString(objv[i]);
	    length = objv[i]->length;
	    if (length > 1 && name[0] == '-') {
		if (strncmp("-displaychars", name, (unsigned) length) == 0) {
		    i++;
		    visible = 1;
		    name = Tcl_GetString(objv[i]);
		    length = objv[i]->length;
		}
		if ((i < objc-1) && (length == 2) && !strcmp("--", name)) {
		    i++;
................................................................................
		    && (TkTextIndexCmp(indexToPtr, &index) > 0)) {
		/*
		 * The insertion point is inside the range to be replaced, so
		 * we have to do some calculations to ensure it doesn't move
		 * unnecessarily.
		 */

		int deleteInsertOffset, insertLength, j;

		insertLength = 0;
		for (j = 4; j < objc; j += 2) {
		    insertLength += Tcl_GetCharLength(objv[j]);
		}

		/*
................................................................................

		deleteInsertOffset = CountIndices(textPtr, indexFromPtr,
			&index, COUNT_CHARS);
		if (deleteInsertOffset > insertLength) {
		    deleteInsertOffset = insertLength;
		}




		result = TextReplaceCmd(textPtr, interp, indexFromPtr,
			indexToPtr, objc, objv, 0);

		if (result == TCL_OK) {
		    /*
		     * Move the insertion position to the correct place.
		     */

                    indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]);



		    TkTextIndexForwChars(NULL, indexFromPtr,
			    deleteInsertOffset, &index, COUNT_INDICES);
		    TkBTreeUnlinkSegment(textPtr->insertMarkPtr,
			    textPtr->insertMarkPtr->body.mark.linePtr);
		    TkBTreeLinkSegment(textPtr->insertMarkPtr, &index);
		}
	    } else {
		result = TextReplaceCmd(textPtr, interp, indexFromPtr,
................................................................................
    TkTextIndex *indexPtr,	/* Where to insert new characters. May be
				 * modified if the index is not valid for
				 * insertion (e.g. if at "end"). */
    Tcl_Obj *stringPtr,		/* Null-terminated string containing new
				 * information to add to text. */
    int viewUpdate)		/* Update the view if set. */
{
    int lineIndex, length;

    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];
    const char *string = Tcl_GetString(stringPtr);

    length = stringPtr->length;
................................................................................

    if (searchSpecPtr->exact && searchSpecPtr->noCase) {
	Tcl_SetObjLength(theLine, Tcl_UtfToLower(Tcl_GetString(theLine)));
    }

    if (lenPtr != NULL) {
	if (searchSpecPtr->exact) {
	    (void)Tcl_GetString(theLine);
	    *lenPtr = theLine->length;
	} else {
	    *lenPtr = Tcl_GetCharLength(theLine);
	}
    }
    return linePtr;
}
................................................................................
	return TCL_ERROR;
    }
    arg++;
    atEnd = 0;
    if (objc == arg) {
	TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
    } else {
	int length;
	const char *str;

	if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
	    return TCL_ERROR;
	}
	str = Tcl_GetString(objv[arg]);
	length = objv[arg]->length;
	if (strncmp(str, "end", (unsigned) length) == 0) {
	    atEnd = 1;
	}
    }
    if (TkTextIndexCmp(&index1, &index2) >= 0) {
	return TCL_OK;
    }
    lineno = TkBTreeLinesTo(textPtr, index1.linePtr);
................................................................................

	if (lineNum == searchSpecPtr->stopLine && searchSpecPtr->backwards) {
	    firstOffset = searchSpecPtr->stopOffset;
	} else {
	    firstOffset = 0;
	}

	if (alreadySearchOffset != -1) {
	    if (searchSpecPtr->backwards) {
		if (alreadySearchOffset < lastOffset) {
		    lastOffset = alreadySearchOffset;
		}
	    } else {
		if (alreadySearchOffset > firstOffset) {
		    firstOffset = alreadySearchOffset;
................................................................................
		    if (searchSpecPtr->backwards) {
			/*
			 * Search back either from the previous match or from
			 * 'startOfLine + lastOffset - 1' until we find a
			 * match.
			 */

			const char c = pattern[0];

			if (alreadySearchOffset != -1) {
			    p = startOfLine + alreadySearchOffset;
			    alreadySearchOffset = -1;
			} else {
			    p = startOfLine + lastOffset -1;
			}
			while (p >= startOfLine + firstOffset) {
			    if (p[0] == c && !strncmp(p, pattern,
				    (unsigned) matchLength)) {
				goto backwardsMatch;
			    }
			    p--;
			}
			break;
		    } else {
			p = strstr(startOfLine + firstOffset, pattern);
................................................................................
			    if ((lastTotal - skipFirst) >= matchLength) {
				/*
				 * We now have enough text to match, so we
				 * make a final test and break whatever the
				 * result.
				 */

				if (strncmp(p,pattern,(unsigned)matchLength)) {
				    p = NULL;
				}
				break;
			    } else {
				/*
				 * Not enough text yet, but check the prefix.
				 */
................................................................................

		if (!searchSpecPtr->overlap) {
		    if (searchSpecPtr->backwards) {
			alreadySearchOffset = p - startOfLine;
			if (firstNewLine != -1) {
			    break;
			} else {

			    alreadySearchOffset -= matchLength;

			}

		    } else {
			firstOffset = p - startOfLine + matchLength;

			if (firstOffset >= lastOffset) {
			    /*
			     * Now, we have to be careful not to find
			     * overlapping matches either on the same or
			     * following lines. Assume that if we did find
			     * something, it goes until the last extra line we
			     * added.
................................................................................
static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{
    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes != NULL) {
	return (objPtr->length == 0);
    }
    (void)Tcl_GetString(objPtr);
    return (objPtr->length == 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpTesttextCmd --







|
>








|



|



|



|







 







|



|



|



|









|







 







|






|







 







|







 







|







 







|







 







>
>
>








|
>
>
>
|







 







|
>







 







|







 







|







|







 







|







 







|

|






|
|







 







|







 







>
|
>
|
>

|
>







 







|
|

<







860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
...
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
....
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
....
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
....
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
....
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
....
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
....
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
....
4180
4181
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192
4193
4194
....
4705
4706
4707
4708
4709
4710
4711
4712
4713
4714
4715
4716
4717
4718
4719
4720
4721
4722
4723
4724
4725
4726
4727
....
5819
5820
5821
5822
5823
5824
5825
5826
5827
5828
5829
5830
5831
5832
5833
....
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
....
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
....
6081
6082
6083
6084
6085
6086
6087
6088
6089
6090
6091
6092
6093
6094
6095
6096
6097
6098
6099
6100
6101
6102
....
6824
6825
6826
6827
6828
6829
6830
6831
6832
6833

6834
6835
6836
6837
6838
6839
6840
	indexToPtr = TkTextGetIndexFromObj(interp, textPtr, objv[objc-1]);
	if (indexToPtr == NULL) {
	    result = TCL_ERROR;
	    goto done;
	}

	for (i = 2; i < objc-2; i++) {
	    int value;
	    size_t length;
	    const char *option = Tcl_GetString(objv[i]);
	    char c;

	    length = objv[i]->length;
	    if (length < 2 || option[0] != '-') {
		goto badOption;
	    }
	    c = option[1];
	    if (c == 'c' && !strncmp("-chars", option, length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_CHARS);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displaychars", option, length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_DISPLAY_CHARS);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displayindices", option,length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_DISPLAY_INDICES);
	    } else if (c == 'd' && (length > 8)
		    && !strncmp("-displaylines", option, length)) {
		TkTextLine *fromPtr, *lastPtr;
		TkTextIndex index, index2;

		int compare = TkTextIndexCmp(indexFromPtr, indexToPtr);
		value = 0;

		if (compare == 0) {
................................................................................
		    }
		}

		if (compare > 0) {
		    value = -value;
		}
	    } else if (c == 'i'
		    && !strncmp("-indices", option, length)) {
		value = CountIndices(textPtr, indexFromPtr, indexToPtr,
			COUNT_INDICES);
	    } else if (c == 'l'
		    && !strncmp("-lines", option, length)) {
		value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr)
			- TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
	    } else if (c == 'u'
		    && !strncmp("-update", option, length)) {
		update = 1;
		continue;
	    } else if (c == 'x'
		    && !strncmp("-xpixels", option, length)) {
		int x1, x2;
		TkTextIndex index;

		index = *indexFromPtr;
		TkTextFindDisplayLineEnd(textPtr, &index, 0, &x1);
		index = *indexToPtr;
		TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2);
		value = x2 - x1;
	    } else if (c == 'y'
		    && !strncmp("-ypixels", option, length)) {
		if (update) {
		    TkTextUpdateLineMetrics(textPtr,
			    TkBTreeLinesTo(textPtr, indexFromPtr->linePtr),
			    TkBTreeLinesTo(textPtr, indexToPtr->linePtr), -1);
		}
		value = TkTextIndexYPixels(textPtr, indexToPtr)
			- TkTextIndexYPixels(textPtr, indexFromPtr);
................................................................................
		if (objc & 1) {
		    indices[i] = indices[i-1];
		    TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i],
			    COUNT_INDICES);
		    objc++;
		}
		useIdx = ckalloc(objc);
		memset(useIdx, 0, (size_t) objc);

		/*
		 * Do a decreasing order sort so that we delete the end ranges
		 * first to maintain index consistency.
		 */

		qsort(indices, (size_t) objc / 2,
			2 * sizeof(TkTextIndex), TextIndexSortProc);
		lastStart = NULL;

		/*
		 * Second pass will handle bogus ranges (end < start) and
		 * overlapping ranges.
		 */
................................................................................
    case TEXT_EDIT:
	result = TextEditCmd(textPtr, interp, objc, objv);
	break;
    case TEXT_GET: {
	Tcl_Obj *objPtr = NULL;
	int i, found = 0, visible = 0;
	const char *name;
	size_t length;

	if (objc < 3) {
	    Tcl_WrongNumArgs(interp, 2, objv,
		    "?-displaychars? ?--? index1 ?index2 ...?");
	    result = TCL_ERROR;
	    goto done;
	}
................................................................................
	 */

	i = 2;
	if (objc > 3) {
	    name = Tcl_GetString(objv[i]);
	    length = objv[i]->length;
	    if (length > 1 && name[0] == '-') {
		if (strncmp("-displaychars", name, length) == 0) {
		    i++;
		    visible = 1;
		    name = Tcl_GetString(objv[i]);
		    length = objv[i]->length;
		}
		if ((i < objc-1) && (length == 2) && !strcmp("--", name)) {
		    i++;
................................................................................
		    && (TkTextIndexCmp(indexToPtr, &index) > 0)) {
		/*
		 * The insertion point is inside the range to be replaced, so
		 * we have to do some calculations to ensure it doesn't move
		 * unnecessarily.
		 */

		int deleteInsertOffset, insertLength, j, indexFromLine, indexFromByteOffset;

		insertLength = 0;
		for (j = 4; j < objc; j += 2) {
		    insertLength += Tcl_GetCharLength(objv[j]);
		}

		/*
................................................................................

		deleteInsertOffset = CountIndices(textPtr, indexFromPtr,
			&index, COUNT_CHARS);
		if (deleteInsertOffset > insertLength) {
		    deleteInsertOffset = insertLength;
		}

                indexFromLine = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr);
                indexFromByteOffset = indexFromPtr->byteIndex;

		result = TextReplaceCmd(textPtr, interp, indexFromPtr,
			indexToPtr, objc, objv, 0);

		if (result == TCL_OK) {
		    /*
		     * Move the insertion position to the correct place.
		     */

                    TkTextIndex indexTmp;

                    TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, indexFromLine,
                            indexFromByteOffset, &indexTmp);
                    TkTextIndexForwChars(NULL, &indexTmp,
			    deleteInsertOffset, &index, COUNT_INDICES);
		    TkBTreeUnlinkSegment(textPtr->insertMarkPtr,
			    textPtr->insertMarkPtr->body.mark.linePtr);
		    TkBTreeLinkSegment(textPtr->insertMarkPtr, &index);
		}
	    } else {
		result = TextReplaceCmd(textPtr, interp, indexFromPtr,
................................................................................
    TkTextIndex *indexPtr,	/* Where to insert new characters. May be
				 * modified if the index is not valid for
				 * insertion (e.g. if at "end"). */
    Tcl_Obj *stringPtr,		/* Null-terminated string containing new
				 * information to add to text. */
    int viewUpdate)		/* Update the view if set. */
{
    int lineIndex;
    size_t length;
    TkText *tPtr;
    int *lineAndByteIndex;
    int resetViewCount;
    int pixels[2*PIXEL_CLIENTS];
    const char *string = Tcl_GetString(stringPtr);

    length = stringPtr->length;
................................................................................

    if (searchSpecPtr->exact && searchSpecPtr->noCase) {
	Tcl_SetObjLength(theLine, Tcl_UtfToLower(Tcl_GetString(theLine)));
    }

    if (lenPtr != NULL) {
	if (searchSpecPtr->exact) {
	    Tcl_GetString(theLine);
	    *lenPtr = theLine->length;
	} else {
	    *lenPtr = Tcl_GetCharLength(theLine);
	}
    }
    return linePtr;
}
................................................................................
	return TCL_ERROR;
    }
    arg++;
    atEnd = 0;
    if (objc == arg) {
	TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES);
    } else {
	size_t length;
	const char *str;

	if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) {
	    return TCL_ERROR;
	}
	str = Tcl_GetString(objv[arg]);
	length = objv[arg]->length;
	if (strncmp(str, "end", length) == 0) {
	    atEnd = 1;
	}
    }
    if (TkTextIndexCmp(&index1, &index2) >= 0) {
	return TCL_OK;
    }
    lineno = TkBTreeLinesTo(textPtr, index1.linePtr);
................................................................................

	if (lineNum == searchSpecPtr->stopLine && searchSpecPtr->backwards) {
	    firstOffset = searchSpecPtr->stopOffset;
	} else {
	    firstOffset = 0;
	}

	if (alreadySearchOffset >= 0) {
	    if (searchSpecPtr->backwards) {
		if (alreadySearchOffset < lastOffset) {
		    lastOffset = alreadySearchOffset;
		}
	    } else {
		if (alreadySearchOffset > firstOffset) {
		    firstOffset = alreadySearchOffset;
................................................................................
		    if (searchSpecPtr->backwards) {
			/*
			 * Search back either from the previous match or from
			 * 'startOfLine + lastOffset - 1' until we find a
			 * match.
			 */

			const char c = matchLength ? pattern[0] : '\0';

			if (alreadySearchOffset >= 0) {
			    p = startOfLine + alreadySearchOffset;
			    alreadySearchOffset = -1;
			} else {
			    p = startOfLine + lastOffset -1;
			}
			while (p >= startOfLine + firstOffset) {
			    if (matchLength == 0 || (p[0] == c && !strncmp(
				     p, pattern, (size_t) matchLength))) {
				goto backwardsMatch;
			    }
			    p--;
			}
			break;
		    } else {
			p = strstr(startOfLine + firstOffset, pattern);
................................................................................
			    if ((lastTotal - skipFirst) >= matchLength) {
				/*
				 * We now have enough text to match, so we
				 * make a final test and break whatever the
				 * result.
				 */

				if (strncmp(p,pattern,(size_t)matchLength)) {
				    p = NULL;
				}
				break;
			    } else {
				/*
				 * Not enough text yet, but check the prefix.
				 */
................................................................................

		if (!searchSpecPtr->overlap) {
		    if (searchSpecPtr->backwards) {
			alreadySearchOffset = p - startOfLine;
			if (firstNewLine != -1) {
			    break;
			} else {
			    alreadySearchOffset -= (matchLength ? matchLength : 1);
                            if (alreadySearchOffset < 0) {
                                break;
                            }
			}
		    } else {
                        firstOffset = matchLength ? p - startOfLine + matchLength
                                                  : p - startOfLine + 1;
			if (firstOffset >= lastOffset) {
			    /*
			     * Now, we have to be careful not to find
			     * overlapping matches either on the same or
			     * following lines. Assume that if we did find
			     * something, it goes until the last extra line we
			     * added.
................................................................................
static int
ObjectIsEmpty(
    Tcl_Obj *objPtr)		/* Object to test. May be NULL. */
{
    if (objPtr == NULL) {
	return 1;
    }
    if (objPtr->bytes == NULL) {
	Tcl_GetString(objPtr);
    }

    return (objPtr->length == 0);
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpTesttextCmd --

Changes to generic/tkTextDisp.c.

20
21
22
23
24
25
26





27
28
29
30
31
32
33
...
199
200
201
202
203
204
205
206





207
208
209

210
211



212
213
214
215
216
217
218
....
3117
3118
3119
3120
3121
3122
3123












3124
3125
3126
3127
3128
3129
3130
....
4132
4133
4134
4135
4136
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157
....
5130
5131
5132
5133
5134
5135
5136

5137
5138
5139
5140
5141
5142
5143
5144

5145
5146
5147
5148
5149
5150
5151
....
5209
5210
5211
5212
5213
5214
5215

5216
5217
5218
5219
5220
5221
5222
....
5233
5234
5235
5236
5237
5238
5239




5240
5241
5242
5243
5244
5245
5246
5247
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
#endif

#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"





#endif

/*
 * "Calculations of line pixel heights and the size of the vertical
 * scrollbar."
 *
 * Given that tag, font and elide changes can happen to large numbers of
................................................................................
 * precision is different (e.g. Intel)
 */

#define FP_EQUAL_SCALE(double1, double2, scaleFactor) \
    (fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3)

/*
 * Macro to make debugging/testing logging a little easier.





 */

#define LOG(toVar,what) \

    Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \
	    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT)




/*
 * The following structure describes one line of the display, which may be
 * either part or all of one line of the text.
 */

typedef struct DLine {
................................................................................
 */

static void
GenerateWidgetViewSyncEvent(
    TkText *textPtr,		/* Information about text widget. */
    Bool InSync)                /* true if in sync, false otherwise */
{












    TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
        Tcl_NewBooleanObj(InSync));
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
	return;
    }

    interp = textPtr->interp;
    Tcl_Preserve(interp);

    if (tkTextDebug) {
	Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY);
    }

    if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x)
	    || (dInfoPtr->maxY <= dInfoPtr->y)) {
	UpdateDisplayInfo(textPtr);
	dInfoPtr->flags &= ~REDRAW_PENDING;
	goto doScrollbars;
    }
    numRedisplays++;
    if (tkTextDebug) {
	Tcl_SetVar2(interp, "tk_textRedraw", NULL, "", TCL_GLOBAL_ONLY);
    }

    /*
     * Choose a new current item if that is needed (this could cause event
     * handlers to be invoked, hence the preserve/release calls and the loop,
     * since the handlers could conceivably necessitate yet another current
     * item calculation). The tkwin check is because the whole window could go
................................................................................
    TkText *textPtr,		/* Widget record for text widget. */
    int mask)			/* OR'd collection of bits showing what has
				 * changed. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    GC newGC;
    XGCValues gcValues;


    /*
     * Schedule the window redisplay. See TkTextChanged for the reason why
     * this has to be done before any calls to FreeDLines.
     */

    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);

    }
    dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE
	    |REPICK_NEEDED;

    /*
     * (Re-)create the graphics context for drawing the traversal highlight.
     */
................................................................................
     * be udpated.
     */

    dInfoPtr->xScrollFirst = dInfoPtr->xScrollLast = -1;
    dInfoPtr->yScrollFirst = dInfoPtr->yScrollLast = -1;

    if (mask & TK_TEXT_LINE_GEOMETRY) {

	/*
	 * Set up line metric recalculation.
	 *
	 * Avoid the special zero value, since that is used to mark individual
	 * lines as being out of date.
	 */

................................................................................

	dInfoPtr->metricEpoch = -1;

	if (dInfoPtr->lineUpdateTimer == NULL) {
	    textPtr->refCount++;
	    dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		    AsyncUpdateLineMetrics, textPtr);




            GenerateWidgetViewSyncEvent(textPtr, 0);
	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *







>
>
>
>
>







 







|
>
>
>
>
>


|
>
|
|
>
>
>







 







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







 







|










|







 







>








>







 







>







 







>
>
>
>
|







20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
...
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
....
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
....
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
....
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
....
5237
5238
5239
5240
5241
5242
5243
5244
5245
5246
5247
5248
5249
5250
5251
....
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271
5272
5273
5274
5275
5276
5277
5278
5279
5280
#include "tkWinInt.h"
#elif defined(__CYGWIN__)
#include "tkUnixInt.h"
#endif

#ifdef MAC_OSX_TK
#include "tkMacOSXInt.h"
#define OK_TO_LOG (!TkpAppIsDrawing())
#define FORCE_DISPLAY(winPtr) TkpDisplayWindow(winPtr)
#else
#define OK_TO_LOG 1
#define FORCE_DISPLAY(winPtr)
#endif

/*
 * "Calculations of line pixel heights and the size of the vertical
 * scrollbar."
 *
 * Given that tag, font and elide changes can happen to large numbers of
................................................................................
 * precision is different (e.g. Intel)
 */

#define FP_EQUAL_SCALE(double1, double2, scaleFactor) \
    (fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3)

/*
 * Macros to make debugging/testing logging a little easier.
 *
 * On OSX 10.14 Drawing procedures are sometimes run because the system has
 * decided to redraw the window.  This can corrupt the data that a test is
 * trying to collect.  So we don't write to the logging variables when the
 * drawing procedure is being run that way.  Other systems can always log.
 */

#define LOG(toVar,what)							\
    if (OK_TO_LOG)							\
        Tcl_SetVar2(textPtr->interp, toVar, NULL, (what),		\
		    TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT)	
#define CLEAR(var)							\
    if (OK_TO_LOG)							\
	Tcl_SetVar2(interp, var, NULL, "", TCL_GLOBAL_ONLY)

/*
 * The following structure describes one line of the display, which may be
 * either part or all of one line of the text.
 */

typedef struct DLine {
................................................................................
 */

static void
GenerateWidgetViewSyncEvent(
    TkText *textPtr,		/* Information about text widget. */
    Bool InSync)                /* true if in sync, false otherwise */
{
    /*
     * OSX 10.14 needs to be told to display the window when the Text Widget
     * is in sync.  (That is, to run DisplayText inside of the drawRect
     * method.)  Otherwise the screen might not get updated until an event
     * like a mouse click is received.  But that extra drawing corrupts the
     * data that the test suite is trying to collect.
     */
    
    if (!tkTextDebug) {
	FORCE_DISPLAY(textPtr->tkwin);
    }
    
    TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync",
        Tcl_NewBooleanObj(InSync));
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
	return;
    }

    interp = textPtr->interp;
    Tcl_Preserve(interp);

    if (tkTextDebug) {
	CLEAR("tk_textRelayout");
    }

    if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x)
	    || (dInfoPtr->maxY <= dInfoPtr->y)) {
	UpdateDisplayInfo(textPtr);
	dInfoPtr->flags &= ~REDRAW_PENDING;
	goto doScrollbars;
    }
    numRedisplays++;
    if (tkTextDebug) {
	CLEAR("tk_textRedraw");
    }

    /*
     * Choose a new current item if that is needed (this could cause event
     * handlers to be invoked, hence the preserve/release calls and the loop,
     * since the handlers could conceivably necessitate yet another current
     * item calculation). The tkwin check is because the whole window could go
................................................................................
    TkText *textPtr,		/* Widget record for text widget. */
    int mask)			/* OR'd collection of bits showing what has
				 * changed. */
{
    TextDInfo *dInfoPtr = textPtr->dInfoPtr;
    GC newGC;
    XGCValues gcValues;
    Bool inSync = 1;

    /*
     * Schedule the window redisplay. See TkTextChanged for the reason why
     * this has to be done before any calls to FreeDLines.
     */

    if (!(dInfoPtr->flags & REDRAW_PENDING)) {
	Tcl_DoWhenIdle(DisplayText, textPtr);
	inSync = 0;
    }
    dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE
	    |REPICK_NEEDED;

    /*
     * (Re-)create the graphics context for drawing the traversal highlight.
     */
................................................................................
     * be udpated.
     */

    dInfoPtr->xScrollFirst = dInfoPtr->xScrollLast = -1;
    dInfoPtr->yScrollFirst = dInfoPtr->yScrollLast = -1;

    if (mask & TK_TEXT_LINE_GEOMETRY) {

	/*
	 * Set up line metric recalculation.
	 *
	 * Avoid the special zero value, since that is used to mark individual
	 * lines as being out of date.
	 */

................................................................................

	dInfoPtr->metricEpoch = -1;

	if (dInfoPtr->lineUpdateTimer == NULL) {
	    textPtr->refCount++;
	    dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1,
		    AsyncUpdateLineMetrics, textPtr);
	    inSync = 0;
	}
	
	if (!inSync) {
	    GenerateWidgetViewSyncEvent(textPtr, 0);
	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *

Changes to generic/tkTextIndex.c.

130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
...
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
...
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
....
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
....
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
 */

static void
UpdateStringOfTextIndex(
    Tcl_Obj *objPtr)
{
    char buffer[TK_POS_CHARS];
    register int len;
    const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr);

    len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer);

    objPtr->bytes = ckalloc(len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
................................................................................
				 * of text). */
    int byteIndex,		/* Byte index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    TkTextSegment *segPtr;
    int index;
    const char *p, *start;
    Tcl_UniChar ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	byteIndex = 0;
    }
    if (byteIndex < 0) {
................................................................................
		 * that byteIndex falls on a character boundary. If the index
		 * falls in the middle of a UTF-8 character, it will be
		 * adjusted to the end of that UTF-8 character.
		 */

		start = segPtr->body.chars + (byteIndex - index);
		p = Tcl_UtfPrev(start, segPtr->body.chars);
		p += Tcl_UtfToUniChar(p, &ch);
		indexPtr->byteIndex += p - start;
	    }
	    break;
	}
	index += segPtr->size;
    }
    return indexPtr;
................................................................................
				 * of text). */
    int charIndex,		/* Index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    register TkTextSegment *segPtr;
    char *p, *start, *end;
    int index, offset;
    Tcl_UniChar ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	charIndex = 0;
    }
    if (charIndex < 0) {
................................................................................
	    end = start + segPtr->size;
	    for (p = start; p < end; p += offset) {
		if (charIndex == 0) {
		    indexPtr->byteIndex = index;
		    return indexPtr;
		}
		charIndex--;
		offset = Tcl_UtfToUniChar(p, &ch);
		index += offset;
	    }
	} else {
	    if (charIndex < segPtr->size) {
		indexPtr->byteIndex = index;
		break;
	    }
................................................................................
    TkTextCountType type)	/* The type of item to count */
{
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    TkTextElideInfo *infoPtr = NULL;
    int byteOffset;
    char *start, *end, *p;
    Tcl_UniChar ch;
    int elide = 0;
    int checkElided = (type & COUNT_DISPLAY);

    if (charCount < 0) {
	TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type);
	return;
    }
................................................................................
		}
	    }

	    if (!elide) {
		if (segPtr->typePtr == &tkTextCharType) {
		    start = segPtr->body.chars + byteOffset;
		    end = segPtr->body.chars + segPtr->size;
		    for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) {
			if (charCount == 0) {
			    dstPtr->byteIndex += (p - start);
			    goto forwardCharDone;
			}
			charCount--;
		    }
		} else if (type & COUNT_INDICES) {







|







 







|







 







|







 







|







 







|







 







|







 







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
...
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
...
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
...
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
...
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
....
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
....
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
 */

static void
UpdateStringOfTextIndex(
    Tcl_Obj *objPtr)
{
    char buffer[TK_POS_CHARS];
    size_t len;
    const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr);

    len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer);

    objPtr->bytes = ckalloc(len + 1);
    strcpy(objPtr->bytes, buffer);
    objPtr->length = len;
................................................................................
				 * of text). */
    int byteIndex,		/* Byte index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    TkTextSegment *segPtr;
    int index;
    const char *p, *start;
    int ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	byteIndex = 0;
    }
    if (byteIndex < 0) {
................................................................................
		 * that byteIndex falls on a character boundary. If the index
		 * falls in the middle of a UTF-8 character, it will be
		 * adjusted to the end of that UTF-8 character.
		 */

		start = segPtr->body.chars + (byteIndex - index);
		p = Tcl_UtfPrev(start, segPtr->body.chars);
		p += TkUtfToUniChar(p, &ch);
		indexPtr->byteIndex += p - start;
	    }
	    break;
	}
	index += segPtr->size;
    }
    return indexPtr;
................................................................................
				 * of text). */
    int charIndex,		/* Index of desired character. */
    TkTextIndex *indexPtr)	/* Structure to fill in. */
{
    register TkTextSegment *segPtr;
    char *p, *start, *end;
    int index, offset;
    int ch;

    indexPtr->tree = tree;
    if (lineIndex < 0) {
	lineIndex = 0;
	charIndex = 0;
    }
    if (charIndex < 0) {
................................................................................
	    end = start + segPtr->size;
	    for (p = start; p < end; p += offset) {
		if (charIndex == 0) {
		    indexPtr->byteIndex = index;
		    return indexPtr;
		}
		charIndex--;
		offset = TkUtfToUniChar(p, &ch);
		index += offset;
	    }
	} else {
	    if (charIndex < segPtr->size) {
		indexPtr->byteIndex = index;
		break;
	    }
................................................................................
    TkTextCountType type)	/* The type of item to count */
{
    TkTextLine *linePtr;
    TkTextSegment *segPtr;
    TkTextElideInfo *infoPtr = NULL;
    int byteOffset;
    char *start, *end, *p;
    int ch;
    int elide = 0;
    int checkElided = (type & COUNT_DISPLAY);

    if (charCount < 0) {
	TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type);
	return;
    }
................................................................................
		}
	    }

	    if (!elide) {
		if (segPtr->typePtr == &tkTextCharType) {
		    start = segPtr->body.chars + byteOffset;
		    end = segPtr->body.chars + segPtr->size;
		    for (p = start; p < end; p += TkUtfToUniChar(p, &ch)) {
			if (charCount == 0) {
			    dstPtr->byteIndex += (p - start);
			    goto forwardCharDone;
			}
			charCount--;
		    }
		} else if (type & COUNT_INDICES) {

Changes to generic/tkUtil.c.

729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
....
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
    int *intPtr)		/* Filled in with number of pages or lines to
				 * scroll, if any. */
{
    const char *arg = Tcl_GetString(objv[2]);
    size_t length = objv[2]->length;

#define ArgPfxEq(str) \
	((arg[0] == str[0]) && !strncmp(arg, str, (unsigned)length))

    if (ArgPfxEq("moveto")) {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) {
................................................................................
 *
 *---------------------------------------------------------------------------
 */

int TkUniCharToUtf(int ch, char *buf)
{
    int size = Tcl_UniCharToUtf(ch, buf);
    if ((ch > 0xffff) && (ch <= 0x10ffff) && (size < 4)) {
	/* Hey, this is wrong, we must be running TCL_UTF_MAX==3
	 * The best thing we can do is spit out 2 surrogates */
	ch -= 0x10000;
	size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf);
	size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size);
    }
    return size;







|







 







|







729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
....
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
    int *intPtr)		/* Filled in with number of pages or lines to
				 * scroll, if any. */
{
    const char *arg = Tcl_GetString(objv[2]);
    size_t length = objv[2]->length;

#define ArgPfxEq(str) \
	((arg[0] == str[0]) && !strncmp(arg, str, length))

    if (ArgPfxEq("moveto")) {
	if (objc != 4) {
	    Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction");
	    return TK_SCROLL_ERROR;
	}
	if (Tcl_GetDoubleFromObj(interp, objv[3], dblPtr) != TCL_OK) {
................................................................................
 *
 *---------------------------------------------------------------------------
 */

int TkUniCharToUtf(int ch, char *buf)
{
    int size = Tcl_UniCharToUtf(ch, buf);
    if ((((unsigned)(ch - 0x10000) <= 0xFFFFF)) && (size < 4)) {
	/* Hey, this is wrong, we must be running TCL_UTF_MAX==3
	 * The best thing we can do is spit out 2 surrogates */
	ch -= 0x10000;
	size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf);
	size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size);
    }
    return size;

Changes to generic/tkWindow.c.

2780
2781
2782
2783
2784
2785
2786












2787
2788
2789
2790
2791
2792
2793

    while (tsdPtr->mainWindowList != NULL) {
	interp = tsdPtr->mainWindowList->interp;
	Tcl_Preserve(interp);
	Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr);
	Tcl_Release(interp);
    }













    /*
     * Iterate destroying the displays until no more displays remain. It is
     * possible for displays to get recreated during exit by any code that
     * calls GetScreen, so we must destroy these new displays as well as the
     * old ones.
     */







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







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

    while (tsdPtr->mainWindowList != NULL) {
	interp = tsdPtr->mainWindowList->interp;
	Tcl_Preserve(interp);
	Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr);
	Tcl_Release(interp);
    }

    /*
     * Let error handlers catch up before actual close of displays.
     * Must be done before tsdPtr->displayList is cleared, otherwise
     * ErrorProc() in tkError.c cannot associate the pending X errors
     * to the remaining error handlers.
     */

    for (dispPtr = tsdPtr->displayList; dispPtr != NULL;
           dispPtr = dispPtr->nextPtr) {
       XSync(dispPtr->display, False);
    }

    /*
     * Iterate destroying the displays until no more displays remain. It is
     * possible for displays to get recreated during exit by any code that
     * calls GetScreen, so we must destroy these new displays as well as the
     * old ones.
     */

Changes to generic/ttk/ttkEntry.c.

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
#ifdef HAVE_XFT
    TkUnixSetXftClipRegion(clipRegion);
#endif

    /* Draw cursor:
     */
    if (showCursor) {

	int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos),
	    cursorY = entryPtr->entry.layoutY,
	    cursorHeight = entryPtr->entry.layoutHeight,
	    cursorWidth = 1;

	Tcl_GetIntFromObj(NULL,es.insertWidthObj,&cursorWidth);
	if (cursorWidth <= 0) {
	    cursorWidth = 1;
	}

	/* @@@ should: maybe: SetCaretPos even when blinked off */
	Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight);








	gc = EntryGetGC(entryPtr, es.insertColorObj, clipRegion);
	XFillRectangle(Tk_Display(tkwin), d, gc,
	    cursorX-cursorWidth/2, cursorY, cursorWidth, cursorHeight);
	XSetClipMask(Tk_Display(tkwin), gc, None);
	Tk_FreeGC(Tk_Display(tkwin), gc);
    }

    /* Draw the text:
     */
    gc = EntryGetGC(entryPtr, es.foregroundObj, clipRegion);
    Tk_DrawTextLayout(







>













>
>
>
>
>
>
>
|

|
<







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
#ifdef HAVE_XFT
    TkUnixSetXftClipRegion(clipRegion);
#endif

    /* Draw cursor:
     */
    if (showCursor) {
        Ttk_Box field = Ttk_ClientRegion(entryPtr->core.layout, "field");
	int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos),
	    cursorY = entryPtr->entry.layoutY,
	    cursorHeight = entryPtr->entry.layoutHeight,
	    cursorWidth = 1;

	Tcl_GetIntFromObj(NULL,es.insertWidthObj,&cursorWidth);
	if (cursorWidth <= 0) {
	    cursorWidth = 1;
	}

	/* @@@ should: maybe: SetCaretPos even when blinked off */
	Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight);

	cursorX -= cursorWidth/2;
	if (cursorX < field.x) {
	    cursorX = field.x;
	} else if (cursorX + cursorWidth > field.x + field.width) {
	    cursorX = field.x + field.width - cursorWidth;
	}

	gc = EntryGetGC(entryPtr, es.insertColorObj, None);
	XFillRectangle(Tk_Display(tkwin), d, gc,
	    cursorX, cursorY, cursorWidth, cursorHeight);

	Tk_FreeGC(Tk_Display(tkwin), gc);
    }

    /* Draw the text:
     */
    gc = EntryGetGC(entryPtr, es.foregroundObj, clipRegion);
    Tk_DrawTextLayout(

Changes to generic/ttk/ttkLayout.c.

698
699
700
701
702
703
704


705
706
707
708
709
710
711
	    tail = tail->next;
	} else {
	    head = tail = Ttk_NewTemplateNode(elementName, flags | sticky);
	}
	if (childSpec) {
	    tail->child = Ttk_ParseLayoutTemplate(interp, childSpec);
	    if (!tail->child) {


		goto error;
	    }
	}
    }

    return head;








>
>







698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
	    tail = tail->next;
	} else {
	    head = tail = Ttk_NewTemplateNode(elementName, flags | sticky);
	}
	if (childSpec) {
	    tail->child = Ttk_ParseLayoutTemplate(interp, childSpec);
	    if (!tail->child) {
                Tcl_SetObjResult(interp, Tcl_ObjPrintf("Invalid -children value"));
                Tcl_SetErrorCode(interp, "TTK", "VALUE", "CHILDREN", NULL);
		goto error;
	    }
	}
    }

    return head;

Changes to generic/ttk/ttkState.c.

126
127
128
129
130
131
132
133

134
135
136
137
138
139
140
...
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158

static void StateSpecUpdateString(Tcl_Obj *objPtr)
{
    unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF;
    unsigned int mask = onbits | offbits;
    Tcl_DString result;
    int i, len;


    Tcl_DStringInit(&result);

    for (i=0; stateNames[i] != NULL; ++i) {
	if (mask & (1<<i)) {
	    if (offbits & (1<<i))
		Tcl_DStringAppend(&result, "!", 1);
................................................................................
	    Tcl_DStringAppend(&result, " ", 1);
	}
    }

    len = Tcl_DStringLength(&result);
    if (len) {
	/* 'len' includes extra trailing ' ' */
	objPtr->bytes = Tcl_Alloc((unsigned)len);
	objPtr->length = len-1;
	strncpy(objPtr->bytes, Tcl_DStringValue(&result), (size_t)len-1);
	objPtr->bytes[len-1] = '\0';
    } else {
	/* empty string */
	objPtr->length = 0;
	objPtr->bytes = Tcl_Alloc(1);
	*objPtr->bytes = '\0';
    }







|
>







 







|

|







126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159

static void StateSpecUpdateString(Tcl_Obj *objPtr)
{
    unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16;
    unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF;
    unsigned int mask = onbits | offbits;
    Tcl_DString result;
    int i;
    size_t len;

    Tcl_DStringInit(&result);

    for (i=0; stateNames[i] != NULL; ++i) {
	if (mask & (1<<i)) {
	    if (offbits & (1<<i))
		Tcl_DStringAppend(&result, "!", 1);
................................................................................
	    Tcl_DStringAppend(&result, " ", 1);
	}
    }

    len = Tcl_DStringLength(&result);
    if (len) {
	/* 'len' includes extra trailing ' ' */
	objPtr->bytes = Tcl_Alloc(len);
	objPtr->length = len-1;
	strncpy(objPtr->bytes, Tcl_DStringValue(&result), len-1);
	objPtr->bytes[len-1] = '\0';
    } else {
	/* empty string */
	objPtr->length = 0;
	objPtr->bytes = Tcl_Alloc(1);
	*objPtr->bytes = '\0';
    }

Changes to generic/ttk/ttkTreeview.c.

1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
 *
 * Returns:
 * 	Row number of the last item drawn.
 */
static int DrawForest(
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{
    while (item && row <= tv->tree.yscroll.last) {
        row = DrawSubtree(tv, item, d, depth, row);
	item = item->next;
    }
    return row;
}

/* + TreeviewDisplay --







|







1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
 *
 * Returns:
 * 	Row number of the last item drawn.
 */
static int DrawForest(
    Treeview *tv, TreeItem *item, Drawable d, int depth, int row)
{
    while (item && row < tv->tree.yscroll.last) {
        row = DrawSubtree(tv, item, d, depth, row);
	item = item->next;
    }
    return row;
}

/* + TreeviewDisplay --

Changes to library/listbox.tcl.

10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

#--------------------------------------------------------------------------
# tk::Priv elements used in this file:
#
# afterId -		Token returned by "after" for autoscanning.
# listboxPrev -		The last element to be selected or deselected
#			during a selection operation.
# listboxSelection -	All of the items that were selected before the
#			current selection operation (such as a mouse
#			drag) started;  used to cancel an operation.
#--------------------------------------------------------------------------

#-------------------------------------------------------------------------







|







10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.

#--------------------------------------------------------------------------
# tk::Priv elements used in this file:
#
# afterId -		Token returned by "after" for autoscanning.
# listboxPrev -	The last element to be selected or deselected
#			during a selection operation.
# listboxSelection -	All of the items that were selected before the
#			current selection operation (such as a mouse
#			drag) started;  used to cancel an operation.
#--------------------------------------------------------------------------

#-------------------------------------------------------------------------

Changes to library/menu.tcl.

605
606
607
608
609
610
611

612

613
614
615
616
617
618
619
proc ::tk::MenuButtonDown menu {
    variable ::tk::Priv

    if {![winfo viewable $menu]} {
        return
    }
    if {[$menu index active] eq "none"} {

        set Priv(window) {}

        return
    }
    $menu postcascade active
    if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} {
	grab -global $Priv(postedMb)
    } else {
	while {[$menu cget -type] eq "normal" \







>
|
>







605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
proc ::tk::MenuButtonDown menu {
    variable ::tk::Priv

    if {![winfo viewable $menu]} {
        return
    }
    if {[$menu index active] eq "none"} {
        if {[$menu cget -type] ne "menubar" } {
            set Priv(window) {}
        }
        return
    }
    $menu postcascade active
    if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} {
	grab -global $Priv(postedMb)
    } else {
	while {[$menu cget -type] eq "normal" \

Changes to library/msgbox.tcl.

230
231
232
233
234
235
236
237

238
239
240
241
242
243
244
	if {[lindex $btn 0] eq $data(-default)} {
	    set valid 1
	    break
	}
    }
    if {!$valid} {
	return -code error -errorcode {TK MSGBOX DEFAULT} \
	    "invalid default button \"$data(-default)\""

    }

    # 2. Set the dialog to be a child window of $parent
    #
    #
    if {$data(-parent) ne "."} {
	set w $data(-parent).__tk__messagebox







|
>







230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
	if {[lindex $btn 0] eq $data(-default)} {
	    set valid 1
	    break
	}
    }
    if {!$valid} {
	return -code error -errorcode {TK MSGBOX DEFAULT} \
	    "bad -default value \"$data(-default)\": must be\
	    abort, retry, ignore, ok, cancel, no, or yes"
    }

    # 2. Set the dialog to be a child window of $parent
    #
    #
    if {$data(-parent) ne "."} {
	set w $data(-parent).__tk__messagebox

Changes to library/palette.tcl.

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

# ::tk::Darken --
# Given a color name, computes a new color value that darkens (or
# brightens) the given color by a given percent.
#
# Arguments:
# color -	Name of starting color.
# perecent -	Integer telling how much to brighten or darken as a
#		percent: 50 means darken by 50%, 110 means brighten
#		by 10%.

proc ::tk::Darken {color percent} {
    foreach {red green blue} [winfo rgb . $color] {
	set red [expr {($red/256)*$percent/100}]
	set green [expr {($green/256)*$percent/100}]
	set blue [expr {($blue/256)*$percent/100}]
	break
    }
    if {$red > 255} {
	set red 255
    }
    if {$green > 255} {
	set green 255
    }
    if {$blue > 255} {
	set blue 255
    }
    return [format "#%02x%02x%02x" $red $green $blue]
}

# ::tk_bisque --
# Reset the Tk color palette to the old "bisque" colors.
#
# Arguments:
# None.







|




|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|







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

# ::tk::Darken --
# Given a color name, computes a new color value that darkens (or
# brightens) the given color by a given percent.
#
# Arguments:
# color -	Name of starting color.
# percent -	Integer telling how much to brighten or darken as a
#		percent: 50 means darken by 50%, 110 means brighten
#		by 10%.

proc ::tk::Darken {color percent} {
    if {$percent < 0} {
        return #000000
    } elseif {$percent > 200} {
        return #ffffff
    } elseif {$percent <= 100} {
        lassign [winfo rgb . $color] r g b
        set r [expr {($r/256)*$percent/100}]
        set g [expr {($g/256)*$percent/100}]
        set b [expr {($b/256)*$percent/100}]
    } elseif {$percent > 100} {
        lassign [winfo rgb . $color] r g b
        set r [expr {255 - ((65535-$r)/256)*(200-$percent)/100}]
        set g [expr {255 - ((65535-$g)/256)*(200-$percent)/100}]
        set b [expr {255 - ((65535-$b)/256)*(200-$percent)/100}]
    }
    return [format #%02x%02x%02x $r $g $b]
}

# ::tk_bisque --
# Reset the Tk color palette to the old "bisque" colors.
#
# Arguments:
# None.

Changes to library/ttk/combobox.tcl.

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
bind ComboboxPopdown	<Unmap>		{ ttk::combobox::UnmapPopdown %W }
bind ComboboxPopdown	<ButtonPress> \
			{ ttk::combobox::Unpost [winfo parent %W] }

### Option database settings.
#

option add *TCombobox*Listbox.font TkTextFont
option add *TCombobox*Listbox.relief flat
option add *TCombobox*Listbox.highlightThickness 0

## Platform-specific settings.
#
switch -- [tk windowingsystem] {
    x11 {
	option add *TCombobox*Listbox.background white
    }
    aqua {
	option add *TCombobox*Listbox.borderWidth 0
    }
}

### Binding procedures.
#

## Press $mode $x $y -- ButtonPress binding for comboboxes.







|
|
|





|


|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
bind ComboboxPopdown	<Unmap>		{ ttk::combobox::UnmapPopdown %W }
bind ComboboxPopdown	<ButtonPress> \
			{ ttk::combobox::Unpost [winfo parent %W] }

### Option database settings.
#

option add *TCombobox*Listbox.font TkTextFont widgetDefault
option add *TCombobox*Listbox.relief flat widgetDefault
option add *TCombobox*Listbox.highlightThickness 0 widgetDefault

## Platform-specific settings.
#
switch -- [tk windowingsystem] {
    x11 {
	option add *TCombobox*Listbox.background white widgetDefault
    }
    aqua {
	option add *TCombobox*Listbox.borderWidth 0 widgetDefault
    }
}

### Binding procedures.
#

## Press $mode $x $y -- ButtonPress binding for comboboxes.

Changes to library/ttk/entry.tcl.

30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
...
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	set State(scanDen) 1
	set State(deadband) 3	;# #pixels for mouse-moved deadband.
    }
}

### Option database settings.
#
option add *TEntry.cursor [ttk::cursor text]

### Bindings.
#
# Removed the following standard Tk bindings:
#
# <Control-Key-space>, <Control-Shift-Key-space>,
# <Key-Select>,  <Shift-Key-Select>:
................................................................................
    }
}

## <B1-Enter> binding
# 	Suspend autoscroll.
#
proc ttk::entry::DragIn {w} {
    ttk::CancelRepeat 
}

## <ButtonRelease-1> binding
#
proc ttk::entry::Release {w} {
    variable State
    set State(selectMode) none
    ttk::CancelRepeat 	;# suspend autoscroll
}

## AutoScroll
#	Called repeatedly when the mouse is outside an entry window
#	with Button 1 down.  Scroll the window left or right,
#	depending on where the mouse left the window, and extend 
#	the selection according to the current selection mode.
#
# TODO: AutoScroll should repeat faster (50ms) than normal autorepeat.
# TODO: Need a way for Repeat scripts to cancel themselves.
#
proc ttk::entry::AutoScroll {w} {
    variable State







|







 







|













|







30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
...
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
	set State(scanDen) 1
	set State(deadband) 3	;# #pixels for mouse-moved deadband.
    }
}

### Option database settings.
#
option add *TEntry.cursor [ttk::cursor text] widgetDefault

### Bindings.
#
# Removed the following standard Tk bindings:
#
# <Control-Key-space>, <Control-Shift-Key-space>,
# <Key-Select>,  <Shift-Key-Select>:
................................................................................
    }
}

## <B1-Enter> binding
# 	Suspend autoscroll.
#
proc ttk::entry::DragIn {w} {
    ttk::CancelRepeat
}

## <ButtonRelease-1> binding
#
proc ttk::entry::Release {w} {
    variable State
    set State(selectMode) none
    ttk::CancelRepeat 	;# suspend autoscroll
}

## AutoScroll
#	Called repeatedly when the mouse is outside an entry window
#	with Button 1 down.  Scroll the window left or right,
#	depending on where the mouse left the window, and extend
#	the selection according to the current selection mode.
#
# TODO: AutoScroll should repeat faster (50ms) than normal autorepeat.
# TODO: Need a way for Repeat scripts to cancel themselves.
#
proc ttk::entry::AutoScroll {w} {
    variable State

Changes to library/ttk/sizegrip.tcl.

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
# NOTE: the sizegrip widget must be in the lower right hand corner.
#

switch -- [tk windowingsystem] {
    x11 -
    win32 {
	option add *TSizegrip.cursor [ttk::cursor seresize]
    }
    aqua {
    	# Aqua sizegrips use default Arrow cursor.
    }
}

namespace eval ttk::sizegrip {







|







5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#
# NOTE: the sizegrip widget must be in the lower right hand corner.
#

switch -- [tk windowingsystem] {
    x11 -
    win32 {
	option add *TSizegrip.cursor [ttk::cursor seresize] widgetDefault
    }
    aqua {
    	# Aqua sizegrips use default Arrow cursor.
    }
}

namespace eval ttk::sizegrip {

Changes to library/ttk/treeview.tcl.

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

## ActivateHeading -- track active heading element
#
proc ttk::treeview::ActivateHeading {w heading} {
    variable State

    if {$w != $State(activeWidget) || $heading != $State(activeHeading)} {
	if {$State(activeHeading) != {}} {
	    $State(activeWidget) heading $State(activeHeading) state !active
	}
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w







|







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

## ActivateHeading -- track active heading element
#
proc ttk::treeview::ActivateHeading {w heading} {
    variable State

    if {$w != $State(activeWidget) || $heading != $State(activeHeading)} {
	if {[winfo exists $State(activeWidget)] && $State(activeHeading) != {}} {
	    $State(activeWidget) heading $State(activeHeading) state !active
	}
	if {$heading != {}} {
	    $w heading $heading state active
	}
	set State(activeHeading) $heading
	set State(activeWidget) $w

Changes to library/ttk/vistaTheme.tcl.

17
18
19
20
21
22
23

24
25
26
27
28
29
30
..
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66


67
68
69
70
71
72
73

74
75

76
77
78
79
80
81
82
    ttk::style theme settings vista {

 	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \

	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

................................................................................
				{!disabled !selected} SystemWindow \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				{!disabled !selected} SystemWindowText \
				selected SystemHighlightText]

        # Label and Toolbutton
	ttk::style configure TLabelframe.Label -foreground "#0046d5"

	ttk::style configure Toolbutton -padding {4 4}

        # Combobox
	ttk::style configure TCombobox -padding 2
        ttk::style element create Combobox.field vsapi \
            COMBOBOX 2 {{} 1}
        ttk::style element create Combobox.border vsapi \
            COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1}


        ttk::style element create Combobox.rightdownarrow vsapi \
            COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style layout TCombobox {
            Combobox.border -sticky nswe -border 0 -children {
                Combobox.rightdownarrow -side right -sticky ns
                Combobox.padding -expand 1 -sticky nswe -children {

                    Combobox.focus -expand 1 -sticky nswe -children {
                        Combobox.textarea -sticky nswe

                    }
                }
            }
        }
        # Vista.Combobox droplist frame
        ttk::style element create ComboboxPopdownFrame.background vsapi\
            LISTBOX 3 {disabled 4 active 3 focus 2 {} 1}







>







 







|





<
<


>
>







>
|
|
>







17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
..
51
52
53
54
55
56
57
58
59
60
61
62
63


64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
    ttk::style theme settings vista {

 	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

................................................................................
				{!disabled !selected} SystemWindow \
				selected SystemHighlight] \
	    -foreground [list   disabled SystemGrayText \
				{!disabled !selected} SystemWindowText \
				selected SystemHighlightText]

        # Label and Toolbutton
	ttk::style configure TLabelframe.Label -foreground SystemButtonText

	ttk::style configure Toolbutton -padding {4 4}

        # Combobox
	ttk::style configure TCombobox -padding 2


        ttk::style element create Combobox.border vsapi \
            COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1}
        ttk::style element create Combobox.background vsapi \
            EDIT 3 {disabled 3 readonly 5 focus 4 hover 2 {} 1}
        ttk::style element create Combobox.rightdownarrow vsapi \
            COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \
            -syssize {SM_CXVSCROLL SM_CYVSCROLL}
        ttk::style layout TCombobox {
            Combobox.border -sticky nswe -border 0 -children {
                Combobox.rightdownarrow -side right -sticky ns
                Combobox.padding -expand 1 -sticky nswe -children {
                    Combobox.background -sticky nswe -children {
                        Combobox.focus -expand 1 -sticky nswe -children {
                            Combobox.textarea -sticky nswe
                        }
                    }
                }
            }
        }
        # Vista.Combobox droplist frame
        ttk::style element create ComboboxPopdownFrame.background vsapi\
            LISTBOX 3 {disabled 4 active 3 focus 2 {} 1}

Changes to library/ttk/winTheme.tcl.

6
7
8
9
10
11
12


13
14
15
16
17
18
19
    ttk::style theme settings winnative {

	ttk::style configure "." \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \


	    -troughcolor SystemScrollbar \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." -foreground [list disabled SystemGrayText] ;
        ttk::style map "." -embossed [list disabled 1] ;








>
>







6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    ttk::style theme settings winnative {

	ttk::style configure "." \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -fieldbackground SystemWindow \
	    -insertcolor SystemWindowText \
	    -troughcolor SystemScrollbar \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." -foreground [list disabled SystemGrayText] ;
        ttk::style map "." -embossed [list disabled 1] ;

Changes to library/ttk/xpTheme.tcl.

7
8
9
10
11
12
13

14
15
16
17
18
19
20
    ttk::style theme settings xpnative {

	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \

	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;








>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
    ttk::style theme settings xpnative {

	ttk::style configure . \
	    -background SystemButtonFace \
	    -foreground SystemWindowText \
	    -selectforeground SystemHighlightText \
	    -selectbackground SystemHighlight \
	    -insertcolor SystemWindowText \
	    -font TkDefaultFont \
	    ;

	ttk::style map "." \
	    -foreground [list disabled SystemGrayText] \
	    ;

Changes to macosx/README.

557
558
559
560
561
562
563










inefficient to iterate through all embedded windows in a Text widget,
looking for those which meet the scrolling area, the damage region
constructed by TkScrollWindow contains only the difference between the
source and destination rectangles for the scrolling.  The embedded
windows are redrawn within the DisplayText function by some
conditional code which is only used for macOS.


















>
>
>
>
>
>
>
>
>
>
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
inefficient to iterate through all embedded windows in a Text widget,
looking for those which meet the scrolling area, the damage region
constructed by TkScrollWindow contains only the difference between the
source and destination rectangles for the scrolling.  The embedded
windows are redrawn within the DisplayText function by some
conditional code which is only used for macOS.

5.0 Dark Mode on 10.14
~~~~~~~~~~~~~~~~~~~~~~~~~~~

10.14 supports system appearance changes, and has added a "Dark Mode"
that casts all window frames and menus as black. Tk 8.6.9 supports Dark
Mode by having the window decorations, menus, and dialogs automatically
take on the appropriate appearance when the system appearance is changed. 
Because the window content itself is drawn by Tk, it will not change when
the system mode changes.  

Changes to macosx/tkMacOSXButton.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
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
...
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
...
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
...
421
422
423
424
425
426
427



428
429
430
431
432
433
434
...
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
...
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
...
906
907
908
909
910
911
912


913

914
915
916
917
918
919
920
 */

#include "tkMacOSXPrivate.h"
#include "tkButton.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXDebug.h"


#define FIRST_DRAW	    2
#define ACTIVE		    4


/*

 * Default insets for controls
 */

#define DEF_INSET_LEFT 12
#define DEF_INSET_RIGHT 12
#define DEF_INSET_TOP 1
#define DEF_INSET_BOTTOM 1

/*
 * Some defines used to control what type of control is drawn.
 */

#define DRAW_LABEL	0	/* Labels are treated genericly. */
#define DRAW_CONTROL	1	/* Draw using the Native control. */
................................................................................

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);

	/*Remove extraneous padding around label widgets.*/
	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight + DEF_INSET_BOTTOM + DEF_INSET_TOP;
	charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

    if (haveImage && haveText) { /* Image and Text */
	switch ((enum compound) butPtr->compound) {
................................................................................
	width += butPtr->indicatorSpace;

    } else if (haveImage) { /* Image only */
      width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
      height = butPtr->height > 0 ? butPtr->height : height;

    } else { /* Text only */
      /*Add four pixels of padding to width for text-only buttons to improve appearance.*/
        width = txtWidth + butPtr->indicatorSpace + 4;
	height = txtHeight;
	if (butPtr->width > 0) {
	   width = butPtr->width * charWidth;
	}
	if (butPtr->height > 0) {
	  height = butPtr->height * fm.linespace;
	}
................................................................................

    if (TkMacOSXComputeButtonDrawParams(butPtr,&drawParams)) {
        HIRect tmpRect;
    	HIRect contBounds;
        int paddingx = 0;
        int paddingy = 0;

    	tmpRect = CGRectMake(0, 0, width, height);

        HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
        /* If the content region has a minimum height, match it. */
        if (height < contBounds.size.height) {
    	  height = contBounds.size.height;
        }

................................................................................
    } else {
        height += butPtr->borderWidth*2;
        width += butPtr->borderWidth*2;
    }

    width += butPtr->inset*2;
    height += butPtr->inset*2;




    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
................................................................................
    } else { /* Text only */
        int x, y;
	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
			butPtr->textWidth + butPtr->indicatorSpace,
			  butPtr->textHeight, &x, &y);
	x += butPtr->indicatorSpace;
	Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout,
			  x, y - DEF_INSET_BOTTOM, 0, -1);
    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect.  If the widget
     * is selected and we use a different background color when selected,
     * must temporarily modify the GC so the stippling is the right color.
................................................................................

        ButtonBackgroundDrawCB(&cntrRect, mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}


	if (mbPtr->btnkind == kThemePushButton) {
	    /*
	     * For some reason, pushbuttons get drawn a bit
	     * too low, normally.  Correct for this.
	     */
	    if (cntrRect.size.height < 22) {
		cntrRect.origin.y -= 1;
	    } else if (cntrRect.size.height < 23) {
		cntrRect.origin.y -= 2;
	    }
	}

        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind  = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
        hiinfo.adornment = mbPtr->drawinfo.adornment;
        hiinfo.animation.time.current = CFAbsoluteTimeGetCurrent();
        if (hiinfo.animation.time.start == 0) {
................................................................................
    TkButton  *butPtr = (TkButton *)ptr;
    Tk_Window  tkwin  = butPtr->tkwin;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }



    /*Overlay Tk elements over button native region: drawing elements within button boundaries/native region causes unpredictable metrics.*/

    DrawButtonImageAndText( butPtr);
}
 
/*
 *--------------------------------------------------------------
 *
 * ButtonEventProc --







<



<

>
|


|
<
|
<







 







<

|







 







<
|







 







|







 







>
>
>







 







|







 







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







 







>
>
|
>







17
18
19
20
21
22
23

24
25
26

27
28
29
30
31
32

33

34
35
36
37
38
39
40
...
311
312
313
314
315
316
317

318
319
320
321
322
323
324
325
326
...
356
357
358
359
360
361
362

363
364
365
366
367
368
369
370
...
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
...
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
...
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
...
780
781
782
783
784
785
786













787
788
789
790
791
792
793
...
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
 */

#include "tkMacOSXPrivate.h"
#include "tkButton.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXDebug.h"


#define FIRST_DRAW	    2
#define ACTIVE		    4


/*
 * Extra padding used for computing the content size that should
 * be allowed when drawing the HITheme button.
 */

#define HI_PADX 2

#define HI_PADY 1


/*
 * Some defines used to control what type of control is drawn.
 */

#define DRAW_LABEL	0	/* Labels are treated genericly. */
#define DRAW_CONTROL	1	/* Draw using the Native control. */
................................................................................

    if (haveImage == 0 || butPtr->compound != COMPOUND_NONE) {
	Tk_FreeTextLayout(butPtr->textLayout);
	butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont,
		Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength,
		butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight);


	txtWidth = butPtr->textWidth;
	txtHeight = butPtr->textHeight;
	charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1);
	Tk_GetFontMetrics(butPtr->tkfont, &fm);
	haveText = (txtWidth != 0 && txtHeight != 0);
    }

    if (haveImage && haveText) { /* Image and Text */
	switch ((enum compound) butPtr->compound) {
................................................................................
	width += butPtr->indicatorSpace;

    } else if (haveImage) { /* Image only */
      width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
      height = butPtr->height > 0 ? butPtr->height : height;

    } else { /* Text only */

        width = txtWidth + butPtr->indicatorSpace;
	height = txtHeight;
	if (butPtr->width > 0) {
	   width = butPtr->width * charWidth;
	}
	if (butPtr->height > 0) {
	  height = butPtr->height * fm.linespace;
	}
................................................................................

    if (TkMacOSXComputeButtonDrawParams(butPtr,&drawParams)) {
        HIRect tmpRect;
    	HIRect contBounds;
        int paddingx = 0;
        int paddingy = 0;

    	tmpRect = CGRectMake(0, 0, width + 2*HI_PADX, height + 2*HI_PADY);

        HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds);
        /* If the content region has a minimum height, match it. */
        if (height < contBounds.size.height) {
    	  height = contBounds.size.height;
        }

................................................................................
    } else {
        height += butPtr->borderWidth*2;
        width += butPtr->borderWidth*2;
    }

    width += butPtr->inset*2;
    height += butPtr->inset*2;
    if ([NSApp macMinorVersion] == 6) {
      width += 12;
    }

    Tk_GeometryRequest(butPtr->tkwin, width, height);
    Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset);
}

/*
 *----------------------------------------------------------------------
................................................................................
    } else { /* Text only */
        int x, y;
	TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY,
			butPtr->textWidth + butPtr->indicatorSpace,
			  butPtr->textHeight, &x, &y);
	x += butPtr->indicatorSpace;
	Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout,
			  x, y, 0, -1);
    }

    /*
     * If the button is disabled with a stipple rather than a special
     * foreground color, generate the stippled effect.  If the widget
     * is selected and we use a different background color when selected,
     * must temporarily modify the GC so the stippling is the right color.
................................................................................

        ButtonBackgroundDrawCB(&cntrRect, mbPtr, 32, true);

	if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) {
	    return;
	}














        hiinfo.version = 0;
        hiinfo.state = mbPtr->drawinfo.state;
        hiinfo.kind  = mbPtr->btnkind;
        hiinfo.value = mbPtr->drawinfo.value;
        hiinfo.adornment = mbPtr->drawinfo.adornment;
        hiinfo.animation.time.current = CFAbsoluteTimeGetCurrent();
        if (hiinfo.animation.time.start == 0) {
................................................................................
    TkButton  *butPtr = (TkButton *)ptr;
    Tk_Window  tkwin  = butPtr->tkwin;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
        return;
    }

    /*
     * Overlay Tk elements over button native region: drawing elements
     * within button boundaries/native region causes unpredictable metrics.
     */
    DrawButtonImageAndText( butPtr);
}
 
/*
 *--------------------------------------------------------------
 *
 * ButtonEventProc --

Changes to macosx/tkMacOSXClipboard.c.

8
9
10
11
12
13
14

15
16
17
18
19
20
21
..
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
...
121
122
123
124
125
126
127


128
129
130
131
132
133
134
135
136
...
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include "tkSelect.h"

static NSInteger changeCount = -1;
static Tk_Window clipboardOwner = NULL;

#pragma mark TKApplication(TKClipboard)

................................................................................
}

- (void) tkCheckPasteboard
{
    if (clipboardOwner && [[NSPasteboard generalPasteboard] changeCount] !=
	    changeCount) {
	TkDisplay *dispPtr = TkGetDisplayList();

	if (dispPtr) {
	    XEvent event;

	    event.xany.type = SelectionClear;
	    event.xany.serial = NextRequest(Tk_Display(clipboardOwner));
	    event.xany.send_event = False;
	    event.xany.window = Tk_WindowId(clipboardOwner);
	    event.xany.display = Tk_Display(clipboardOwner);
	    event.xselectionclear.selection = dispPtr->clipboardAtom;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
................................................................................
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    int result = TCL_ERROR;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;



    if (dispPtr && selection == dispPtr->clipboardAtom && (target == XA_STRING
	    || target == dispPtr->utf8Atom)) {
	NSString *string = nil;
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:
		NSStringPboardType]];

	if (type) {
	    string = [pb stringForType:type];
................................................................................
{
    TkDisplay *dispPtr = TkGetDisplayList();

    if (dispPtr && selection == dispPtr->clipboardAtom) {
	clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL;
	if (!dispPtr->clipboardActive) {
	    NSPasteboard *pb = [NSPasteboard generalPasteboard];

	    changeCount = [pb declareTypes:[NSArray array] owner:NSApp];
	}
    }
    return Success;
}
 
/*
................................................................................
 */

void
TkSelPropProc(
    register XEvent *eventPtr)	/* X PropertyChange event. */
{
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkSuspendClipboard --
 *
 *	Handle clipboard conversion as required by the suppend event.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	The local scrap is moved to the global scrap.
 *
 *----------------------------------------------------------------------
 */

void
TkSuspendClipboard(void)
{
    changeCount = [[NSPasteboard generalPasteboard] changeCount];
}
 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







>







 







<


<







 







>
>
|
|







 







<







 







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









8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
..
67
68
69
70
71
72
73

74
75

76
77
78
79
80
81
82
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
...
173
174
175
176
177
178
179

180
181
182
183
184
185
186
...
284
285
286
287
288
289
290






















291
292
293
294
295
296
297
298
299
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXConstants.h"
#include "tkSelect.h"

static NSInteger changeCount = -1;
static Tk_Window clipboardOwner = NULL;

#pragma mark TKApplication(TKClipboard)

................................................................................
}

- (void) tkCheckPasteboard
{
    if (clipboardOwner && [[NSPasteboard generalPasteboard] changeCount] !=
	    changeCount) {
	TkDisplay *dispPtr = TkGetDisplayList();

	if (dispPtr) {
	    XEvent event;

	    event.xany.type = SelectionClear;
	    event.xany.serial = NextRequest(Tk_Display(clipboardOwner));
	    event.xany.send_event = False;
	    event.xany.window = Tk_WindowId(clipboardOwner);
	    event.xany.display = Tk_Display(clipboardOwner);
	    event.xselectionclear.selection = dispPtr->clipboardAtom;
	    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
................................................................................
    Tk_GetSelProc *proc,	/* Procedure to call to process the selection,
				 * once it has been retrieved. */
    ClientData clientData)	/* Arbitrary value to pass to proc. */
{
    int result = TCL_ERROR;
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;

    int haveExternalClip = ([[NSPasteboard generalPasteboard] changeCount] != changeCount);
    if (dispPtr && (haveExternalClip || dispPtr->clipboardActive)
	        && selection == dispPtr->clipboardAtom
	        && (target == XA_STRING || target == dispPtr->utf8Atom)) {
	NSString *string = nil;
	NSPasteboard *pb = [NSPasteboard generalPasteboard];
	NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject:
		NSStringPboardType]];

	if (type) {
	    string = [pb stringForType:type];
................................................................................
{
    TkDisplay *dispPtr = TkGetDisplayList();

    if (dispPtr && selection == dispPtr->clipboardAtom) {
	clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL;
	if (!dispPtr->clipboardActive) {
	    NSPasteboard *pb = [NSPasteboard generalPasteboard];

	    changeCount = [pb declareTypes:[NSArray array] owner:NSApp];
	}
    }
    return Success;
}
 
/*
................................................................................
 */

void
TkSelPropProc(
    register XEvent *eventPtr)	/* X PropertyChange event. */
{
}






















 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXConstants.h.

11
12
13
14
15
16
17




18
19
20
21
22





23
24
25
26




27
28
29

30
31
32
33
34
35
36
..
75
76
77
78
79
80
81

82
83
84
85
86
87
88
89
90
91
92

93
94






95




 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMACCONSTANTS
#define _TKMACCONSTANTS





/*
 * Let's raise a glass for the project manager who improves our lives by
 * generating deprecation warnings about pointless changes of the names
 * of constants.
 */






#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
#define NSOKButton NSModalResponseOK
#endif





#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
#define NSAppKitDefined NSEventTypeAppKitDefined

#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated
#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated
#define NSWindowExposedEventType NSEventSubtypeWindowExposed
#define NSScreenChangedEventType NSEventSubtypeScreenChanged
#define NSWindowMovedEventType NSEventSubtypeWindowMoved
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
................................................................................
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
#define NSFlagsChanged NSEventTypeFlagsChanged
#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
#define NSShiftKeyMask NSEventModifierFlagShift
#define NSAnyEventMask NSEventMaskAny

#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
#define NSTitledWindowMask NSWindowStyleMaskTitled
#define NSClosableWindowMask NSWindowStyleMaskClosable
#define NSResizableWindowMask NSWindowStyleMaskResizable
#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
#define NSBorderlessWindowMask NSWindowStyleMaskBorderless

#endif







#endif











>
>
>
>





>
>
>
>
>




>
>
>
>



>







 







>











>


>
>
>
>
>
>

>
>
>
>
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
..
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#ifndef _TKMACCONSTANTS
#define _TKMACCONSTANTS

#if MAC_OS_X_VERSION_MAX_ALLOWED < 1070
#define NSFullScreenWindowMask (1 << 14)
#endif

/*
 * Let's raise a glass for the project manager who improves our lives by
 * generating deprecation warnings about pointless changes of the names
 * of constants.
 */

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090
#define kCTFontDefaultOrientation kCTFontOrientationDefault
#define kCTFontVerticalOrientation kCTFontOrientationVertical
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
#define NSOKButton NSModalResponseOK
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101100
#define kCTFontUserFixedPitchFontType kCTFontUIFontUserFixedPitch
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
#define NSAppKitDefined NSEventTypeAppKitDefined
#define NSApplicationDefined NSEventTypeApplicationDefined
#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated
#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated
#define NSWindowExposedEventType NSEventSubtypeWindowExposed
#define NSScreenChangedEventType NSEventSubtypeScreenChanged
#define NSWindowMovedEventType NSEventSubtypeWindowMoved
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
................................................................................
#define NSFunctionKeyMask NSEventModifierFlagFunction
#define NSKeyUp NSEventTypeKeyUp
#define NSKeyDown NSEventTypeKeyDown
#define NSFlagsChanged NSEventTypeFlagsChanged
#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
#define NSShiftKeyMask NSEventModifierFlagShift
#define NSAnyEventMask NSEventMaskAny
#define NSApplicationDefinedMask NSEventMaskApplicationDefined
#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
#define NSTitledWindowMask NSWindowStyleMaskTitled
#define NSClosableWindowMask NSWindowStyleMaskClosable
#define NSResizableWindowMask NSWindowStyleMaskResizable
#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
#define NSBorderlessWindowMask NSWindowStyleMaskBorderless
#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen
#endif

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define NSStringPboardType NSPasteboardTypeString
#define NSOnState NSControlStateValueOn
#define NSOffState NSControlStateValueOff
// Now we are also changing names of methods!
#define graphicsContextWithGraphicsPort graphicsContextWithCGContext
#endif


#endif

Changes to macosx/tkMacOSXDialog.c.

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
...
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
....
1194
1195
1196
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
....
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
....
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
....
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
....
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
static const char *const alertIconStrings[] = {
    "error", "info", "question", "warning", NULL
};
enum alertIconOptions {
    ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
};
static const char *const alertButtonStrings[] = {
    "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL
};

static const NSString *const alertButtonNames[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {@"Abort", @"Retry", @"Ignore"},
    [TYPE_OK] =			{@"OK"},
    [TYPE_OKCANCEL] =		{@"OK", @"Cancel"},
    [TYPE_RETRYCANCEL] =	{@"Retry", @"Cancel"},
................................................................................

static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = {
			    /*  abort retry ignore ok   cancel yes   no */
    [TYPE_ABORTRETRYIGNORE] =   {1,    2,    3,    0,    0,    0,    0},
    [TYPE_OK] =			{0,    0,    0,    1,    0,    0,    0},
    [TYPE_OKCANCEL] =		{0,    0,    0,    1,    2,    0,    0},
    [TYPE_RETRYCANCEL] =	{0,    1,    0,    0,    2,    0,    0},
    [TYPE_YESNO] =		{0,    0,    0,    0,    0,    1,    2},
    [TYPE_YESNOCANCEL] =	{0,    0,    0,    0,    3,    1,    2},
};

/*
 * Need also the inverse mapping, from NSAlertFirstButtonReturn etc to the
 * descriptive button text string index.
 */

static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {0, 1, 2},
    [TYPE_OK] =			{3, 0, 0},
    [TYPE_OKCANCEL] =		{3, 4, 0},
    [TYPE_RETRYCANCEL] =	{1, 4, 0},
    [TYPE_YESNO] =		{5, 6, 0},
    [TYPE_YESNOCANCEL] =	{5, 6, 4},
};

/*
 * Construct a file URL from directory and filename.  Either may
 * be nil.  If both are nil, returns nil.
 */
static NSURL *getFileURL(NSString *directory, NSString *filename) {
................................................................................
    }

    if ((typeVariablePtr && (modalReturnCode == NSOKButton)) &&
	filterInfo.doFileTypes) {
	/*
	 * The -typevariable must be set to the selected file type, if the dialog was not cancelled
	 */
	NSInteger selectedFilterIndex = filterInfo.fileTypeIndex;
	NSString *selectedFilter = NULL;
	if (filterInfo.userHasSelectedFilter) {
	    selectedFilterIndex = filterInfo.fileTypeIndex;
	    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
	} else {
	    /* Difficult case: the user has not touched the filter settings, but we must
	     * return something in the typevariable. First check if the preselected type is compatible
................................................................................
	    NSString *extension = [selectedFile pathExtension];
	    if (filterInfo.preselectFilter &&
		filterCompatible(extension, filterInfo.fileTypeIndex)) {
		selectedFilterIndex = filterInfo.fileTypeIndex;  // The preselection from the typevariable
		selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
	    } else {
		// scan the list
		int i;
		for (i = 0; i < [filterInfo.fileTypeNames count]; i++) {
		    if (filterCompatible(extension, i)) {
			selectedFilterIndex = i;
			break;
		    }
		}
		if (i == selectedFilterIndex) {
................................................................................

    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatter setDateFormat:@"Y"];

    NSString *year = [dateFormatter stringFromDate:[NSDate date]];

    [dateFormatter release];

    NSMutableParagraphStyle *style =

	    [[[NSParagraphStyle defaultParagraphStyle] mutableCopy]
	    autorelease];


    [style setAlignment:NSCenterTextAlignment];





    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
	    @"Tcl & Tk", @"ApplicationName",
	    @"Tcl " TCL_VERSION " & Tk " TK_VERSION, @"ApplicationVersion",
	    @TK_PATCH_LEVEL, @"Version",
	    image, @"ApplicationIcon",
	    [NSString stringWithFormat:@"Copyright %1$C 1987-%2$@.", 0xA9,
	    year], @"Copyright",
	    [[[NSAttributedString alloc] initWithString:
	    [NSString stringWithFormat:


	    @"%1$C 1987-%2$@ Tcl Core Team." "\n\n"
		"%1$C 1989-%2$@ Contributors." "\n\n"
		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n"
		"%1$C 2014-%2$@ Marc Culler." "\n\n"
		"%1$C 2002-%2$@ Daniel A. Steffen." "\n\n"
		"%1$C 2001-2009 Apple Inc." "\n\n"
		"%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n"
		"%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n"
		"%1$C 1998-2000 Scriptics Inc." "\n\n"
		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes:

	    [NSDictionary dictionaryWithObject:style
	    forKey:NSParagraphStyleAttributeName]] autorelease], @"Credits",
	    nil];
    [NSApp orderFrontStandardAboutPanelWithOptions:options];






}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
................................................................................
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]];
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --
................................................................................
		    Tcl_GetString(objv[i + 1])];
	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
		    sizeof(char *), "value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
................................................................................
		    Tcl_GetString(objv[i + 1])];
	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
		    sizeof(char *), "value", TCL_EXACT, &typeIndex) != TCL_OK) {
		goto end;
	    }
	    break;
	case ALERT_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
................................................................................
    if (indexDefaultOption) {
	/*
	 * Any '-default' option needs to know the '-type' option, which is
	 * why we do this here.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1],
		alertButtonStrings, sizeof(char *), "value", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}

	/*
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */








|







 







|
|












|
|







 







|







 







|







 







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







 







|







 







|







 







|







 







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
...
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
...
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
....
1194
1195
1196
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
....
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
....
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
....
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
....
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
static const char *const alertIconStrings[] = {
    "error", "info", "question", "warning", NULL
};
enum alertIconOptions {
    ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING
};
static const char *const alertButtonStrings[] = {
    "abort", "retry", "ignore", "ok", "cancel", "no", "yes", NULL
};

static const NSString *const alertButtonNames[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {@"Abort", @"Retry", @"Ignore"},
    [TYPE_OK] =			{@"OK"},
    [TYPE_OKCANCEL] =		{@"OK", @"Cancel"},
    [TYPE_RETRYCANCEL] =	{@"Retry", @"Cancel"},
................................................................................

static const short alertButtonIndexAndTypeToNativeButtonIndex[][7] = {
			    /*  abort retry ignore ok   cancel yes   no */
    [TYPE_ABORTRETRYIGNORE] =   {1,    2,    3,    0,    0,    0,    0},
    [TYPE_OK] =			{0,    0,    0,    1,    0,    0,    0},
    [TYPE_OKCANCEL] =		{0,    0,    0,    1,    2,    0,    0},
    [TYPE_RETRYCANCEL] =	{0,    1,    0,    0,    2,    0,    0},
    [TYPE_YESNO] =		{0,    0,    0,    0,    0,    2,    1},
    [TYPE_YESNOCANCEL] =	{0,    0,    0,    0,    3,    2,    1},
};

/*
 * Need also the inverse mapping, from NSAlertFirstButtonReturn etc to the
 * descriptive button text string index.
 */

static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = {
    [TYPE_ABORTRETRYIGNORE] =   {0, 1, 2},
    [TYPE_OK] =			{3, 0, 0},
    [TYPE_OKCANCEL] =		{3, 4, 0},
    [TYPE_RETRYCANCEL] =	{1, 4, 0},
    [TYPE_YESNO] =		{6, 5, 0},
    [TYPE_YESNOCANCEL] =	{6, 5, 4},
};

/*
 * Construct a file URL from directory and filename.  Either may
 * be nil.  If both are nil, returns nil.
 */
static NSURL *getFileURL(NSString *directory, NSString *filename) {
................................................................................
    }

    if ((typeVariablePtr && (modalReturnCode == NSOKButton)) &&
	filterInfo.doFileTypes) {
	/*
	 * The -typevariable must be set to the selected file type, if the dialog was not cancelled
	 */
	NSUInteger selectedFilterIndex = filterInfo.fileTypeIndex;
	NSString *selectedFilter = NULL;
	if (filterInfo.userHasSelectedFilter) {
	    selectedFilterIndex = filterInfo.fileTypeIndex;
	    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
	} else {
	    /* Difficult case: the user has not touched the filter settings, but we must
	     * return something in the typevariable. First check if the preselected type is compatible
................................................................................
	    NSString *extension = [selectedFile pathExtension];
	    if (filterInfo.preselectFilter &&
		filterCompatible(extension, filterInfo.fileTypeIndex)) {
		selectedFilterIndex = filterInfo.fileTypeIndex;  // The preselection from the typevariable
		selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
	    } else {
		// scan the list
		NSUInteger i;
		for (i = 0; i < [filterInfo.fileTypeNames count]; i++) {
		    if (filterCompatible(extension, i)) {
			selectedFilterIndex = i;
			break;
		    }
		}
		if (i == selectedFilterIndex) {
................................................................................

    [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
    [dateFormatter setDateFormat:@"Y"];

    NSString *year = [dateFormatter stringFromDate:[NSDate date]];

    [dateFormatter release];
   

    /*
     * This replaces the old about dialog with a standard alert that displays
     * correctly on 10.14.
     */
    


    NSString *version =  @"Tcl " TCL_PATCH_LEVEL " & Tk " TCL_PATCH_LEVEL;
    NSString *url =   @"www.tcl-lang.org";
    NSTextView *credits = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,300)];
    NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSize]];
    NSDictionary *textAttributes = [NSDictionary dictionaryWithObject:font



					        forKey:NSFontAttributeName];


    [credits insertText: [[NSAttributedString alloc]
		 initWithString:[NSString stringWithFormat: @"\n"
		"Tcl and Tk are distributed under a modified BSD license: "
		"www.tcl.tk/software/tcltk/license.html\n\n"
		"%1$C 1987-%2$@ Tcl Core Team and Contributers.\n\n"

		"%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC.\n\n"
		"%1$C 2014-%2$@ Marc Culler.\n\n"
		"%1$C 2002-2012 Daniel A. Steffen.\n\n"
		"%1$C 2001-2009 Apple Inc.\n\n"
		"%1$C 2001-2002 Jim Ingham & Ian Reid\n\n"
		"%1$C 1998-2000 Jim Ingham & Ray Johnson\n\n"
		"%1$C 1998-2000 Scriptics Inc.\n\n"
		"%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year]
	     attributes:textAttributes]
             replacementRange:NSMakeRange(0,0)];
    [credits setDrawsBackground:NO];
    [credits setEditable:NO];
     NSAlert *about = [[NSAlert alloc] init];
    [[about window] setTitle:@"About Tcl & Tk"];
    [about setMessageText: version];
    [about setInformativeText:url];
    about.accessoryView = credits;
    [about runModal];
    [about release];
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXStandardAboutPanelObjCmd --
 *
................................................................................
    int objc,			/* Number of arguments. */
    Tcl_Obj *const objv[])	/* Argument objects. */
{
    if (objc > 1) {
	Tcl_WrongNumArgs(interp, 1, objv, NULL);
	return TCL_ERROR;
    }
    TkAboutDlg();
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * Tk_MessageBoxObjCmd --
................................................................................
		    Tcl_GetString(objv[i + 1])];
	    [alert setInformativeText:message];
	    [message release];
	    break;

	case ALERT_ICON:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings,
		    sizeof(char *), "-icon value", TCL_EXACT, &iconIndex) != TCL_OK) {
		goto end;
	    }
	    break;

	case ALERT_MESSAGE:
	    message = [[NSString alloc] initWithUTF8String:
		    Tcl_GetString(objv[i + 1])];
................................................................................
		    Tcl_GetString(objv[i + 1])];
	    [[alert window] setTitle:title];
	    [title release];
	    break;

	case ALERT_TYPE:
	    if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings,
		    sizeof(char *), "-type value", TCL_EXACT, &typeIndex) != TCL_OK) {
		goto end;
	    }
	    break;
	case ALERT_COMMAND:
	    cmdObj = objv[i+1];
	    break;
	}
................................................................................
    if (indexDefaultOption) {
	/*
	 * Any '-default' option needs to know the '-type' option, which is
	 * why we do this here.
	 */

	if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1],
		alertButtonStrings, sizeof(char *), "-default value", TCL_EXACT, &index) != TCL_OK) {
	    goto end;
	}

	/*
	 * Need to map from "ok" etc. to 1, 2, 3, right to left.
	 */

Changes to macosx/tkMacOSXDraw.c.

14
15
16
17
18
19
20






21
22
23
24
25
26
27
...
101
102
103
104
105
106
107



















108
109
110
111
112
113
114
...
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139

140
141
142
143
144
145
146
147
148
149
150
151

152
153
154

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








168
169
170
171
172
173
174
...
201
202
203
204
205
206
207

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

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


240
241
242
243
244
245
246
247
248
249
...
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
...
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
...
329
330
331
332
333
334
335
336
337
338
339


340
341
342
343
344
345
346
...
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
...
592
593
594
595
596
597
598
599
600
601
602
603


604
605
606
607
608
609
610
....
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
....
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
....
1579
1580
1581
1582
1583
1584
1585

1586







1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
....
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
....
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
....
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
....
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
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkButton.h"







/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
#endif
*/

................................................................................
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXBitmapRepFromDrawableRect
 *
 *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
 *



















 * Results:
 *	Returns an NSBitmapRep representing the image of the given
 *      rectangle of the given drawable.  This object is retained.
 *      The caller is responsible for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system with
 *      origin at the top left, as used by XImage and CGImage, not bottom
................................................................................
        Drawable drawable,
	int x,
	int y,
	unsigned int width,
	unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *) drawable;
    CGContextRef cg_context=NULL;
    CGImageRef cg_image=NULL, sub_cg_image=NULL;
    NSBitmapImageRep *bitmap_rep=NULL;
    NSView *view=NULL;
    if ( mac_drawable->flags & TK_IS_PIXMAP ) {

	/*
	 * This means that the MacDrawable is functioning as a
	 * Tk Pixmap, so its view field is NULL.
	*/

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
	CGRect image_rect = CGRectMake(x, y, width, height);
	cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
	sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
	if ( sub_cg_image ) {
	    bitmap_rep = [NSBitmapImageRep alloc];
	    [bitmap_rep initWithCGImage:sub_cg_image];
	}
	if ( cg_image ) {
	    CGImageRelease(cg_image);
	}
    } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) {

	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
			       view_height - height - y - mac_drawable->yOff,
			       width, height);

	if ( [view lockFocusIfCanDraw] ) {
	    bitmap_rep = [NSBitmapImageRep alloc];
	    bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect];
	    [view unlockFocus];
	} else {
	    TkMacOSXDbgMsg("Could not lock focus on view.");
	}









    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return bitmap_rep;
}
 
/*
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;
    CGImageRef img = NULL;


    display->request++;

    if (!width || !height) {
	/* This happens all the time.
	TkMacOSXDbgMsg("Drawing of empty area requested");
	*/
	return;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	return;
	/*TkMacOSXDbgMsg("Failed to setup drawing context.");*/
    }

    if ( dc.context ) {
	if (srcDraw->flags & TK_IS_PIXMAP) {
	    img = TkMacOSXCreateCGImageWithDrawable(src);
	}else if (TkMacOSXDrawableWindow(src)) {
	    bitmap_rep =  TkMacOSXBitmapRepFromDrawableRect(src, src_x, src_y, width, height);

	    if ( bitmap_rep ) {
		img = [bitmap_rep CGImage];
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
	}

	if (img) {
	    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
			CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
			CGRectMake(src_x, src_y, width, height),
			CGRectMake(dest_x, dest_y, width, height));


	    CFRelease(img);


	} else {
	    TkMacOSXDbgMsg("Failed to construct CGImage.");
	}

    } else {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return;
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    MacDrawable *dstDraw = (MacDrawable *) dst;

    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
................................................................................
	CGContextRef context = dc.context;
	if (context) {
	    CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);
	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;
                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
		    CGRect srcRect = CGRectMake(src_x, src_y, width, height);
		    CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
		    CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect);
		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);
		    rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
		    CGContextSaveGState(context);
		    /* Move the origin of the destination to top left. */
		    CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect));
................................................................................
		    CGContextFillRect(context, rect);
		    CGContextRestoreGState(context);
		    CGImageRelease(img);
		    CGImageRelease(mask);
		    CGImageRelease(submask);
		    CGImageRelease(subimage);
		} else {
		    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
				CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
				CGRectMake(src_x, src_y, width, height),
				CGRectMake(dest_x, dest_y, width, height));


		    CGImageRelease(img);
		}
	    } else { /* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
................................................................................
TkMacOSXGetNSImageWithTkImage(
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
    MacDrawable *macDraw = (MacDrawable *) pixmap;
    NSImage *nsImage;

    macDraw->flags |= TK_USE_XIMAGE_ALPHA;
    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}
 
................................................................................
	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
	    if (subImage) {
		image = subImage;
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);

	if (CGImageIsMask(image)) {
	    /*CGContextSaveGState(context);*/
	    if (macDraw->flags & TK_IS_BW_PIXMAP) {
		/* Set fill color to black, background comes from the context, or is transparent. */


		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    CGContextClearRect(context, dstBounds);
		}
		CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
	    } else {
		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    TkMacOSXSetColorInContext(gc, imageBackground, context);
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

int
TkMacOSXSetupDrawingContext(
    Drawable d,
    GC gc,
    int useCG, /* advisory only ! */
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = ((MacDrawable*)d);
    int dontDraw = 0, isWin = 0;

    TkMacOSXDrawingContext dc = {};
    CGRect clipBounds;






















    dc.clipRgn = TkMacOSXGetClipRgn(d);
    if (!dontDraw) {
	ClipToGC(d, gc, &dc.clipRgn);
	dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0;
    }
    if (dontDraw) {

	goto end;
    }
    if (useCG) {
	dc.context = TkMacOSXGetCGContextForDrawable(d);
    }
    if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) {
	isWin = (TkMacOSXDrawableWindow(d) != nil);





    }

    if (dc.context) {
	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
    } else if (isWin) {
	NSView *view = TkMacOSXDrawableView(macDraw);
	if (view) {
	    if (view != [NSView focusView]) {
		dc.focusLocked = [view lockFocusIfCanDraw];
		dontDraw = !dc.focusLocked;
	    } else {
		dontDraw = ![view canDraw];
	    }
	    if (dontDraw) {















		goto end;
	    }
	    [[view window] disableFlushWindow];
	    dc.view = view;
	    dc.context = [[NSGraphicsContext currentContext] graphicsPort];

	    dc.portBounds = NSRectToCGRect([view bounds]);
	    if (dc.clipRgn) {
		clipBounds = CGContextGetClipBoundingBox(dc.context);
	    }
	} else {
	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}
    } else {
	Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		"no context to draw into !");
    }





    if (dc.context) {
	CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
		.ty = dc.portBounds.size.height};
	dc.portBounds.origin.x += macDraw->xOff;
	dc.portBounds.origin.y += macDraw->yOff;
	if (!dc.focusLocked) {
	    CGContextSaveGState(dc.context);
	}
	CGContextSetTextDrawingMode(dc.context, kCGTextFill);
	CGContextConcatCTM(dc.context, t);
	if (dc.clipRgn) {
#ifdef TK_MAC_DEBUG_DRAWING
	    CGContextSaveGState(dc.context);
	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
................................................................................
		[JoinRound] = kCGLineJoinRound,
		[JoinBevel] = kCGLineJoinBevel,
	    };
	    bool shouldAntialias;
	    double w = gc->line_width;

	    TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	    if (isWin) {
		CGContextSetPatternPhase(dc.context, CGSizeMake(
			dc.portBounds.size.width, dc.portBounds.size.height));
	    }
	    if(gc->function != GXcopy) {
		TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			"not supported for CG drawing!");
	    }
................................................................................
	    }
	    if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
		CGContextSetLineJoin(dc.context,
			cgJoin[(unsigned)gc->join_style]);
	    }
	}
    }

end:







    if (dontDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
    *dcPtr = dc;
    return !dontDraw;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRestoreDrawingContext --
 *
................................................................................

void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);
	[[dcPtr->view window] setViewsNeedDisplay:YES];
	[[dcPtr->view window] enableFlushWindow];
	if (dcPtr->focusLocked) {
	    [dcPtr->view unlockFocus];
	} else {
	    CGContextRestoreGState(dcPtr->context);
	}
    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
    }
#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */
................................................................................
    HIShapeRef clipRgn = NULL;

    if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);
	NSView *view = TkMacOSXDrawableView(macDraw);
	if ([view lockFocusIfCanDraw]) {
	    CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
	    CGContextSaveGState(context);
	    CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
		    -1.0, 0.0, [view bounds].size.height));
	    ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
	    CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
	    CGContextEOFillPath(context);
	    CGContextRestoreGState(context);
	    [view unlockFocus];
	}
#endif /* TK_MAC_DEBUG_DRAWING */
    }

    if (macDraw->drawRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->drawRgn);
    } else if (macDraw->visRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->visRgn);
................................................................................
TkpClipDrawableToRect(
    Display *display,
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *) d;
    NSView *view = TkMacOSXDrawableView(macDraw);

    if (macDraw->drawRgn) {
	CFRelease(macDraw->drawRgn);
	macDraw->drawRgn = NULL;
    }

    if (width >= 0 && height >= 0) {
	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
		width, height);
	HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect);

	if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	    TkMacOSXUpdateClipRgn(macDraw->winPtr);
................................................................................
	if (macDraw->visRgn) {
	    macDraw->drawRgn = HIShapeCreateIntersection(macDraw->visRgn,
		    drawRgn);
	    CFRelease(drawRgn);
	} else {
	    macDraw->drawRgn = drawRgn;
	}
	if (view && view != [NSView focusView] && [view lockFocusIfCanDraw]) {
	    clipRect.origin.y = [view bounds].size.height -
		    (clipRect.origin.y + clipRect.size.height);
	    NSRectClip(NSRectFromCGRect(clipRect));
	    macDraw->flags |= TK_FOCUSED_VIEW;
	}
    } else {
	if (view && (macDraw->flags & TK_FOCUSED_VIEW)) {
	    [view unlockFocus];
	    macDraw->flags &= ~TK_FOCUSED_VIEW;
	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * ClipToGC --







>
>
>
>
>
>







 







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







 







|
|
|


>

<
|
|
>












>



>





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







 







>


<

<
<
<





|






|
>








<
|
|
|
>
>

<
<







 







|







 







|







 







<
|
|
|
>
>







 







<


<







 







|
|
|
|
|
>
>







 







|







|
>



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

<
|
|
<
<
>


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


|


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

<
>












>
>
>
>
>





<
|
<







 







|







 







>

>
>
>
>
>
>
>
|




|







 







<
<
<
<
<
|
<







 







<
<
|
|
|
|
|
|
|
<
<







 







<





<







 







<
<
<
<
<
<
<
<
<
<
<







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
...
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
149
150
151
152
153
154
155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
237
238
239
240
241
242
243
244
245
246

247



248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269

270
271
272
273
274
275


276
277
278
279
280
281
282
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
...
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
...
362
363
364
365
366
367
368

369
370
371
372
373
374
375
376
377
378
379
380
...
470
471
472
473
474
475
476

477
478

479
480
481
482
483
484
485
...
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
....
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
....
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
....
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
....
1685
1686
1687
1688
1689
1690
1691





1692

1693
1694
1695
1696
1697
1698
1699
....
1724
1725
1726
1727
1728
1729
1730


1731
1732
1733
1734
1735
1736
1737


1738
1739
1740
1741
1742
1743
1744
....
1790
1791
1792
1793
1794
1795
1796

1797
1798
1799
1800
1801

1802
1803
1804
1805
1806
1807
1808
....
1810
1811
1812
1813
1814
1815
1816











1817
1818
1819
1820
1821
1822
1823
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXDebug.h"
#include "tkButton.h"

#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] CGContext]
#else
#define GET_CGCONTEXT [[NSGraphicsContext currentContext] graphicsPort]
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_DRAWING
#define TK_MAC_DEBUG_IMAGE_DRAWING
#endif
*/

................................................................................
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXBitmapRepFromDrawableRect
 *
 *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
 *
 *      This is only used by XGetImage, which is never called.  And this
 *      implementation does not work correctly.  Originally it relied on
 *      [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was
 *      deprecated by Apple in OSX 10.14 and also required the use of other
 *      deprecated functions such as [NSView lockFocus]. Apple's suggested
 *      replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that
 *      is what is being used here.  However, that method only works when the
 *      view has a valid CGContext, and a view is only guaranteed to have a
 *      valid context during a call to [NSView drawRect].  To further
 *      complicate matters, cacheDisplayInRect calls [NSView drawRect].
 *      Essentially it is asking the view to draw a subrectangle of itself into
 *      a special graphics context which is linked to the BitmapImageRep.  But
 *      our implementation of [NSView drawRect] does not allow recursive calls.
 *      If called recursively it returns immediately without doing any drawing.
 *      So the bottom line is that this function either returns a NULL pointer
 *      or a black image.  To make it useful would require a significant amount
 *      of rewriting of the drawRect method.  Perhaps the next release of OSX
 *      will include some more helpful ways of doing this.
 *
 * Results:
 *	Returns an NSBitmapRep representing the image of the given
 *      rectangle of the given drawable.  This object is retained.
 *      The caller is responsible for releasing it.
 *
 *      NOTE: The x,y coordinates should be relative to a coordinate system with
 *      origin at the top left, as used by XImage and CGImage, not bottom
................................................................................
        Drawable drawable,
	int x,
	int y,
	unsigned int width,
	unsigned int height)
{
    MacDrawable *mac_drawable = (MacDrawable *) drawable;
    CGContextRef cg_context = NULL;
    CGImageRef cg_image=NULL, sub_cg_image = NULL;
    NSBitmapImageRep *bitmap_rep = NULL;
    NSView *view=NULL;
    if ( mac_drawable->flags & TK_IS_PIXMAP ) {

	/*

	 * This MacDrawable is a bitmap, so its view is NULL.
	 */

	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
	CGRect image_rect = CGRectMake(x, y, width, height);
	cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
	sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
	if ( sub_cg_image ) {
	    bitmap_rep = [NSBitmapImageRep alloc];
	    [bitmap_rep initWithCGImage:sub_cg_image];
	}
	if ( cg_image ) {
	    CGImageRelease(cg_image);
	}
    } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) {

	/*
	 * Convert Tk top-left to NSView bottom-left coordinates.
	 */

	int view_height = [view bounds].size.height;
	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
			       view_height - height - y - mac_drawable->yOff,
			       width, height);

	/*
	 * Attempt to copy from the view to a bitmapImageRep.  If the view does
	 * not have a valid CGContext, doing this will silently corrupt memory
	 * and make a big mess. So, in that case, we mark the view as needing
	 * display and return NULL.
	 */

	if (view == [NSView focusView]) {
	    bitmap_rep = [view bitmapImageRepForCachingDisplayInRect: view_rect];
	    [bitmap_rep retain];
	    [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmap_rep];
	} else {
	    TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap.");
	    [view setNeedsDisplay:YES];
	    return NULL;
	}
    } else {
	TkMacOSXDbgMsg("Invalid source drawable");
    }
    return bitmap_rep;
}
 
/*
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y)
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    NSBitmapImageRep *bitmap_rep = NULL;
    CGImageRef img = NULL;
    CGRect bounds, srcRect, dstRect;

    display->request++;

    if (!width || !height) {



	return;
    }

    if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) {
	return;
	TkMacOSXDbgMsg("Failed to setup drawing context.");
    }

    if ( dc.context ) {
	if (srcDraw->flags & TK_IS_PIXMAP) {
	    img = TkMacOSXCreateCGImageWithDrawable(src);
	}else if (TkMacOSXDrawableWindow(src)) {
	    bitmap_rep =  TkMacOSXBitmapRepFromDrawableRect(src,
				   src_x, src_y, width, height);
	    if ( bitmap_rep ) {
		img = [bitmap_rep CGImage];
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
	}

	if (img) {

	    bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
	    srcRect = CGRectMake(src_x, src_y, width, height);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(dst, gc, dc.context, img,
		     gc->foreground, gc->background, bounds, srcRect, dstRect);
	    CFRelease(img);


	} else {
	    TkMacOSXDbgMsg("Failed to construct CGImage.");
	}

    } else {
	TkMacOSXDbgMsg("Invalid destination drawable - no context.");
	return;
................................................................................
    int dest_x,			/* Dest X & Y on dest rect. */
    int dest_y,
    unsigned long plane)	/* Which plane to copy. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *srcDraw = (MacDrawable *) src;
    MacDrawable *dstDraw = (MacDrawable *) dst;
    CGRect bounds, srcRect, dstRect;
    display->request++;
    if (!width || !height) {
	/* TkMacOSXDbgMsg("Drawing of empty area requested"); */
	return;
    }
    if (plane != 1) {
	Tcl_Panic("Unexpected plane specified for XCopyPlane");
................................................................................
	CGContextRef context = dc.context;
	if (context) {
	    CGImageRef img = TkMacOSXCreateCGImageWithDrawable(src);
	    if (img) {
		TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask;
		unsigned long imageBackground  = gc->background;
                if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap);
		    CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect);
		    CGRect rect = CGRectMake(dest_x, dest_y, width, height);
		    rect = CGRectOffset(rect, dstDraw->xOff, dstDraw->yOff);
		    CGContextSaveGState(context);
		    /* Move the origin of the destination to top left. */
		    CGContextTranslateCTM(context, 0, rect.origin.y + CGRectGetMaxY(rect));
................................................................................
		    CGContextFillRect(context, rect);
		    CGContextRestoreGState(context);
		    CGImageRelease(img);
		    CGImageRelease(mask);
		    CGImageRelease(submask);
		    CGImageRelease(subimage);
		} else {

		    bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height);
		    srcRect = CGRectMake(src_x, src_y, width, height);
		    dstRect = CGRectMake(dest_x, dest_y, width, height);
		    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground,
					imageBackground, bounds, srcRect, dstRect);
		    CGImageRelease(img);
		}
	    } else { /* no image */
		TkMacOSXDbgMsg("Invalid source drawable");
	    }
	} else {
	    TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
................................................................................
TkMacOSXGetNSImageWithTkImage(
    Display *display,
    Tk_Image image,
    int width,
    int height)
{
    Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);

    NSImage *nsImage;


    Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
    nsImage = CreateNSImageWithPixmap(pixmap, width, height);
    Tk_FreePixmap(display, pixmap);

    return [nsImage autorelease];
}
 
................................................................................
	    subImage = CGImageCreateWithImageInRect(image, CGRectOffset(
		    srcBounds, -imageBounds.origin.x, -imageBounds.origin.y));
	    if (subImage) {
		image = subImage;
	    }
	}
	dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff);
	if (CGImageIsMask(image)) {
	    if (macDraw->flags & TK_IS_BW_PIXMAP) {

		/* Set fill color to black; background comes from the context,
		 * or is transparent.
		 */

		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    CGContextClearRect(context, dstBounds);
		}
		CGContextSetRGBFillColor(context, 0.0, 0.0, 0.0, 1.0);
	    } else {
		if (imageBackground != TRANSPARENT_PIXEL << 24) {
		    TkMacOSXSetColorInContext(gc, imageBackground, context);
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

Bool
TkMacOSXSetupDrawingContext(
    Drawable d,
    GC gc,
    int useCG, /* advisory only ! */
    TkMacOSXDrawingContext *dcPtr)
{
    MacDrawable *macDraw = ((MacDrawable*)d);
    Bool canDraw = true;
    NSWindow *win = NULL;
    TkMacOSXDrawingContext dc = {};
    CGRect clipBounds;

    /*
     * If we are simulating drawing for tests, just return false.
     */

    if ([NSApp simulateDrawing]) {
	return false;
    }

    /*
     * If the drawable is not a pixmap and it has an associated
     * NSWindow then we know we are drawing to a window.
     */

    if (!(macDraw->flags & TK_IS_PIXMAP)) {
	win = TkMacOSXDrawableWindow(d);
    }

    /*
     * Check that we have a non-empty clipping region.
     */

    dc.clipRgn = TkMacOSXGetClipRgn(d);

    ClipToGC(d, gc, &dc.clipRgn);
    if (dc.clipRgn && HIShapeIsEmpty(dc.clipRgn)) {


	canDraw = false;
	goto end;
    }





    /*
     * If we already have a CGContext, use it.  Otherwise, if we
     * are drawing to a window then we can get one from the
     * window.
     */

    dc.context = TkMacOSXGetCGContextForDrawable(d);
    if (dc.context) {
	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
    } else if (win) {
	NSView *view = TkMacOSXDrawableView(macDraw);
	if (view) {







	    /*
	     * We can only draw into the view when the current CGContext is
	     * valid and belongs to the view.  Validity can only be guaranteed
	     * inside of a view's drawRect or setFrame methods.  The isDrawing
	     * attribute tells us whether we are being called from one of those
	     * methods.
	     *
	     * If the CGContext is not valid, or belongs to a different View,
	     * then we mark our view as needing display and return failure.
	     * It should get drawn in a later call to drawRect.
	     */

           if (view != [NSView focusView]) {
	       [view setNeedsDisplay:YES];
	       canDraw = false;
	       goto end;
	   }

	    dc.view = view;

	    dc.context = GET_CGCONTEXT;
	    dc.portBounds = NSRectToCGRect([view bounds]);
	    if (dc.clipRgn) {
		clipBounds = CGContextGetClipBoundingBox(dc.context);
	    }
	} else {
	    Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		    "no NSView to draw into !");
	}
    } else {
	Tcl_Panic("TkMacOSXSetupDrawingContext(): "
		"no context to draw into !");
    }

    /*
     * Configure the drawing context.
     */

    if (dc.context) {
	CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
		.ty = dc.portBounds.size.height};
	dc.portBounds.origin.x += macDraw->xOff;
	dc.portBounds.origin.y += macDraw->yOff;

	CGContextSaveGState(dc.context);

	CGContextSetTextDrawingMode(dc.context, kCGTextFill);
	CGContextConcatCTM(dc.context, t);
	if (dc.clipRgn) {
#ifdef TK_MAC_DEBUG_DRAWING
	    CGContextSaveGState(dc.context);
	    ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context);
	    CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1);
................................................................................
		[JoinRound] = kCGLineJoinRound,
		[JoinBevel] = kCGLineJoinBevel,
	    };
	    bool shouldAntialias;
	    double w = gc->line_width;

	    TkMacOSXSetColorInContext(gc, gc->foreground, dc.context);
	    if (win) {
		CGContextSetPatternPhase(dc.context, CGSizeMake(
			dc.portBounds.size.width, dc.portBounds.size.height));
	    }
	    if(gc->function != GXcopy) {
		TkMacOSXDbgMsg("Logical functions other than GXcopy are "
			"not supported for CG drawing!");
	    }
................................................................................
	    }
	    if ((unsigned)gc->join_style < sizeof(cgJoin)/sizeof(CGLineJoin)) {
		CGContextSetLineJoin(dc.context,
			cgJoin[(unsigned)gc->join_style]);
	    }
	}
    }

end:
#ifdef TK_MAC_DEBUG_DRAWING
    if (!canDraw && win != NULL) {
	TkWindow *winPtr = TkMacOSXGetTkWindow(win);
	if (winPtr) fprintf(stderr, "Cannot draw in %s - postponing.\n",
			    Tk_PathName(winPtr));
    }
#endif
    if (!canDraw && dc.clipRgn) {
	CFRelease(dc.clipRgn);
	dc.clipRgn = NULL;
    }
    *dcPtr = dc;
    return canDraw;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRestoreDrawingContext --
 *
................................................................................

void
TkMacOSXRestoreDrawingContext(
    TkMacOSXDrawingContext *dcPtr)
{
    if (dcPtr->context) {
	CGContextSynchronize(dcPtr->context);





	CGContextRestoreGState(dcPtr->context);

    }
    if (dcPtr->clipRgn) {
	CFRelease(dcPtr->clipRgn);
    }
#ifdef TK_MAC_DEBUG
    bzero(dcPtr, sizeof(TkMacOSXDrawingContext));
#endif /* TK_MAC_DEBUG */
................................................................................
    HIShapeRef clipRgn = NULL;

    if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	TkMacOSXUpdateClipRgn(macDraw->winPtr);
#ifdef TK_MAC_DEBUG_DRAWING
	TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName);
	NSView *view = TkMacOSXDrawableView(macDraw);


	CGContextSaveGState(context);
	CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0,
	      -1.0, 0.0, [view bounds].size.height));
	ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context);
	CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1);
	CGContextEOFillPath(context);
	CGContextRestoreGState(context);


#endif /* TK_MAC_DEBUG_DRAWING */
    }

    if (macDraw->drawRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->drawRgn);
    } else if (macDraw->visRgn) {
	clipRgn = HIShapeCreateCopy(macDraw->visRgn);
................................................................................
TkpClipDrawableToRect(
    Display *display,
    Drawable d,
    int x, int y,
    int width, int height)
{
    MacDrawable *macDraw = (MacDrawable *) d;


    if (macDraw->drawRgn) {
	CFRelease(macDraw->drawRgn);
	macDraw->drawRgn = NULL;
    }

    if (width >= 0 && height >= 0) {
	CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff,
		width, height);
	HIShapeRef drawRgn = HIShapeCreateWithRect(&clipRect);

	if (macDraw->winPtr && macDraw->flags & TK_CLIP_INVALID) {
	    TkMacOSXUpdateClipRgn(macDraw->winPtr);
................................................................................
	if (macDraw->visRgn) {
	    macDraw->drawRgn = HIShapeCreateIntersection(macDraw->visRgn,
		    drawRgn);
	    CFRelease(drawRgn);
	} else {
	    macDraw->drawRgn = drawRgn;
	}











    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * ClipToGC --

Changes to macosx/tkMacOSXEmbed.c.

801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

    if (!firstContainerPtr) {
	/*
	 * When the interpreter is being dismantled this can be nil.
	 */
	return;
    }
    
    /*
     * Ignore any X protocol errors that happen in this procedure (almost any
     * operation could fail, for example, if the embedded application has
     * deleted its window).
     */

    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,







|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

    if (!firstContainerPtr) {
	/*
	 * When the interpreter is being dismantled this can be nil.
	 */
	return;
    }

    /*
     * Ignore any X protocol errors that happen in this procedure (almost any
     * operation could fail, for example, if the embedded application has
     * deleted its window).
     */

    errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,

Changes to macosx/tkMacOSXEvent.c.

108
109
110
111
112
113
114
115
116








117
118
119
120
121
122

123
124
125
126
127
128
129
130



131
132
133
134

135
136
137
138
139
140
141
142
143
144
145
146
147
#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFlushWindows --
 *
 *	This routine flushes all the visible windows of the application. It is
 *	called by XSync().








 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Flushes all visible Cocoa windows

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

MODULE_SCOPE void
TkMacOSXFlushWindows(void)
{
    NSArray *macWindows = [NSApp orderedWindows];




    for (NSWindow *w in macWindows) {
	if (TkMacOSXGetXWindow(w)) {
	    [w flushWindow];

	}
    }
}

 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







|
|
>
>
>
>
>
>
>
>





|
>








>
>
>
|

|
<
>
|












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

146
147
148
149
150
151
152
153
154
155
156
157
158
159
#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXFlushWindows --
 *
 *	This routine is a stub called by XSync, which is called during the Tk
 *      update command.  The language specification does not require that the
 *      update command be synchronous but many of the tests assume that is the
 *      case.  It is not naturally the case on macOS since many idle tasks are
 *      run inside of the drawRect method of a window's contentView, and that
 *      method will not be called until after this function returns.  To make
 *      the tests work, we attempt to force this to be synchronous by waiting
 *      until drawRect has been called for each window.  The mechanism we use
 *      for this is to have drawRect post an ApplicationDefined NSEvent on the
 *      AppKit event queue when it finishes drawing, and wait for it here.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Calls the drawRect method of the contentView of each visible
 *      window.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void
TkMacOSXFlushWindows(void)
{
    NSArray *macWindows = [NSApp orderedWindows];
    if ([NSApp simulateDrawing]) {
	[NSApp setSimulateDrawing:NO];
	return;
    }
    for (NSWindow *w in macWindows) {
    	if (TkMacOSXGetXWindow(w)) {

    	    [w displayIfNeeded];
    	}
    }
}

 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXFont.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
...
847
848
849
850
851
852
853




854
855
856
857
858
859
860
861
862
863





864
865
866
867
868
869


















870
871
872





873
874
875
876
877
878
879
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"


#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation
#else
#define defaultOrientation kCTFontOrientationDefault
#define verticalOrientation kCTFontOrientationVertical
#endif
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101100
#define fixedPitch kCTFontUserFixedPitchFontType
#else
#define fixedPitch kCTFontUIFontUserFixedPitch
#endif

/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/

................................................................................
	line = CTTypesetterCreateLine(typesetter, range);
	width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    } else {
	double maxWidth = maxLength + offset;
	NSCharacterSet *cs;





	index = start;
	if (flags & TK_WHOLE_WORDS) {
	    index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth);
	    if (index <= start && (flags & TK_AT_LEAST_ONE)) {
		flags &= ~TK_WHOLE_WORDS;
	    }
	}
	if (index <= start && !(flags & TK_WHOLE_WORDS)) {
	    index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth);
	}





	cs = (index <= len && (flags & TK_WHOLE_WORDS)) ?
		whitespaceCharacterSet : lineendingCharacterSet;
	while (index > start &&
		[cs characterIsMember:[string characterAtIndex:(index - 1)]]) {
	    index--;
	}


















	if (index <= start && (flags & TK_AT_LEAST_ONE)) {
	    index = start + 1;
	}





	if (index > 0) {
	    range.length = index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	} else {
	    width = 0;







>

<


<
<
<
<
<

<
<
<







 







>
>
>
>










>
>
>
>
>






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



>
>
>
>
>







10
11
12
13
14
15
16
17
18

19
20





21



22
23
24
25
26
27
28
...
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "tkMacOSXFont.h"
#include "tkMacOSXConstants.h"


#define defaultOrientation kCTFontDefaultOrientation
#define verticalOrientation kCTFontVerticalOrientation





#define fixedPitch kCTFontUserFixedPitchFontType




/*
#ifdef TK_MAC_DEBUG
#define TK_MAC_DEBUG_FONTS
#endif
*/

................................................................................
	line = CTTypesetterCreateLine(typesetter, range);
	width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	CFRelease(line);
    } else {
	double maxWidth = maxLength + offset;
	NSCharacterSet *cs;

        /*
         * Get a line breakpoint in the source string.
         */

	index = start;
	if (flags & TK_WHOLE_WORDS) {
	    index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth);
	    if (index <= start && (flags & TK_AT_LEAST_ONE)) {
		flags &= ~TK_WHOLE_WORDS;
	    }
	}
	if (index <= start && !(flags & TK_WHOLE_WORDS)) {
	    index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth);
	}

        /*
         * Trim right whitespace/lineending characters.
         */

	cs = (index <= len && (flags & TK_WHOLE_WORDS)) ?
		whitespaceCharacterSet : lineendingCharacterSet;
	while (index > start &&
		[cs characterIsMember:[string characterAtIndex:(index - 1)]]) {
	    index--;
	}

        /*
         * If there is no line breakpoint in the source string between
         * its start and the index position that fits in maxWidth, then
         * CTTypesetterSuggestLineBreak() returns that very last index.
         * However if the TK_WHOLE_WORDS flag is set, we want to break
         * at a word boundary. In this situation, unless TK_AT_LEAST_ONE
         * is set, we must report that zero chars actually fit (in other
         * words the smallest word of the source string is still larger
         * than maxWidth).
         */

        if ((index >= start) && (index < len) &&
                (flags & TK_WHOLE_WORDS) && !(flags & TK_AT_LEAST_ONE) &&
                ![cs characterIsMember:[string characterAtIndex:index]]) {
            index = start;
        }

	if (index <= start && (flags & TK_AT_LEAST_ONE)) {
	    index = start + 1;
	}

        /*
         * Now measure the string width in pixels.
         */

	if (index > 0) {
	    range.length = index;
	    line = CTTypesetterCreateLine(typesetter, range);
	    width = CTLineGetTypographicBounds(line, NULL, NULL, NULL);
	    CFRelease(line);
	} else {
	    width = 0;

Changes to macosx/tkMacOSXImage.c.

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
25
26
27
28
29
30
31
32

33
34
35
36
37
38
39
..
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
..
84
85
86
87
88
89
90

91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
124
125
126
127
128
129
130
131





132
133
134
135
136
137
138
...
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180

181
182
183

184
185
186
187
188
189
190
191
192
193
194

195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237

238
239
240
241

242
243
244
245
246
247
248
...
510
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
...
538
539
540
541
542
543
544
545
546
547
548
549
550
551

552
553







554

555





556
557
558
559
560
561



562
563
564
565
566
567
568
 * tkMacOSXImage.c --
 *
 *	The code in this file provides an interface for XImages,
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2017 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "xbytes.h"
................................................................................
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithXImage --
 *
 *	Create CGImage from XImage, copying the image data.

 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
................................................................................

static void ReleaseData(void *info, const void *data, size_t size) {
    ckfree(info);
}

CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image,
    int use_ximage_alpha)
{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;
    CGBitmapInfo bitmapInfo;
    CGDataProviderRef provider = NULL;
................................................................................
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
	}
    } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {

	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		      kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little);
	if (use_ximage_alpha) {
	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
	} else {
	    bitmapInfo |= kCGImageAlphaNoneSkipFirst;
	}
	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
................................................................................
 

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.





 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *	constructed.  NOTE: If we are copying from a window on a Retina
 *	display, the dimensions of the XImage will be 2*width x 2*height.
 *
................................................................................
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;
    unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
    NSWindow *win = TkMacOSXDrawableWindow(drawable);
    MacDrawable *macDraw = ((MacDrawable*)drawable);
    static enum {unknown, no, yes} has_retina = unknown;

    if (win && has_retina == unknown) {
#ifdef __clang__
	has_retina = [win respondsToSelector:@selector(backingScaleFactor)]?
	    yes : no;
#else
	has_retina = no;
#endif
    }

    if (has_retina == yes) {

	/*
	 * We only allow scale factors 1 or 2, as Apple currently does.
	 */

#ifdef __clang__
	scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
#endif
	scaled_height *= scalefactor;
	scaled_width *= scalefactor;
    }

    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    return NULL;
	}

	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
		         x, y, width, height);
	if (!bitmap_rep) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}
	bitmap_fmt = [bitmap_rep bitmapFormat];
	size = [bitmap_rep bytesPerPlane];
	bytes_per_row = [bitmap_rep bytesPerRow];
	bitmap = ckalloc(size);
	if (!bitmap                              ||
	    (bitmap_fmt != 0 && bitmap_fmt != 1) ||
	    [bitmap_rep samplesPerPixel] != 4    ||
	    [bitmap_rep isPlanar] != 0           ||
	    bytes_per_row != 4 * scaled_width    ||
	    size != bytes_per_row*scaled_height  ) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmap_rep);
	    return NULL;
	}

	if (macDraw->flags & TK_USE_XIMAGE_ALPHA) {
	    /*
	     * When called by TkImgPhotoDisplay we are being asked to return a
	     * background image to be blended with the photoimage using its
	     * alpha channel, if it has one.  Returning a black pixmap here
	     * makes TkImgPhotoDisplay create an XImage with a premultiplied
	     * alpha channel, as favored by Apple.  When TkImgPhotoDisplay
	     * passes this XImage to TkPutImage, targeting a pixmap, it creates
	     * an image with correct transparency.  This is used, for example,
	     * when creating an iconphoto or a menu image from a PNG
	     * photoimage.
	     */
	    bzero(bitmap, size);
	} else {
	    memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
	}
	CFRelease(bitmap_rep);

	/*
	 * When Apple extracts a bitmap from an NSView, it may be in
	 * either BGRA or ABGR format.  For an XImage we need RGBA.
	 */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;

	for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
	    for (m=n; m<n+bytes_per_row; m+=4) {

		R = *(bitmap + m + pixel.r);
		G = *(bitmap + m + pixel.g);
		B = *(bitmap + m + pixel.b);
		A = *(bitmap + m + pixel.a);

		*(bitmap + m)     = R;
		*(bitmap + m + 1) = G;
................................................................................
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --
 *
 *	Copies a subimage from an in-memory image to a rectangle of
 *	of the specified drawable.

 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
................................................................................
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	        /* Same width & height for both */
    unsigned int height)	/* distination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = ((MacDrawable*)drawable);

    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {

	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image,
			     macDraw->flags & TK_USE_XIMAGE_ALPHA);







	if (img) {

	    /* If the XImage has big pixels, rescale the source dimensions.*/





	    int pp = image->pixelpower;
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
		    img, gc->foreground, gc->background,
		    CGRectMake(0, 0, image->width<<pp, image->height<<pp),
		    CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
		    CGRectMake(dest_x, dest_y, width, height));



	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
    }







|







 







|
>







 







|
<







 







>





<



|
<
<
<
|
<







 







|
>
>
>
>
>







 







<












>



>











>

|












|





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






>


<
|
>







 







|
|
>







 







|






>
|
|
>
>
>
>
>
>
>

>
|
>
>
>
>
>

<
<
|
|
|
>
>
>







2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
..
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
..
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
..
84
85
86
87
88
89
90
91
92
93
94
95
96

97
98
99
100



101

102
103
104
105
106
107
108
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
162
163
164
165
166
167
168

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217















218

219
220
221
222
223
224
225
226
227

228
229
230
231
232
233
234
235
236
...
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
...
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559


560
561
562
563
564
565
566
567
568
569
570
571
572
 * tkMacOSXImage.c --
 *
 *	The code in this file provides an interface for XImages,
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2017-2018 Marc Culler.
 *
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"
#include "xbytes.h"
................................................................................
}

/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXCreateCGImageWithXImage --
 *
 *	Create CGImage from XImage, copying the image data.  Called
 *      in Tk_PutImage and (currently) nowhere else.
 *
 * Results:
 *	CGImage, release after use.
 *
 * Side effects:
 *	None.
 *
................................................................................

static void ReleaseData(void *info, const void *data, size_t size) {
    ckfree(info);
}

CGImageRef
TkMacOSXCreateCGImageWithXImage(
    XImage *image)

{
    CGImageRef img = NULL;
    size_t bitsPerComponent, bitsPerPixel;
    size_t len = image->bytes_per_line * image->height;
    const CGFloat *decode = NULL;
    CGBitmapInfo bitmapInfo;
    CGDataProviderRef provider = NULL;
................................................................................
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
	}
    } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {

	/*
	 * Color image
	 */

	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

	bitsPerComponent = 8;
	bitsPerPixel = 32;
	bitmapInfo = (image->byte_order == MSBFirst ?
		      kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big);



	bitmapInfo |= kCGImageAlphaLast;

	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
	if (data) {
	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
	}
	if (provider) {
	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
................................................................................
 

/*
 *----------------------------------------------------------------------
 *
 * XGetImage --
 *
 *	This function copies data from a pixmap or window into an XImage.  It
 *      is essentially never used. At one time it was called by
 *      pTkImgPhotoDisplay, but that is no longer the case. Currently it is
 *      called two places, one of which is requesting an XY image which we do
 *      not support.  It probably does not work correctly -- see the comments
 *      for TkMacOSXBitmapRepFromDrawableRect.
 *
 * Results:
 *	Returns a newly allocated XImage containing the data from the given
 *	rectangle of the given drawable, or NULL if the XImage could not be
 *	constructed.  NOTE: If we are copying from a window on a Retina
 *	display, the dimensions of the XImage will be 2*width x 2*height.
 *
................................................................................
    XImage* imagePtr = NULL;
    char* bitmap = NULL;
    char R, G, B, A;
    int depth = 32, offset = 0, bitmap_pad = 0;
    unsigned int bytes_per_row, size, row, n, m;
    unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
    NSWindow *win = TkMacOSXDrawableWindow(drawable);

    static enum {unknown, no, yes} has_retina = unknown;

    if (win && has_retina == unknown) {
#ifdef __clang__
	has_retina = [win respondsToSelector:@selector(backingScaleFactor)]?
	    yes : no;
#else
	has_retina = no;
#endif
    }

    if (has_retina == yes) {

	/*
	 * We only allow scale factors 1 or 2, as Apple currently does.
	 */

#ifdef __clang__
	scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
#endif
	scaled_height *= scalefactor;
	scaled_width *= scalefactor;
    }

    if (format == ZPixmap) {
	if (width == 0 || height == 0) {
	    return NULL;
	}

	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
			  x, y, width, height);
	if (!bitmap_rep) {
	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
	    return NULL;
	}
	bitmap_fmt = [bitmap_rep bitmapFormat];
	size = [bitmap_rep bytesPerPlane];
	bytes_per_row = [bitmap_rep bytesPerRow];
	bitmap = ckalloc(size);
	if (!bitmap                              ||
	    (bitmap_fmt != 0 && bitmap_fmt != 1) ||
	    [bitmap_rep samplesPerPixel] != 4    ||
	    [bitmap_rep isPlanar] != 0           ||
	    bytes_per_row < 4 * scaled_width    ||
	    size != bytes_per_row*scaled_height  ) {
	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
	    CFRelease(bitmap_rep);
	    return NULL;
	}















	memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);

	CFRelease(bitmap_rep);

	/*
	 * When Apple extracts a bitmap from an NSView, it may be in
	 * either BGRA or ABGR format.  For an XImage we need RGBA.
	 */

	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;


	for (row = 0, n = 0; row < scaled_height; row++, n += bytes_per_row) {
	    for (m = n; m < n + 4*scaled_width; m += 4) {
		R = *(bitmap + m + pixel.r);
		G = *(bitmap + m + pixel.g);
		B = *(bitmap + m + pixel.b);
		A = *(bitmap + m + pixel.a);

		*(bitmap + m)     = R;
		*(bitmap + m + 1) = G;
................................................................................
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkPutImage --
 *
 *	Copies a rectangular subimage of an XImage into a drawable.
 *      Currently this is only called by TkImgPhotoDisplay, using
 *      a Window as the drawable.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws the image on the specified drawable.
 *
................................................................................
    int src_y,
    int dest_x,			/* Destination X & Y. */
    int dest_y,
    unsigned int width,	        /* Same width & height for both */
    unsigned int height)	/* distination and source. */
{
    TkMacOSXDrawingContext dc;
    MacDrawable *macDraw = (MacDrawable *) drawable;

    display->request++;
    if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
	return BadDrawable;
    }
    if (dc.context) {
	CGRect bounds, srcRect, dstRect;
	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image);
	if (macDraw->flags & TK_IS_PIXMAP) {
	    /*
	     * The CGContext for a pixmap is RGB only, with A = 0.
	     */
	    CGContextSetBlendMode(dc.context, kCGImageAlphaNoneSkipLast);
	} else {
	    CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop);
	}
	if (img) {

	    /* If the XImage has big pixels, the source is rescaled to reflect
	     * the actual pixel dimensions.  This is not currently used, but
	     * could arise if the image were copied from a retina monitor and
	     * redrawn on an ordinary monitor.
	     */

	    int pp = image->pixelpower;


	    bounds = CGRectMake(0, 0, image->width, image->height);
	    srcRect = CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp);
	    dstRect = CGRectMake(dest_x, dest_y, width, height);
	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
				img, gc->foreground, gc->background,
				bounds, srcRect, dstRect);
	    CFRelease(img);
	} else {
	    TkMacOSXDbgMsg("Invalid source drawable");
	}
    } else {
	TkMacOSXDbgMsg("Invalid destination drawable");
    }

Changes to macosx/tkMacOSXInit.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
..
44
45
46
47
48
49
50



51
52
53
54
55
56
57
...
148
149
150
151
152
153
154




















155
156
157
158
159
160
161
162

163
164
165
166
167
168
169
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include <sys/stat.h>
#include <sys/utsname.h>
#include <dlfcn.h>
#include <objc/objc-auto.h>

static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";

long tkMacOSXMacOSXVersion = 0;

#pragma mark TKApplication(TKInit)

@interface TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification;
@end

#define TKApplication_NSApplicationDelegate <NSApplicationDelegate>
................................................................................

@interface TKApplication(TKMenus)
- (void) _setupMenus;
@end

@implementation TKApplication
@synthesize poolLock = _poolLock;



@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK
................................................................................

    /*
     * Install the global autoreleasePool.
     */
    _mainPool = [NSAutoreleasePool new];
    [NSApp setPoolLock:0];





















    /*
     * Be our own delegate.
     */
    [self setDelegate:self];

    /*
     * Make sure we are allowed to open windows.
     */

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

    /*
     * If no icon has been set from an Info.plist file, use the Wish icon from
     * the Tk framework.
     */
    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
................................................................................
    /*
     * Since it is possible for TkInit to be called multiple times and we
     * don't want to do the following initialization multiple times we protect
     * against doing it more than once.
     */

    if (!initialized) {
	struct utsname name;
	struct stat st;

	initialized = 1;

	/*
	 * Initialize/check OS version variable for runtime checks.
	 */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#   error Mac OS X 10.6 required
#endif

	if (!uname(&name)) {
	    tkMacOSXMacOSXVersion = (strtod(name.release, NULL) + 96) * 10;
	}
       /*Check for new versioning scheme on Yosemite (10.10) and later.*/
	if (MAC_OS_X_VERSION_MIN_REQUIRED > 100000) {
		tkMacOSXMacOSXVersion = MAC_OS_X_VERSION_MIN_REQUIRED/100;
	    }
	if (tkMacOSXMacOSXVersion && MAC_OS_X_VERSION_MIN_REQUIRED < 100000 &&
		tkMacOSXMacOSXVersion/10 < MAC_OS_X_VERSION_MIN_REQUIRED/10) {
	    Tcl_Panic("Mac OS X 10.%d or later required !",
		    (MAC_OS_X_VERSION_MIN_REQUIRED/10)-100);
	}


#ifdef TK_FRAMEWORK
	/*
	 * When Tk is in a framework, force tcl_findLibrary to look in the
	 * framework scripts directory.
	 * FIXME: Should we come up with a more generic way of doing this?
	 */







<












<
<







 







>
>
>







 







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








>







 







<











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







12
13
14
15
16
17
18

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


31
32
33
34
35
36
37
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
272
273
274
275
276
277
278

279
280
281
282
283
284
285
286
287
288
289














290
291
292
293
294
295
296
 * See the file "license.terms" for information on usage and redistribution of
 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkMacOSXPrivate.h"

#include <sys/stat.h>

#include <dlfcn.h>
#include <objc/objc-auto.h>

static char tkLibPath[PATH_MAX + 1] = "";

/*
 * If the App is in an App package, then we want to add the Scripts directory
 * to the auto_path.
 */

static char scriptPath[PATH_MAX + 1] = "";



#pragma mark TKApplication(TKInit)

@interface TKApplication(TKKeyboard)
- (void) keyboardChanged: (NSNotification *) notification;
@end

#define TKApplication_NSApplicationDelegate <NSApplicationDelegate>
................................................................................

@interface TKApplication(TKMenus)
- (void) _setupMenus;
@end

@implementation TKApplication
@synthesize poolLock = _poolLock;
@synthesize macMinorVersion = _macMinorVersion;
@synthesize isDrawing = _isDrawing;
@synthesize simulateDrawing = _simulateDrawing;
@end

/*
 * #define this to see a message on stderr whenever _resetAutoreleasePool is
 * called while the pool is locked.
 */
#undef DEBUG_LOCK
................................................................................

    /*
     * Install the global autoreleasePool.
     */
    _mainPool = [NSAutoreleasePool new];
    [NSApp setPoolLock:0];

    /*
     * Record the OS version we are running on.
     */
    int minorVersion;
#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
    Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion);
#else
    NSOperatingSystemVersion systemVersion;
    systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
    minorVersion = systemVersion.minorVersion;
#endif
    [NSApp setMacMinorVersion: minorVersion];

    /*
     * We are not drawing yet.
     */

    [NSApp setIsDrawing:NO];
    [NSApp setSimulateDrawing:NO];

    /*
     * Be our own delegate.
     */
    [self setDelegate:self];

    /*
     * Make sure we are allowed to open windows.
     */

    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];

    /*
     * If no icon has been set from an Info.plist file, use the Wish icon from
     * the Tk framework.
     */
    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
................................................................................
    /*
     * Since it is possible for TkInit to be called multiple times and we
     * don't want to do the following initialization multiple times we protect
     * against doing it more than once.
     */

    if (!initialized) {

	struct stat st;

	initialized = 1;

	/*
	 * Initialize/check OS version variable for runtime checks.
	 */

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
#   error Mac OS X 10.6 required
#endif















#ifdef TK_FRAMEWORK
	/*
	 * When Tk is in a framework, force tcl_findLibrary to look in the
	 * framework scripts directory.
	 * FIXME: Should we come up with a more generic way of doing this?
	 */

Changes to macosx/tkMacOSXInt.h.

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

91
92
93
94
95
96
97
...
195
196
197
198
199
200
201




202
203
204
205
206
207
208
 * Defines use for the flags field of the MacDrawable data structure.
 */

#define TK_SCROLLBAR_GROW	0x01
#define TK_CLIP_INVALID		0x02
#define TK_HOST_EXISTS		0x04
#define TK_DRAWN_UNDER_MENU	0x08
#define TK_FOCUSED_VIEW		0x10
#define TK_IS_PIXMAP		0x20
#define TK_IS_BW_PIXMAP		0x40
#define TK_DO_NOT_DRAW          0x80
#define TK_USE_XIMAGE_ALPHA     0x100

/*
 * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
................................................................................
	int clip_y_origin, XRectangle* rectangles, int n, int ordering);
#endif
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(TkRegion r);
MODULE_SCOPE void TkpReleaseRegion(TkRegion r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);




/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"

#endif /* _TKMACINT */







<
|
|
|
<
>







 







>
>
>
>







79
80
81
82
83
84
85

86
87
88

89
90
91
92
93
94
95
96
...
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
 * Defines use for the flags field of the MacDrawable data structure.
 */

#define TK_SCROLLBAR_GROW	0x01
#define TK_CLIP_INVALID		0x02
#define TK_HOST_EXISTS		0x04
#define TK_DRAWN_UNDER_MENU	0x08

#define TK_IS_PIXMAP		0x10
#define TK_IS_BW_PIXMAP		0x20
#define TK_DO_NOT_DRAW          0x40


/*
 * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
 * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
 * TkWindow structure for the window, but in the MacWin. This way we can
 * still tell what the correct port is after the TKWindow structure has been
 * freed. This actually happens when you bind destroy of a toplevel to
 * Destroy of a child.
................................................................................
	int clip_y_origin, XRectangle* rectangles, int n, int ordering);
#endif
MODULE_SCOPE void TkpClipDrawableToRect(Display *display, Drawable d, int x,
	int y, int width, int height);
MODULE_SCOPE void TkpRetainRegion(TkRegion r);
MODULE_SCOPE void TkpReleaseRegion(TkRegion r);
MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta);
MODULE_SCOPE Bool TkpAppIsDrawing(void);
MODULE_SCOPE void TkpDisplayWindow(Tk_Window tkwin);
MODULE_SCOPE void TkTestSimulateDrawing(Bool);

/*
 * Include the stubbed internal platform-specific API.
 */

#include "tkIntPlatDecls.h"

#endif /* _TKMACINT */

Changes to macosx/tkMacOSXKeyEvent.c.

37
38
39
40
41
42
43


44
45
46
47
48
49
50
..
61
62
63
64
65
66
67









68
69
70
71
72

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

87
88
89
90
91
92
93
94
95
...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271

272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
...
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
...
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
...
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
static BOOL finishedCompose = NO;

static int caret_x = 0, caret_y = 0, caret_height = 0;

static void setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state);
static unsigned isFunctionKey(unsigned int code);




#pragma mark TKApplication(TKKeyEvent)

@implementation TKApplication(TKKeyEvent)

- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
................................................................................
    static NSMutableArray *nsEvArray;

    if (nsEvArray == nil)
      {
        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
      }










    switch (type) {
    case NSKeyUp:
      if (finishedCompose)
        {

          // if we were composing, swallow the last release since we already sent
          finishedCompose = NO;
          return theEvent;
        }
    case NSKeyDown:
	repeat = [theEvent isARepeat];
	characters = [theEvent characters];
	charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers];
        len = [charactersIgnoringModifiers length];
    case NSFlagsChanged:
	modifiers = [theEvent modifierFlags];
	keyCode = [theEvent keyCode];
	//	w = [self windowWithWindowNumber:[theEvent windowNumber]];
	w = [theEvent window];

#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
	NSLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);
#endif
	break;

    default:
	return theEvent; /* Unrecognized key event. */
    }

................................................................................
              /*
               * Set keycode (which was zero) to the changed modifier
               */

              xEvent.xkey.keycode = (modifiers ^ savedModifiers);
            } else {
              if (type == NSKeyUp || repeat) {
                xEvent.xany.type = KeyRelease;
              } else {
                xEvent.xany.type = KeyPress;
              }

              /* For command key, take input manager's word so things
                 like dvorak / qwerty layout work. */
              if ((modifiers & NSCommandKeyMask) == NSCommandKeyMask
................................................................................
/* <NSTextInput>: called when done composing;
   NOTE: also called when we delete over working text, followed immed.
         by doCommandBySelector: deleteBackward: */
- (void)insertText: (id)aString
{
  int i, len = [(NSString *)aString length];
  XEvent xEvent;
  TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
  Tk_Window tkwin = (Tk_Window) winPtr;

  if (NS_KEYLOG)
    NSLog (@"insertText '%@'\tlen = %d", aString, len);
  processingCompose = NO;
  finishedCompose = YES;

  /* first, clear any working text */
  if (privateWorkingText != nil)
    [self deleteWorkingText];

  /* now insert the string as keystrokes */
  setupXEvent(&xEvent, [self window], 0);
  xEvent.xany.type = KeyPress;

  for (i =0; i<len; i++)
    {
      xEvent.xkey.keycode = (UInt16) [aString characterAtIndex: i];
      [[aString substringWithRange: NSMakeRange(i,1)]
        getCString: xEvent.xkey.trans_chars
         maxLength: XMaxTransChars encoding: NSUTF8StringEncoding];
      xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars);
      xEvent.xany.type = KeyPress;
      Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);

      xEvent.xany.type = KeyRelease;
      xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
      Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);
      xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));
    }

}


/* <NSTextInput>: inserts display of composing characters */
- (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange
{
  NSString *str = [aString respondsToSelector: @selector (string)] ?
    [aString string] : aString;
  if (NS_KEYLOG)
    NSLog (@"setMarkedText '%@' len =%lu range %lu from %lu", str,
	   (unsigned long) [str length], (unsigned long) selRange.length,
	   (unsigned long) selRange.location);

  if (privateWorkingText != nil)
    [self deleteWorkingText];
  if ([str length] == 0)
    return;
................................................................................


- (NSRange)markedRange
{
  NSRange rng = privateWorkingText != nil
    ? NSMakeRange (0, [privateWorkingText length]) : NSMakeRange (NSNotFound, 0);
  if (NS_KEYLOG)
    NSLog (@"markedRange request");
  return rng;
}


- (void)unmarkText
{
  if (NS_KEYLOG)
    NSLog (@"unmark (accept) text");
  [self deleteWorkingText];
  processingCompose = NO;
}


/* used to position char selection windows, etc. */
- (NSRect)firstRectForCharacterRange: (NSRange)theRange
................................................................................
  NSRect rect;
  NSPoint pt;

  pt.x = caret_x;
  pt.y = caret_y;

  pt = [self convertPoint: pt toView: nil];
  pt = [[self window] convertPointToScreen: pt];
  pt.y -= caret_height;

  rect.origin = pt;
  rect.size.width = caret_height;
  rect.size.height = caret_height;
  return rect;
}
................................................................................
  return (NSInteger)self;
}


- (void)doCommandBySelector: (SEL)aSelector
{
  if (NS_KEYLOG)
    NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector));
  processingCompose = NO;
  if (aSelector == @selector (deleteBackward:))
    {
      /* happens when user backspaces over an ongoing composition:
         throw a 'delete' into the event queue */
      XEvent xEvent;
      setupXEvent(&xEvent, [self window], 0);
................................................................................
  return arr;
}


- (NSRange)selectedRange
{
  if (NS_KEYLOG)
    NSLog (@"selectedRange request");
  return NSMakeRange (NSNotFound, 0);
}


- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
{
  if (NS_KEYLOG)
    NSLog (@"characterIndexForPoint request");
  return 0;
}


- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
{
  static NSAttributedString *str = nil;
  if (str == nil) str = [NSAttributedString new];
  if (NS_KEYLOG)
    NSLog (@"attributedSubstringFromRange request");
  return str;
}
/* End <NSTextInput> impl. */
@end
 

@implementation TKContentView(TKKeyEvent)
/* delete display of composing characters [not in <NSTextInput>] */
- (void)deleteWorkingText
{
  if (privateWorkingText == nil)
    return;
  if (NS_KEYLOG)
    NSLog(@"deleteWorkingText len = %lu\n",
	    (unsigned long)[privateWorkingText length]);
  [privateWorkingText release];
  privateWorkingText = nil;
  processingCompose = NO;

  //PENDING: delete working text
}







>
>







 







>
>
>
>
>
>
>
>
>



|
<
>
|
|
|
<








<
<
>

|







 







|







 







<
<


|












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









|







 







|







|







 







|







 







|







 







|







|









|













|







37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
..
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

83
84
85
86

87
88
89
90
91
92
93
94


95
96
97
98
99
100
101
102
103
104
...
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
...
243
244
245
246
247
248
249


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



273

274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
...
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
...
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
...
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
static BOOL finishedCompose = NO;

static int caret_x = 0, caret_y = 0, caret_height = 0;

static void setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state);
static unsigned isFunctionKey(unsigned int code);

unsigned short releaseCode;


#pragma mark TKApplication(TKKeyEvent)

@implementation TKApplication(TKKeyEvent)

- (NSEvent *) tkProcessKeyEvent: (NSEvent *) theEvent
{
................................................................................
    static NSMutableArray *nsEvArray;

    if (nsEvArray == nil)
      {
        nsEvArray = [[NSMutableArray alloc] initWithCapacity: 1];
        processingCompose = NO;
      }

    w = [theEvent window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;
    XEvent xEvent;

    if (!winPtr) {
	return theEvent;
    }

    switch (type) {
    case NSKeyUp:
	/*Fix for bug #1ba71a86bb: key release firing on key press.*/

	setupXEvent(&xEvent, w, 0);
	xEvent.xany.type = KeyRelease;
	xEvent.xkey.keycode = releaseCode;
	xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin));

    case NSKeyDown:
	repeat = [theEvent isARepeat];
	characters = [theEvent characters];
	charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers];
        len = [charactersIgnoringModifiers length];
    case NSFlagsChanged:
	modifiers = [theEvent modifierFlags];
	keyCode = [theEvent keyCode];



#if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1
	TKLog(@"-[%@(%p) %s] r=%d mods=%u '%@' '%@' code=%u c=%d %@ %d", [self class], self, _cmd, repeat, modifiers, characters, charactersIgnoringModifiers, keyCode,([charactersIgnoringModifiers length] == 0) ? 0 : [charactersIgnoringModifiers characterAtIndex: 0], w, type);
#endif
	break;

    default:
	return theEvent; /* Unrecognized key event. */
    }

................................................................................
              /*
               * Set keycode (which was zero) to the changed modifier
               */

              xEvent.xkey.keycode = (modifiers ^ savedModifiers);
            } else {
              if (type == NSKeyUp || repeat) {
		  xEvent.xany.type = KeyRelease;
              } else {
                xEvent.xany.type = KeyPress;
              }

              /* For command key, take input manager's word so things
                 like dvorak / qwerty layout work. */
              if ((modifiers & NSCommandKeyMask) == NSCommandKeyMask
................................................................................
/* <NSTextInput>: called when done composing;
   NOTE: also called when we delete over working text, followed immed.
         by doCommandBySelector: deleteBackward: */
- (void)insertText: (id)aString
{
  int i, len = [(NSString *)aString length];
  XEvent xEvent;



  if (NS_KEYLOG)
    TKLog (@"insertText '%@'\tlen = %d", aString, len);
  processingCompose = NO;
  finishedCompose = YES;

  /* first, clear any working text */
  if (privateWorkingText != nil)
    [self deleteWorkingText];

  /* now insert the string as keystrokes */
  setupXEvent(&xEvent, [self window], 0);
  xEvent.xany.type = KeyPress;

  for (i =0; i<len; i++)
      {
	  xEvent.xkey.keycode = (UInt16) [aString characterAtIndex: i];
	  [[aString substringWithRange: NSMakeRange(i,1)]
	      getCString: xEvent.xkey.trans_chars
	       maxLength: XMaxTransChars encoding: NSUTF8StringEncoding];
	  xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars);
	  xEvent.xany.type = KeyPress;
	  releaseCode =  (UInt16) [aString characterAtIndex: 0];



	  Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL);

      }
  releaseCode =  (UInt16) [aString characterAtIndex: 0];
}


/* <NSTextInput>: inserts display of composing characters */
- (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange
{
  NSString *str = [aString respondsToSelector: @selector (string)] ?
    [aString string] : aString;
  if (NS_KEYLOG)
    TKLog (@"setMarkedText '%@' len =%lu range %lu from %lu", str,
	   (unsigned long) [str length], (unsigned long) selRange.length,
	   (unsigned long) selRange.location);

  if (privateWorkingText != nil)
    [self deleteWorkingText];
  if ([str length] == 0)
    return;
................................................................................


- (NSRange)markedRange
{
  NSRange rng = privateWorkingText != nil
    ? NSMakeRange (0, [privateWorkingText length]) : NSMakeRange (NSNotFound, 0);
  if (NS_KEYLOG)
    TKLog (@"markedRange request");
  return rng;
}


- (void)unmarkText
{
  if (NS_KEYLOG)
    TKLog (@"unmark (accept) text");
  [self deleteWorkingText];
  processingCompose = NO;
}


/* used to position char selection windows, etc. */
- (NSRect)firstRectForCharacterRange: (NSRange)theRange
................................................................................
  NSRect rect;
  NSPoint pt;

  pt.x = caret_x;
  pt.y = caret_y;

  pt = [self convertPoint: pt toView: nil];
  pt = [[self window] tkConvertPointToScreen: pt];
  pt.y -= caret_height;

  rect.origin = pt;
  rect.size.width = caret_height;
  rect.size.height = caret_height;
  return rect;
}
................................................................................
  return (NSInteger)self;
}


- (void)doCommandBySelector: (SEL)aSelector
{
  if (NS_KEYLOG)
    TKLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector));
  processingCompose = NO;
  if (aSelector == @selector (deleteBackward:))
    {
      /* happens when user backspaces over an ongoing composition:
         throw a 'delete' into the event queue */
      XEvent xEvent;
      setupXEvent(&xEvent, [self window], 0);
................................................................................
  return arr;
}


- (NSRange)selectedRange
{
  if (NS_KEYLOG)
    TKLog (@"selectedRange request");
  return NSMakeRange (NSNotFound, 0);
}


- (NSUInteger)characterIndexForPoint: (NSPoint)thePoint
{
  if (NS_KEYLOG)
    TKLog (@"characterIndexForPoint request");
  return 0;
}


- (NSAttributedString *)attributedSubstringFromRange: (NSRange)theRange
{
  static NSAttributedString *str = nil;
  if (str == nil) str = [NSAttributedString new];
  if (NS_KEYLOG)
    TKLog (@"attributedSubstringFromRange request");
  return str;
}
/* End <NSTextInput> impl. */
@end
 

@implementation TKContentView(TKKeyEvent)
/* delete display of composing characters [not in <NSTextInput>] */
- (void)deleteWorkingText
{
  if (privateWorkingText == nil)
    return;
  if (NS_KEYLOG)
    TKLog(@"deleteWorkingText len = %lu\n",
	    (unsigned long)[privateWorkingText length]);
  [privateWorkingText release];
  privateWorkingText = nil;
  processingCompose = NO;

  //PENDING: delete working text
}

Changes to macosx/tkMacOSXKeyboard.c.

686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
    KeySym keysym,
    XEvent *eventPtr)
{
    if (keysym == NoSymbol) {
	eventPtr->xkey.keycode = 0;
    } else if ( modKeyArray[0] <= keysym &&
		keysym <= modKeyArray[NUM_MOD_KEYCODES - 1]) {
	/* 
	 * Keysyms for pure modifiers only arise in generated events.
	 * We should just copy them to the keycode.
	 */
	eventPtr->xkey.keycode = keysym;
    } else {
	Display *display = Tk_Display(tkwin);
	int macKeycode = XKeysymToMacKeycode(display, keysym);







|







686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
    KeySym keysym,
    XEvent *eventPtr)
{
    if (keysym == NoSymbol) {
	eventPtr->xkey.keycode = 0;
    } else if ( modKeyArray[0] <= keysym &&
		keysym <= modKeyArray[NUM_MOD_KEYCODES - 1]) {
	/*
	 * Keysyms for pure modifiers only arise in generated events.
	 * We should just copy them to the keycode.
	 */
	eventPtr->xkey.keycode = keysym;
    } else {
	Display *display = Tk_Display(tkwin);
	int macKeycode = XKeysymToMacKeycode(display, keysym);

Changes to macosx/tkMacOSXMenu.c.

769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
....
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
....
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636

    Drawable d = Tk_WindowId(root);
    NSView *rootview = TkMacOSXGetRootControl(d);
    NSWindow *win = [rootview window];
    int result;

    inPostMenu = 1;
    
    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
        inPostMenu = 0;
        return result;
    }

    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
    NSView *view = [win contentView];
    NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);

    frame.origin = [view convertPoint:
	    [win convertPointFromScreen:frame.origin] fromView:nil];

    NSMenu *menu = (NSMenu *) menuPtr->platformData;
    NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]
	    initTextCell:@"" pullsDown:NO];

    [popUpButtonCell setAltersStateOfSelectedItem:NO];
    [popUpButtonCell setMenu:menu];
................................................................................
		columnEntryPtr = menuPtr->entries[j];
		columnEntryPtr->indicatorSpace = maxIndicatorSpace;
		columnEntryPtr->width = maxIndicatorSpace + maxWidth
			+ 2 * activeBorderWidth;
		columnEntryPtr->x = x;
		columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    }
	    x += maxIndicatorSpace + maxWidth + 2 * borderWidth;
	    maxWidth = maxIndicatorSpace = 0;
	    lastColumnBreak = i;
	    y = borderWidth;
	}
	accelWidth = modifierWidth = indicatorSpace = 0;
	if (mePtr->type == SEPARATOR_ENTRY || mePtr->type == TEAROFF_ENTRY) {
	    mePtr->height = menuSeparatorHeight;
................................................................................
				/* Precalculated metrics for menu */
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawArrow)		/* Whether or not to draw the cascade arrow
				 * for cascade items. Only applies to
				 * Windows. */
{
}

#pragma mark Obsolete
 
/*
 *----------------------------------------------------------------------







|











|







 







|







 







|
<







769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
....
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
....
1621
1622
1623
1624
1625
1626
1627
1628

1629
1630
1631
1632
1633
1634
1635

    Drawable d = Tk_WindowId(root);
    NSView *rootview = TkMacOSXGetRootControl(d);
    NSWindow *win = [rootview window];
    int result;

    inPostMenu = 1;

    result = TkPreprocessMenu(menuPtr);
    if (result != TCL_OK) {
        inPostMenu = 0;
        return result;
    }

    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
    NSView *view = [win contentView];
    NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);

    frame.origin = [view convertPoint:
	    [win tkConvertPointFromScreen:frame.origin] fromView:nil];

    NSMenu *menu = (NSMenu *) menuPtr->platformData;
    NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc]
	    initTextCell:@"" pullsDown:NO];

    [popUpButtonCell setAltersStateOfSelectedItem:NO];
    [popUpButtonCell setMenu:menu];
................................................................................
		columnEntryPtr = menuPtr->entries[j];
		columnEntryPtr->indicatorSpace = maxIndicatorSpace;
		columnEntryPtr->width = maxIndicatorSpace + maxWidth
			+ 2 * activeBorderWidth;
		columnEntryPtr->x = x;
		columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN;
	    }
	    x += maxIndicatorSpace + maxWidth + 2 * activeBorderWidth;
	    maxWidth = maxIndicatorSpace = 0;
	    lastColumnBreak = i;
	    y = borderWidth;
	}
	accelWidth = modifierWidth = indicatorSpace = 0;
	if (mePtr->type == SEPARATOR_ENTRY || mePtr->type == TEAROFF_ENTRY) {
	    mePtr->height = menuSeparatorHeight;
................................................................................
				/* Precalculated metrics for menu */
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawArrow)		/* Whether or not to draw the cascade arrow
				 * for cascade items. */

{
}

#pragma mark Obsolete
 
/*
 *----------------------------------------------------------------------

Changes to macosx/tkMacOSXMouseEvent.c.

86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	_windowWithMouse = eventWindow;
	[_windowWithMouse retain];
    }

    /* Create an Xevent to add to the Tk queue. */
    NSPoint global, local = [theEvent locationInWindow];
    if (eventWindow) { /* local will be in window coordinates. */
	global = [eventWindow convertPointToScreen: local];
	local.y = [eventWindow frame].size.height - local.y;
	global.y = tkMacOSXZeroScreenHeight - global.y;
    } else { /* local will be in screen coordinates. */
	if (_windowWithMouse ) {
	    eventWindow = _windowWithMouse;
	    global = local;
	    local = [eventWindow convertPointFromScreen: local];
	    local.y = [eventWindow frame].size.height - local.y;
	    global.y = tkMacOSXZeroScreenHeight - global.y;
	} else { /* We have no window. Use the screen???*/
	    local.y = tkMacOSXZeroScreenHeight - local.y;
	    global = local;
	}
    }
................................................................................
	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *) w;
	    NSWindow *win = TkMacOSXDrawableWindow(w);

	    if (win) {
		NSPoint local;

		local = [win convertPointFromScreen:global];
		local.y = [win frame].size.height - local.y;
		if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
		    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
		    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
		}
		*win_x_return = local.x;
		*win_y_return = local.y;
................................................................................
    med.global.h = x;
    med.global.v = y;
    med.local = med.global;

    if (win) {
	NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);

	local = [win convertPointFromScreen:local];
	local.y = [win frame].size.height - local.y;
	if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
	    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
	    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
	}
	med.local.h = local.x;
	med.local.v = tkMacOSXZeroScreenHeight - local.y;







|






|







 







|







 







|







86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
...
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
	_windowWithMouse = eventWindow;
	[_windowWithMouse retain];
    }

    /* Create an Xevent to add to the Tk queue. */
    NSPoint global, local = [theEvent locationInWindow];
    if (eventWindow) { /* local will be in window coordinates. */
	global = [eventWindow tkConvertPointToScreen: local];
	local.y = [eventWindow frame].size.height - local.y;
	global.y = tkMacOSXZeroScreenHeight - global.y;
    } else { /* local will be in screen coordinates. */
	if (_windowWithMouse ) {
	    eventWindow = _windowWithMouse;
	    global = local;
	    local = [eventWindow tkConvertPointFromScreen: local];
	    local.y = [eventWindow frame].size.height - local.y;
	    global.y = tkMacOSXZeroScreenHeight - global.y;
	} else { /* We have no window. Use the screen???*/
	    local.y = tkMacOSXZeroScreenHeight - local.y;
	    global = local;
	}
    }
................................................................................
	if (getLocal) {
	    MacDrawable *macWin = (MacDrawable *) w;
	    NSWindow *win = TkMacOSXDrawableWindow(w);

	    if (win) {
		NSPoint local;

		local = [win tkConvertPointFromScreen:global];
		local.y = [win frame].size.height - local.y;
		if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
		    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
		    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
		}
		*win_x_return = local.x;
		*win_y_return = local.y;
................................................................................
    med.global.h = x;
    med.global.v = y;
    med.local = med.global;

    if (win) {
	NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);

	local = [win tkConvertPointFromScreen:local];
	local.y = [win frame].size.height - local.y;
	if (macWin->winPtr && macWin->winPtr->wmInfoPtr) {
	    local.x -= macWin->winPtr->wmInfoPtr->xInParent;
	    local.y -= macWin->winPtr->wmInfoPtr->yInParent;
	}
	med.local.h = local.x;
	med.local.v = tkMacOSXZeroScreenHeight - local.y;

Changes to macosx/tkMacOSXNotify.c.

27
28
29
30
31
32
33
34
35









































36
37
38
39
40




41
42
43




44
45
46




47


48
49















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




66




















67
68
69
70
71
72
73
74




75
76
77
78
79
80
81
..
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
...
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308

#define TSD_INIT() ThreadSpecificData *tsdPtr = \
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);

#pragma mark TKApplication(TKNotify)










































@interface NSApplication(TKNotify)
/* We need to declare this hidden method. */
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
@end





@implementation NSWindow(TKNotify)
- (id) tkDisplayIfNeeded




{
    if (![self isAutodisplay]) {
	[self displayIfNeeded];




    }


    return nil;
}















@end

@implementation TKApplication(TKNotify)
/* Display all windows each time an event is removed from the queue.*/
- (NSEvent *) nextEventMatchingMask: (NSUInteger) mask
	untilDate: (NSDate *) expiration inMode: (NSString *) mode
	dequeue: (BOOL) deqFlag
{
    NSEvent *event = [super nextEventMatchingMask:mask
					untilDate:expiration
					   inMode:mode
					  dequeue:deqFlag];
    /* Retain this event for later use. Must be released.*/
    [event retain];
    [NSApp makeWindowsPerform:@selector(tkDisplayIfNeeded) inOrder:NO];
    return event;




}





















/*
 * Call super then check the pasteboard.
 */
- (void) sendEvent: (NSEvent *) theEvent
{
    [super sendEvent:theEvent];
    [NSApp tkCheckPasteboard];




}
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

static NSString *
GetRunLoopMode(NSModalSession modalSession)
{
    NSString *runLoopMode = nil;

    if (modalSession) {
	runLoopMode = NSModalPanelRunLoopMode;
    } else if (TkMacOSXGetCapture()) {
................................................................................
				       untilDate:[NSDate distantPast]
				       inMode:GetRunLoopMode(TkMacOSXGetModalSession())
				       dequeue:NO];
	if (currentEvent) {
	    if (currentEvent.type > 0) {
		Tcl_SetMaxBlockTime(&zeroBlockTime);
	    }
	    [currentEvent release];
	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
#endif
		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];
		    } else {
			[NSApp sendEvent:currentEvent];
		    }
		}
		[currentEvent release];
	    } else {
		break;
	    }
	} while (1);
	/* Now we can unlock the pool. */
	[NSApp _unlockAutoreleasePool];
    }








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

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

>
>
|

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

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








>
>
>
>







 







|







 







<







 







<







27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77




78
79
80
81
82


83
84
85
86
87


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




115








116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
...
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
...
303
304
305
306
307
308
309

310
311
312
313
314
315
316
...
371
372
373
374
375
376
377

378
379
380
381
382
383
384

#define TSD_INIT() ThreadSpecificData *tsdPtr = \
	Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData))

static void TkMacOSXNotifyExitHandler(ClientData clientData);
static void TkMacOSXEventsSetupProc(ClientData clientData, int flags);
static void TkMacOSXEventsCheckProc(ClientData clientData, int flags);

#ifdef TK_MAC_DEBUG_EVENTS
static char* Tk_EventName[39] = {
    "",
    "",
    "KeyPress",		/*2*/
    "KeyRelease",      	/*3*/
    "ButtonPress",     	/*4*/
    "ButtonRelease",	/*5*/
    "MotionNotify",    	/*6*/
    "EnterNotify",     	/*7*/
    "LeaveNotify",     	/*8*/
    "FocusIn",		/*9*/
    "FocusOut",		/*10*/
    "KeymapNotify",    	/*11*/
    "Expose",		/*12*/
    "GraphicsExpose",	/*13*/
    "NoExpose",		/*14*/
    "VisibilityNotify",	/*15*/
    "CreateNotify",    	/*16*/
    "DestroyNotify",	/*17*/
    "UnmapNotify",     	/*18*/
    "MapNotify",       	/*19*/
    "MapRequest",      	/*20*/
    "ReparentNotify",	/*21*/
    "ConfigureNotify",	/*22*/
    "ConfigureRequest",	/*23*/
    "GravityNotify",	/*24*/
    "ResizeRequest",	/*25*/
    "CirculateNotify",	/*26*/
    "CirculateRequest",	/*27*/
    "PropertyNotify",	/*28*/
    "SelectionClear",	/*29*/
    "SelectionRequest",	/*30*/
    "SelectionNotify",	/*31*/
    "ColormapNotify",	/*32*/
    "ClientMessage",	/*33*/
    "MappingNotify",	/*34*/
    "VirtualEvent",    	/*35*/
    "ActivateNotify",	/*36*/
    "DeactivateNotify",	/*37*/
    "MouseWheelEvent"	/*38*/
};





static Tk_RestrictAction
InspectQueueRestrictProc(
     ClientData arg,
     XEvent *eventPtr)
{


    XVirtualEvent* ve = (XVirtualEvent*) eventPtr;
    const char *name;
    long serial = ve->serial;
    long time = eventPtr->xkey.time;
    


    if (eventPtr->type == VirtualEvent) {
	name = ve->name;
    } else {
	name = Tk_EventName[eventPtr->type];
    }
    fprintf(stderr, "    > %s;serial = %lu; time=%lu)\n",
	    name, serial, time);
    return TK_DEFER_EVENT;
}

/*
 * Debugging tool which prints the current Tcl queue.
 */

void DebugPrintQueue(void)
{
    ClientData oldArg;
    Tk_RestrictProc *oldProc;

    oldProc = Tk_RestrictEvents(InspectQueueRestrictProc, NULL, &oldArg);
    fprintf(stderr, "Current queue:\n");
    while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT)) {};
    Tk_RestrictEvents(oldProc, oldArg, &oldArg);
}
# endif

#pragma mark TKApplication(TKNotify)













@interface NSApplication(TKNotify)
/* We need to declare this hidden method. */
- (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event;
@end

@implementation TKApplication(TKNotify)
/*
 * Earlier versions of Tk would override nextEventMatchingMask here, adding a
 * call to displayIfNeeded on all windows after calling super. This would cause
 * windows to be redisplayed (if necessary) each time that an event was
 * received.  This was intended to replace Apple's default autoDisplay
 * mechanism, which the earlier versions of Tk would disable.  When autoDisplay
 * is set to the default value of YES, the Apple event loop will call
 * displayIfNeeded on all windows at the beginning of each iteration of their
 * event loop.  Since Tk does not call the Apple event loop, it was thought
 * that the autoDisplay behavior needed to be replicated.
 *
 * However, as of OSX 10.14 (Mojave) the autoDisplay property became
 * deprecated.  Luckily it turns out that, even though we don't ever start the
 * Apple event loop, the Apple window manager still calls displayIfNeeded on
 * all windows on a regular basis, perhaps each time the queue is empty.  So we
 * no longer, and perhaps never did need to set autoDisplay to NO, nor call
 * displayIfNeeded on our windows.  We can just leave all of that to the window
 * manager.
 */

/*
 * Call super then check the pasteboard.
 */
- (void) sendEvent: (NSEvent *) theEvent
{
    [super sendEvent:theEvent];
    [NSApp tkCheckPasteboard];
#ifdef TK_MAC_DEBUG_EVENTS
    fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]); 
    DebugPrintQueue();
#endif
}
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
................................................................................
 *
 * Side effects:
 *	None.
 *
 *----------------------------------------------------------------------
 */

NSString *
GetRunLoopMode(NSModalSession modalSession)
{
    NSString *runLoopMode = nil;

    if (modalSession) {
	runLoopMode = NSModalPanelRunLoopMode;
    } else if (TkMacOSXGetCapture()) {
................................................................................
				       untilDate:[NSDate distantPast]
				       inMode:GetRunLoopMode(TkMacOSXGetModalSession())
				       dequeue:NO];
	if (currentEvent) {
	    if (currentEvent.type > 0) {
		Tcl_SetMaxBlockTime(&zeroBlockTime);
	    }

	}
    }
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
#endif
		    if (modalSession) {
			[NSApp _modalSession:modalSession sendEvent:currentEvent];
		    } else {
			[NSApp sendEvent:currentEvent];
		    }
		}

	    } else {
		break;
	    }
	} while (1);
	/* Now we can unlock the pool. */
	[NSApp _unlockAutoreleasePool];
    }

Changes to macosx/tkMacOSXPrivate.h.

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
...
261
262
263
264
265
266
267



268
269
270



271
272
273
274
275
276
277
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;
    CGRect portBounds;
    int focusLocked;
} TkMacOSXDrawingContext;

/*
 * Variables internal to TkAqua.
 */

MODULE_SCOPE CGFloat tkMacOSXZeroScreenHeight;
................................................................................
			    int activeFlag);
MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
			    int x, int y, unsigned int width, unsigned int height);
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image,
			    int use_ximage_alpha);
MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
			    CGImageRef image, unsigned long imageForeground,
			    unsigned long imageBackground, CGRect imageBounds,
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    int useCG, TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
................................................................................
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems;
    NSWindow *_windowWithMouse;
    NSAutoreleasePool *_mainPool;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;



#endif
}
@property int poolLock;




@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
................................................................................

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
@end

@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
- (void) generateExposeEvents: (HIShapeRef) shape;
- (void) viewDidEndLiveResize;
- (void) tkToolbarButton: (id) sender;
- (BOOL) isOpaque;
- (BOOL) wantsDefaultClipping;
- (BOOL) acceptsFirstResponder;
- (void) keyDown: (NSEvent *) theEvent;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
@end

@interface NSWindow(TKWm)
- (NSPoint) convertPointToScreen:(NSPoint)point;
- (NSPoint) convertPointFromScreen:(NSPoint)point;
@end

#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;







<







 







|
<







 







>
>
>



>
>
>







 







|
<












|
|







127
128
129
130
131
132
133

134
135
136
137
138
139
140
...
185
186
187
188
189
190
191
192

193
194
195
196
197
198
199
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
...
329
330
331
332
333
334
335
336

337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
 */

typedef struct TkMacOSXDrawingContext {
    CGContextRef context;
    NSView *view;
    HIShapeRef clipRgn;
    CGRect portBounds;

} TkMacOSXDrawingContext;

/*
 * Variables internal to TkAqua.
 */

MODULE_SCOPE CGFloat tkMacOSXZeroScreenHeight;
................................................................................
			    int activeFlag);
MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
			    int x, int y, unsigned int width, unsigned int height);
MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image);

MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
			    CGImageRef image, unsigned long imageForeground,
			    unsigned long imageBackground, CGRect imageBounds,
			    CGRect srcBounds, CGRect dstBounds);
MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
			    int useCG, TkMacOSXDrawingContext *dcPtr);
MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
................................................................................
    NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
    NSArray *_defaultHelpMenuItems;
    NSWindow *_windowWithMouse;
    NSAutoreleasePool *_mainPool;
#ifdef __i386__
    /* The Objective C runtime used on i386 requires this. */
    int _poolLock;
    int _macMinorVersion;
    Bool _isDrawing;
    Bool _simulateDrawing;
#endif
}
@property int poolLock;
@property int macMinorVersion;
@property Bool isDrawing;
@property Bool simulateDrawing;

@end
@interface TKApplication(TKInit)
- (NSString *)tkFrameworkImagePath:(NSString*)image;
- (void)_resetAutoreleasePool;
- (void)_lockAutoreleasePool;
- (void)_unlockAutoreleasePool;
................................................................................

@interface TKContentView(TKKeyEvent)
- (void) deleteWorkingText;
@end

@interface TKContentView(TKWindowEvent)
- (void) drawRect: (NSRect) rect;
- (void) generateExposeEvents: (HIShapeRef) shape; 

- (void) tkToolbarButton: (id) sender;
- (BOOL) isOpaque;
- (BOOL) wantsDefaultClipping;
- (BOOL) acceptsFirstResponder;
- (void) keyDown: (NSEvent *) theEvent;
@end

VISIBILITY_HIDDEN
@interface TKWindow : NSWindow
@end

@interface NSWindow(TKWm)
- (NSPoint) tkConvertPointToScreen:(NSPoint)point;
- (NSPoint) tkConvertPointFromScreen:(NSPoint)point;
@end

#pragma mark NSMenu & NSMenuItem Utilities

@interface NSMenu(TKUtils)
+ (id)menuWithTitle:(NSString *)title;
+ (id)menuWithTitle:(NSString *)title menuItems:(NSArray *)items;

Changes to macosx/tkMacOSXScrlbr.c.

4
5
6
7
8
9
10

11
12
13
14
15
16
17
..
22
23
24
25
26
27
28
29
30
31
32
33
34
35




36
37
38
39

40
41
42
43
44
45



46








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

69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
...
107
108
109
110
111
112
113


114
115










116
117
118
119
120
121
122
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142

143
144
145
146
147
148
149
...
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
...
183
184
185
186
187
188
189
190
191
192


193
194
195
196
197
198
199
200
201
202
...
214
215
216
217
218
219
220

221
222
223
224
225
226
227













228
229
230
231
232
233
234
235
236



237
238

239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

273
274
275
276
277
278
279


280

281

282


283
284
285
286
287
288
289
290
291
292
293
294
295
296
...
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406


407
408
409
410
411
412
413
414
415

416
417
418


419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
...
442
443
444
445
446
447
448

449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
...
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527

528
529
530
531
532
533
534

535












536

537





538

















539







540


541
542

543


544
545

546
547
548
549
550
551
552
553
...
581
582
583
584
585
586
587
588
589
590
591
592
593









 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.

 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
#include "tkMacOSXPrivate.h"
................................................................................
/*
 * Minimum slider length, in pixels (designed to make sure that the slider is
 * always easy to grab with the mouse).
 */

#define MIN_SLIDER_LENGTH	5

/*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/
#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */





#define MOUNTAIN_LION_STYLE (NSAppKitVersionNumber < 1138)

/*
 * Declaration of Mac specific scrollbar structure.

 */

typedef struct MacScrollbar {
    TkScrollbar information;	 /* Generic scrollbar info. */
    GC troughGC;		/* For drawing trough. */
    GC copyGC;			/* Used for copying from pixmap onto screen. */



} MacScrollbar;









/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

................................................................................
    sizeof(Tk_ClassProcs),	/* size */
    NULL,					/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};


/*Information on scrollbar layout, metrics, and draw info.*/
typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;


static ScrollbarMetrics metrics[2] = {
    {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */
    {11, 40, 20, 10, 10, kControlSizeSmall},  /* kThemeScrollBarSmall  */
};
HIThemeTrackDrawInfo info = {
    .version = 0,
    .min = 0.0,
    .max = 100.0,
    .attributes = kThemeTrackShowThumb,
};


/*
 * Forward declarations for procedures defined later in this file:
 */

static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr);
static int ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr);
static void UpdateControlValues(TkScrollbar  *scrollPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
................................................................................
		   Tk_Window tkwin)
{

    MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));

    scrollPtr->troughGC = None;
    scrollPtr->copyGC = None;



    Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr);











    return (TkScrollbar *) scrollPtr;
}
 
/*
 *--------------------------------------------------------------
 *
................................................................................
 *	invoked as a do-when-idle handler, so it only runs when there's
 *	nothing else for the application to do.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Information appears on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
		    ClientData clientData)	/* Information about window. */
{
    register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;

    register Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
................................................................................
    }

    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
			    .ty = viewHeight};
    CGContextConcatCTM(dc.context, t);

    /*Draw Unix-style scroll trough to provide rect for native scrollbar.*/
    if (scrollPtr->highlightWidth != 0) {
    	GC fgGC, bgGC;

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
................................................................................
    		       Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
    		       scrollPtr->borderWidth, scrollPtr->relief);
    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
    		       scrollPtr->inset, scrollPtr->inset,
    		       Tk_Width(tkwin) - 2*scrollPtr->inset,
    		       Tk_Height(tkwin) - 2*scrollPtr->inset, 0, TK_RELIEF_FLAT);

    /*Update values and draw in native rect.*/
    UpdateControlValues(scrollPtr);
    if (MOUNTAIN_LION_STYLE) {


      HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationInverted);
    } else {
      HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal);
    }
    TkMacOSXRestoreDrawingContext(&dc);

    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
................................................................................
 * Side effects:
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */



 extern void
TkpComputeScrollbarGeometry(
			    register TkScrollbar *scrollPtr)
/* Scrollbar whose geometry may have
 * changed. */
{














    int variant, fieldLength;

    if (scrollPtr->highlightWidth < 0) {
    	scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    variant = ((scrollPtr->vertical ? Tk_Width(scrollPtr->tkwin) :
		Tk_Height(scrollPtr->tkwin)) - 2 * scrollPtr->inset
	       < metrics[0].width) ? 1 : 0;



    scrollPtr->arrowLength = (metrics[variant].topArrowHeight +
			      metrics[variant].bottomArrowHeight) / 2;

    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
		   : Tk_Width(scrollPtr->tkwin))
	- 2 * (scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
    	fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength * scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength * scrollPtr->lastFraction;

    /*
     * Adjust the slider so that some piece of it is always
     * displayed in the scrollbar and so that it has at least
     * a minimal width (so it can be grabbed with the mouse).
     */

    if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) {
    	scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth;
    }
    if (scrollPtr->sliderFirst < 0) {
    	scrollPtr->sliderFirst = 0;
    }
    if (scrollPtr->sliderLast < (scrollPtr->sliderFirst +
				 metrics[variant].minThumbHeight)) {
    	scrollPtr->sliderLast = scrollPtr->sliderFirst +
	    metrics[variant].minThumbHeight;
    }
    if (scrollPtr->sliderLast > fieldLength) {
    	scrollPtr->sliderLast = fieldLength;
    }

    scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset;



    /* Register the desired geometry for the window (leave enough space
     * for the two arrows plus a minimum-size slider, plus border around
     * the whole window, if any). Then arrange for the window to be
     * redisplayed.
     */

    if (scrollPtr->vertical) {


    	Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width + 2 * scrollPtr->inset, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) +  metrics[variant].minThumbHeight);

    } else {

    	Tk_GeometryRequest(scrollPtr->tkwin, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) + metrics[variant].minThumbHeight, scrollPtr->width + 2 * scrollPtr->inset);


    }
    Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);

}




/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyScrollbar --
 *
 *	Free data structures associated with the scrollbar control.
................................................................................

    if (macScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }

    macScrollPtr=NULL;
}

/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *
 *	This procedure is called after the generic code has finished
 *	processing configuration options, in order to configure platform
 *	specific options.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Configuration info may get changed.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
		      register TkScrollbar *scrollPtr)
/* Information about widget; may or may not
 * already have values for some fields. */
{

}

/*
 *--------------------------------------------------------------
 *
................................................................................
int
TkpScrollbarPosition(
    register TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{

  /*
   * Using code from tkUnixScrlbr.c because Unix scroll bindings are
   * driving the display at the script level. All the Mac scrollbar
   * has to do is re-draw itself.
   */

    int length, fieldlength, width, tmp;
    register const int inset = scrollPtr->inset;
    register const int arrowSize = scrollPtr->arrowLength + inset;

    if (scrollPtr->vertical) {
  	length = Tk_Height(scrollPtr->tkwin);
  	fieldlength = length - 2 * arrowSize;
  	width = Tk_Width(scrollPtr->tkwin);
    } else {
  	tmp = x;
  	x = y;
  	y = tmp;
  	length = Tk_Width(scrollPtr->tkwin);
  	fieldlength = length - 2 * arrowSize;
  	width = Tk_Height(scrollPtr->tkwin);
    }

    fieldlength = fieldlength < 0 ? 0 : fieldlength;

    if (x<inset || x>=width-inset || y<inset || y>=length-inset) {
  	return OUTSIDE;
    }

    /*
     * All of the calculations in this procedure mirror those in
     * TkpDisplayScrollbar. Be sure to keep the two consistent.


     */

    if (y < scrollPtr->sliderFirst) {
  	return TOP_GAP;
    }
    if (y < scrollPtr->sliderLast) {
  	return SLIDER;
    }
    if (y < fieldlength){

  	return BOTTOM_GAP;
    }
    if (y < fieldlength + arrowSize) {


  	return TOP_ARROW;
    }
    return BOTTOM_ARROW;

}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlValues --
 *
 *	This procedure updates the Macintosh scrollbar control to
 *	display the values defined by the Tk scrollbar. This is the
 *	key interface to the Mac-native * scrollbar; the Unix bindings
 *	drive scrolling in the Tk window and all the Mac scrollbar has
 *	to do is redraw itself.
 *
 * Results:
 *	None.
 *
 * Side effects:
................................................................................
 *--------------------------------------------------------------
 */

static void
UpdateControlValues(
		    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{

    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect  contrlRect;
    int variant;
    short width, height;

    NSView *view = TkMacOSXDrawableView(macWin);
    CGFloat viewHeight = [view bounds].size.height;
    NSRect frame;
    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
		       Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height;

   variant = contrlRect.size.width < metrics[0].width ? 1 : 0;

    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

    info.bounds = contrlRect;
    if (scrollPtr->vertical) {
      info.attributes &= ~kThemeTrackHorizontal;
    } else {
      info.attributes |= kThemeTrackHorizontal;
    }

    /*
     * Given the Tk parameters for the fractions of the start and end of the
     * thumb, the following calculation determines the location for the
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
................................................................................
     * the view area.
     */

    double maximum = 100,  factor;
    factor = RangeToFactor(maximum);
    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction)
	* factor;
    info.max =  MIN_SCROLLBAR_VALUE +
	factor - dViewSize;
    info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
      if (MOUNTAIN_LION_STYLE) {
	info.value = factor * scrollPtr->firstFraction;
      } else {
	info.value = info.max - factor * scrollPtr->firstFraction;
      }
    } else {
	 info.value =  MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction;
    }

    if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
       || height <= metrics[variant].minHeight) {
    	info.enableState = kThemeTrackHideTrack;
    } else {
    	info.enableState = kThemeTrackActive;
    	info.attributes = kThemeTrackShowThumb |  kThemeTrackThumbRgnIsNotGhost;
    }

}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarPress --
 *
 *	This procedure is invoked in response to <ButtonPress>, <ButtonRelease>,
 *      <EnterNotify>, and <LeaveNotify> events. Scrollbar appearance is modified.

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

static int
ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr)
{














  if (eventPtr->type == ButtonPress) {

    UpdateControlValues(scrollPtr);





    info.trackInfo.scrollbar.pressState = 1;

















  }







   if (eventPtr->type == EnterNotify) {


    info.trackInfo.scrollbar.pressState = 1;
  }

  if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) {


    info.trackInfo.scrollbar.pressState = 0;
  }

  return TCL_OK;
}



/*
 *--------------------------------------------------------------
 *
................................................................................
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:
    case ButtonRelease:
    case EnterNotify:
    case LeaveNotify:
    	ScrollbarPress(clientData, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
    }
}
















>







 







|






>
>
>
>
|


<
>



|


>
>
>

>
>
>
>
>
>
>
>







 







|






>
|
|
<
<
<
<
<
<
<




|



|







 







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







 







|









>







 







|







 







|

<
>
>
|

|







 







>
|

|
|
|


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


|


<
<
<
>
>
>
|
<
>

|
|

|

|
|


|
|
|


|
|


|

|
<
|
<


|

<
|
|

<
>
|
|
|
|


|
>
>
|
>

>
|
>
>


|
<
<
<
<







 







<
<









|





|







<
<







 







|
|
|
<


|

<



<






<



|
|
<




|
|
>
>


|

|
|

|
<
>

|
<
>
>

|
|
<









|







 







>




<











|




<
<





|

|

|







 







|

|

|
|

|


|



|
|

|
|







|


|
>





|

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







 







|





>
>
>
>
>
>
>
>
>
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
..
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
..
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
...
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
...
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
...
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
...
205
206
207
208
209
210
211
212
213

214
215
216
217
218
219
220
221
222
223
224
225
...
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270



271
272
273
274

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

298

299
300
301
302

303
304
305

306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325




326
327
328
329
330
331
332
...
348
349
350
351
352
353
354


355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377


378
379
380
381
382
383
384
...
400
401
402
403
404
405
406
407
408
409

410
411
412
413

414
415
416

417
418
419
420
421
422

423
424
425
426
427

428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443

444
445
446

447
448
449
450
451

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

483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498


499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
...
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
...
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
 *	This file implements the Macintosh specific portion of the scrollbar
 *	widget.
 *
 * Copyright (c) 1996 by Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC.
 * Copyright (c) 2018 Marc Culler
 * See the file "license.terms" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 */

#include "tkInt.h"
#include "tkScrollbar.h"
#include "tkMacOSXPrivate.h"
................................................................................
/*
 * Minimum slider length, in pixels (designed to make sure that the slider is
 * always easy to grab with the mouse).
 */

#define MIN_SLIDER_LENGTH	5

/*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling.*/
#ifdef __LP64__
#define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum))
#else
#define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum))
#endif /* __LP64__ */

/*
 * Apple reversed the scroll direction with the release of OSX 10.7 Lion.
 */

#define SNOW_LEOPARD_STYLE (NSAppKitVersionNumber < 1138)

/*

 * Declaration of an extended scrollbar structure with Mac specific additions.
 */

typedef struct MacScrollbar {
    TkScrollbar information;	/* Generic scrollbar info. */
    GC troughGC;		/* For drawing trough. */
    GC copyGC;			/* Used for copying from pixmap onto screen. */
    Bool buttonDown;            /* Is the mouse button down? */  
    Bool mouseOver;             /* Is the pointer over the scrollbar. */
    HIThemeTrackDrawInfo info;  /* Controls how the scrollbar is drawn. */
} MacScrollbar;

/* Used to initialize a MacScrollbar's info field. */
HIThemeTrackDrawInfo defaultInfo = {
    .version = 0,
    .min = 0.0,
    .max = 100.0,
    .attributes = kThemeTrackShowThumb,
};

/*
 * The class procedure table for the scrollbar widget. All fields except size
 * are left initialized to NULL, which should happen automatically since the
 * variable is declared at this scope.
 */

................................................................................
    sizeof(Tk_ClassProcs),	/* size */
    NULL,					/* worldChangedProc */
    NULL,					/* createProc */
    NULL					/* modalProc */
};


/* Information on scrollbar layout, metrics, and draw info.*/
typedef struct ScrollbarMetrics {
    SInt32 width, minThumbHeight;
    int minHeight, topArrowHeight, bottomArrowHeight;
    NSControlSize controlSize;
} ScrollbarMetrics;


static ScrollbarMetrics metrics = {
  15, 54, 26, 14, 14, kControlSizeNormal /* kThemeScrollBarMedium */







};


/*
 * Declarations of static functions defined later in this file:
 */

static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr);
static int ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr);
static void UpdateControlValues(TkScrollbar  *scrollPtr);

/*
 *----------------------------------------------------------------------
 *
 * TkpCreateScrollbar --
 *
................................................................................
		   Tk_Window tkwin)
{

    MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar));

    scrollPtr->troughGC = None;
    scrollPtr->copyGC = None;
    scrollPtr->info = defaultInfo;
    scrollPtr->buttonDown = false;
    

    Tk_CreateEventHandler(tkwin,
			  ExposureMask        |
			  StructureNotifyMask |
			  FocusChangeMask     |
			  ButtonPressMask     |
			  ButtonReleaseMask   |
			  EnterWindowMask     |
			  LeaveWindowMask     |
			  VisibilityChangeMask,
			  ScrollbarEventProc, scrollPtr);

    return (TkScrollbar *) scrollPtr;
}
 
/*
 *--------------------------------------------------------------
 *
................................................................................
 *	invoked as a do-when-idle handler, so it only runs when there's
 *	nothing else for the application to do.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Draws a scrollbar on the screen.
 *
 *--------------------------------------------------------------
 */

void
TkpDisplayScrollbar(
		    ClientData clientData)	/* Information about window. */
{
    register TkScrollbar *scrollPtr = (TkScrollbar *) clientData;
    MacScrollbar *msPtr = (MacScrollbar *) scrollPtr;
    register Tk_Window tkwin = scrollPtr->tkwin;
    TkWindow *winPtr = (TkWindow *) tkwin;
    TkMacOSXDrawingContext dc;

    scrollPtr->flags &= ~REDRAW_PENDING;

    if (tkwin == NULL || !Tk_IsMapped(tkwin)) {
................................................................................
    }

    CGFloat viewHeight = [view bounds].size.height;
    CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0,
			    .ty = viewHeight};
    CGContextConcatCTM(dc.context, t);

    /*Draw a 3D rectangle to provide a base for the native scrollbar.*/
    if (scrollPtr->highlightWidth != 0) {
    	GC fgGC, bgGC;

    	bgGC = Tk_GCForColor(scrollPtr->highlightBgColorPtr, (Pixmap) macWin);
    	if (scrollPtr->flags & GOT_FOCUS) {
    	    fgGC = Tk_GCForColor(scrollPtr->highlightColorPtr, (Pixmap) macWin);
    	} else {
................................................................................
    		       Tk_Height(tkwin) - 2*scrollPtr->highlightWidth,
    		       scrollPtr->borderWidth, scrollPtr->relief);
    Tk_Fill3DRectangle(tkwin, (Pixmap) macWin, scrollPtr->bgBorder,
    		       scrollPtr->inset, scrollPtr->inset,
    		       Tk_Width(tkwin) - 2*scrollPtr->inset,
    		       Tk_Height(tkwin) - 2*scrollPtr->inset, 0, TK_RELIEF_FLAT);

    /* Update values and then draw the native scrollbar over the rectangle.*/
    UpdateControlValues(scrollPtr);


    if (SNOW_LEOPARD_STYLE) {
	HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationInverted);
    } else {
	HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationNormal);
    }
    TkMacOSXRestoreDrawingContext(&dc);

    scrollPtr->flags &= ~REDRAW_PENDING;
}

/*
................................................................................
 * Side effects:
 *	The scrollbar will be displayed differently.
 *
 *----------------------------------------------------------------------
 */



extern void
TkpComputeScrollbarGeometry(
    register TkScrollbar *scrollPtr)
                           /* Scrollbar whose geometry may have
                           * changed. */
{

   /*
    * The code below is borrowed from tkUnixScrlbr.c but has been adjusted to
    * account for some differences between macOS and X11. The Unix scrollbar
    * has an arrow button on each end.  On macOS 10.6 (Snow Leopard) the
    * scrollbars by default have both arrow buttons at the bottom or right.
    * (There is a preferences setting to use the Unix layout, but we are not
    * supporting that!)  On more recent versions of macOS there are no arrow
    * buttons at all. The case of no arrow buttons can be handled as a special
    * case of having both buttons at the end, but where scrollPtr->arrowLength
    * happens to be zero.  To adjust for having both arrows at the same end we
    * shift the scrollbar up by the arrowLength.
    */

    int fieldLength;

    if (scrollPtr->highlightWidth < 0) {
       scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;



    if ([NSApp macMinorVersion] == 6) {
      scrollPtr->arrowLength = scrollPtr->width;
    } else {
      scrollPtr->arrowLength = 0;

    }
    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
           : Tk_Width(scrollPtr->tkwin))
           - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
       fieldLength = 0;
    }
    scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction;
    scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction;

    /*
     * Adjust the slider so that some piece of it is always displayed in the
     * scrollbar and so that it has at least a minimal width (so it can be
     * grabbed with the mouse).
     */

    if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) {
       scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH;
    }
    if (scrollPtr->sliderFirst < 0) {
       scrollPtr->sliderFirst = 0;
    }
    if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) {

       scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH;

    }
    if (scrollPtr->sliderLast > fieldLength) {
       scrollPtr->sliderLast = fieldLength;
    }

    scrollPtr->sliderFirst += -scrollPtr->arrowLength + scrollPtr->inset;
    scrollPtr->sliderLast += scrollPtr->inset;


    /*
     * Register the desired geometry for the window. Leave enough space for the
     * two arrows, if there are any arrows, plus a minimum-size slider, plus
     * border around the whole window, if any. Then arrange for the window to
     * be redisplayed.
     */

      if (scrollPtr->vertical) {
       Tk_GeometryRequest(scrollPtr->tkwin,
              scrollPtr->width + 2*scrollPtr->inset,
              2*(scrollPtr->arrowLength + scrollPtr->borderWidth
              + scrollPtr->inset) + metrics.minThumbHeight);
    } else {
       Tk_GeometryRequest(scrollPtr->tkwin,
              2*(scrollPtr->arrowLength + scrollPtr->borderWidth
              + scrollPtr->inset) + metrics.minThumbHeight,
              scrollPtr->width + 2*scrollPtr->inset);
    }
    Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset);
}





/*
 *----------------------------------------------------------------------
 *
 * TkpDestroyScrollbar --
 *
 *	Free data structures associated with the scrollbar control.
................................................................................

    if (macScrollPtr->troughGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->troughGC);
    }
    if (macScrollPtr->copyGC != None) {
	Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC);
    }


}

/*
 *----------------------------------------------------------------------
 *
 * TkpConfigureScrollbar --
 *
 *	This procedure is called after the generic code has finished
 *	processing configuration options, in order to configure platform
 *	specific options.  There are no such option on the Mac, however.
 *
 * Results:
 *	None.
 *
 * Side effects:
 *	Currently, none.
 *
 *----------------------------------------------------------------------
 */

void
TkpConfigureScrollbar(
		      register TkScrollbar *scrollPtr)


{

}

/*
 *--------------------------------------------------------------
 *
................................................................................
int
TkpScrollbarPosition(
    register TkScrollbar *scrollPtr,
				/* Scrollbar widget record. */
    int x, int y)		/* Coordinates within scrollPtr's window. */
{

   /*
   * The code below is borrowed from tkUnixScrlbr.c and needs no adjustment
   * since it does not involve the arrow buttons.

   */

    int length, width, tmp;
    register const int inset = scrollPtr->inset;


    if (scrollPtr->vertical) {
  	length = Tk_Height(scrollPtr->tkwin);

  	width = Tk_Width(scrollPtr->tkwin);
    } else {
  	tmp = x;
  	x = y;
  	y = tmp;
  	length = Tk_Width(scrollPtr->tkwin);

  	width = Tk_Height(scrollPtr->tkwin);
    }

    if (x < inset || x >= width - inset ||
	y < inset || y >= length - inset) {

  	return OUTSIDE;
    }

    /*
     * Here we assume that the scrollbar is layed out with both arrow buttons
     * at the bottom (or right).  Except on 10.6, however, the arrows do not
     * actually exist, i.e. the arrowLength is 0.  These are the same
     * assumptions which are being made in TkpComputeScrollbarGeometry.
     */

    if (y < scrollPtr->sliderFirst + scrollPtr->arrowLength) {
  	return TOP_GAP;
      }
      if (y < scrollPtr->sliderLast) {
  	return SLIDER;
      }

      if (y < length - (2*scrollPtr->arrowLength + inset)) {
  	return BOTTOM_GAP;
      }

      /* On systems newer than 10.6 we have already returned. */
      if (y < length - (scrollPtr->arrowLength + inset)) {
  	return TOP_ARROW;
      }
      return BOTTOM_ARROW;

}

/*
 *--------------------------------------------------------------
 *
 * UpdateControlValues --
 *
 *	This procedure updates the Macintosh scrollbar control to
 *	display the values defined by the Tk scrollbar. This is the
 *	key interface to the Mac-native  scrollbar; the Unix bindings
 *	drive scrolling in the Tk window and all the Mac scrollbar has
 *	to do is redraw itself.
 *
 * Results:
 *	None.
 *
 * Side effects:
................................................................................
 *--------------------------------------------------------------
 */

static void
UpdateControlValues(
		    TkScrollbar *scrollPtr)		/* Scrollbar data struct. */
{
    MacScrollbar *msPtr = (MacScrollbar *)scrollPtr;
    Tk_Window tkwin = scrollPtr->tkwin;
    MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin);
    double dViewSize;
    HIRect  contrlRect;

    short width, height;

    NSView *view = TkMacOSXDrawableView(macWin);
    CGFloat viewHeight = [view bounds].size.height;
    NSRect frame;
    frame = NSMakeRect(macWin->xOff, macWin->yOff, Tk_Width(tkwin),
		       Tk_Height(tkwin));
    frame = NSInsetRect(frame, scrollPtr->inset, scrollPtr->inset);
    frame.origin.y = viewHeight - (frame.origin.y + frame.size.height);

    contrlRect = NSRectToCGRect(frame);
    msPtr->info.bounds = contrlRect;

    width = contrlRect.size.width;
    height = contrlRect.size.height;



    /*
     * Ensure we set scrollbar control bounds only once all size adjustments
     * have been computed.
     */

    msPtr->info.bounds = contrlRect;
    if (scrollPtr->vertical) {
      msPtr->info.attributes &= ~kThemeTrackHorizontal;
    } else {
      msPtr->info.attributes |= kThemeTrackHorizontal;
    }

    /*
     * Given the Tk parameters for the fractions of the start and end of the
     * thumb, the following calculation determines the location for the
     * Macintosh thumb. The Aqua scroll control works as follows. The
     * scrollbar's value is the position of the left (or top) side of the view
................................................................................
     * the view area.
     */

    double maximum = 100,  factor;
    factor = RangeToFactor(maximum);
    dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction)
	* factor;
    msPtr->info.max =  MIN_SCROLLBAR_VALUE +
	factor - dViewSize;
    msPtr->info.trackInfo.scrollbar.viewsize = dViewSize;
    if (scrollPtr->vertical) {
      if (SNOW_LEOPARD_STYLE) {
	msPtr->info.value = factor * scrollPtr->firstFraction;
      } else {
	msPtr->info.value = msPtr->info.max - factor * scrollPtr->firstFraction;
      }
    } else {
	 msPtr->info.value =  MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction;
    }

    if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0)
       || height <= metrics.minHeight) {
    	msPtr->info.enableState = kThemeTrackHideTrack;
    } else {
        msPtr->info.enableState = kThemeTrackActive;
    	msPtr->info.attributes = kThemeTrackShowThumb |  kThemeTrackThumbRgnIsNotGhost;
    }

}

/*
 *--------------------------------------------------------------
 *
 * ScrollbarEvent --
 *
 *	This procedure is invoked in response to <ButtonPress>, <ButtonRelease>,
 *      <EnterNotify>, and <LeaveNotify> events. The Scrollbar appearance is
 *      modified for each event.
 *
 *--------------------------------------------------------------
 */

static int
ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr)
{
    MacScrollbar *msPtr = (MacScrollbar *)scrollPtr;
    
    /* The pressState does not indicate whether the moused button was
     * pressed at some location in the Scrollbar.  Rather, it indicates
     * that the scrollbar should appear as if it were pressed in that
     * location. The standard Mac behavior is that once the button is
     * pressed inside the Scrollbar the appearance should not change until
     * the button is released, even if the mouse moves outside of the
     * scrollbar.  However, if the mouse lies over the scrollbar but the
     * button is not pressed then the appearance should be the same as if
     * the button had been pressed on the slider, i.e. kThemeThumbPressed.
     * See the file Appearance.r, or HIToolbox.bridgesupport on 10.14.
     */

    if (eventPtr->type == ButtonPress) {
	msPtr->buttonDown = true;
	UpdateControlValues(scrollPtr);
	int where = TkpScrollbarPosition(scrollPtr,
					 eventPtr->xbutton.x,
					 eventPtr->xbutton.y);
	switch(where) {
	case OUTSIDE:
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	    break;
	case TOP_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeTopTrackPressed;
	    break;
	case SLIDER:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	    break;
	case BOTTOM_GAP:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomTrackPressed;
	    break;
	case TOP_ARROW:
	    /* This looks wrong and the docs say it is wrong but it works. */
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeTopInsideArrowPressed;
	    break;
	case BOTTOM_ARROW:
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomOutsideArrowPressed;
	    break;
	}
    }
    if (eventPtr->type == ButtonRelease) {
	msPtr->buttonDown = false;
	if (!msPtr->mouseOver) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }
    if (eventPtr->type == EnterNotify) {
	msPtr->mouseOver = true;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed;
	}
    }
    if (eventPtr->type == LeaveNotify) {
	msPtr->mouseOver = false;
	if (!msPtr->buttonDown) {
	    msPtr->info.trackInfo.scrollbar.pressState = 0;
	}
    }
    return TCL_OK;
}



/*
 *--------------------------------------------------------------
 *
................................................................................
    case DeactivateNotify:
	TkScrollbarEventuallyRedraw(scrollPtr);
	break;
    case ButtonPress:
    case ButtonRelease:
    case EnterNotify:
    case LeaveNotify:
    	ScrollbarEvent(clientData, eventPtr);
	break;
    default:
	TkScrollbarEventProc(clientData, eventPtr);
    }
}

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXSubwindows.c.

201
202
203
204
205
206
207







208
209
210
211
212
213
214
...
291
292
293
294
295
296
297

298
299
300
301

302
303
304
305
306
307
308
...
376
377
378
379
380
381
382

383
384
385
386

387
388
389
390
391
392
393
...
466
467
468
469
470
471
472

473
474
475
476
477
478
479
480

481
482
483
484
485
486
487
...
565
566
567
568
569
570
571

572
573
574
575
576
577
578
...
599
600
601
602
603
604
605

606
607
608
609
610
611
612
613
...
870
871
872
873
874
875
876

877
878
879
880
881
882
883
....
1130
1131
1132
1133
1134
1135
1136

1137
1138
1139
1140
1141
1142
1143
....
1310
1311
1312
1313
1314
1315
1316

1317
1318
1319
1320
1321
1322
1323
     */

    event.xany.send_event = False;
    event.xany.display = display;
    event.xvisibility.type = VisibilityNotify;
    event.xvisibility.state = VisibilityUnobscured;
    NotifyVisibility(macWin->winPtr, &event);







}
 
/*
 *----------------------------------------------------------------------
 *
 * NotifyVisibility --
 *
................................................................................

	event.xunmap.type = UnmapNotify;
	event.xunmap.window = window;
	event.xunmap.event = window;
	event.xunmap.from_configure = false;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    } else {

	/*
	 * Rebuild the visRgn clip region for the parent so it will be allowed
	 * to draw in the space from which this subwindow was removed.
	 */

	if (parentPtr && parentPtr->privatePtr->visRgn) {
	    TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(parentPtr->privatePtr),
					 parentPtr->privatePtr->visRgn);
	}
	TkMacOSXInvalClipRgns((Tk_Window) parentPtr);
	TkMacOSXUpdateClipRgn(parentPtr);
    }
................................................................................
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;
	if (w) {

	    /* We explicitly convert everything to doubles so we don't get
	     * surprised (again) by what happens when you do arithmetic with
	     * unsigned ints.
	     */

	    CGFloat X = (CGFloat)x;
	    CGFloat Y = (CGFloat)y;
	    CGFloat Width = (CGFloat)width;
	    CGFloat Height = (CGFloat)height;
	    CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent;
	    CGFloat YOff = (CGFloat)macWin->winPtr->wmInfoPtr->yInParent;
	    NSRect r = NSMakeRect(X + XOff,
................................................................................

    if (Tk_IsEmbedded(macWin->winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr);

	if (contWinPtr) {
	    macParent = contWinPtr->privatePtr;
	} else {

	    /*
	     * Here we should handle out of process embedding. At this point,
	     * we are assuming that the changes.x,y is not maintained, if you
	     * need the info get it from Tk_GetRootCoords, and that the
	     * toplevel sits at 0,0 when it is drawn.
	     */
	}
    } else {

	/*
	 * TODO: update all xOff & yOffs
	 */

	macParent = macWin->winPtr->parentPtr->privatePtr;
	parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
    }
................................................................................
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {

	/*
	 * TODO: this should generate damage
	 */
    }
}
 
#if 0
................................................................................
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {

	/*
	 * TODO: this should generate damage
	 */
    }
}
#endif
 
/*
................................................................................
		if (!HIShapeIsEmpty(diffRgn)) {
		    macWin->visRgn = HIShapeCreateCopy(rgn);
		}
		CFRelease(diffRgn);
	    }
	    CFRelease(rgn);
	} else {

	    /*
	     * An unmapped window has empty clip regions to prevent any
	     * (erroneous) drawing into it or its children from becoming
	     * visible. [Bug 940117]
	     */

	    if (!Tk_IsTopLevel(winPtr)) {
................................................................................
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetRootControl(
    Drawable drawable)
{

    /*
     * will probably need to fix this up for embedding
     */

    return TkMacOSXDrawableView((MacDrawable *) drawable);
}
 
................................................................................
    TkWindow *winPtr,
    int deltaX,
    int deltaY)
{
    TkWindow *childPtr;

    if (winPtr->privatePtr == NULL) {

	/*
	 * We haven't called Tk_MakeWindowExist for this window yet. The offset
	 * information will be postponed and calulated at that time. (This will
	 * usually only happen when a mapped parent is being moved but has
	 * child windows that have yet to be mapped.)
	 */








>
>
>
>
>
>
>







 







>




>







 







>




>







 







>








>







 







>







 







>
|







 







>







 







>







 







>







201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
...
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
...
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
...
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
...
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
...
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
...
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
....
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
....
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
     */

    event.xany.send_event = False;
    event.xany.display = display;
    event.xvisibility.type = VisibilityNotify;
    event.xvisibility.state = VisibilityUnobscured;
    NotifyVisibility(macWin->winPtr, &event);

    /*
     * Make sure that subwindows get displayed.
     */

    GenerateConfigureNotify(macWin->winPtr, 1);

}
 
/*
 *----------------------------------------------------------------------
 *
 * NotifyVisibility --
 *
................................................................................

	event.xunmap.type = UnmapNotify;
	event.xunmap.window = window;
	event.xunmap.event = window;
	event.xunmap.from_configure = false;
	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
    } else {

	/*
	 * Rebuild the visRgn clip region for the parent so it will be allowed
	 * to draw in the space from which this subwindow was removed.
	 */

	if (parentPtr && parentPtr->privatePtr->visRgn) {
	    TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(parentPtr->privatePtr),
					 parentPtr->privatePtr->visRgn);
	}
	TkMacOSXInvalClipRgns((Tk_Window) parentPtr);
	TkMacOSXUpdateClipRgn(parentPtr);
    }
................................................................................
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	NSWindow *w = macWin->winPtr->wmInfoPtr->window;
	if (w) {

	    /* We explicitly convert everything to doubles so we don't get
	     * surprised (again) by what happens when you do arithmetic with
	     * unsigned ints.
	     */

	    CGFloat X = (CGFloat)x;
	    CGFloat Y = (CGFloat)y;
	    CGFloat Width = (CGFloat)width;
	    CGFloat Height = (CGFloat)height;
	    CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent;
	    CGFloat YOff = (CGFloat)macWin->winPtr->wmInfoPtr->yInParent;
	    NSRect r = NSMakeRect(X + XOff,
................................................................................

    if (Tk_IsEmbedded(macWin->winPtr)) {
	TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr);

	if (contWinPtr) {
	    macParent = contWinPtr->privatePtr;
	} else {

	    /*
	     * Here we should handle out of process embedding. At this point,
	     * we are assuming that the changes.x,y is not maintained, if you
	     * need the info get it from Tk_GetRootCoords, and that the
	     * toplevel sits at 0,0 when it is drawn.
	     */
	}
    } else {

	/*
	 * TODO: update all xOff & yOffs
	 */

	macParent = macWin->winPtr->parentPtr->privatePtr;
	parentBorderwidth = macWin->winPtr->parentPtr->changes.border_width;
    }
................................................................................
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Above, NULL);
    } else {

	/*
	 * TODO: this should generate damage
	 */
    }
}
 
#if 0
................................................................................
{
    MacDrawable *macWin = (MacDrawable *) window;

    display->request++;
    if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) {
	TkWmRestackToplevel(macWin->winPtr, Below, NULL);
    } else {

        /*
	 * TODO: this should generate damage
	 */
    }
}
#endif
 
/*
................................................................................
		if (!HIShapeIsEmpty(diffRgn)) {
		    macWin->visRgn = HIShapeCreateCopy(rgn);
		}
		CFRelease(diffRgn);
	    }
	    CFRelease(rgn);
	} else {

	    /*
	     * An unmapped window has empty clip regions to prevent any
	     * (erroneous) drawing into it or its children from becoming
	     * visible. [Bug 940117]
	     */

	    if (!Tk_IsTopLevel(winPtr)) {
................................................................................
 *----------------------------------------------------------------------
 */

void *
TkMacOSXGetRootControl(
    Drawable drawable)
{

    /*
     * will probably need to fix this up for embedding
     */

    return TkMacOSXDrawableView((MacDrawable *) drawable);
}
 
................................................................................
    TkWindow *winPtr,
    int deltaX,
    int deltaY)
{
    TkWindow *childPtr;

    if (winPtr->privatePtr == NULL) {

	/*
	 * We haven't called Tk_MakeWindowExist for this window yet. The offset
	 * information will be postponed and calulated at that time. (This will
	 * usually only happen when a mapped parent is being moved but has
	 * child windows that have yet to be mapped.)
	 */

Changes to macosx/tkMacOSXTest.c.

75
76
77
78
79
80
81





























82
83
84
85
86
87
88
89
    int objc,				/* Not used. */
    Tcl_Obj *const objv[])			/* Not used. */
{
    Debugger();
    return TCL_OK;
}
 





























/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */







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








75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
    int objc,				/* Not used. */
    Tcl_Obj *const objv[])			/* Not used. */
{
    Debugger();
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkTestSimulateDrawing --
 *
 *      A test widget display procedure which records calls can use this to
 *      avoid duplicate calls which would occur due to fact that no valid
 *      graphics context is available to the idle task which is running the
 *      display proc.  Note that no actual drawing to the screen will take
 *      place when this flag is set.  This is just a wrapper for the NSApp
 *      property.
 *
 *
 * Results:
 *      Calls to low level drawing routines will return without actually
 *	drawing anything to the screen.
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */
MODULE_SCOPE void
TkTestSimulateDrawing(Bool yesno) {
    [NSApp setSimulateDrawing:yesno];
}

 

/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to macosx/tkMacOSXWindowEvent.c.

64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
..
92
93
94
95
96
97
98

99
100
101
102
103
104
105
...
115
116
117
118
119
120
121

122
123
124
125
126
127
128
...
169
170
171
172
173
174
175

176
177
178
179
180
181
182
...
209
210
211
212
213
214
215


216
217
218
219
220
221
222
...
232
233
234
235
236
237
238

239
240
241
242
243
244
245
...
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
...
292
293
294
295
296
297
298

























299
300
301
302
303
304
305
306
307
308
309
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
...
575
576
577
578
579
580
581

582
583
584
585

586
587
588
589
590
591
592
593
594
595
596

597
598
599
600

601
602
603
604
605
606
607
...
792
793
794
795
796
797
798
799
800
801


802
803
804
805
806
807

















808
809
810
811
812






813
814
815
816
817

818
819
820
821
822
823
824
825
826
827



828
829
830
831
832
833
834
835
836







837
838
839
840
841

842
843
844
845

846
847
848
849
850
851
852
853
854
855
856

857


858
859
860
861
862
863

864


865
866
867
868

869


870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898


899

900
901
902
903
904
905
906


907
908
909
910

911


912


913


914
915
916
917
918
919





920
921
922
923
924













925

926
927
928
929
930

931
932
933
934
935
936
937
...
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967

- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    BOOL movedOnly = [[notification name]
	    isEqualToString:NSWindowDidMoveNotification];

    if (movedOnly) {
	/* constraining to screen after move not needed with AppKit */
    }

    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	WmInfo *wmPtr = winPtr->wmInfoPtr;
	NSRect bounds = [w frame];
................................................................................
	if (!movedOnly && (winPtr->changes.width != bounds.size.width ||
		winPtr->changes.height !=  bounds.size.height)) {
	    width = bounds.size.width - wmPtr->xInParent;
	    height = bounds.size.height - wmPtr->yInParent;
	    flags |= TK_SIZE_CHANGED;
	}
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {

	    /*
	     * Propagate geometry changes immediately.
	     */

	    flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
	}
	TkGenWMConfigureEvent((Tk_Window) winPtr, x, y, width, height, flags);
................................................................................
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
	Tk_MapWindow((Tk_Window) winPtr);
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {

	    /*
	     * Process all Tk events generated by Tk_MapWindow().
	     */

	    while (Tcl_ServiceEvent(0)) {}
	    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}

................................................................................
    /*
     * If necessary, TkGenWMDestroyEvent() handles [close]ing the window,
     * so can always return NO from -windowShouldClose: for a Tk window.
     */

    return (winPtr ? NO : YES);
}


#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}
................................................................................
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window) winPtr);
    }
}


#endif /* TK_MAC_DEBUG_NOTIFICATIONS */

- (void) _setupWindowNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
................................................................................
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
    observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
#endif
#undef observe

}
@end
 
#pragma mark TKApplication(TKApplicationEvent)

@implementation TKApplication(TKApplicationEvent)

................................................................................
}

- (void) applicationDeactivate: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    TkSuspendClipboard();
}

- (void) applicationShowHide: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
................................................................................
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *

























 * GenerateUpdates --
 *
 *	Given a Macintosh update region and a Tk window this function geneates
 *	a X Expose event for the window if it is within the update region. The
 *	function will then recursivly have each damaged window generate Expose
 *	events for its child windows.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
................................................................................
    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
    event.xexpose.width = damageBounds.size.width;
    event.xexpose.height = damageBounds.size.height;
    event.xexpose.count = 0;
    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

#ifdef TK_MAC_DEBUG_DRAWING
    NSLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
	event.xexpose.y, event.xexpose.width, event.xexpose.height);
#endif

    /*
     * Generate updates for the children of this window
     */

................................................................................
	    wmPtr->x = x;
	    wmPtr->y = y;
	    wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
	}
	if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) &&
		((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
	    if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {

		/*
		 * Don't set external width, since the user didn't change it
		 * from what the widgets asked for.
		 */

	    } else if (wmPtr->gridWin != NULL) {
		wmPtr->width = wmPtr->reqGridWidth
			+ (width - winPtr->reqWidth)/wmPtr->widthInc;
		if (wmPtr->width < 0) {
		    wmPtr->width = 0;
		}
	    } else {
		wmPtr->width = width;
	    }

	    if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) {

		/*
		 * Don't set external height, since the user didn't change it
		 * from what the widgets asked for.
		 */

	    } else if (wmPtr->gridWin != NULL) {
		wmPtr->height = wmPtr->reqGridHeight
			+ (height - winPtr->reqHeight)/wmPtr->heightInc;
		if (wmPtr->height < 0) {
		    wmPtr->height = 0;
		}
	    } else {
................................................................................
@implementation TKContentView(TKWindowEvent)

- (void) drawRect: (NSRect) rect
{
    const NSRect *rectsBeingDrawn;
    NSInteger rectsBeingDrawnCount;

    [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];

#ifdef TK_MAC_DEBUG_DRAWING


    TKLog(@"-[%@(%p) %s%@]", [self class], self, _cmd, NSStringFromRect(rect));
    [[NSColor colorWithDeviceRed:0.0 green:1.0 blue:0.0 alpha:.1] setFill];
    NSRectFillListUsingOperation(rectsBeingDrawn, rectsBeingDrawnCount,
	    NSCompositeSourceOver);
#endif


















    CGFloat height = [self bounds].size.height;
    HIMutableShapeRef drawShape = HIShapeCreateMutable();

    while (rectsBeingDrawnCount--) {
	CGRect r = NSRectToCGRect(*rectsBeingDrawn++);






	r.origin.y = height - (r.origin.y + r.size.height);
	HIShapeUnionWithRect(drawShape, &r);
    }
    if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) {
	[self generateExposeEvents:(HIShapeRef)drawShape];

    } else {
	[self performSelectorOnMainThread:@selector(generateExposeEvents:)
		withObject:(id)drawShape waitUntilDone:NO
		modes:[NSArray arrayWithObjects:NSRunLoopCommonModes,

			NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode,
			nil]];
    }

    CFRelease(drawShape);



}

-(void) setFrameSize: (NSSize)newsize
{
    [super setFrameSize: newsize];
    if ([self inLiveResize]) {
	NSWindow *w = [self window];
	TkWindow *winPtr = TkMacOSXGetTkWindow(w);
	Tk_Window tkwin = (Tk_Window) winPtr;







	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	ClientData oldArg;
    	Tk_RestrictProc *oldProc;


	/* This can be called from outside the Tk event loop.
	 * Since it calls Tcl_DoOneEvent, we need to make sure we
	 * don't clobber the AutoreleasePool set up by the caller.
	 */

	[NSApp _lockAutoreleasePool];

	/*
	 * Try to prevent flickers and flashes.
	 */
	[w disableFlushWindow];
	NSDisableScreenUpdates();

	/* Disable Tk drawing until the window has been completely configured.*/
	TkMacOSXSetDrawingEnabled(winPtr, 0);


	 /* Generate and handle a ConfigureNotify event for the new size.*/


	TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height,
			      TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
    	oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg);
	while (Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT)) {}
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);


	/* Now that Tk has configured all subwindows we can create the clip regions. */


	TkMacOSXSetDrawingEnabled(winPtr, 1);
	TkMacOSXInvalClipRgns(tkwin);
	TkMacOSXUpdateClipRgn(winPtr);


	 /* Finally, generate and process expose events to redraw the window. */


	HIRect bounds = NSRectToCGRect([self bounds]);
	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
	[self generateExposeEvents: shape];
	while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {}
	[w enableFlushWindow];
	[w flushWindowIfNeeded];
	NSEnableScreenUpdates();
	[NSApp _unlockAutoreleasePool];
    }
}

/*
 * As insurance against bugs that might cause layout glitches during a live
 * resize, we redraw the window one more time at the end of the resize
 * operation.
 */

- (void)viewDidEndLiveResize
{
    HIRect bounds = NSRectToCGRect([self bounds]);
    HIShapeRef shape = HIShapeCreateWithRect(&bounds);
    [super viewDidEndLiveResize];
    [self generateExposeEvents: shape];
}

/* Core method of this class: generates expose events for redrawing.  If the
 * Tcl_ServiceMode is set to TCL_SERVICE_ALL then the expose events will be
 * immediately removed from the Tcl event loop and processed.  Typically, they
 * should be queued, however.


 */

- (void) generateExposeEvents: (HIShapeRef) shape
{
    unsigned long serial;
    CGRect updateBounds;
    int updatesNeeded;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);



    if (!winPtr) {
		return;
    }


    /* Generate Tk Expose events. */


    HIShapeGetBounds(shape, &updateBounds);


    /* All of these events will share the same serial number. */


    serial = LastKnownRequestProcessed(Tk_Display(winPtr));
    updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr);

    /* Process the Expose events if the service mode is TCL_SERVICE_ALL */
    if (updatesNeeded && Tcl_GetServiceMode() == TCL_SERVICE_ALL) {
	ClientData oldArg;





    	Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc,
						     UINT2PTR(serial), &oldArg);
    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);
    }













}


/*
 * This is no-op on 10.7 and up because Apple has removed this widget,
 * but we are leaving it here for backwards compatibility.
 */

- (void) tkToolbarButton: (id) sender
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
................................................................................
    event.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

- (BOOL) isOpaque
{
    NSWindow *w = [self window];

      return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) ||
    	    ![w isOpaque]) ? NO : YES);
}

- (BOOL) wantsDefaultClipping
{
    return NO;







|
<
<
<
<







 







>







 







>







 







>







 







>
>







 







>







 







<







 







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



|







 







|







 







>




>











>




>







 







<
<

>
>
|
<
<
<


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





>
>
>
>
>
>



<
|
>
|
<
<
<

<
<
<
<
<
>
>
>





<
|
|
|
>
>
>
>
>
>
>





>
|



>



|

<
<

<


>
|
>
>



<


>
|
>
>




>
|
>
>



|
|
|
|
<




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

>






<
>
>

|


>
|
>
>

>
>
|
>
>



<
|
<
>
>
>
>
>
|
<
|

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





>







 







<







64
65
66
67
68
69
70
71




72
73
74
75
76
77
78
..
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
...
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
...
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
...
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
...
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
...
254
255
256
257
258
259
260

261
262
263
264
265
266
267
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
...
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
...
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
...
822
823
824
825
826
827
828


829
830
831
832



833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865

866
867
868



869





870
871
872
873
874
875
876
877

878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903


904

905
906
907
908
909
910
911
912
913

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

935
936
937
938













939

940

941
942
943
944
945
946
947
948
949
950

951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969

970

971
972
973
974
975
976

977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
....
1023
1024
1025
1026
1027
1028
1029

1030
1031
1032
1033
1034
1035
1036

- (void) windowBoundsChanged: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
    BOOL movedOnly = [[notification name]
			 isEqualToString:NSWindowDidMoveNotification];





    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	WmInfo *wmPtr = winPtr->wmInfoPtr;
	NSRect bounds = [w frame];
................................................................................
	if (!movedOnly && (winPtr->changes.width != bounds.size.width ||
		winPtr->changes.height !=  bounds.size.height)) {
	    width = bounds.size.width - wmPtr->xInParent;
	    height = bounds.size.height - wmPtr->yInParent;
	    flags |= TK_SIZE_CHANGED;
	}
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {

	    /*
	     * Propagate geometry changes immediately.
	     */

	    flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY;
	}
	TkGenWMConfigureEvent((Tk_Window) winPtr, x, y, width, height, flags);
................................................................................
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	winPtr->wmInfoPtr->hints.initial_state =
		TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState;
	Tk_MapWindow((Tk_Window) winPtr);
	if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) {

	    /*
	     * Process all Tk events generated by Tk_MapWindow().
	     */

	    while (Tcl_ServiceEvent(0)) {}
	    while (Tcl_DoOneEvent(TCL_IDLE_EVENTS|TCL_DONT_WAIT)) {}

................................................................................
    /*
     * If necessary, TkGenWMDestroyEvent() handles [close]ing the window,
     * so can always return NO from -windowShouldClose: for a Tk window.
     */

    return (winPtr ? NO : YES);
}


#ifdef TK_MAC_DEBUG_NOTIFICATIONS

- (void) windowDragStart: (NSNotification *) notification
{
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
}
................................................................................
    NSWindow *w = [notification object];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);

    if (winPtr) {
	//Tk_UnmapWindow((Tk_Window) winPtr);
    }
}


#endif /* TK_MAC_DEBUG_NOTIFICATIONS */

- (void) _setupWindowNotifications
{
    NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];

#define observe(n, s) \
................................................................................
    observe(NSWindowWillStartLiveResizeNotification, windowLiveResize:);
    observe(NSWindowDidEndLiveResizeNotification, windowLiveResize:);
    observe(NSWindowWillOrderOnScreenNotification, windowMapped:);
    observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:);
    observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:);
#endif
#undef observe

}
@end
 
#pragma mark TKApplication(TKApplicationEvent)

@implementation TKApplication(TKApplicationEvent)

................................................................................
}

- (void) applicationDeactivate: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif

}

- (void) applicationShowHide: (NSNotification *) notification
{
#ifdef TK_MAC_DEBUG_NOTIFICATIONS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
#endif
................................................................................
@end

#pragma mark -
 
/*
 *----------------------------------------------------------------------
 *
 * TkpAppIsDrawing --
 *
 *      A widget display procedure can call this to determine whether it
 *      is being run inside of the drawRect method.  This is needed for
 *      some tests, especially of the Text widget, which record data in
 *      a global Tcl variable and assume that display procedures will be
 *      run in a predictable sequence as Tcl idle tasks.
 *
 * Results:
 *	True only while running the drawRect method of a TKContentView;
 *
 * Side effects:
 *	None
 *
 *----------------------------------------------------------------------
 */
MODULE_SCOPE Bool
TkpAppIsDrawing(void) {
    return [NSApp isDrawing];
}

 
/*
 *----------------------------------------------------------------------
 *
 * GenerateUpdates --
 *
 *	Given a Macintosh update region and a Tk window this function geneates
 *	an X Expose event for the window if it meets the update region. The
 *	function will then recursivly have each damaged window generate Expose
 *	events for its child windows.
 *
 * Results:
 *	True if event(s) are generated - false otherwise.
 *
 * Side effects:
................................................................................
    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
    event.xexpose.width = damageBounds.size.width;
    event.xexpose.height = damageBounds.size.height;
    event.xexpose.count = 0;
    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);

#ifdef TK_MAC_DEBUG_DRAWING
    TKLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
	event.xexpose.y, event.xexpose.width, event.xexpose.height);
#endif

    /*
     * Generate updates for the children of this window
     */

................................................................................
	    wmPtr->x = x;
	    wmPtr->y = y;
	    wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y);
	}
	if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) &&
		((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) {
	    if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) {

		/*
		 * Don't set external width, since the user didn't change it
		 * from what the widgets asked for.
		 */

	    } else if (wmPtr->gridWin != NULL) {
		wmPtr->width = wmPtr->reqGridWidth
			+ (width - winPtr->reqWidth)/wmPtr->widthInc;
		if (wmPtr->width < 0) {
		    wmPtr->width = 0;
		}
	    } else {
		wmPtr->width = width;
	    }

	    if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) {

		/*
		 * Don't set external height, since the user didn't change it
		 * from what the widgets asked for.
		 */

	    } else if (wmPtr->gridWin != NULL) {
		wmPtr->height = wmPtr->reqGridHeight
			+ (height - winPtr->reqHeight)/wmPtr->heightInc;
		if (wmPtr->height < 0) {
		    wmPtr->height = 0;
		}
	    } else {
................................................................................
@implementation TKContentView(TKWindowEvent)

- (void) drawRect: (NSRect) rect
{
    const NSRect *rectsBeingDrawn;
    NSInteger rectsBeingDrawnCount;



#ifdef TK_MAC_DEBUG_DRAWING
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
    if (winPtr) fprintf(stderr, "drawRect: drawing %s\n",
			Tk_PathName(winPtr));



#endif

    if ([NSApp simulateDrawing]) {
    	return;
    }

    /*
     * We do not allow recursive calls to drawRect, but we only log
     * them on OSX > 10.13, where they should never happen.
     */

    if ([NSApp isDrawing] && [NSApp macMinorVersion] > 13) {
	TKLog(@"WARNING: a recursive call to drawRect was aborted.");
	return;
    }

    [NSApp setIsDrawing: YES];

    [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount];
    CGFloat height = [self bounds].size.height;
    HIMutableShapeRef drawShape = HIShapeCreateMutable();

    while (rectsBeingDrawnCount--) {
	CGRect r = NSRectToCGRect(*rectsBeingDrawn++);

#ifdef TK_MAC_DEBUG_DRAWING
	fprintf(stderr, "drawRect: %dx%d@(%d,%d)\n", (int)r.size.width,
	       (int)r.size.height, (int)r.origin.x, (int)r.origin.y);
#endif

	r.origin.y = height - (r.origin.y + r.size.height);
	HIShapeUnionWithRect(drawShape, &r);
    }

    [self generateExposeEvents:(HIShapeRef)drawShape];
    CFRelease(drawShape);
    [NSApp setIsDrawing: NO];









#ifdef TK_MAC_DEBUG_DRAWING
    fprintf(stderr, "drawRect: done.\n");
#endif
}

-(void) setFrameSize: (NSSize)newsize
{
    [super setFrameSize: newsize];

    NSWindow *w = [self window];
    TkWindow *winPtr = TkMacOSXGetTkWindow(w);
    Tk_Window tkwin = (Tk_Window) winPtr;
    if (winPtr) {
	/* On OSX versions below 10.14 setFrame calls drawRect.
	 * On 10.14 it does its own drawing.
	 */
	if ([NSApp macMinorVersion] > 13) {
	    [NSApp setIsDrawing:YES];
	}
	unsigned int width = (unsigned int)newsize.width;
	unsigned int height=(unsigned int)newsize.height;
	ClientData oldArg;
    	Tk_RestrictProc *oldProc;

	/*
	 * This can be called from outside the Tk event loop.
	 * Since it calls Tcl_DoOneEvent, we need to make sure we
	 * don't clobber the AutoreleasePool set up by the caller.
	 */

	[NSApp _lockAutoreleasePool];

	/*
	 * Disable Tk drawing until the window has been completely configured.
	 */




	TkMacOSXSetDrawingEnabled(winPtr, 0);

	 /*
	  * Generate and handle a ConfigureNotify event for the new size.
	  */

	TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height,
			      TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY);
    	oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg);

    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);

	/*
	 * Now that Tk has configured all subwindows, create the clip regions.
	 */

	TkMacOSXSetDrawingEnabled(winPtr, 1);
	TkMacOSXInvalClipRgns(tkwin);
	TkMacOSXUpdateClipRgn(winPtr);

	 /*
	  * Finally, generate and process expose events to redraw the window.
	  */

	HIRect bounds = NSRectToCGRect([self bounds]);
	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
	[self generateExposeEvents: shape];
	[w displayIfNeeded];
	if ([NSApp macMinorVersion] > 13) {
	    [NSApp setIsDrawing:NO];
	}

    }
}

/*













 * Core method of this class: generates expose events for redrawing.  The

 * expose events are immediately removed from the Tcl event loop and processed.

 * This causes drawing procedures to be scheduled as idle events.  Then all
 * pending idle events are processed so the drawing will actually take place.
 */

- (void) generateExposeEvents: (HIShapeRef) shape
{
    unsigned long serial;
    CGRect updateBounds;
    int updatesNeeded;
    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);

    ClientData oldArg;
    Tk_RestrictProc *oldProc;
    if (!winPtr) {
	return;
    }

    /*
     * Generate Tk Expose events.
     */

    HIShapeGetBounds(shape, &updateBounds);

    /*
     * All of these events will share the same serial number.
     */

    serial = LastKnownRequestProcessed(Tk_Display(winPtr));
    updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr);


    if (updatesNeeded) {


	/*
	 * First process all of the Expose events.
	 */

    	oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg);

    	while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {};
    	Tk_RestrictEvents(oldProc, oldArg, &oldArg);

	/*
	 * Starting with OSX 10.14, which uses Core Animation to draw windows,
	 * all drawing must be done within the drawRect method.  (The CGContext
	 * which draws to the backing CALayer is created by the NSView before
	 * calling drawRect, and destroyed when drawRect returns.  Drawing done
	 * with the current CGContext outside of the drawRect method has no
	 * effect.)
	 *
	 * Fortunately, Tk schedules all drawing to be done while Tcl is idle.
	 * So we can do the drawing by processing all of the idle events that
	 * were created when the expose events were processed.
	 */
	while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {}
    }
} 

/*
 * This is no-op on 10.7 and up because Apple has removed this widget,
 * but we are leaving it here for backwards compatibility.
 */

- (void) tkToolbarButton: (id) sender
{
#ifdef TK_MAC_DEBUG_EVENTS
    TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd);
#endif
    XVirtualEvent event;
    int x, y;
................................................................................
    event.name = Tk_GetUid("ToolbarButton");
    Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
}

- (BOOL) isOpaque
{
    NSWindow *w = [self window];

      return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) ||
    	    ![w isOpaque]) ? NO : YES);
}

- (BOOL) wantsDefaultClipping
{
    return NO;

Changes to macosx/tkMacOSXWm.c.

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















234
235
236
237
238
239
240
...
368
369
370
371
372
373
374
375

376
377
378




379




380
381
382
383





384
385

386


387
388











389
390
391
392
393
394
395
...
406
407
408
409
410
411
412

413
414
415
416
417
418
419
420
...
562
563
564
565
566
567
568
569
570
571
572
573

574
575
576
577
578
579
580
581
582
583
584
...
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
...
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
....
3426
3427
3428
3429
3430
3431
3432








3433
3434
3435
3436
3437
3438
3439
3440
3441
3442
3443
3444
3445
3446
3447
3448
3449
3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462

3463
3464
3465
3466
3467
3468
3469
....
4247
4248
4249
4250
4251
4252
4253
4254
4255
4256
4257
4258
4259
4260
4261
4262

4263
4264
4265
4266
4267
4268
4269
....
5608
5609
5610
5611
5612
5613
5614
5615
5616
5617
5618
5619
5620
5621
5622
5623
5624
5625
5626
5627
5628
5629
5630
5631
5632
5633
5634
5635
....
5637
5638
5639
5640
5641
5642
5643
5644
5645
5646
5647



























5648
5649
5650
5651
5652
5653
5654
....
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275




6276
6277
6278
6279
6280
6281
6282
6283
....
6453
6454
6455
6456
6457
6458
6459
6460
6461
6462
6463
6464
6465
6466
6467
6468
6469
6470
6471
6472
....
6473
6474
6475
6476
6477
6478
6479
6480
6481
6482
6483
6484
6485

6486
6487
6488
6489
6490
6491
6492
6493
6494
6495
6496
6497
6498
6499



6500
6501

6502
6503





6504
6505
6506








6507















6508
6509
6510
6511
6512



6513
6514
6515


6516
6517
6518
6519
6520
6521

6522
6523
6524
6525





6526
6527

6528
6529
6530
6531
6532
6533
6534
6535
6536
6537
6538

/*
 * Conversion of coordinates between window and screen.
 */

@implementation NSWindow(TKWm)
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) convertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) convertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
#else
- (NSPoint) convertPointToScreen: (NSPoint) point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectToScreen:pointrect].origin;
}
- (NSPoint) convertPointFromScreen: (NSPoint)point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectFromScreen:pointrect].origin;
}
#endif
















@end

#pragma mark -


/*
 * Forward declarations for procedures defined in this file:
................................................................................
{
    id _i1, _i2;
}
@end


@implementation TKWindow: NSWindow
#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12

/*
 * Override automatic fullscreen button on >10.12 because system fullscreen API
 * confuses Tk window geometry.




 */




- (void)toggleFullScreen:(id)sender
{
    if ([self isZoomed]) {
	TkMacOSXZoomToplevel(self, inZoomIn);





    } else {
	TkMacOSXZoomToplevel(self, inZoomOut);

    }


}
#endif











@end

@implementation TKWindow(TKWm)

- (BOOL) canBecomeKeyWindow
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
................................................................................
{
    id result = [super retain];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 1){

	printf("Retained <%s>. Count is: %lu\n", title, [self retainCount]);
    }
    return result;
}

- (id) autorelease
{
    id result = [super autorelease];
................................................................................

static TkWindow*
FrontWindowAtPoint(
    int x, int y)
{
    NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
    NSArray *windows = [NSApp orderedWindows];
    TkWindow *front = NULL;

    for (NSWindow *w in windows) {
	    if (w && NSMouseInRect(p, [w frame], NO)) {
		front = TkMacOSXGetTkWindow(w);

		break;
	    }
	}
    return front;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
................................................................................

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Create the underlying Mac window for this Tk window.
	 */

	if (!TkMacOSXHostToplevelExists(winPtr)) {
	    TkMacOSXMakeRealWindowExist(winPtr);
................................................................................
     */

    XMapWindow(winPtr->display, winPtr->window);

    /*Add window to Window menu.*/
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    [win setExcludedFromWindowsMenu:NO];

}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *
................................................................................
	    ckfree(wmPtr->masterWindowName);
	}
	wmPtr->masterWindowName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {
	    return TCL_ERROR;
	}








	Tk_MakeWindowExist(master);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = ((TkWindow *) master)->wmInfoPtr;

	/* Under some circumstances, wmPtr2 is NULL here */
	if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a master: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	if ((TkWindow *) master == winPtr) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" its own master", Tk_PathName(winPtr)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
	    return TCL_ERROR;
	}

	wmPtr->master = Tk_WindowId(master);
	masterWindowName = Tcl_GetStringFromObj(objv[3], &length);

	if (wmPtr->masterWindowName != NULL) {
	    ckfree(wmPtr->masterWindowName);
	}
	wmPtr->masterWindowName = ckalloc(length+1);
	strcpy(wmPtr->masterWindowName, masterWindowName);
    }
    ApplyMasterOverrideChanges(winPtr, NULL);
................................................................................

	    /*
	     * The container window is in the same application. Query its
	     * coordinates.
	     */

	    winPtr = otherPtr;

	    /*
	     * Remember to offset by the container window here, since at the
	     * end of this if branch, we will pop out to the container's
	     * parent...
	     */

	    x += winPtr->changes.x + winPtr->changes.border_width;
	    y += winPtr->changes.y + winPtr->changes.border_width;

	}
	winPtr = winPtr->parentPtr;
    }
    *xPtr = x;
    *yPtr = y;
}
 
................................................................................
    NSWindow *window = [[winClass alloc] initWithContentRect:contentRect
	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
    if (!window) {
    	Tcl_Panic("couldn't allocate new Mac window");
    }
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];
    [window setColorSpace:[NSColorSpace deviceRGBColorSpace]];
    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];
    [window setAutodisplay:NO];
    if (styleMask & NSUtilityWindowMask) {
	[(NSPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
	 * Workaround for [Bug 2824538]: Texured windows are draggable
	 *                               from opaque content.
	 */
	[window setMovableByWindowBackground:NO];
    }

    [window setDocumentEdited:NO];
    wmPtr->window = window;
................................................................................
    TkMacOSXApplyWindowAttributes(winPtr, window);

    NSRect geometry = InitialWindowBounds(winPtr, window);
    geometry.size.width +=  structureRect.size.width;
    geometry.size.height += structureRect.size.height;
    geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y +
	    geometry.size.height);
    [window setFrame:geometry display:NO];
    TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
    macWin->flags |= TK_HOST_EXISTS;
}



























 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRegisterOffScreenWindow --
 *
 *	This function adds the passed in Off Screen Port to the hash table
................................................................................
	if ((changedAttributes & (kWindowResizableAttribute |
		kWindowFullZoomAttribute)) || initial) {
	    [macWindow setShowsResizeIndicator:
		    !!(newAttributes & kWindowResizableAttribute)];
	    [[macWindow standardWindowButton:NSWindowZoomButton]
		    setEnabled:(newAttributes & kWindowResizableAttribute) &&
		    (newAttributes & kWindowFullZoomAttribute)];
	    if (newAttributes & kWindowResizableAttribute) {
		wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE |
			WM_HEIGHT_NOT_RESIZABLE);
	    } else {
		wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE |




			WM_HEIGHT_NOT_RESIZABLE);
	    }
	    WmUpdateGeom(wmPtr, winPtr);
	}
	if ((changedAttributes & kWindowToolbarButtonAttribute) || initial) {
	    [macWindow setShowsToolbarButton:
		    !!(newAttributes & kWindowToolbarButtonAttribute)];
	    if ((newAttributes & kWindowToolbarButtonAttribute) &&
................................................................................
TkMacOSXMakeFullscreen(
    TkWindow *winPtr,
    NSWindow *window,
    int fullscreen,
    Tcl_Interp *interp)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN);
    static unsigned long prevMask = 0, prevPres = 0;

    if (fullscreen) {
	int screenWidth =  WidthOfScreen(Tk_Screen(winPtr));
	int screenHeight = HeightOfScreen(Tk_Screen(winPtr));

	/*
	 * Check max width and height if set by the user.
	 */

	if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth)
		|| (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) {
................................................................................
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set fullscreen attribute for \"%s\": max"
			" width/height is too small", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "FULLSCREEN",
			"CONSTRAINT_FAILURE", NULL);
	    }
	    result = TCL_ERROR;
	    wmPtr->flags &= ~WM_FULLSCREEN;
	} else {
	    Tk_UnmapWindow((Tk_Window) winPtr);
	    NSRect bounds = [window contentRectForFrameRect:[window frame]];
	    NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight);


	    if (!NSEqualRects(bounds, screenBounds) && !wasFullscreen) {
		wmPtr->configX = wmPtr->x;
		wmPtr->configY = wmPtr->y;
		wmPtr->configAttributes = wmPtr->attributes;
		wmPtr->attributes &= ~kWindowResizableAttribute;
		ApplyWindowAttributeFlagChanges(winPtr, window,
			wmPtr->configAttributes, wmPtr->flags, 1, 0);
		wmPtr->flags |= WM_SYNC_PENDING;
		[window setFrame:[window frameRectForContentRect:
			screenBounds] display:YES];
		wmPtr->flags &= ~WM_SYNC_PENDING;
	    }
	    wmPtr->flags |= WM_FULLSCREEN;



	}


	prevMask = [window styleMask];
	prevPres = [NSApp presentationOptions];





	[window setStyleMask: NSBorderlessWindowMask];
	[NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock
	                          | NSApplicationPresentationAutoHideMenuBar];








	Tk_MapWindow((Tk_Window) winPtr);















    } else {
	wmPtr->flags &= ~WM_FULLSCREEN;
	[NSApp setPresentationOptions: prevPres];
	[window setStyleMask: prevMask];
    }




    if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) {
	Tk_UnmapWindow((Tk_Window) winPtr);


	UInt64 oldAttributes = wmPtr->attributes;
	NSRect bounds = NSMakeRect(wmPtr->configX, tkMacOSXZeroScreenHeight -
		(wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight),
		wmPtr->xInParent + wmPtr->configWidth,
		wmPtr->yInParent + wmPtr->configHeight);


	wmPtr->attributes |= wmPtr->configAttributes &
		kWindowResizableAttribute;
	ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes,
		wmPtr->flags, 1, 0);





	wmPtr->flags |= WM_SYNC_PENDING;
	[window setFrame:[window frameRectForContentRect:bounds] display:YES];

	wmPtr->flags &= ~WM_SYNC_PENDING;
       Tk_MapWindow((Tk_Window) winPtr);
    }
    return result;
}
 
/*
 *----------------------------------------------------------------------
 *
 * GetMinSize --
 *







|



|




|







|









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







 







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


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







 







>
|







 







|


<
|
>
|
|
|
|







 







<







 







<







 







>
>
>
>
>
>
>
>
|









|
<









|






|
|
>







 







<
<
<
<
<
<
<
<
<
>







 







<





<






|







 







|



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







 







|
|
<

|
>
>
>
>
|







 







|
|


<
<







 







<

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

<
<
<
|
>
>
>

<
<
>
>

<
<
<
<
<
>




>
>
>
>
>

<
>

<

|







200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
...
383
384
385
386
387
388
389

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


405
406
407
408
409
410

411
412
413
414
415

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
...
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
...
601
602
603
604
605
606
607
608
609
610

611
612
613
614
615
616
617
618
619
620
621
622
623
...
737
738
739
740
741
742
743

744
745
746
747
748
749
750
...
808
809
810
811
812
813
814

815
816
817
818
819
820
821
....
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479
3480
3481
3482
3483
3484
3485
3486
3487
3488

3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
3513
3514
....
4292
4293
4294
4295
4296
4297
4298









4299
4300
4301
4302
4303
4304
4305
4306
....
5645
5646
5647
5648
5649
5650
5651

5652
5653
5654
5655
5656

5657
5658
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669
5670
....
5672
5673
5674
5675
5676
5677
5678
5679
5680
5681
5682
5683
5684
5685
5686
5687
5688
5689
5690
5691
5692
5693
5694
5695
5696
5697
5698
5699
5700
5701
5702
5703
5704
5705
5706
5707
5708
5709
5710
5711
5712
5713
5714
5715
5716
....
6326
6327
6328
6329
6330
6331
6332
6333
6334

6335
6336
6337
6338
6339
6340
6341
6342
6343
6344
6345
6346
6347
6348
....
6518
6519
6520
6521
6522
6523
6524
6525
6526
6527
6528


6529
6530
6531
6532
6533
6534
6535
....
6536
6537
6538
6539
6540
6541
6542

6543




6544
6545











6546

6547
6548
6549
6550

6551
6552
6553
6554
6555
6556
6557
6558
6559
6560
6561
6562
6563
6564
6565
6566
6567
6568
6569
6570
6571
6572
6573
6574
6575
6576
6577
6578
6579
6580
6581
6582
6583
6584
6585
6586



6587
6588
6589
6590
6591


6592
6593
6594





6595
6596
6597
6598
6599
6600
6601
6602
6603
6604
6605

6606
6607

6608
6609
6610
6611
6612
6613
6614
6615
6616

/*
 * Conversion of coordinates between window and screen.
 */

@implementation NSWindow(TKWm)
#if MAC_OS_X_VERSION_MIN_REQUIRED < 1070
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    return [self convertBaseToScreen:point];
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    return [self convertScreenToBase:point];
}
#else
- (NSPoint) tkConvertPointToScreen: (NSPoint) point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectToScreen:pointrect].origin;
}
- (NSPoint) tkConvertPointFromScreen: (NSPoint)point
{
    NSRect pointrect;
    pointrect.origin = point;
    pointrect.size.width = 0;
    pointrect.size.height = 0;
    return [self convertRectFromScreen:pointrect].origin;
}
#endif

- (NSSize)windowWillResize:(NSWindow *)sender
                    toSize:(NSSize)frameSize
{
    NSRect currentFrame = [sender frame];
    TkWindow *winPtr = TkMacOSXGetTkWindow(sender);
    if (winPtr) {
	if (winPtr->wmInfoPtr->flags & WM_WIDTH_NOT_RESIZABLE) {
	    frameSize.width = currentFrame.size.width;
	}
	if (winPtr->wmInfoPtr->flags & WM_HEIGHT_NOT_RESIZABLE) {
	    frameSize.height = currentFrame.size.height;
	}
    }
    return frameSize;
}
@end

#pragma mark -


/*
 * Forward declarations for procedures defined in this file:
................................................................................
{
    id _i1, _i2;
}
@end


@implementation TKWindow: NSWindow


/* Custom fullscreen implementation on 10.13 and above. On older versions of
 * macOS dating back to 10.7, the NSWindow fullscreen API was opt-in, requiring
 * explicit calls to toggleFullScreen. On 10.13, the API became implicit,
 * applying to all NSWindows unless they were marked non-resizable; this caused
 * issues with Tk, which was not aware of changes in screen geometry. Here we
 * override the toggleFullScreen call to hook directly into Tk's own fullscreen
 * API, allowing Tk to function smoothly with the Mac's fullscreen button.
*/

NSStatusItem *exitFullScreen;


- (void)toggleFullScreen:(id)sender
{


  TkWindow *winPtr = TkMacOSXGetTkWindow(self);
  Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);
  if ([NSApp macMinorVersion] > 12) {
      if (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask) {
	  TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
      } else {

	  TkMacOSXMakeFullscreen(winPtr, self, 1, interp);
      }
  } else {
      TKLog (@"toggleFullScreen is ignored by Tk on OSX versions < 10.13");
  }

}

-(void)restoreOldScreen:(id)sender {

  TkWindow *winPtr = TkMacOSXGetTkWindow(self);
  Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr);

  TkMacOSXMakeFullscreen(winPtr, self, 0, interp);
  [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen];
}

@end

@implementation TKWindow(TKWm)

- (BOOL) canBecomeKeyWindow
{
    TkWindow *winPtr = TkMacOSXGetTkWindow(self);
................................................................................
{
    id result = [super retain];
    const char *title = [[self title] UTF8String];
    if (title == nil) {
	title = "unnamed window";
    }
    if (DEBUG_ZOMBIES > 1){
	fprintf(stderr, "Retained <%s>. Count is: %lu\n",
		title, [self retainCount]);
    }
    return result;
}

- (id) autorelease
{
    id result = [super autorelease];
................................................................................

static TkWindow*
FrontWindowAtPoint(
    int x, int y)
{
    NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y);
    NSArray *windows = [NSApp orderedWindows];
    TkWindow *winPtr = NULL;

    for (NSWindow *w in windows) {

	winPtr = TkMacOSXGetTkWindow(w);
	if (winPtr && NSMouseInRect(p, [w frame], NO)) {
	    break;
	}
    }
    return winPtr;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmNewWindow --
 *
................................................................................

void
TkWmMapWindow(
    TkWindow *winPtr)		/* Top-level window that's about to be
				 * mapped. */
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;

    if (wmPtr->flags & WM_NEVER_MAPPED) {
	/*
	 * Create the underlying Mac window for this Tk window.
	 */

	if (!TkMacOSXHostToplevelExists(winPtr)) {
	    TkMacOSXMakeRealWindowExist(winPtr);
................................................................................
     */

    XMapWindow(winPtr->display, winPtr->window);

    /*Add window to Window menu.*/
    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
    [win setExcludedFromWindowsMenu:NO];

}
 
/*
 *----------------------------------------------------------------------
 *
 * TkWmUnmapWindow --
 *
................................................................................
	    ckfree(wmPtr->masterWindowName);
	}
	wmPtr->masterWindowName = NULL;
    } else {
	if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) {
	    return TCL_ERROR;
	}
	TkWindow* masterPtr = (TkWindow*) master;
	while (!Tk_TopWinHierarchy(masterPtr)) {
            /*
             * Ensure that the master window is actually a Tk toplevel.
             */

            masterPtr = masterPtr->parentPtr;
        }
	Tk_MakeWindowExist((Tk_Window)masterPtr);

	if (wmPtr->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a transient: it is an icon for %s",
		    Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	wmPtr2 = masterPtr->wmInfoPtr;

	/* Under some circumstances, wmPtr2 is NULL here */
	if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" a master: it is an icon for %s",
		    Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL);
	    return TCL_ERROR;
	}

	if (masterPtr == winPtr) {
	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
		    "can't make \"%s\" its own master", Tk_PathName(winPtr)));
	    Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL);
	    return TCL_ERROR;
	}

	wmPtr->master = Tk_WindowId(masterPtr);
	masterWindowName = masterPtr->pathName;
	length = strlen(masterWindowName);
	if (wmPtr->masterWindowName != NULL) {
	    ckfree(wmPtr->masterWindowName);
	}
	wmPtr->masterWindowName = ckalloc(length+1);
	strcpy(wmPtr->masterWindowName, masterWindowName);
    }
    ApplyMasterOverrideChanges(winPtr, NULL);
................................................................................

	    /*
	     * The container window is in the same application. Query its
	     * coordinates.
	     */

	    winPtr = otherPtr;









            continue;
	}
	winPtr = winPtr->parentPtr;
    }
    *xPtr = x;
    *yPtr = y;
}
 
................................................................................
    NSWindow *window = [[winClass alloc] initWithContentRect:contentRect
	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
    if (!window) {
    	Tcl_Panic("couldn't allocate new Mac window");
    }
    TKContentView *contentView = [[TKContentView alloc]
				     initWithFrame:NSZeroRect];

    [window setContentView:contentView];
    [contentView release];
    [window setDelegate:NSApp];
    [window setAcceptsMouseMovedEvents:YES];
    [window setReleasedWhenClosed:NO];

    if (styleMask & NSUtilityWindowMask) {
	[(NSPanel*)window setFloatingPanel:YES];
    }
    if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) &&
	    !(styleMask & NSDocModalWindowMask)) {
        /*
	 * Workaround for [Bug 2824538]: Textured windows are draggable
	 *                               from opaque content.
	 */
	[window setMovableByWindowBackground:NO];
    }

    [window setDocumentEdited:NO];
    wmPtr->window = window;
................................................................................
    TkMacOSXApplyWindowAttributes(winPtr, window);

    NSRect geometry = InitialWindowBounds(winPtr, window);
    geometry.size.width +=  structureRect.size.width;
    geometry.size.height += structureRect.size.height;
    geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y +
	    geometry.size.height);
    [window setFrame:geometry display:YES];
    TkMacOSXRegisterOffScreenWindow((Window) macWin, window);
    macWin->flags |= TK_HOST_EXISTS;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpDisplayWindow --
 *
 *      Mark the contentView of this window as needing display so the
 *      window will be drawn by the window manager.  If this is called
 *      within the drawRect method, do nothing.
 *
 * Results:
 *      None.
 *
 * Side effects:
 *      The window's contentView is marked as needing display.
 *
 *----------------------------------------------------------------------
 */

MODULE_SCOPE void
TkpDisplayWindow(Tk_Window tkwin) {
    if (![NSApp isDrawing]) {
    	TkWindow *winPtr = (TkWindow*)tkwin;
    	NSWindow *w = TkMacOSXDrawableWindow(winPtr->window);
    	[[w contentView] setNeedsDisplay: YES];
    }
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkMacOSXRegisterOffScreenWindow --
 *
 *	This function adds the passed in Off Screen Port to the hash table
................................................................................
	if ((changedAttributes & (kWindowResizableAttribute |
		kWindowFullZoomAttribute)) || initial) {
	    [macWindow setShowsResizeIndicator:
		    !!(newAttributes & kWindowResizableAttribute)];
	    [[macWindow standardWindowButton:NSWindowZoomButton]
		    setEnabled:(newAttributes & kWindowResizableAttribute) &&
		    (newAttributes & kWindowFullZoomAttribute)];
	    if (newAttributes & kWindowHorizontalZoomAttribute) {
		wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE);

	    } else {
		wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE);
	    }
	    if (newAttributes & kWindowVerticalZoomAttribute) {
		wmPtr->flags &= ~(WM_HEIGHT_NOT_RESIZABLE);
	    } else {
		wmPtr->flags |= (WM_HEIGHT_NOT_RESIZABLE);
	    }
	    WmUpdateGeom(wmPtr, winPtr);
	}
	if ((changedAttributes & kWindowToolbarButtonAttribute) || initial) {
	    [macWindow setShowsToolbarButton:
		    !!(newAttributes & kWindowToolbarButtonAttribute)];
	    if ((newAttributes & kWindowToolbarButtonAttribute) &&
................................................................................
TkMacOSXMakeFullscreen(
    TkWindow *winPtr,
    NSWindow *window,
    int fullscreen,
    Tcl_Interp *interp)
{
    WmInfo *wmPtr = winPtr->wmInfoPtr;
    int screenWidth =  WidthOfScreen(Tk_Screen(winPtr));
    int screenHeight = HeightOfScreen(Tk_Screen(winPtr));

    if (fullscreen) {



	/*
	 * Check max width and height if set by the user.
	 */

	if ((wmPtr->maxWidth > 0 && wmPtr->maxWidth < screenWidth)
		|| (wmPtr->maxHeight > 0 && wmPtr->maxHeight < screenHeight)) {
................................................................................
	    if (interp) {
		Tcl_SetObjResult(interp, Tcl_ObjPrintf(
			"can't set fullscreen attribute for \"%s\": max"
			" width/height is too small", winPtr->pathName));
		Tcl_SetErrorCode(interp, "TK", "FULLSCREEN",
			"CONSTRAINT_FAILURE", NULL);
	    }

	    wmPtr->flags &= ~WM_FULLSCREEN;




	    return TCL_ERROR;
	}













	/*
	 * Save the current window state.
	 */


	wmPtr->cachedBounds = [window frame];
	wmPtr->cachedStyle = [window styleMask];
	wmPtr->cachedPresentation = [NSApp presentationOptions];

	/*
	 * Adjust the window style so it looks like a Fullscreen window.
	 */

	[window setStyleMask: NSFullScreenWindowMask];
	[NSApp setPresentationOptions: (NSApplicationPresentationAutoHideDock |
					NSApplicationPresentationAutoHideMenuBar)];

	/*For 10.13 and later add a button for exiting Fullscreen.*/
	if ([NSApp macMinorVersion] > 12) {
#if MAC_OS_X_VERSION_MAX_ALLOWED > 101200
	    exitFullScreen = [[[NSStatusBar systemStatusBar]
				   statusItemWithLength:NSVariableStatusItemLength] retain];
	    NSImage *exitIcon = [NSImage imageNamed:@"NSExitFullScreenTemplate"];
	    exitFullScreen.button.image = exitIcon;
	    exitFullScreen.button.cell.highlighted = NO;
	    exitFullScreen.button.toolTip = @"Exit Full Screen";
	    exitFullScreen.button.target = window;
	    exitFullScreen.button.action = @selector(restoreOldScreen:);
#endif
	}

	/*
	 * Resize the window to fill the screen. (After setting the style!)
	 */

	wmPtr->flags |= WM_SYNC_PENDING;
	NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight);
	[window setFrame:screenBounds display:YES];
	wmPtr->flags &= ~WM_SYNC_PENDING;
	wmPtr->flags |= WM_FULLSCREEN;
    } else {




	/*
	 * Restore the previous styles and attributes.
	 */



	[NSApp setPresentationOptions: wmPtr->cachedPresentation];
	[window setStyleMask: wmPtr->cachedStyle];
	UInt64 oldAttributes = wmPtr->attributes;





	wmPtr->flags &= ~WM_FULLSCREEN;
	wmPtr->attributes |= wmPtr->configAttributes &
		kWindowResizableAttribute;
	ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes,
		wmPtr->flags, 1, 0);

	/*
	 * Resize the window to its previous size.
	 */

	wmPtr->flags |= WM_SYNC_PENDING;

	[window setFrame:wmPtr->cachedBounds display:YES];
	wmPtr->flags &= ~WM_SYNC_PENDING;

    }
    return TCL_OK;
}
 
/*
 *----------------------------------------------------------------------
 *
 * GetMinSize --
 *

Changes to macosx/tkMacOSXWm.h.

181
182
183
184
185
186
187









188
189
190
191
192
193
194
     */

    WindowClass macClass;
    UInt64 attributes, configAttributes;
    TkWindow *scrollWinPtr;	/* Ptr to scrollbar handling grow widget. */
    TkMenu *menuPtr;
    NSWindow *window;









} WmInfo;

/*
 * Flag values for WmInfo structures:
 *
 * WM_NEVER_MAPPED -		non-zero means window has never been mapped;
 *				need to update all info when window is first







>
>
>
>
>
>
>
>
>







181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
     */

    WindowClass macClass;
    UInt64 attributes, configAttributes;
    TkWindow *scrollWinPtr;	/* Ptr to scrollbar handling grow widget. */
    TkMenu *menuPtr;
    NSWindow *window;

    /*
     * Space to cache current window state when window becomes Fullscreen.
     */

    unsigned long cachedStyle;
    unsigned long cachedPresentation;
    NSRect cachedBounds;

} WmInfo;

/*
 * Flag values for WmInfo structures:
 *
 * WM_NEVER_MAPPED -		non-zero means window has never been mapped;
 *				need to update all info when window is first

Changes to macosx/tkMacOSXXStubs.c.

1
2
3
4
5
6
7
8
9
10
11
12
13
..
36
37
38
39
40
41
42

43
44
45
46



47
48
49
50
51
52
53
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
...
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
...
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950









951
952
953
954
955
956
957
...
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
/*
 * tkMacOSXXStubs.c --
 *
 *	This file contains most of the X calls called by Tk. Many of these
 *	calls are just stubs and either don't make sense on the Macintosh or
 *	their implamentation just doesn't do anything. Other calls will
 *	eventually be moved into other files.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2014 Marc Culler.
 *
................................................................................
CGFloat tkMacOSXZeroScreenHeight = 0;
CGFloat tkMacOSXZeroScreenTop = 0;

/*
 * Declarations of static variables used in this file.
 */


static TkDisplay *gMacDisplay = NULL;
				/* Macintosh display. */
static const char *macScreenName = ":0";
				/* Default name of macintosh display. */




/*
 * Forward declarations of procedures used in this file.
 */

static XID		MacXIdAlloc(Display *display);
static int		DefaultErrorHandler(Display *display,
................................................................................
	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
		NSAppKitVersionNumber);
    }
    display->vendor = vendor;
    {
	int major, minor, patch;

#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = systemVersion.majorVersion;
	minor = systemVersion.minorVersion;
................................................................................
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
    screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
    screen->ext_data	= (XExtData *) &maxBounds;

    screen->root_visual = ckalloc(sizeof(Visual));
    screen->root_visual->visualid     = 0;
    screen->root_visual->class	      = TrueColor;
    screen->root_visual->alpha_mask   = 0xFF000000;
    screen->root_visual->red_mask     = 0x00FF0000;
    screen->root_visual->green_mask   = 0x0000FF00;
    screen->root_visual->blue_mask    = 0x000000FF;
    screen->root_visual->bits_per_rgb = 24;
    screen->root_visual->map_entries  = 256;

    /*
................................................................................
 */

const char *
TkGetDefaultScreenName(
    Tcl_Interp *interp,		/* Not used. */
    const char *screenName)		/* If NULL, use default string. */
{
#if 0
    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = macScreenName;
    }
    return screenName;
#endif
    return macScreenName;
}
 
/*
 *----------------------------------------------------------------------
 *
 * Tk_GetUserInactiveTime --
 *
................................................................................
    if (result != KERN_SUCCESS || props == NULL) {
	return -1l;
    }

    timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime"));

    if (timeObj) {
	CFTypeID type = CFGetTypeID(timeObj);

	if (type == CFDataGetTypeID()) { /* Jaguar */
	    CFDataGetBytes((CFDataRef) timeObj,
		    CFRangeMake(0, sizeof(time)), (UInt8 *) &time);
	    /* Convert nanoseconds to milliseconds. */
	    /* ret /= kMillisecondScale; */
	    ret = (long) (time/kMillisecondScale);
	} else if (type == CFNumberGetTypeID()) { /* Panther+ */
	    CFNumberGetValue((CFNumberRef)timeObj,
		    kCFNumberSInt64Type, &time);
	    /* Convert nanoseconds to milliseconds. */
	    /* ret /= kMillisecondScale; */
	    ret = (long) (time/kMillisecondScale);
	} else {
	    ret = -1l;
	}
    }
    /* Cleanup */
    CFRelease(props);










    return ret;
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    Display *dpy)
{
    IOGPoint loc = {0, 0};
    kern_return_t kr;
    NXEvent nullEvent = {NX_NULLEVENT, {0, 0}, 0, -1, 0};
    enum { kNULLEventPostThrottle = 10 };
    static io_connect_t io_connection = MACH_PORT_NULL;

    if (io_connection == MACH_PORT_NULL) {
	io_service_t service = IOServiceGetMatchingService(
		kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass));

	if (service == MACH_PORT_NULL) {
	    return;
	}
	kr = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType,
		&io_connection);
	IOObjectRelease(service);
	if (kr != KERN_SUCCESS) {
	    return;
	}
    }
    kr = IOHIDPostEvent(io_connection, NX_NULLEVENT, loc, &nullEvent.data,
	    FALSE, 0, FALSE);
}
 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */





|







 







>

|

<
>
>
>







 







|







 







<







 







<




<
<







 







<
<
<
<
<
<
<
<
<



<

<
<
<



>
>
>
>
>
>
>
>
>







 







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










1
2
3
4
5
6
7
8
9
10
11
12
13
..
36
37
38
39
40
41
42
43
44
45
46

47
48
49
50
51
52
53
54
55
56
...
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
...
199
200
201
202
203
204
205

206
207
208
209
210
211
212
...
872
873
874
875
876
877
878

879
880
881
882


883
884
885
886
887
888
889
...
923
924
925
926
927
928
929









930
931
932

933



934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
...
964
965
966
967
968
969
970
971





















972
973
974
975
976
977
978
979
980
981
/*
 * tkMacOSXXStubs.c --
 *
 *	This file contains most of the X calls called by Tk. Many of these
 *	calls are just stubs and either don't make sense on the Macintosh or
 *	their implementation just doesn't do anything. Other calls will
 *	eventually be moved into other files.
 *
 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
 * Copyright 2001-2009, Apple Inc.
 * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net>
 * Copyright 2014 Marc Culler.
 *
................................................................................
CGFloat tkMacOSXZeroScreenHeight = 0;
CGFloat tkMacOSXZeroScreenTop = 0;

/*
 * Declarations of static variables used in this file.
 */

/* The unique Macintosh display. */
static TkDisplay *gMacDisplay = NULL;
/* The default name of the Macintosh display. */
static const char *macScreenName = ":0";

/* Timestamp showing the last reset of the inactivity timer. */
static Time lastInactivityReset = 0;


/*
 * Forward declarations of procedures used in this file.
 */

static XID		MacXIdAlloc(Display *display);
static int		DefaultErrorHandler(Display *display,
................................................................................
	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
		NSAppKitVersionNumber);
    }
    display->vendor = vendor;
    {
	int major, minor, patch;

#if MAC_OS_X_VERSION_MIN_REQUIRED < 101000
	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
#else
	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
	major = systemVersion.majorVersion;
	minor = systemVersion.minorVersion;
................................................................................
    screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
    screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
    screen->ext_data	= (XExtData *) &maxBounds;

    screen->root_visual = ckalloc(sizeof(Visual));
    screen->root_visual->visualid     = 0;
    screen->root_visual->class	      = TrueColor;

    screen->root_visual->red_mask     = 0x00FF0000;
    screen->root_visual->green_mask   = 0x0000FF00;
    screen->root_visual->blue_mask    = 0x000000FF;
    screen->root_visual->bits_per_rgb = 24;
    screen->root_visual->map_entries  = 256;

    /*
................................................................................
 */

const char *
TkGetDefaultScreenName(
    Tcl_Interp *interp,		/* Not used. */
    const char *screenName)		/* If NULL, use default string. */
{

    if ((screenName == NULL) || (screenName[0] == '\0')) {
	screenName = macScreenName;
    }
    return screenName;


}
 
/*
 *----------------------------------------------------------------------
 *
 * Tk_GetUserInactiveTime --
 *
................................................................................
    if (result != KERN_SUCCESS || props == NULL) {
	return -1l;
    }

    timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime"));

    if (timeObj) {









	    CFNumberGetValue((CFNumberRef)timeObj,
		    kCFNumberSInt64Type, &time);
	    /* Convert nanoseconds to milliseconds. */

	    ret = (long) (time/kMillisecondScale);



    }
    /* Cleanup */
    CFRelease(props);

    /*
     * If the idle time reported by the system is larger than the elapsed
     * time since the last reset, return the elapsed time.
     */
    long elapsed = (long)(TkpGetMS() - lastInactivityReset);
    if (ret > elapsed) {
    	ret = elapsed;
    }

    return ret;
}
 
/*
 *----------------------------------------------------------------------
 *
................................................................................
 *----------------------------------------------------------------------
 */

void
Tk_ResetUserInactiveTime(
    Display *dpy)
{
    lastInactivityReset = TkpGetMS();





















}
 
/*
 * Local Variables:
 * mode: objc
 * c-basic-offset: 4
 * fill-column: 79
 * coding: utf-8
 * End:
 */

Changes to tests/bind.test.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}

# This function fills the pattern matcher's ring buffer with events of
# the specified type.  This can be used when testing with generated
# events to make sure that there are no stray events in the ring
# buffer which might cause the pattern matcher to find unintended
# matches.  The size of the ring buffer is EVENT_BUFFER_SIZE, which is
# currently set to 30.  If this changes, the code below will need to
# change.
proc clearRingBuffer {{event}} {
    for {set i 0} {$i < 30} {incr i} {
	event generate . $event
    }
}

# move the mouse pointer away of the testing area
# otherwise some spurious events may pollute the tests
toplevel .top







|
|

|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
}

# This function fills the pattern matcher's ring buffer with events of
# the specified type.  This can be used when testing with generated
# events to make sure that there are no stray events in the ring
# buffer which might cause the pattern matcher to find unintended
# matches.  The size of the ring buffer is EVENT_BUFFER_SIZE, which is
# currently set to 30 (or 45 on macOS).  If this changes, the code
# below will need to change.
proc clearRingBuffer {{event}} {
    for {set i 0} {$i < 45} {incr i} {
	event generate . $event
    }
}

# move the mouse pointer away of the testing area
# otherwise some spurious events may pollute the tests
toplevel .top

Changes to tests/bitmap.test.

80
81
82
83
84
85
86


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

105
106
107
108
109
110
111
    lappend result [testbitmap questhead]
} -cleanup {
    destroy .b1 .b2 .b3     ;# destroying just in case
} -result {{{3 1}} {{2 1}} {{1 1}} {}}

test bitmap-4.1 {FreeBitmapObjProc} -constraints {
    testbitmap


} -body {
    set x [join questhead]
    button .b -bitmap $x
    set y [join questhead]
    .b configure -bitmap $y
    set z [join questhead]
    .b configure -bitmap $z
    set result {}
    lappend result [testbitmap questhead]
    set x red
    lappend result [testbitmap questhead]
    set z 32
    lappend result [testbitmap questhead]
    destroy .b
    lappend result [testbitmap questhead]
    set y bogus
    return $result
} -cleanup {

    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}


# cleanup
cleanupTests
return







>
>

|

|

|












>







80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
    lappend result [testbitmap questhead]
} -cleanup {
    destroy .b1 .b2 .b3     ;# destroying just in case
} -result {{{3 1}} {{2 1}} {{1 1}} {}}

test bitmap-4.1 {FreeBitmapObjProc} -constraints {
    testbitmap
} -setup {
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    set x [copy questhead]
    button .b -bitmap $x
    set y [copy questhead]
    .b configure -bitmap $y
    set z [copy questhead]
    .b configure -bitmap $z
    set result {}
    lappend result [testbitmap questhead]
    set x red
    lappend result [testbitmap questhead]
    set z 32
    lappend result [testbitmap questhead]
    destroy .b
    lappend result [testbitmap questhead]
    set y bogus
    return $result
} -cleanup {
    rename copy {}
    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}


# cleanup
cleanupTests
return

Changes to tests/border.test.

127
128
129
130
131
132
133

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

151
152
153
154
155
156
157
    destroy .b .t2 .t3 .t
} -result {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}

test border-3.1 {FreeBorderObjProc} -constraints {  
    testborder 
} -setup {
    set result {}

} -body {
    set x [join purple]
    button .b -bg $x -text .b1
    set y [join purple]
    .b configure -bg $y
    set z [join purple]
    .b configure -bg $z
    lappend result [testborder purple]
    set x red
    lappend result [testborder purple]
    set z 32
    lappend result [testborder purple]
    destroy .b
    lappend result [testborder purple]
    set y bogus
    return $result
} -cleanup {

    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}

test border-4.1 {Tk_GetReliefFromObj} -body {
    button .b -relief flat
    .b cget -relief
} -cleanup {







>

|

|

|











>







127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
    destroy .b .t2 .t3 .t
} -result {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}

test border-3.1 {FreeBorderObjProc} -constraints {  
    testborder 
} -setup {
    set result {}
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    set x [copy purple]
    button .b -bg $x -text .b1
    set y [copy purple]
    .b configure -bg $y
    set z [copy purple]
    .b configure -bg $z
    lappend result [testborder purple]
    set x red
    lappend result [testborder purple]
    set z 32
    lappend result [testborder purple]
    destroy .b
    lappend result [testborder purple]
    set y bogus
    return $result
} -cleanup {
    rename copy {}
    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}

test border-4.1 {Tk_GetReliefFromObj} -body {
    button .b -relief flat
    .b cget -relief
} -cleanup {

Changes to tests/canvImg.test.

169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
...
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
    .c itemconfigure i1 -image foo2
    update
    list $x $y [.c bbox i1]
} -cleanup {
	.c delete all
	image delete foo
	image delete foo2
} -result {{{foo free}} {{foo2 get} {foo2 display 0 0 80 60 30 30}} {50 100 130 160}}
test canvImg-4.3 {ConfiugreImage procedure} -constraints testImageType -setup {
    .c delete all
} -body {
	image create test foo -variable x
    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags i1 -anchor nw
................................................................................
    set x {}
    foo changed 2 4 6 8 30 15
    update
    return $x
} -cleanup {
	.c delete all
	image delete foo
} -result {{foo display 2 4 6 8 30 30}}

test canvImg-11.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
} -body {
	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
................................................................................
    set x {}
    foo changed 2 4 6 8 40 50
    update
    return $x
} -cleanup {
	.c delete all
	image delete foo
} -result {{foo display 0 0 40 50 30 30}}
test canvImg-11.2 {ImageChangedProc procedure} -constraints {
	testImageType 
} -setup {
    .c delete all
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor center
................................................................................
    set y {}
    image create test foo -variable x
    update
    return $y
} -cleanup {
	.c delete all
	image delete foo foo2
} -result {{foo2 display 0 0 20 40 50 40}}

# cleanup
imageFinish
cleanupTests
return

# Local variables:
# mode: tcl
# End:







|







 







|







 







|







 







|









169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
...
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
...
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
...
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
    .c itemconfigure i1 -image foo2
    update
    list $x $y [.c bbox i1]
} -cleanup {
	.c delete all
	image delete foo
	image delete foo2
} -result {{{foo free}} {{foo2 get} {foo2 display 0 0 80 60}} {50 100 130 160}}
test canvImg-4.3 {ConfiugreImage procedure} -constraints testImageType -setup {
    .c delete all
} -body {
	image create test foo -variable x
    image create test foo2 -variable y
    foo2 changed 0 0 0 0 80 60
    .c create image 50 100 -image foo -tags i1 -anchor nw
................................................................................
    set x {}
    foo changed 2 4 6 8 30 15
    update
    return $x
} -cleanup {
	.c delete all
	image delete foo
} -result {{foo display 2 4 6 8}}

test canvImg-11.1 {TranslateImage procedure} -constraints testImageType -setup {
    .c delete all
} -body {
	image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor nw
    update
................................................................................
    set x {}
    foo changed 2 4 6 8 40 50
    update
    return $x
} -cleanup {
	.c delete all
	image delete foo
} -result {{foo display 0 0 40 50}}
test canvImg-11.2 {ImageChangedProc procedure} -constraints {
	testImageType 
} -setup {
    .c delete all
} -body {
    image create test foo -variable x
    .c create image 50 100 -image foo -tags image -anchor center
................................................................................
    set y {}
    image create test foo -variable x
    update
    return $y
} -cleanup {
	.c delete all
	image delete foo foo2
} -result {{foo2 display 0 0 20 40}}

# cleanup
imageFinish
cleanupTests
return

# Local variables:
# mode: tcl
# End:

Changes to tests/canvText.test.

51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    .c itemconfigure test -justify xyz
} -returnCodes error -result {bad justification "xyz": must be left, right, or center}
test canvText-1.10 {configuration options: good value for "stipple"} -body {
    .c itemconfigure test -stipple gray50
    list [lindex [.c itemconfigure test -stipple] 4] [.c itemcget test -stipple]
} -result {gray50 gray50}
test canvasText-1.11 {configuration options: bad value for "stipple"} -body {
    .c itemconfigure test -stipple xyz
} -returnCodes error -result {bitmap "xyz" not defined}
test canvText-1.12 {configuration options: good value for "underline"} -body {
    .c itemconfigure test -underline 0
    list [lindex [.c itemconfigure test -underline] 4] [.c itemcget test -underline]
} -result {0 0}
test canvasText-1.13 {configuration options: bad value for "underline"} -body {
    .c itemconfigure test -underline xyz
} -returnCodes error -result {expected integer but got "xyz"}







|
|







51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
    .c itemconfigure test -justify xyz
} -returnCodes error -result {bad justification "xyz": must be left, right, or center}
test canvText-1.10 {configuration options: good value for "stipple"} -body {
    .c itemconfigure test -stipple gray50
    list [lindex [.c itemconfigure test -stipple] 4] [.c itemcget test -stipple]
} -result {gray50 gray50}
test canvasText-1.11 {configuration options: bad value for "stipple"} -body {
    .c itemconfigure test -stipple abcxyz
} -returnCodes error -result {bitmap "abcxyz" not defined}
test canvText-1.12 {configuration options: good value for "underline"} -body {
    .c itemconfigure test -underline 0
    list [lindex [.c itemconfigure test -underline] 4] [.c itemcget test -underline]
} -result {0 0}
test canvasText-1.13 {configuration options: bad value for "underline"} -body {
    .c itemconfigure test -underline xyz
} -returnCodes error -result {expected integer but got "xyz"}

Changes to tests/choosedir.test.

81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103



104
105
106
107
108
109
110
111
# Make a dir for us to rely on for tests
set real [makeDirectory choosedirTest]
set dir [file dirname $real]
set fake [file join $dir non-existant]

set parent .

test choosedir-1.1 {tk_chooseDirectory command} -constraints unix -body {
    tk_chooseDirectory -initialdir
} -returnCodes error -result {value for "-initialdir" missing}
test choosedir-1.2 {tk_chooseDirectory command} -constraints unix -body {
    tk_chooseDirectory -mustexist
} -returnCodes error -result {value for "-mustexist" missing}
test choosedir-1.3 {tk_chooseDirectory command} -constraints unix -body {
    tk_chooseDirectory -parent
} -returnCodes error -result {value for "-parent" missing}
test choosedir-1.4 {tk_chooseDirectory command} -constraints unix -body {
    tk_chooseDirectory -title
} -returnCodes error -result {value for "-title" missing}

test choosedir-1.5 {tk_chooseDirectory command} -constraints unix -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}



test choosedir-1.6 {tk_chooseDirectory command} -constraints unix -body {
    tk_chooseDirectory -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


test choosedir-2.1 {tk_chooseDirectory command, cancel gives null} -constraints {
	unix notAqua
} -body {







|


|


|


|


<
|


>
>
>
|







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

100
101
102
103
104
105
106
107
108
109
110
111
112
113
# Make a dir for us to rely on for tests
set real [makeDirectory choosedirTest]
set dir [file dirname $real]
set fake [file join $dir non-existant]

set parent .

test choosedir-1.1 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -initialdir
} -returnCodes error -result {value for "-initialdir" missing}
test choosedir-1.2 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -mustexist
} -returnCodes error -result {value for "-mustexist" missing}
test choosedir-1.3 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -parent
} -returnCodes error -result {value for "-parent" missing}
test choosedir-1.4 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -title
} -returnCodes error -result {value for "-title" missing}

test choosedir-1.5.1 {tk_chooseDirectory command} -constraints notAqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title}
test choosedir-1.5.2 {tk_chooseDirectory command} -constraints aqua -body {
    tk_chooseDirectory -foo bar
} -returnCodes error -result {bad option "-foo": must be -initialdir, -message, -mustexist, -parent, -title, or -command}
test choosedir-1.6 {tk_chooseDirectory command} -body {
    tk_chooseDirectory -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


test choosedir-2.1 {tk_chooseDirectory command, cancel gives null} -constraints {
	unix notAqua
} -body {

Changes to tests/clipboard.test.

157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
...
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
...
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "STRING" not defined}
test clipboard-4.3 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    selection clear -s CLIPBOARD
    catch {clipboard get}
	clipboard get -t TEST
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined}
test clipboard-4.4 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
................................................................................
test clipboard-4.5 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    clipboard append "Test3"
    selection clear -s CLIPBOARD
    catch {clipboard get}
	clipboard get -t TEST
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined}



##############################################################################
................................................................................
    clipboard append "first chunk"
    selection own -s CLIPBOARD .
	clipboard append " second chunk"
	clipboard get
} -cleanup {
    clipboard clear
}  -returnCodes ok -result {first chunk second chunk}
test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints unix -setup {
    clipboard clear
} -body {
    setupbg
    clipboard append -f INTEGER -t TEST "16"
    set result [dobg {clipboard get TEST}]
    return $result
} -cleanup {







<
|







 







<
|







 







|







157
158
159
160
161
162
163

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

186
187
188
189
190
191
192
193
...
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "STRING" not defined}
test clipboard-4.3 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    selection clear -s CLIPBOARD

    clipboard get -t TEST
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined}
test clipboard-4.4 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
................................................................................
test clipboard-4.5 {ClipboardLostSel procedure} -setup {
    clipboard clear
} -body {
    clipboard append "Test"
    clipboard append -t TEST "Test2"
    clipboard append "Test3"
    selection clear -s CLIPBOARD

    clipboard get -t TEST
} -cleanup {
    clipboard clear
}  -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined}



##############################################################################
................................................................................
    clipboard append "first chunk"
    selection own -s CLIPBOARD .
	clipboard append " second chunk"
	clipboard get
} -cleanup {
    clipboard clear
}  -returnCodes ok -result {first chunk second chunk}
test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints x11 -setup {
    clipboard clear
} -body {
    setupbg
    clipboard append -f INTEGER -t TEST "16"
    set result [dobg {clipboard get TEST}]
    return $result
} -cleanup {

Changes to tests/color.test.

273
274
275
276
277
278
279
280




281
282

283
284

285
286

287
288
289
290
291
292
293
294
295
296
297


298
299
300
301
302
303
304
    lappend result [testcolor purple]
    destroy .t3
    lappend result [testcolor purple]
    destroy .t
    lappend result [testcolor purple]
} {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}

test color-4.1 {FreeColorObjProc} colorsFree {




    destroy .b
    set x [format purple]

    button .b -foreground $x -text .b1
    set y [format purple]

    .b configure -foreground $y
    set z [format purple]

    .b configure -foreground $z
    set result {}
    lappend result [testcolor purple]
    set x red
    lappend result [testcolor purple]
    set z 32
    lappend result [testcolor purple]
    destroy .b
    lappend result [testcolor purple]
    set y bogus
    set result


} {{{1 3}} {{1 2}} {{1 1}} {}}

destroy .t

# cleanup
cleanupTests
return







|
>
>
>
>

<
>

<
>

<
>











>
>
|






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

286
287

288
289

290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
    lappend result [testcolor purple]
    destroy .t3
    lappend result [testcolor purple]
    destroy .t
    lappend result [testcolor purple]
} {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}}

test color-4.1 {FreeColorObjProc} -constraints {
    colorsFree
} -setup {
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    destroy .b

    set x [copy purple]
    button .b -foreground $x -text .b1

    set y [copy purple]
    .b configure -foreground $y

    set z [copy purple]
    .b configure -foreground $z
    set result {}
    lappend result [testcolor purple]
    set x red
    lappend result [testcolor purple]
    set z 32
    lappend result [testcolor purple]
    destroy .b
    lappend result [testcolor purple]
    set y bogus
    set result
} -cleanup {
    rename copy {}
} -result {{{1 3}} {{1 2}} {{1 1}} {}}

destroy .t

# cleanup
cleanupTests
return

Changes to tests/config.test.

675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {gray50}
test config-4.57 {DoObjConfig - invalid bitmap} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -bitmap foo
} -cleanup {
    killTables
} -returnCodes error -result {bitmap "foo" not defined}
test config-4.58 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.59 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}







|


|







675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
    .foo cget -bitmap
} -cleanup {
    killTables
} -returnCodes ok -result {gray50}
test config-4.57 {DoObjConfig - invalid bitmap} -constraints {
    testobjconfig
} -body {
    testobjconfig alltypes .foo -bitmap foobar
} -cleanup {
    killTables
} -returnCodes error -result {bitmap "foobar" not defined}
test config-4.58 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}
} -cleanup {
    killTables
} -returnCodes ok -result {.foo}
test config-4.59 {DoObjConfig - null bitmap} -constraints testobjconfig -body {
    testobjconfig alltypes .foo -bitmap {}

Changes to tests/cursor.test.

140
141
142
143
144
145
146


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164

165
166
167
168
169
170
171
    lappend result [testcursor heart]
    destroy .b3
    lappend result [testcursor heart]
} -result {{{3 1}} {{2 1}} {{1 1}} {}}

test cursor-4.1 {FreeCursorObjProc} -constraints {
    testcursor


} -body {
    set x [join heart]
    button .b -cursor $x
    set y [join heart]
    .b configure -cursor $y
    set z [join heart]
    .b configure -cursor $z
    set result {}
    lappend result [testcursor heart]
    set x red
    lappend result [testcursor heart]
    set z 32
    lappend result [testcursor heart]
    destroy .b
    lappend result [testcursor heart]
    set y bogus
    set result
} -cleanup {

    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}

# -------------------------------------------------------------------------
test cursor-5.1 {assert consistent cursor configuration command} -setup {
    button .b
} -body {







>
>

|

|

|












>







140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
    lappend result [testcursor heart]
    destroy .b3
    lappend result [testcursor heart]
} -result {{{3 1}} {{2 1}} {{1 1}} {}}

test cursor-4.1 {FreeCursorObjProc} -constraints {
    testcursor
} -setup {
    proc copy {s} {return [string index $s 0][string range $s 1 end]}
} -body {
    set x [copy heart]
    button .b -cursor $x
    set y [copy heart]
    .b configure -cursor $y
    set z [copy heart]
    .b configure -cursor $z
    set result {}
    lappend result [testcursor heart]
    set x red
    lappend result [testcursor heart]
    set z 32
    lappend result [testcursor heart]
    destroy .b
    lappend result [testcursor heart]
    set y bogus
    set result
} -cleanup {
    rename copy {}
    destroy .b
} -result {{{1 3}} {{1 2}} {{1 1}} {}}

# -------------------------------------------------------------------------
test cursor-5.1 {assert consistent cursor configuration command} -setup {
    button .b
} -body {

Added tests/deferredClearCode.gif.

cannot compute difference between binary files

Changes to tests/filebox.test.

106
107
108
109
110
111
112
113

114

115
116
117
118
119
120
121
...
151
152
153
154
155
156
157



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



174
175
176
177
178
179
180
181
182
183
...
285
286
287
288
289
290
291



292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307



308
309
310
311
312
313
314
315
316
317

if {$tcl_platform(platform) == "unix"} {
    set modes "0 1"
} else {
    set modes 1
}

set unknownOptionsMsg(tk_getOpenFile) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}

set unknownOptionsMsg(tk_getSaveFile) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable}


set tmpFile "filebox.tmp"
makeFile {
    # this file can be empty!
} $tmpFile

array set filters {
................................................................................
	# Extension adding is only done when using the non-motif file
	# box with an extension-less filename
	if {!$mode} {
	    set addedExtensions {NONE {} .txt .txt}
	}
    }




    test filebox-1.1-$mode "tk_getOpenFile command" -body {
	tk_getOpenFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile)

    catch {tk_getOpenFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options
    
    foreach option $options {
        if {[string index $option 0] eq "-"} {
	    test filebox-1.2-$mode$option "tk_getOpenFile command" -body {
		tk_getOpenFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
        }
    }




    test filebox-1.3-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile)
    test filebox-1.4-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-1.5-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-1.6-$mode "tk_getOpenFile command" -body {
................................................................................
	    } else {
		set typeName "-unset-"
	    }
	    set typeName
        } $res
    }




    test filebox-4.1-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile)

    catch {tk_getSaveFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options

    foreach option $options {
	if {[string index $option 0] eq "-"} {
	    test filebox-4.2-$mode$option "tk_getSaveFile command" -body {
		tk_getSaveFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
	}
    }




    test filebox-4.3-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile)
    test filebox-4.4-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-4.5-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-4.6-$mode "tk_getSaveFile command" -body {







|
>
|
>







 







>
>
>
|

|













>
>
>
|

|







 







>
>
>
|

|













>
>
>
|

|







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
...
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
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 {$tcl_platform(platform) == "unix"} {
    set modes "0 1"
} else {
    set modes 1
}

set unknownOptionsMsg(tk_getOpenFile,notAqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getOpenFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -multiple, -parent, -title, -typevariable, or -command}
set unknownOptionsMsg(tk_getSaveFile,notAqua) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable}
set unknownOptionsMsg(tk_getSaveFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -parent, -title, -typevariable, -command, or -confirmoverwrite}

set tmpFile "filebox.tmp"
makeFile {
    # this file can be empty!
} $tmpFile

array set filters {
................................................................................
	# Extension adding is only done when using the non-motif file
	# box with an extension-less filename
	if {!$mode} {
	    set addedExtensions {NONE {} .txt .txt}
	}
    }

    test filebox-1.1.1-$mode "tk_getOpenFile command" -constraints notAqua -body {
	tk_getOpenFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,notAqua)
    test filebox-1.1.2-$mode "tk_getOpenFile command" -constraints aqua -body {
	tk_getOpenFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,aqua)

    catch {tk_getOpenFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options
    
    foreach option $options {
        if {[string index $option 0] eq "-"} {
	    test filebox-1.2-$mode$option "tk_getOpenFile command" -body {
		tk_getOpenFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
        }
    }

    test filebox-1.3.1-$mode "tk_getOpenFile command" -constraints notAqua -body {
        tk_getOpenFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,notAqua)
    test filebox-1.3.2-$mode "tk_getOpenFile command" -constraints aqua -body {
        tk_getOpenFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,aqua)
    test filebox-1.4-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-1.5-$mode "tk_getOpenFile command" -body {
        tk_getOpenFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-1.6-$mode "tk_getOpenFile command" -body {
................................................................................
	    } else {
		set typeName "-unset-"
	    }
	    set typeName
        } $res
    }

    test filebox-4.1.1-$mode "tk_getSaveFile command" -constraints notAqua -body {
	tk_getSaveFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,notAqua)
    test filebox-4.1.2-$mode "tk_getSaveFile command" -constraints aqua -body {
	tk_getSaveFile -foo
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,aqua)

    catch {tk_getSaveFile -foo 1} msg
    regsub -all ,      $msg "" options
    regsub \"-foo\" $options "" options

    foreach option $options {
	if {[string index $option 0] eq "-"} {
	    test filebox-4.2-$mode$option "tk_getSaveFile command" -body {
		tk_getSaveFile $option
	    } -returnCodes error -result "value for \"$option\" missing"
	}
    }

    test filebox-4.3.1-$mode "tk_getSaveFile command" -constraints notAqua -body {
	tk_getSaveFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,notAqua)
    test filebox-4.3.2-$mode "tk_getSaveFile command" -constraints aqua -body {
	tk_getSaveFile -foo bar
    } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,aqua)
    test filebox-4.4-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -initialdir
    } -returnCodes error -result {value for "-initialdir" missing}
    test filebox-4.5-$mode "tk_getSaveFile command" -body {
	tk_getSaveFile -parent foo.bar
    } -returnCodes error -result {bad window path name "foo.bar"}
    test filebox-4.6-$mode "tk_getSaveFile command" -body {

Changes to tests/font.test.

34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
....
2352
2353
2354
2355
2356
2357
2358
2359

2360


2361
2362


2363
2364
2365
2366
2367
2368
2369
deleteWindows
# Toplevel used (in some tests) of the whole file
toplevel .t
wm geom .t +0+0
update idletasks

switch [tk windowingsystem] {
    x11	 	{set fixed "fixed"}
    win32	{set fixed "courier 12"}
    aqua	{set fixed "monaco 9"}
}


# Procedure used in tests: 24.15, 26.*, 28.*, 30.*, 31.*, 32.1
proc csetup {{str ""}} {
................................................................................
    if {[string match lucida*bright $x]} {
		psfontname "{lucida bright} 10"
    } else {
		set x {LucidaBright}
    }
} -result {LucidaBright}
test font-21.6 {Tk_PostscriptFontName procedure: spaces} -constraints {
	unix 
} -body {
    psfontname "{new century schoolbook} 10"
} -result {NewCenturySchlbk-Roman}

test font-21.7 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix 
} -body {
................................................................................

test font-45.1 {TkFontGetAliasList: no match} -body {
    font actual {snarky 10} -family
} -result [font actual {-size 10} -family]
test font-45.2 {TkFontGetAliasList: match} -constraints win -body {
    font actual {times 10} -family
} -result {Times New Roman}
test font-45.3 {TkFontGetAliasList: match} -constraints {unix noExceed} -body {

    # can fail on Unix systems that have a real "times new roman" font


    font actual {{times new roman} 10} -family
} -result [font actual {times 10} -family]




test font-46.1 {font actual, with character, no option, no --} -body {
	font actual {times 10} a
} -match glob -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]








|







 







|







 







|
>
|
>
>
|
|
>
>







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
...
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
....
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
deleteWindows
# Toplevel used (in some tests) of the whole file
toplevel .t
wm geom .t +0+0
update idletasks

switch [tk windowingsystem] {
    x11	 	{set fixed "TkFixedFont"}
    win32	{set fixed "courier 12"}
    aqua	{set fixed "monaco 9"}
}


# Procedure used in tests: 24.15, 26.*, 28.*, 30.*, 31.*, 32.1
proc csetup {{str ""}} {
................................................................................
    if {[string match lucida*bright $x]} {
		psfontname "{lucida bright} 10"
    } else {
		set x {LucidaBright}
    }
} -result {LucidaBright}
test font-21.6 {Tk_PostscriptFontName procedure: spaces} -constraints {
	x11 
} -body {
    psfontname "{new century schoolbook} 10"
} -result {NewCenturySchlbk-Roman}

test font-21.7 {Tk_PostscriptFontName procedure: exhaustive} -constraints {
    unix 
} -body {
................................................................................

test font-45.1 {TkFontGetAliasList: no match} -body {
    font actual {snarky 10} -family
} -result [font actual {-size 10} -family]
test font-45.2 {TkFontGetAliasList: match} -constraints win -body {
    font actual {times 10} -family
} -result {Times New Roman}
test font-45.3 {TkFontGetAliasList: match} -constraints {noExceed} -body {
    if {[font actual {{times new roman} 10} -family] eq "Times New Roman"} {
        # avoid test failure on systems that have a real "times new roman" font
        set res 1
    } else {
        set res [expr {[font actual {{times new roman} 10} -family] eq \
                       [font actual {times 10} -family]} ]
    }
} -result {1}


test font-46.1 {font actual, with character, no option, no --} -body {
	font actual {times 10} a
} -match glob -result [list -family [font actual {times 10} -family] -size *\
		 -slant roman -underline 0 -overstrike 0]

Changes to tests/image.test.

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
..
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
...
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
    update
    set x {}
    image create test myimage -variable x
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{myimage free} {myimage free} {myimage delete} {myimage get} {myimage get} {myimage display 0 0 30 15 30 30} {myimage display 0 0 30 15 30 130}}
test image-1.8 {Tk_ImageCmd procedure, "create" option} -constraints {
	testImageType 
} -setup {
    .c delete all
    imageCleanup
} -body {
    image create test myimage -variable x
................................................................................
    set x {}
    image create test myimage -variable x
    update
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{myimage get} {myimage get} {myimage display 0 0 30 15 30 30} {myimage display 0 0 30 15 30 130}}
test image-1.9 {Tk_ImageCmd procedure, "create" option} -constraints {
	testImageType 
} -body {
    image create test -badName foo
} -returnCodes error -result {bad option name "-badName"}
test image-1.10 {Tk_ImageCmd procedure, "create" option} -constraints {
    testImageType 
................................................................................
    set x {}
    foo changed 5 6 7 8 30 15
    update
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 7 8 30 30}}
test image-9.2 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
................................................................................
    set x {}
    foo changed 5 6 7 8 30 15
    update
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 25 9 30 30} {foo display 0 0 12 14 65 74}}


test image-10.1 {Tk_GetImage procedure} -setup {
    imageCleanup
} -body {
    .c create image 100 10 -image bad_name
} -cleanup {
................................................................................
    .c delete i1
    pack .c
    update
    list [imageNames] $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {foo {{foo free} {foo display 0 0 30 15 103 121}}}
test image-11.2 {Tk_FreeImage procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    set names [imageNames]







|







 







|







 







|







 







|







 







|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
..
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
...
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
...
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
    update
    set x {}
    image create test myimage -variable x
    update
    return $x
} -cleanup {
    imageCleanup
} -result {{myimage free} {myimage free} {myimage delete} {myimage get} {myimage get} {myimage display 0 0 30 15} {myimage display 0 0 30 15}}
test image-1.8 {Tk_ImageCmd procedure, "create" option} -constraints {
	testImageType 
} -setup {
    .c delete all
    imageCleanup
} -body {
    image create test myimage -variable x
................................................................................
    set x {}
    image create test myimage -variable x
    update
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{myimage get} {myimage get} {myimage display 0 0 30 15} {myimage display 0 0 30 15}}
test image-1.9 {Tk_ImageCmd procedure, "create" option} -constraints {
	testImageType 
} -body {
    image create test -badName foo
} -returnCodes error -result {bad option name "-badName"}
test image-1.10 {Tk_ImageCmd procedure, "create" option} -constraints {
    testImageType 
................................................................................
    set x {}
    foo changed 5 6 7 8 30 15
    update
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 7 8}}
test image-9.2 {Tk_ImageChanged procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo
    .c create image 90 100 -image foo
................................................................................
    set x {}
    foo changed 5 6 7 8 30 15
    update
    return $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {{foo display 5 6 25 9} {foo display 0 0 12 14}}


test image-10.1 {Tk_GetImage procedure} -setup {
    imageCleanup
} -body {
    .c create image 100 10 -image bad_name
} -cleanup {
................................................................................
    .c delete i1
    pack .c
    update
    list [imageNames] $x
} -cleanup {
    .c delete all
    imageCleanup
} -result {foo {{foo free} {foo display 0 0 30 15}}}
test image-11.2 {Tk_FreeImage procedure} -constraints testImageType -setup {
    .c delete all
    imageCleanup
} -body {
    image create test foo -variable x
    .c create image 50 50 -image foo -tags i1
    set names [imageNames]

Changes to tests/imgPhoto.test.

1197
1198
1199
1200
1201
1202
1203










1204
1205
1206
1207
1208
1209
1210
} -body {
    # This crashes Tk up to 8.4.17 and 8.5.0
    set i [image create photo]
    $i configure -data $data
} -cleanup {
    image delete $i
} -returnCodes error -result {malformed image}











test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} -constraints {
    nonPortable
} -body {
    # This is not portable to very large machines with more than around 3GB of
    # free memory available...
    image create photo -width 32000 -height 32000







>
>
>
>
>
>
>
>
>
>







1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
} -body {
    # This crashes Tk up to 8.4.17 and 8.5.0
    set i [image create photo]
    $i configure -data $data
} -cleanup {
    image delete $i
} -returnCodes error -result {malformed image}
test imgPhoto-14.5 {Bug [fbaed1f66b] - GIF decoder with deferred clear code} -setup {
    set fileName [file join [file dirname [info script]] deferredClearCode.gif]
} -body {
    # This erroneously produced "malformed image" error.
    # The animated GIF "deferredClearCode.gif" has two frames, and calling for -index 2
    # simply is an easy way to trigger the problem of improper management of a deferred
    # clear code. The effect was that the GIF decoder bailed out before the end of the
    # image reading, and produced the inappropriate "malformed image error".
    image create photo -file $fileName -format "gif -index 2"
} -returnCodes error -result {no image data for this index}

test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} -constraints {
    nonPortable
} -body {
    # This is not portable to very large machines with more than around 3GB of
    # free memory available...
    image create photo -width 32000 -height 32000

Changes to tests/msgbox.test.

7
8
9
10
11
12
13
14
15
16
17



18
19



20
21
22
23
24
25
26
..
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

75
76
77
78
79
80
81

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


test msgbox-1.1 {tk_messageBox command} -body {
    tk_messageBox -foo
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}
test msgbox-1.2 {tk_messageBox command} -body {



    tk_messageBox -foo bar
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}




test msgbox-1.3 {tk_messageBox command} -body {
    tk_messageBox -default
} -returnCodes error -result {value for "-default" missing}
test msgbox-1.4 {tk_messageBox command} -body {
    tk_messageBox -detail
} -returnCodes error -result {value for "-detail" missing}
................................................................................
    tk_messageBox -default
} -returnCodes error -result {value for "-default" missing}

test msgbox-1.11 {tk_messageBox command} -body {
    tk_messageBox -type foo
} -returnCodes error -result {bad -type value "foo": must be abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel}

test msgbox-1.12 {tk_messageBox command} -constraints unix -body {
    tk_messageBox -default 1.1
} -returnCodes error -result {invalid default button "1.1"}
test msgbox-1.13 {tk_messageBox command} -constraints macOrWin -body {
    tk_messageBox -default 1.1
} -returnCodes error -result {bad -default value "1.1": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.14 {tk_messageBox command} -constraints unix -body {
    tk_messageBox -default foo
} -returnCodes error -result {invalid default button "foo"}
test msgbox-1.15 {tk_messageBox command} -constraints macOrWin -body {
    tk_messageBox -default foo
} -returnCodes error -result {bad -default value "foo": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.16 {tk_messageBox command} -constraints unix -body {
    tk_messageBox -type yesno -default 3
} -returnCodes error -result {invalid default button "3"}
test msgbox-1.17 {tk_messageBox command} -constraints macOrWin -body {
    tk_messageBox -type yesno -default 3
} -returnCodes error -result {bad -default value "3": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.18 {tk_messageBox command} -body {
    tk_messageBox -icon foo
} -returnCodes error -result {bad -icon value "foo": must be error, info, question, or warning}

test msgbox-1.19 {tk_messageBox command} -body {
    tk_messageBox -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


catch {tk_messageBox -foo bar}
set isNative [expr {[info commands tk::MessageBox] == ""}]







|


|
>
>
>


>
>
>







 







<
<
<
|



|
<
<
<



|
<
<
<






>







7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
..
50
51
52
53
54
55
56



57
58
59
60
61



62
63
64
65



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

package require tcltest 2.2
eval tcltest::configure $argv
tcltest::loadTestedCommands
namespace import -force tcltest::test


test msgbox-1.1.1 {tk_messageBox command} -constraints notAqua -body {
    tk_messageBox -foo
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}
test msgbox-1.1.2 {tk_messageBox command} -constraints aqua -body {
    tk_messageBox -foo
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, -type, or -command}
test msgbox-1.2.1 {tk_messageBox command} -constraints notAqua -body {
    tk_messageBox -foo bar
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type}
test msgbox-1.2.2 {tk_messageBox command} -constraints aqua -body {
    tk_messageBox -foo bar
} -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, -type, or -command}

test msgbox-1.3 {tk_messageBox command} -body {
    tk_messageBox -default
} -returnCodes error -result {value for "-default" missing}
test msgbox-1.4 {tk_messageBox command} -body {
    tk_messageBox -detail
} -returnCodes error -result {value for "-detail" missing}
................................................................................
    tk_messageBox -default
} -returnCodes error -result {value for "-default" missing}

test msgbox-1.11 {tk_messageBox command} -body {
    tk_messageBox -type foo
} -returnCodes error -result {bad -type value "foo": must be abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel}




test msgbox-1.13 {tk_messageBox command} -body {
    tk_messageBox -default 1.1
} -returnCodes error -result {bad -default value "1.1": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.14 {tk_messageBox command} -body {



    tk_messageBox -default foo
} -returnCodes error -result {bad -default value "foo": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.16 {tk_messageBox command} -body {



    tk_messageBox -type yesno -default 3
} -returnCodes error -result {bad -default value "3": must be abort, retry, ignore, ok, cancel, no, or yes}

test msgbox-1.18 {tk_messageBox command} -body {
    tk_messageBox -icon foo
} -returnCodes error -result {bad -icon value "foo": must be error, info, question, or warning}

test msgbox-1.19 {tk_messageBox command} -body {
    tk_messageBox -parent foo.bar
} -returnCodes error -result {bad window path name "foo.bar"}


catch {tk_messageBox -foo bar}
set isNative [expr {[info commands tk::MessageBox] == ""}]

Changes to tests/option.test.

382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
...
410
411
412
413
414
415
416
















417
418
419
420
421
422
423
424
425
test option-15.6 {database files} -body {
    option read $option1
	option get . x6 color
} -result {}
test option-15.7 {database files} -body {
    option read $option1
	option get . x9 color
} -result " \t\\A\n"
test option-15.8 {database files} -body {
    option read $option1 widget foo
} -returnCodes error -result {wrong # args: should be "option readfile fileName ?priority?"}
test option-15.9 {database files} -body {
    option add *x3 burgundy
    catch {option read $option1 userDefault}
    option get . x3 color
................................................................................
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    list [option get . x7 color] [option get . x8 color]
} -cleanup {
    removeFile $option4
} -result {true false}

















deleteWindows

# cleanup
cleanupTests
return










|







 







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









382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
...
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
test option-15.6 {database files} -body {
    option read $option1
	option get . x6 color
} -result {}
test option-15.7 {database files} -body {
    option read $option1
	option get . x9 color
} -result " \\\t\\A\n"
test option-15.8 {database files} -body {
    option read $option1 widget foo
} -returnCodes error -result {wrong # args: should be "option readfile fileName ?priority?"}
test option-15.9 {database files} -body {
    option add *x3 burgundy
    catch {option read $option1 userDefault}
    option get . x3 color
................................................................................
    puts $file "*x7: true\n*x8: false"
    close $file
    option read $option4 userDefault
    list [option get . x7 color] [option get . x8 color]
} -cleanup {
    removeFile $option4
} -result {true false}

set opt162val {label {
  foo bar
}
}
set opt162list [split $opt162val \n]

test option-16.2 {ticket 766ef52f3} {
    set option5 [makeFile {} option.file4]
    set file [open $option5 w]
    fconfigure $file -translation crlf
    puts $file "*notok: $opt162list"
    close $file
    option read $option5 userDefault
    option get . notok notok
} $opt162list

deleteWindows

# cleanup
cleanupTests
return



Changes to tests/scrollbar.test.

14
15
16
17
18
19
20

21
22
23
24
25
26


27
28
29
30
31
32
33
34
35
36
37












38
39
40
41
42
43
44
...
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
...
277
278
279
280
281
282
283

284
285

286




287
288
289
290
291
292
293
...
313
314
315
316
317
318
319
320
321
322




323
324
325
326
327
328
329
330
331
332
333
334
335




336
337
338
339
340
341
342
...
451
452
453
454
455
456
457
458
459
460
461




462
463




464
465
466
467
468
469
470
...
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521




522
523
524




525
526
527
528
529
530
531
...
546
547
548
549
550
551
552
553
554
555




556
557
558
559
560
561




562
563
564
565
566
567
568
...
578
579
580
581
582
583
584
585


586
587
588
589
590
591
592
...
597
598
599
600
601
602
603
604


605
606
607
608
609
610
611
...
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648














649
650
651
652
653
654
655
656
657
658
659
660














661
662
663
664
665
666
667
proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

proc getTroughSize {w} {
    if {[testConstraint testmetrics]} {

	if [string match v* [$w cget -orient]] {
	    return [expr [winfo height $w] - 2*[testmetrics cyvscroll $w]]
	} else {
	    return [expr [winfo width $w] - 2*[testmetrics cxhscroll $w]]
	}	    
    } else {


	if [string match v* [$w cget -orient]] {
	    return [expr [winfo height $w] \
		    - ([winfo width $w] \
			- [$w cget -highlightthickness] \
			- [$w cget -bd] + 1)*2]
	} else {
	    return [expr [winfo width $w] \
		    - ([winfo height $w] \
			- [$w cget -highlightthickness] \
			- [$w cget -bd] + 1)*2]
	}












    }
}

# XXX Note: this test file is woefully incomplete.  Right now there are
# only bits and pieces of tests.  Please make this file more complete
# as you fix bugs and add features.

................................................................................
test scrollbar-3.34 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 1000]
} {1}
test scrollbar-3.35 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 21]
} [format %.6g [expr (21.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)]]
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} unix {
    format {%.6g} [.s fraction 4 179]
} {1}
test scrollbar-3.37 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics} {
    format {%.6g} [.s fraction 4 [expr 200 - [testmetrics cyvscroll .s]]]
} {1}
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} unix {
    format {%.6g} [.s fraction 4 178]
} {0.993711}
test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} {
    expr \
    [format {%.6g} [.s fraction 4 [expr 200 - [testmetrics cyvscroll .s] - 2]]] \
	== [format %g [expr (200.0 - [testmetrics cyvscroll .s]*2 - 2) \
			   / ($height - 1 - [testmetrics cyvscroll .s]*2)]]
................................................................................
place .t.s -width 201
update

test scrollbar-3.41 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0.5}
if {[testConstraint testmetrics]} {

    place configure .t.s -width [expr 2*[testmetrics cxhscroll .t.s]+1]
} else {

    place configure .t.s -width [expr [winfo reqwidth .t.s] - 4]




}
update
test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0}
destroy .t
test scrollbar-3.43 {ScrollbarWidgetCmd procedure, "get" option} {
................................................................................
} {1 {wrong # args: should be ".s identify x y"}}
test scrollbar-3.48 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify bogus 2} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify -1 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.50 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 5
} {arrow1}




test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 35
} {trough1}
test scrollbar-3.52 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s set .3 .6
    .s identify 5 80
} {slider}
test scrollbar-3.53 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 145
} {trough2}
test scrollbar-3.54 {ScrollbarWidgetCmd procedure, "identify" option} {unixOrPc} {
    .s identify 5 195
} {arrow2}




test scrollbar-3.56 {ScrollbarWidgetCmd procedure, "identify" option} unix {
    .s identify 0 0
} {}
test scrollbar-3.57 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set abc def} msg] $msg
} {1 {expected floating-point number but got "abc"}}
test scrollbar-3.58 {ScrollbarWidgetCmd procedure, "set" option} {
................................................................................
} {}
test scrollbar-6.9 {ScrollbarPosition procedure} {
    .s identify -1 [expr [winfo height .s] / 2]
} {}
test scrollbar-6.10 {ScrollbarPosition procedure} {
    .s identify [winfo width .s] [expr [winfo height .s] / 2]
} {}
test scrollbar-6.11 {ScrollbarPosition procedure} unix {
    .s identify 8 4
} {arrow1}
test scrollbar-6.12 {ScrollbarPosition procedure} unix {




    .s identify 8 19
} {arrow1}




test scrollbar-6.14 {ScrollbarPosition procedure} win {
    .s identify [expr [winfo width .s] / 2] 0 
} {arrow1}
test scrollbar-6.15 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr [testmetrics cyvscroll .s] - 1]
} {arrow1}
test scrollbar-6.16 {ScrollbarPosition procedure} unix {
................................................................................
} {slider}
test scrollbar-6.24 {ScrollbarPosition procedure} unix {
    .s identify 8 84
} {trough2}
test scrollbar-6.25 {ScrollbarPosition procedure} unix {
    .s identify 8 179
} {trough2}
test scrollbar-6.27 {ScrollbarPosition procedure} {testmetrics win knownBug} {
    # This asks for 8,21, which is actually the slider, but there is a
    # bug in that GetSystemMetrics(SM_CYVTHUMB) actually returns a value
    # that is larger than the thumb displayed, skewing the ability to
    # calculate the trough2 area correctly (Win2k).  -- hobbs
    .s identify [expr [winfo width .s] / 2] [expr int(.4 / [.s delta 0 1]) \
						 + [testmetrics cyvscroll .s]]
} {trough2}
test scrollbar-6.28 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] \
						 - [testmetrics cyvscroll .s] - 1]
} {trough2}
test scrollbar-6.29 {ScrollbarPosition procedure} unix {
    .s identify 8 180
} {arrow2}




test scrollbar-6.30 {ScrollbarPosition procedure} unix {
    .s identify 8 195
} {arrow2}




test scrollbar-6.32 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2]  [expr [winfo height .s] \
						  - [testmetrics cyvscroll .s]]
} {arrow2}
test scrollbar-6.33 {ScrollbarPosition procedure} win {
    .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] - 1]
} {arrow2}
................................................................................
toplevel .t -width 250 -height 150
wm geometry .t +0+0
scrollbar .t.s -orient horizontal -relief sunken -bd 2 -highlightthickness 2
place .t.s -width 200
.t.s set .2 .4
update

test scrollbar-6.39 {ScrollbarPosition procedure} unix {
    .t.s identify 4 8
} {arrow1}




test scrollbar-6.40 {ScrollbarPosition procedure} win {
    .t.s identify 0 [expr [winfo height .t.s] / 2]
} {arrow1}
test scrollbar-6.41 {ScrollbarPosition procedure} unix {
    .t.s identify 82 8
} {slider}




test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} {
    .t.s identify [expr int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s] \
		       - 1] [expr [winfo height .t.s] / 2] 
} {slider}
test scrollbar-6.44 {ScrollbarPosition procedure} unix {
    .t.s identify 100 18
} {trough2}
................................................................................
    update
    lappend result [.s cget -orient]
} {horizontal vertical}

catch {destroy .t}
toplevel .t
wm geometry .t +0+0
test scrollbar-8.1 {TkScrollbarEventProc: recursive deletion} {


    proc doit {args} { destroy .t.f }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
................................................................................
    event generate .t.f.s <ButtonPress> -button 1 -x [expr [winfo width .t.f.s] / 2] -y 5
    event generate .t <ButtonRelease> -button 1
    update
    lappend result [winfo exists .t.f.s] [winfo exists .t.f]
    rename bgerror {}
    set result
} {1 0 0}
test scrollbar-8.2 {TkScrollbarEventProc: recursive deletion} {


    proc doit {args} { destroy .t.f.s }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
................................................................................
    catch {destroy .s}
    scrollbar .s
    interp hide {} .s
    destroy .s
    list [winfo children .] [interp hidden]
} [list {} $l]

test scrollbar-10.1 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup {
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}















test scrollbar-10.2 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0














} -cleanup {
    destroy .t .s
} -result {1.4}

test scrollbar-11.1 {bug fix: [011706ec42] Scrollbar unsafe wrt widget destruction} -body {
    proc destroy_scrollbar {} {
        if {[winfo exists .top.s]} {







>






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







 







|





|







 







>


>
|
>
>
>
>







 







|


>
>
>
>










|


>
>
>
>







 







|


|
>
>
>
>


>
>
>
>







 







|
<
<
<
<







|


>
>
>
>
|


>
>
>
>







 







|


>
>
>
>



|


>
>
>
>







 







|
>
>







 







|
>
>







 







|













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

|










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







14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
...
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
...
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
...
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
...
537
538
539
540
541
542
543
544




545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
...
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
...
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
...
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
proc scroll args {
    global scrollInfo
    set scrollInfo $args
}

proc getTroughSize {w} {
    if {[testConstraint testmetrics]} {
        # Only Windows has [testmetrics]
	if [string match v* [$w cget -orient]] {
	    return [expr [winfo height $w] - 2*[testmetrics cyvscroll $w]]
	} else {
	    return [expr [winfo width $w] - 2*[testmetrics cxhscroll $w]]
	}	    
    } else {
        if {[tk windowingsystem] eq "x11"} {
            # Calculations here assume that the arrow area is a square.
	    if [string match v* [$w cget -orient]] {
	        return [expr [winfo height $w] \
		        - ([winfo width $w] \
			    - [$w cget -highlightthickness] \
			    - [$w cget -bd] + 1)*2]
	    } else {
	        return [expr [winfo width $w] \
		        - ([winfo height $w] \
			    - [$w cget -highlightthickness] \
			    - [$w cget -bd] + 1)*2]
	    }
        } else {
            # macOS aqua
	    if [string match v* [$w cget -orient]] {
	        return [expr [winfo height $w] \
			- ([$w cget -highlightthickness] \
			  +[$w cget -bd])*2]
	    } else {
	        return [expr [winfo width $w] \
			- ([$w cget -highlightthickness] \
			  +[$w cget -bd])*2]
	    }
        }
    }
}

# XXX Note: this test file is woefully incomplete.  Right now there are
# only bits and pieces of tests.  Please make this file more complete
# as you fix bugs and add features.

................................................................................
test scrollbar-3.34 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 0 1000]
} {1}
test scrollbar-3.35 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.s fraction 4 21]
} [format %.6g [expr (21.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \
       /([getTroughSize .s] - 1)]]
test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} x11 {
    format {%.6g} [.s fraction 4 179]
} {1}
test scrollbar-3.37 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics} {
    format {%.6g} [.s fraction 4 [expr 200 - [testmetrics cyvscroll .s]]]
} {1}
test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} x11 {
    format {%.6g} [.s fraction 4 178]
} {0.993711}
test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} {
    expr \
    [format {%.6g} [.s fraction 4 [expr 200 - [testmetrics cyvscroll .s] - 2]]] \
	== [format %g [expr (200.0 - [testmetrics cyvscroll .s]*2 - 2) \
			   / ($height - 1 - [testmetrics cyvscroll .s]*2)]]
................................................................................
place .t.s -width 201
update

test scrollbar-3.41 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0.5}
if {[testConstraint testmetrics]} {
    # Only Windows has [testmetrics]
    place configure .t.s -width [expr 2*[testmetrics cxhscroll .t.s]+1]
} else {
    if {[tk windowingsystem] eq "x11"} {
        place configure .t.s -width [expr [winfo height .t.s] - 2*([.t.s cget -highlightthickness] + [.t.s cget -bd] + 1)]
    } else {
        # macOS aqua
        place configure .t.s -width [expr 2*([.t.s cget -highlightthickness] + [.t.s cget -bd])]
    }
}
update
test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} {
    format {%.6g} [.t.s fraction 100 0]
} {0}
destroy .t
test scrollbar-3.43 {ScrollbarWidgetCmd procedure, "get" option} {
................................................................................
} {1 {wrong # args: should be ".s identify x y"}}
test scrollbar-3.48 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify bogus 2} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} {
    list [catch {.s identify -1 bogus} msg] $msg
} {1 {expected integer but got "bogus"}}
test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 5
} {arrow1}
test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 5 5
} {trough1}
test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 35
} {trough1}
test scrollbar-3.52 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s set .3 .6
    .s identify 5 80
} {slider}
test scrollbar-3.53 {ScrollbarWidgetCmd procedure, "identify" option} {
    .s identify 5 145
} {trough2}
test scrollbar-3.54.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua {
    .s identify 5 195
} {arrow2}
test scrollbar-3.54.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 5 195
} {trough2}
test scrollbar-3.56 {ScrollbarWidgetCmd procedure, "identify" option} unix {
    .s identify 0 0
} {}
test scrollbar-3.57 {ScrollbarWidgetCmd procedure, "set" option} {
    list [catch {.s set abc def} msg] $msg
} {1 {expected floating-point number but got "abc"}}
test scrollbar-3.58 {ScrollbarWidgetCmd procedure, "set" option} {
................................................................................
} {}
test scrollbar-6.9 {ScrollbarPosition procedure} {
    .s identify -1 [expr [winfo height .s] / 2]
} {}
test scrollbar-6.10 {ScrollbarPosition procedure} {
    .s identify [winfo width .s] [expr [winfo height .s] / 2]
} {}
test scrollbar-6.11.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 4
} {arrow1}
test scrollbar-6.11.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 4
} {trough1}
test scrollbar-6.12.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 19
} {arrow1}
test scrollbar-6.12.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 19
} {trough1}
test scrollbar-6.14 {ScrollbarPosition procedure} win {
    .s identify [expr [winfo width .s] / 2] 0 
} {arrow1}
test scrollbar-6.15 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr [testmetrics cyvscroll .s] - 1]
} {arrow1}
test scrollbar-6.16 {ScrollbarPosition procedure} unix {
................................................................................
} {slider}
test scrollbar-6.24 {ScrollbarPosition procedure} unix {
    .s identify 8 84
} {trough2}
test scrollbar-6.25 {ScrollbarPosition procedure} unix {
    .s identify 8 179
} {trough2}
test scrollbar-6.27 {ScrollbarPosition procedure} {testmetrics win} {




    .s identify [expr [winfo width .s] / 2] [expr int(.4 / [.s delta 0 1]) \
						 + [testmetrics cyvscroll .s]]
} {trough2}
test scrollbar-6.28 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] \
						 - [testmetrics cyvscroll .s] - 1]
} {trough2}
test scrollbar-6.29.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 180
} {arrow2}
test scrollbar-6.29.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 180
} {trough2}
test scrollbar-6.30.1 {ScrollbarPosition procedure} x11 {
    .s identify 8 195
} {arrow2}
test scrollbar-6.30.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .s identify 8 195
} {trough2}
test scrollbar-6.32 {ScrollbarPosition procedure} {testmetrics win} {
    .s identify [expr [winfo width .s] / 2]  [expr [winfo height .s] \
						  - [testmetrics cyvscroll .s]]
} {arrow2}
test scrollbar-6.33 {ScrollbarPosition procedure} win {
    .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] - 1]
} {arrow2}
................................................................................
toplevel .t -width 250 -height 150
wm geometry .t +0+0
scrollbar .t.s -orient horizontal -relief sunken -bd 2 -highlightthickness 2
place .t.s -width 200
.t.s set .2 .4
update

test scrollbar-6.39.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 4 8
} {arrow1}
test scrollbar-6.39.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .t.s identify 4 8
} {trough1}
test scrollbar-6.40 {ScrollbarPosition procedure} win {
    .t.s identify 0 [expr [winfo height .t.s] / 2]
} {arrow1}
test scrollbar-6.41.1 {ScrollbarPosition procedure} x11 {
    .t.s identify 82 8
} {slider}
test scrollbar-6.41.2 {ScrollbarPosition procedure} aqua {
    # macOS scrollbars have no arrows nowadays
    .t.s identify 82 8
} {trough2}
test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} {
    .t.s identify [expr int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s] \
		       - 1] [expr [winfo height .t.s] / 2] 
} {slider}
test scrollbar-6.44 {ScrollbarPosition procedure} unix {
    .t.s identify 100 18
} {trough2}
................................................................................
    update
    lappend result [.s cget -orient]
} {horizontal vertical}

catch {destroy .t}
toplevel .t
wm geometry .t +0+0
test scrollbar-8.1 {TkScrollbarEventProc: recursive deletion} notAqua {
    # constrained by notAqua because this test clicks on an arrow of the
    # scrollbar - but macOS has no such arrows in modern scrollbars
    proc doit {args} { destroy .t.f }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
................................................................................
    event generate .t.f.s <ButtonPress> -button 1 -x [expr [winfo width .t.f.s] / 2] -y 5
    event generate .t <ButtonRelease> -button 1
    update
    lappend result [winfo exists .t.f.s] [winfo exists .t.f]
    rename bgerror {}
    set result
} {1 0 0}
test scrollbar-8.2 {TkScrollbarEventProc: recursive deletion} notAqua {
    # constrained by notAqua because this test clicks on an arrow of the
    # scrollbar - but macOS has no such arrows in modern scrollbars
    proc doit {args} { destroy .t.f.s }
    proc bgerror {args} {}
    destroy .t.f
    frame .t.f
    scrollbar .t.f.s -command doit
    pack .t.f -fill both -expand 1
    pack .t.f.s -fill y -expand 1 -side right
................................................................................
    catch {destroy .s}
    scrollbar .s
    interp hide {} .s
    destroy .s
    list [winfo children .] [interp hidden]
} [list {} $l]

test scrollbar-10.1.1 {<MouseWheel> event on scrollbar} -constraints {notAqua} -setup {
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}
test scrollbar-10.1.2 {<MouseWheel> event on scrollbar} -constraints {aqua} -setup {
    destroy .t .s
} -body {
    pack [text .t -yscrollcommand {.s set}] -side left
    for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"}
    pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left
    update
    focus -force .s
    event generate .s <MouseWheel> -delta -4
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {5.0}

test scrollbar-10.2.1 {<MouseWheel> event on scrollbar} -constraints {notAqua} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Shift-MouseWheel> -delta -120
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}
test scrollbar-10.2.2 {<MouseWheel> event on scrollbar} -constraints {aqua} -setup {
    destroy .t .s
} -body {
    pack [text .t -xscrollcommand {.s set} -wrap none] -side top
    for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "}
    pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top
    update
    focus -force .s
    event generate .s <Shift-MouseWheel> -delta -4
    after 200 {set eventprocessed 1} ; vwait eventprocessed
    .t index @0,0
} -cleanup {
    destroy .t .s
} -result {1.4}

test scrollbar-11.1 {bug fix: [011706ec42] Scrollbar unsafe wrt widget destruction} -body {
    proc destroy_scrollbar {} {
        if {[winfo exists .top.s]} {

Changes to tests/select.test.

329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
...
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
860
861
862
863
864
865
866
867
868
869
870
871
872
873

874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
...
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
...
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
....
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
....
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
....
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
....
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
....
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel {lost2} } .f1
    set result $lostSel
    selection clear .f1
    lappend result $lostSel
} -result {owned lost2}
test select-3.7 {Tk_OwnSelection procedure} -constraints unix -setup {
    global lostSel
    setup
    setupbg
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
................................................................................
    selection own -selection CLIPBOARD
} -result {.f1}
test select-4.3 {Tk_ClearSelection procedure} -setup {
    setup
} -body {
    list [selection clear .f1] [selection clear .f1]
} -result {{} {}}
test select-4.4 {Tk_ClearSelection procedure} -constraints unix -setup {
    global lostSel
    setup
    setupbg
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
................................................................................
    selection own -command { set lostSel2 {lost2} } .f2
    update
    selection clear -displayof .f2
    update
    list $lostSel $lostSel2
} -result {owned lost2}
test select-4.6 {Tk_ClearSelection procedure} -constraints {
    unix altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    set lostSel {owned}
    set lostSel2 {owned2}
................................................................................
    set selInfo ""
    selection handle .f1 {apply {{type offset count} {
	selection clear
	handler $type $offset $count
    }} STRING}
    list [selection get] $selInfo [catch {selection get} msg] $msg
} -result "$longValue {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000} 1 {PRIMARY selection doesn't exist or form \"STRING\" not defined}"
test select-5.9 {Tk_GetSelection procedure} -constraints unix -setup {
    setup
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-5.10 {Tk_GetSelection procedure} -constraints unix -setup {
    setup
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
................................................................................
    set result [list [catch {selection get TEST} msg] $msg $selInfo]
    set selValue "Test value2"
    set selInfo ""
    lappend result [catch {selection get -displayof .f2 TEST} msg] $msg \
	    $selInfo
} -result {0 {Test value} {TEST 0 4000} 1 {PRIMARY selection doesn't exist or form "TEST" not defined} {}}
test select-5.13 {Tk_GetSelection procedure} -constraints {
    unix altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
................................................................................
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection get -displayof .t TEST"]
    set selValue "Test value2"
    lappend result [dobg "selection get TEST"]
    cleanupbg
    lappend result $selInfo
} -result {{Test value} {Test value2} {TEST2 0 4000 TEST 0 4000}}
test select-5.14 {Tk_GetSelection procedure} -constraints {
    unix altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
................................................................................
    destroy .f1
    lappend result [selection own] [catch {selection get} msg] $msg
} -result {.f1 {} 1 {PRIMARY selection doesn't exist or form "STRING" not defined}}

##############################################################################

# Check reentrancy on losing selection
test select-8.1 {TkSelEventProc procedure} -constraints unix -setup {
    setup
    setupbg
} -body {
    selection own -selection CLIPBOARD -command {destroy .f1} .f1
    update
    dobg {selection own -selection CLIPBOARD .}

} -cleanup {
    cleanupbg
} -result {}

##############################################################################

test select-9.1 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints unix -body {
    set selValue "1024"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
        .f1 {handler TEST}
    update
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 } {TEST 0 4000}}
test select-9.2 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints unix -body {
    set selValue "1024 0xffff  2048 -2  "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 0xffff 0x800 0xfffffffe } {TEST 0 4000}}
test select-9.3 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints unix -body {
    set selValue "   "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{ } {TEST 0 4000}}
test select-9.4 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints unix -body {
    set selValue "16 foobar 32"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x10 0x0 0x20 } {TEST 0 4000}}
test select-9.5 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints unix -body {
    # Ensure that lists of atoms are constructed correctly, even when the
    # atom names have spaces in. [Bug 1353414]
    set selValue "foo bar"
    set selInfo ""
    set selType {text/x-tk-test;detail="foo bar"}
    selection handle -selection PRIMARY -format STRING -type $selType \
    .f1 [list handler $selType]
................................................................................
} -result {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW {text/x-tk-test;detail="foo bar"}}

##############################################################################
# note, we are not testing MULTIPLE style selections

# most control paths have been exercised above
test select-10.1 {ConvertSelection procedure, race with selection clear} -constraints {
    unix 
} -setup {
    setup
} -body {
    proc Ready {fd} {
	variable x
	lappend x [gets $fd]
    }
................................................................................
    puts $fd {exit}
    flush $fd
    # Don't understand why, but the [loadTkCommand] above causes
    # a "broken pipe" error when Tk was actually [load]ed in the child.
    catch {close $fd}
    lappend x $selInfo
} -result {{1:PRIMARY selection doesn't exist or form "STRING" not defined} {}}
test select-10.2 {ConvertSelection procedure} -constraints unix -setup {
    setup
    setupbg
} -body {
    set selValue [string range $longValue 0 3999]
    set selInfo ""
    selection handle .f1 {handler STRING}
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result [list [string range $longValue 0 3999] {STRING 0 4000 STRING 4000 4000 STRING 0 4000 STRING 4000 4000}]
test select-10.3 {ConvertSelection procedure} -constraints unix -setup {
    setup
    setupbg
} -body {
    selection handle .f1 ERROR errHandler
    dobg {selection get ERROR}
} -cleanup {
    cleanupbg
} -result {PRIMARY selection doesn't exist or form "ERROR" not defined}
# testing timers
# This one hangs in Exceed
test select-10.4 {ConvertSelection procedure} -constraints {
    unix noExceed
} -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {errIncrHandler STRING}
................................................................................
    set result ""
    set pass 0
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000 STRING 0 4000 STRING 4000 4000}}
test select-10.5 {ConvertSelection procedure, reentrancy issues} -constraints {
    unix 
} -setup {
    setup
    setupbg
} -body {
    set selValue "Test value"
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
................................................................................
    selection handle -type STRING .f1 { badHandler .f1 STRING }
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000}}
test select-10.6 {ConvertSelection procedure, reentrancy issues} -constraints {
    unix 
} -setup {
    setup
    setupbg
} -body {
    proc weirdHandler {type offset count} {
	destroy .f1
	handler $type $offset $count
................................................................................
} -cleanup {
    rename weirdHandler {}
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {STRING 0 4000}}

##############################################################################

# testing reentrancy
test select-11.1 {TkSelPropProc procedure} -constraints unix -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { reallyBadHandler .f1 STRING }
................................................................................
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {.f1 STRING 0 4000 .f1 STRING 4000 4000 .f1 STRING 8000 4000 .f1 STRING 12000 4000 .f1 STRING 16000 4000 .f1 STRING 0 4000 .f1 STRING 4000 4000}}

##############################################################################

# Note, this assumes we are using CurrentTtime
test select-12.1 {DefaultSelection procedure} -constraints unix -body {
    setup
    set result [selection get -type TIMESTAMP]
    setupbg
    lappend result [dobg {selection get -type TIMESTAMP}]
    cleanupbg
    set result
} -result {0x0 {0x0 }}
test select-12.2 {DefaultSelection procedure} -constraints unix -body {
    setup
    set result [lsort [list [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} -result {{MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.3 {DefaultSelection procedure} -constraints unix -body {
    setup
    selection handle .f1 {handler TEST} TEST
    set result [list [lsort [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} -result {{MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.4 {DefaultSelection procedure} -constraints unix -setup {
    setup
    set result ""
} -body {
    lappend result [selection get -type TK_APPLICATION]
    setupbg
    lappend result [dobg {selection get -type TK_APPLICATION}]
    cleanupbg
    set result
} -result [list [winfo name .] [winfo name .]]
test select-12.5 {DefaultSelection procedure} -constraints unix -body {
    setup
    set result [selection get -type TK_WINDOW]
    setupbg
    lappend result [dobg {selection get -type TK_WINDOW}]
    cleanupbg
    set result
} -result {.f1 .f1}
................................................................................
    set selInfo ""
    set result [list [selection get TARGETS] $selInfo]
    selection handle .f1 {} TARGETS
    lappend result [selection get TARGETS]
} -result {{Targets value} {TARGETS.f1 0 4000} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}

test select-13.1 {SelectionSize procedure, handler deleted} -constraints {
    unix 
} -setup {
    setup
    setupbg
} -body {
    proc badHandler {path type offset count} {
	global selValue selInfo abortCount
	incr abortCount -1







|







 







|







 







|







 







|












|







 







|







 







|







 







|






>









|













|












|












|












|







 







|







 







|











|











|







 







|







 







|







 







|







 







|







|







|








|









|







 







|







329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
...
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
...
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
...
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
...
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
...
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
...
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
...
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
....
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
....
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
....
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
....
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
....
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    selection own -command { set lostSel {lost2} } .f1
    set result $lostSel
    selection clear .f1
    lappend result $lostSel
} -result {owned lost2}
test select-3.7 {Tk_OwnSelection procedure} -constraints x11 -setup {
    global lostSel
    setup
    setupbg
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
................................................................................
    selection own -selection CLIPBOARD
} -result {.f1}
test select-4.3 {Tk_ClearSelection procedure} -setup {
    setup
} -body {
    list [selection clear .f1] [selection clear .f1]
} -result {{} {}}
test select-4.4 {Tk_ClearSelection procedure} -constraints x11 -setup {
    global lostSel
    setup
    setupbg
} -body {
    set lostSel {owned}
    selection own -command { set lostSel {lost1} } .f1
    update
................................................................................
    selection own -command { set lostSel2 {lost2} } .f2
    update
    selection clear -displayof .f2
    update
    list $lostSel $lostSel2
} -result {owned lost2}
test select-4.6 {Tk_ClearSelection procedure} -constraints {
    x11 altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    set lostSel {owned}
    set lostSel2 {owned2}
................................................................................
    set selInfo ""
    selection handle .f1 {apply {{type offset count} {
	selection clear
	handler $type $offset $count
    }} STRING}
    list [selection get] $selInfo [catch {selection get} msg] $msg
} -result "$longValue {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000} 1 {PRIMARY selection doesn't exist or form \"STRING\" not defined}"
test select-5.9 {Tk_GetSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{Test value} {TEST 0 4000}}
test select-5.10 {Tk_GetSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    update
    set selValue "Test value"
    set selInfo ""
................................................................................
    set result [list [catch {selection get TEST} msg] $msg $selInfo]
    set selValue "Test value2"
    set selInfo ""
    lappend result [catch {selection get -displayof .f2 TEST} msg] $msg \
	    $selInfo
} -result {0 {Test value} {TEST 0 4000} 1 {PRIMARY selection doesn't exist or form "TEST" not defined} {}}
test select-5.13 {Tk_GetSelection procedure} -constraints {
    x11 altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
................................................................................
    lappend result [dobg "toplevel .t -screen $env(TK_ALT_DISPLAY); wm geom .t +0+0; selection get -displayof .t TEST"]
    set selValue "Test value2"
    lappend result [dobg "selection get TEST"]
    cleanupbg
    lappend result $selInfo
} -result {{Test value} {Test value2} {TEST2 0 4000 TEST 0 4000}}
test select-5.14 {Tk_GetSelection procedure} -constraints {
    x11 altDisplay
} -setup {
    setup .f1
    setup .f2 $env(TK_ALT_DISPLAY)
    setupbg
} -body {
    selection handle -selection PRIMARY .f1 {handler TEST} TEST
    selection own .f1
................................................................................
    destroy .f1
    lappend result [selection own] [catch {selection get} msg] $msg
} -result {.f1 {} 1 {PRIMARY selection doesn't exist or form "STRING" not defined}}

##############################################################################

# Check reentrancy on losing selection
test select-8.1 {TkSelEventProc procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection own -selection CLIPBOARD -command {destroy .f1} .f1
    update
    dobg {selection own -selection CLIPBOARD .}
    winfo children .
} -cleanup {
    cleanupbg
} -result {}

##############################################################################

test select-9.1 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
    set selValue "1024"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
        .f1 {handler TEST}
    update
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 } {TEST 0 4000}}
test select-9.2 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
    set selValue "1024 0xffff  2048 -2  "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x400 0xffff 0x800 0xfffffffe } {TEST 0 4000}}
test select-9.3 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
    set selValue "   "
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{ } {TEST 0 4000}}
test select-9.4 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
    set selValue "16 foobar 32"
    set selInfo ""
    selection handle -selection PRIMARY -format INTEGER -type TEST \
	.f1 {handler TEST}
    set result ""
    lappend result [dobg {selection get TEST}]
    cleanupbg
    lappend result $selInfo
} -result {{0x10 0x0 0x20 } {TEST 0 4000}}
test select-9.5 {SelCvtToX and SelCvtFromX procedures} -setup {
    setup
    setupbg
} -constraints x11 -body {
    # Ensure that lists of atoms are constructed correctly, even when the
    # atom names have spaces in. [Bug 1353414]
    set selValue "foo bar"
    set selInfo ""
    set selType {text/x-tk-test;detail="foo bar"}
    selection handle -selection PRIMARY -format STRING -type $selType \
    .f1 [list handler $selType]
................................................................................
} -result {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW {text/x-tk-test;detail="foo bar"}}

##############################################################################
# note, we are not testing MULTIPLE style selections

# most control paths have been exercised above
test select-10.1 {ConvertSelection procedure, race with selection clear} -constraints {
    x11 
} -setup {
    setup
} -body {
    proc Ready {fd} {
	variable x
	lappend x [gets $fd]
    }
................................................................................
    puts $fd {exit}
    flush $fd
    # Don't understand why, but the [loadTkCommand] above causes
    # a "broken pipe" error when Tk was actually [load]ed in the child.
    catch {close $fd}
    lappend x $selInfo
} -result {{1:PRIMARY selection doesn't exist or form "STRING" not defined} {}}
test select-10.2 {ConvertSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    set selValue [string range $longValue 0 3999]
    set selInfo ""
    selection handle .f1 {handler STRING}
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result [list [string range $longValue 0 3999] {STRING 0 4000 STRING 4000 4000 STRING 0 4000 STRING 4000 4000}]
test select-10.3 {ConvertSelection procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    selection handle .f1 ERROR errHandler
    dobg {selection get ERROR}
} -cleanup {
    cleanupbg
} -result {PRIMARY selection doesn't exist or form "ERROR" not defined}
# testing timers
# This one hangs in Exceed
test select-10.4 {ConvertSelection procedure} -constraints {
    x11 noExceed
} -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle .f1 {errIncrHandler STRING}
................................................................................
    set result ""
    set pass 0
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {STRING 0 4000 STRING 4000 4000 STRING 8000 4000 STRING 12000 4000 STRING 16000 4000 STRING 0 4000 STRING 4000 4000}}
test select-10.5 {ConvertSelection procedure, reentrancy issues} -constraints {
    x11 
} -setup {
    setup
    setupbg
} -body {
    set selValue "Test value"
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
................................................................................
    selection handle -type STRING .f1 { badHandler .f1 STRING }
    set result ""
    lappend result [dobg {selection get}]
    cleanupbg
    lappend result $selInfo
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000}}
test select-10.6 {ConvertSelection procedure, reentrancy issues} -constraints {
    x11 
} -setup {
    setup
    setupbg
} -body {
    proc weirdHandler {type offset count} {
	destroy .f1
	handler $type $offset $count
................................................................................
} -cleanup {
    rename weirdHandler {}
} -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {STRING 0 4000}}

##############################################################################

# testing reentrancy
test select-11.1 {TkSelPropProc procedure} -constraints x11 -setup {
    setup
    setupbg
} -body {
    set selValue $longValue
    set selInfo ""
    selection handle -type TEST .f1 { handler TEST }
    selection handle -type STRING .f1 { reallyBadHandler .f1 STRING }
................................................................................
    cleanupbg
    lappend result $selInfo
} -result {{selection owner didn't respond} {.f1 STRING 0 4000 .f1 STRING 4000 4000 .f1 STRING 8000 4000 .f1 STRING 12000 4000 .f1 STRING 16000 4000 .f1 STRING 0 4000 .f1 STRING 4000 4000}}

##############################################################################

# Note, this assumes we are using CurrentTtime
test select-12.1 {DefaultSelection procedure} -constraints x11 -body {
    setup
    set result [selection get -type TIMESTAMP]
    setupbg
    lappend result [dobg {selection get -type TIMESTAMP}]
    cleanupbg
    set result
} -result {0x0 {0x0 }}
test select-12.2 {DefaultSelection procedure} -constraints x11 -body {
    setup
    set result [lsort [list [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} -result {{MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.3 {DefaultSelection procedure} -constraints x11 -body {
    setup
    selection handle .f1 {handler TEST} TEST
    set result [list [lsort [selection get -type TARGETS]]]
    setupbg
    lappend result [dobg {lsort [selection get -type TARGETS]}]
    cleanupbg
    set result
} -result {{MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}}
test select-12.4 {DefaultSelection procedure} -constraints x11 -setup {
    setup
    set result ""
} -body {
    lappend result [selection get -type TK_APPLICATION]
    setupbg
    lappend result [dobg {selection get -type TK_APPLICATION}]
    cleanupbg
    set result
} -result [list [winfo name .] [winfo name .]]
test select-12.5 {DefaultSelection procedure} -constraints x11 -body {
    setup
    set result [selection get -type TK_WINDOW]
    setupbg
    lappend result [dobg {selection get -type TK_WINDOW}]
    cleanupbg
    set result
} -result {.f1 .f1}
................................................................................
    set selInfo ""
    set result [list [selection get TARGETS] $selInfo]
    selection handle .f1 {} TARGETS
    lappend result [selection get TARGETS]
} -result {{Targets value} {TARGETS.f1 0 4000} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}}

test select-13.1 {SelectionSize procedure, handler deleted} -constraints {
    x11 
} -setup {
    setup
    setupbg
} -body {
    proc badHandler {path type offset count} {
	global selValue selInfo abortCount
	incr abortCount -1

Changes to tests/text.test.

1583
1584
1585
1586
1587
1588
1589









1590
1591
1592
1593
1594
1595
1596
....
5544
5545
5546
5547
5548
5549
5550
5551
5552
5553
5554
5555
5556
5557
5558
5559
5560
5561
5562
5563
5564
5565
5566
5567
5568
5569
5570
5571
....
5575
5576
5577
5578
5579
5580
5581
5582
5583
5584
5585
5586
5587
5588
5589
5590
5591
5592
5593
5594
5595
5596
5597
5598
5599
5600
5601
5602
5603
5604
5605
....
5860
5861
5862
5863
5864
5865
5866
5867





















































































































































































































5868
5869
5870
5871
5872
5873
5874
    .tt insert 0.0 \na
    for {set i 0} {$i < 2} {incr i} {
        .tt replace 2.0 3.0 b
    }
} -cleanup {
    destroy .tt
} -result {}











test text-9.1 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get
} -cleanup {
................................................................................
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {(b+\nc+\nb+)\na+} 1.0] $foo
} -cleanup {
    destroy .t
} -result {2.0 19}
test text-22.199 {TextSearchCmd, regexp search multi-line} -constraints {
    knownBug
} -body {
    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {(a+|b+\nc+\nb+)\na+} 1.0] $foo
} -cleanup {
    destroy .t
} -result {2.0 19}
test text-22.200 {TextSearchCmd, regexp search multi-line} -constraints {
    knownBug
} -body {
    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {(a+|b+\nc+\nb+)+\na+} 1.0] $foo
} -cleanup {
    destroy .t
................................................................................
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {((a+|b+\nc+\nb+)+\n)+a+} 1.0] $foo
} -cleanup {
    destroy .t
} -result {1.0 24}
test text-22.202 {TextSearchCmd, regexp search multi-line} -constraints {
    knownBug
} -body {
    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n"
    list [.t search -regexp -backward -all -count foo \
      -- {b+\n|a+\n(b+\n)+} end] $foo
} -cleanup {
    destroy .t
} -result {1.0 25}
test text-22.203 {TextSearchCmd, regexp search multi-line} -constraints {
    knownBug
} -body {
    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n"
    .t search -regexp -backward -- {b+\n|a+\n(b+\n)+} end
# Should match at 1.0 for a true greedy match
} -cleanup {
    destroy .t
} -result {1.0}
test text-22.204 {TextSearchCmd, regexp search multi-line} -body {
    pack [text .t]
    .t insert 1.0 "line0\nline1\nline1\nline1\nline1\nline2\nline2\nline2\nline3\n"
    .t search -nolinestop -regexp -nocase -forwards -- {^(.*)\n(\1\n)+} 1.0 end
................................................................................
test text-22.225 {TextSearchCmd, strict limits} -body {
    pack [text .t]
    .t insert 1.0 "Hello world!\nThis is a test\n"
    .t search -regexp -strictlimits -backward -- "world" 2.3 1.8
} -cleanup {
    destroy .t
} -result {}























































































































































































































test text-23.1 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs "\{{}"







>
>
>
>
>
>
>
>
>







 







|
<
<








|
<
<







 







|
<
<



|



|
<
<


|
<







 







<
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
....
5553
5554
5555
5556
5557
5558
5559
5560


5561
5562
5563
5564
5565
5566
5567
5568
5569


5570
5571
5572
5573
5574
5575
5576
....
5580
5581
5582
5583
5584
5585
5586
5587


5588
5589
5590
5591
5592
5593
5594
5595


5596
5597
5598

5599
5600
5601
5602
5603
5604
5605
....
5860
5861
5862
5863
5864
5865
5866

5867
5868
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879
5880
5881
5882
5883
5884
5885
5886
5887
5888
5889
5890
5891
5892
5893
5894
5895
5896
5897
5898
5899
5900
5901
5902
5903
5904
5905
5906
5907
5908
5909
5910
5911
5912
5913
5914
5915
5916
5917
5918
5919
5920
5921
5922
5923
5924
5925
5926
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937
5938
5939
5940
5941
5942
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5955
5956
5957
5958
5959
5960
5961
5962
5963
5964
5965
5966
5967
5968
5969
5970
5971
5972
5973
5974
5975
5976
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987
5988
5989
5990
5991
5992
5993
5994
5995
5996
5997
5998
5999
6000
6001
6002
6003
6004
6005
6006
6007
6008
6009
6010
6011
6012
6013
6014
6015
6016
6017
6018
6019
6020
6021
6022
6023
6024
6025
6026
6027
6028
6029
6030
6031
6032
6033
6034
6035
6036
6037
6038
6039
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050
6051
6052
6053
6054
6055
6056
6057
6058
6059
6060
6061
6062
6063
6064
6065
6066
6067
6068
6069
6070
6071
6072
6073
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
    .tt insert 0.0 \na
    for {set i 0} {$i < 2} {incr i} {
        .tt replace 2.0 3.0 b
    }
} -cleanup {
    destroy .tt
} -result {}
test text-8.28 {TextWidgetCmd procedure, "replace" option crash} -setup {
    text .tt
} -body {
    .tt insert end "foo\n"
    .tt tag add sel 1.0 end
    .tt replace sel.first sel.last "bar"
} -cleanup {
    destroy .tt
} -result {}


test text-9.1 {TextWidgetCmd procedure, "get" option} -setup {
    text .t
} -body {
    .t get
} -cleanup {
................................................................................
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {(b+\nc+\nb+)\na+} 1.0] $foo
} -cleanup {
    destroy .t
} -result {2.0 19}
test text-22.199 {TextSearchCmd, regexp search multi-line} -body {


    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {(a+|b+\nc+\nb+)\na+} 1.0] $foo
} -cleanup {
    destroy .t
} -result {2.0 19}
test text-22.200 {TextSearchCmd, regexp search multi-line} -body {


    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {(a+|b+\nc+\nb+)+\na+} 1.0] $foo
} -cleanup {
    destroy .t
................................................................................
    .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n"
    set foo {}
    list [.t search -regexp -forward -all -count foo \
      -- {((a+|b+\nc+\nb+)+\n)+a+} 1.0] $foo
} -cleanup {
    destroy .t
} -result {1.0 24}
test text-22.202 {TextSearchCmd, regexp search multi-line} -body {


    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n"
    list [.t search -regexp -backward -all -count foo \
      -- {(b+\n|a+\n)(b+\n)+} end] $foo
} -cleanup {
    destroy .t
} -result {1.0 25}
test text-22.203 {TextSearchCmd, regexp search multi-line} -body {


    pack [text .t]
    .t insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n"
    .t search -regexp -backward -- {(b+\n|a+\n)(b+\n)+} end

} -cleanup {
    destroy .t
} -result {1.0}
test text-22.204 {TextSearchCmd, regexp search multi-line} -body {
    pack [text .t]
    .t insert 1.0 "line0\nline1\nline1\nline1\nline1\nline2\nline2\nline2\nline3\n"
    .t search -nolinestop -regexp -nocase -forwards -- {^(.*)\n(\1\n)+} 1.0 end
................................................................................
test text-22.225 {TextSearchCmd, strict limits} -body {
    pack [text .t]
    .t insert 1.0 "Hello world!\nThis is a test\n"
    .t search -regexp -strictlimits -backward -- "world" 2.3 1.8
} -cleanup {
    destroy .t
} -result {}

test text-22.226 {TextSearchCmd, exact search for the empty string} -body {
    text .t
    set res [.t search -count C "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.227 {TextSearchCmd, exact search for the empty string} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C "" 2.5]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.5 0}
test text-22.228 {TextSearchCmd, exact search all empty strings} -body {
    text .t
    set res [.t search -count C -all "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.229 {TextSearchCmd, exact search all empty strings} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -all "" 2.5 2.8]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.5 2.6 2.7 {0 0 0}}
test text-22.230 {TextSearchCmd, exact search all empty strings, with overlap} -body {
    text .t
    set res [.t search -count C -all -overlap "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.231 {TextSearchCmd, exact search all empty strings, with overlap} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -all -overlap "" 2.5 2.8]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.5 2.6 2.7 {0 0 0}}
test text-22.232 {TextSearchCmd, regexp search for the empty string} -body {
    text .t
    set res [.t search -count C -regexp "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.233 {TextSearchCmd, regexp search for the empty string} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -regexp "" 2.5]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.5 0}
test text-22.234 {TextSearchCmd, regexp search all empty strings} -body {
    text .t
    set res [.t search -count C -all -regexp "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.235 {TextSearchCmd, regexp search all empty strings} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -all -regexp "" 2.5 2.8]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.5 2.6 2.7 {0 0 0}}
test text-22.236 {TextSearchCmd, regexp search all empty strings, with overlap} -body {
    text .t
    set res [.t search -count C -all -regexp -overlap "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.237 {TextSearchCmd, regexp search all empty strings, with overlap} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -all -regexp -overlap "" 2.5 2.8]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.5 2.6 2.7 {0 0 0}}
test text-22.238 {TextSearchCmd, exact backwards search for the empty string} -body {
    text .t
    set res [.t search -count C -backwards "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.239 {TextSearchCmd, exact backwards search for the empty string} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -backwards "" 2.5]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.4 0}
test text-22.240 {TextSearchCmd, exact backwards search all empty strings} -body {
    text .t
    set res [.t search -count C -backwards -all "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.241 {TextSearchCmd, exact backwards search all empty strings} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -backwards -all "" 2.5 2.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}}
test text-22.242 {TextSearchCmd, exact backwards search all empty strings, with overlap} -body {
    text .t
    set res [.t search -count C -backwards -all -overlap "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.243 {TextSearchCmd, exact backwards search all empty strings, with overlap} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -backwards -all -overlap "" 2.5 2.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}}
test text-22.244 {TextSearchCmd, regexp backwards search for the empty string} -body {
    text .t
    set res [.t search -count C -backwards -regexp "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.245 {TextSearchCmd, regexpbackwards search for the empty string} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -backwards -regexp "" 2.5]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.4 0}
test text-22.246 {TextSearchCmd, regexp backwards search all empty strings} -body {
    text .t
    set res [.t search -count C -backwards -all -regexp "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.247 {TextSearchCmd, regexp backwards search all empty strings} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -backwards -all -regexp "" 2.5 2.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}}
test text-22.248 {TextSearchCmd, regexp backwards search all empty strings, with overlap} -body {
    text .t
    set res [.t search -count C -backwards -all -regexp -overlap "" 1.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {1.0 0}
test text-22.249 {TextSearchCmd, regexp backwards search all empty strings, with overlap} -body {
    text .t
    .t insert end "Searching for the\nempty string!"
    set res [.t search -count C -backwards -all -regexp -overlap "" 2.5 2.0]
    lappend res $C
} -cleanup {
    destroy .t
    unset -nocomplain res C
} -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}}
test text-22.250 {TextSearchCmd, backwards search all matching at start of line} -body {
    text .t
    .t insert end "abc"
    set res [.t search -backwards -all b end]      ; # works
    lappend res [.t search -backwards a end]       ; # works
    lappend res [.t search -backwards -all a end]  ; # used to hang
} -cleanup {
    destroy .t
} -result {1.1 1.0 1.0}

test text-23.1 {TkTextGetTabs procedure} -setup {
    text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100
    pack .t
} -body {
    .t insert end "1\t2\t3\t4\t55.5"
    .t configure -tabs "\{{}"

Changes to tests/textDisp.test.

3370
3371
3372
3373
3374
3375
3376










3377
3378
3379
3380
3381
3382
3383
test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {textfonts} {
    .t delete 1.0 end
    .t tag configure x -justify center
    .t insert 1.0 aa\tbb\tcc\tdd\t
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.10]
} [list [list 45 3 7 $fixedHeight] [list 94 3 7 $fixedHeight]]











.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
    -tabs 100
update
test textDisp-25.1 {CharBboxProc procedure, check tab width} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\td\tfgh







>
>
>
>
>
>
>
>
>
>







3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3392
3393
test textDisp-24.24 {TkTextCharLayoutProc, justification and tabs} {textfonts} {
    .t delete 1.0 end
    .t tag configure x -justify center
    .t insert 1.0 aa\tbb\tcc\tdd\t
    .t tag add x 1.0 end
    list [.t bbox 1.0] [.t bbox 1.10]
} [list [list 45 3 7 $fixedHeight] [list 94 3 7 $fixedHeight]]
test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -constraints {textfonts} -setup {
    text .tt -tabs {40 right} -wrap none -font $fixedFont
    pack .tt
} -body {
    .tt insert end \t9\n\t99\n\t999
    update
    list [.tt bbox 1.1] [.tt bbox 2.2] [.tt bbox 3.3]
} -cleanup {
    destroy .tt
} -result [list [list 38 5 7 $fixedHeight] [list 38 20 7 $fixedHeight] [list 38 35 7 $fixedHeight]]

.t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \
    -tabs 100
update
test textDisp-25.1 {CharBboxProc procedure, check tab width} {textfonts} {
    .t delete 1.0 end
    .t insert 1.0 abc\td\tfgh

Changes to tests/textWind.test.

6
7
8
9
10
11
12
13
14
15
16

17
18
19
20
21
22
23


24

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







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




56

57
58
59
60
61
62
63
64
65
66




67

68
69
70
71
72
73
74
75

76
77
78
79
80

81
82
83
84


85


86
87
88
89
90
91
92
93
94


95


96
97
98
99
100
101
102
103
104


105
106
107
108
109
110
111
112
...
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312
313
314
315
316

317
318
319
320
321
322
323
324
325
326
327
328
329
330


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

344
345
346
347
348
349
350
351
352
353
354
355
356
357


358
359
360
361
362
363
364
365
366
367
368
369
370


371
372
373
374
375
376
377
...
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464

465
466
467
468
469
470
471
472
473
474
475
476



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

489
490
491
492
493
494
495
496
497
498
499
500



501
502
503
504
505
506
507
508
509
510
511
512


513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528




529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549

550
551
552
553
554
555
556
557
558
559
560
561
562


563
564
565
566
567
568
569
570
571
572
573
574
575
576




577
578
579
580
581
582
583
584
...
611
612
613
614
615
616
617

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639

640
641
642
643
644
645
646
...
648
649
650
651
652
653
654

655



656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
...
689
690
691
692
693
694
695
696
697
698
699


700
701
702
703
704
705
706
707
708
709
710
711
712
713
...
714
715
716
717
718
719
720
721

722
723
724
725
726
727
728
729
730
731
732
733

734
735
736
737
738
739
740
741
742
743
744
745

746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765

766


767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
...
800
801
802
803
804
805
806

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

824
825
826
827
828
829
830
831
832
833
834
835
836
837
838

839
840
841
842
843
844
845
846
847
848
849
850



851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866

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

882
883
884
885
886
887
888
889
890
891
892
893
894

895
896
897
898
899
900
901
...
905
906
907
908
909
910
911
912

913
914
915
916
917
918
919
...
923
924
925
926
927
928
929
930

931
932
933
934
935
936
937
...
945
946
947
948
949
950
951

952
953
954
955
956
957
958
959
960
961
...
965
966
967
968
969
970
971
972




973
974
975
976
977
978
979
980
981
982
...
986
987
988
989
990
991
992
993
994
995
996



997
998
999
1000
1001
1002
1003
....
1031
1032
1033
1034
1035
1036
1037
1038



1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050



1051
1052
1053
1054
1055
1056
1057
1058
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
....
1153
1154
1155
1156
1157
1158
1159

1160
1161
1162
1163
1164
1165
1166
....
1172
1173
1174
1175
1176
1177
1178

1179
1180
1181
1182
1183
1184
1185
....
1187
1188
1189
1190
1191
1192
1193

1194
1195
1196
1197
1198
1199
1200
....
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
....
1241
1242
1243
1244
1245
1246
1247

1248
1249
1250
1251
1252
1253
1254
....
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
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

# Create entries in the option database to be sure that geometry options
# like border width have predictable values.


option add *Text.borderWidth 2
option add *Text.highlightThickness 2
option add *Text.font {Courier -12}


deleteWindows
# Widget used in tests 1.* - 16.*


text .t -width 30 -height 6 -bd 2 -highlightthickness 2

pack .t -expand 1 -fill both
update
.t debug on

# 15 on XP, 13 on Solaris 8
set fixedHeight [font metrics {Courier -12} -linespace]
set fixedDiff [expr {$fixedHeight - 13}] ;# 2 on XP
set color [expr {[winfo depth .t] > 1 ? "green" : "black"}]

wm geometry . {}
 
# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .








# ----------------------------------------------------------------------

test textWind-1.1 {basic tests of options} -constraints fonts -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -window]




} -result {1 3x3+19+23 {19 23 3 3} {-window {} {} {} .f}}

test textWind-1.2 {basic tests of options} -constraints fonts -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f -align top
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -align]




} -result {1 3x3+19+18 {19 18 3 3} {-align {} {} center top}}

test textWind-1.3 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    .t window create 2.2 -create "Test script"
    .t window configure 2.2 -create
} -result {-create {} {} {} {Test script}}

test textWind-1.4 {basic tests of options} -constraints fonts -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"

    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -padx 5
    update
    list [winfo geom .f] [.t window configure .f -padx] [.t bbox 2.3]


} -result {10x20+24+18 {-padx {} {} 0 5} {39 21 7 13}}


test textWind-1.5 {basic tests of options} -constraints fonts -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -pady 4
    update
    list [winfo geom .f] [.t window configure .f -pady] [.t bbox 2.31]


} -result {10x20+19+22 {-pady {} {} 0 4} {19 46 7 13}}


test textWind-1.6 {basic tests of options} -constraints fonts -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 5 -height 5 -bg $color
    .t window create 2.2 -window .f -stretch 1
    update
    list [winfo geom .f] [.t window configure .f -stretch]


} -result {5x13+19+18 {-stretch {} {} 0 1}}


.t delete 1.0 end
.t insert end "This is the first line"
test textWind-2.1 {TkTextWindowCmd procedure} -body {
    .t window
} -returnCodes error -result {wrong # args: should be ".t window option ?arg ...?"}
................................................................................
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f
    .t window configure 1.0 -foo bar
} -cleanup {
    destroy .f
} -returnCodes error -result {unknown option "-foo"}

test textWind-3.2 {EmbWinConfigure procedure} -constraints fonts -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    .t window configure 1.3 -window {}
    update
    .t index .f
} -cleanup {
    destroy .f
} -returnCodes error -result {bad text index ".f"}

test textWind-3.3 {EmbWinConfigure procedure} -constraints fonts -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    .t window configure 1.3 -window {}
    update
    catch {.t index .f}
    list [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result {0 {26 5 7 13}}


test textWind-3.4 {EmbWinConfigure procedure} -constraints fonts -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    .t window configure 1.3 -window {}
    update
    .t index .t.f
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad text index ".t.f"}

test textWind-3.5 {EmbWinConfigure procedure} -constraints fonts -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    .t window configure 1.3 -window {}
    update
    catch {.t index .t.f}
    list [winfo ismapped .t.f] [.t bbox 1.4]
} -cleanup {
    destroy .t.f
} -result {0 {26 5 7 13}}


test textWind-3.6 {EmbWinConfigure procedure} -constraints fonts -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3
    update
    .t window configure 1.3 -window .f
    update
    list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result {0 1.3 1 {36 8 7 13}}


test textWind-3.7 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f
    frame .f.f -width 15 -height 20 -bg $color
    pack .f.f
................................................................................
} -returnCodes error -result {bad align "gorp": must be baseline, bottom, center, or top}
test textWind-4.6 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align top
    catch {.t window configure 1.0 -align gorp}
    .t window configure 1.0 -align
} -result {-align {} {} center top}


test textWind-5.1 {EmbWinStructureProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    .t index .f
} -returnCodes error -result {bad text index ".f"}

test textWind-5.2 {EmbWinStructureProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result {{19 11 0 0} {19 5 7 13}}



test textWind-5.3 {EmbWinStructureProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    .t index .f
} -returnCodes error -result {bad text index ".f"}

test textWind-5.4 {EmbWinStructureProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result {{19 18 0 0} {19 5 7 13}}



test textWind-5.5 {EmbWinStructureProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.2 -create {frame .f -width 10 -height 20 -bg $color}
    update
    .t window configure 1.2 -create {frame .f -width 20 -height 10 -bg $color}
    destroy .f
    update
    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]
} -result {0 1.2 {19 6 20 10} {39 5 7 13}}




test textWind-6.1 {EmbWinRequestProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
    set result {}
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    lappend result [.t bbox 1.2] [.t bbox 1.3]
    .f configure -width 25 -height 30
    lappend result [.t bbox 1.2] [.t bbox 1.3]
} -cleanup {
    destroy .f
} -result {{19 5 10 20} {29 8 7 13} {19 5 25 30} {44 13 7 13}}






test textWind-7.1 {EmbWinLostSlaveProc procedure} -constraints {
    textfonts
} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    place .f -in .t -x 100 -y 50
    update
    list [winfo geom .f] [.t bbox 1.2]
} -cleanup {
    destroy .f
} -result [list 10x20+105+55 [list 19 [expr {11+$fixedDiff/2}] 0 0]]
test textWind-7.2 {EmbWinLostSlaveProc procedure} -constraints {
    textfonts
} -setup {

    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    place .t.f -x 100 -y 50
    update
    list [winfo geom .t.f] [.t bbox 1.2]
} -cleanup {
    destroy .t.f
} -result [list 10x20+105+55 [list 19 [expr {11+$fixedDiff/2}] 0 0]]




test textWind-8.1 {EmbWinDeleteProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    list $x [.t bbox 1.2] [.t bbox 1.3] [winfo exists .f]
} -result {destroyed {19 5 7 13} {26 5 7 13} 0}




test textWind-8.2 {EmbWinDeleteProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
................................................................................
        frame .f -width 10 -height 20 -bg $color
    }
    update
    list [winfo exists .f] [winfo width .f] [winfo height .f] [.t index .f]
} -cleanup {
    destroy .f
} -result {1 10 20 1.5}

test textWind-10.2 {EmbWinLayoutProc procedure, error in creating window} -constraints {
    fonts
} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
        .t window create 1.5 -create {
        error "couldn't create window"
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result {{{couldn't create window}} {40 11 0 0}}
test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} -constraints {
    fonts
} -setup {

    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
        concat gorp
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}

} -result {{{bad window path name "gorp"}} {40 11 0 0}}



    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
            lappend msg $args
        }
    }

test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} -constraints {
    textfonts
} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    set msg {}
    after idle {
        .t window create 1.5 -create {
            frame .t.f
................................................................................
        .t bbox 1.5
        after 10
    }
    lappend msg [.t bbox 1.5] [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result [list {{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} [list 40 [expr {11+$fixedDiff/2}] 0 0] 1]
test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} -constraints {
    textfonts
} -setup {


    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        frame .t.f
        frame .t.f.f -width 10 -height 20 -bg $color
    }
................................................................................
    set msg {}
    update idletasks
    lappend msg [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result {{{can't embed .t.f.f relative to .t}} 1}
catch {destroy .t.f}

test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} -constraints {
    textfonts
} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"

    .t window create 1.5 -create {
        concat .t
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list {{can't embed .t relative to .t}} [list 40 [expr {11+$fixedDiff/2}] 0 0]]
test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -constraints {
    textfonts
} -setup {

    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}

} -result [list {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} [list 40 [expr {11+$fixedDiff/2}] 0 0]]


test textWind-10.8 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
................................................................................
    update
    .t window create 1.3 -create {concat .t.b}
    update
    .t index .t.b
} -cleanup {
    destroy .t.b
} -result {1.3}

test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints {
    fonts
} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 125 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result {{89 5 126 20} {5 25 7 13}}
test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints {
    fonts
} -setup {

    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 126 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result {{89 5 126 20} {5 25 7 13}}
test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints {
    fonts
} -setup {

    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 127 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result {{5 18 127 20} {132 21 7 13}}



test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result {{89 5 126 20} {}}
test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints {
    fonts
} -setup {

    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result {{89 5 126 78} {}}
test textWind-10.15 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints {
    fonts
} -setup {

    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 250 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result {{5 18 210 65} {}}



test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
} -body {
................................................................................
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    winfo geom .f
} -cleanup {
    destroy .f
    place forget .t
} -result {30x20+119+55}

test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .t.f
    place forget .t
    pack .t
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
    .t window create 1.12 -window .t.f
    update
    winfo geom .t.f
} -cleanup {
    destroy .t.f
    place forget .t
    pack .t
} -result {30x20+89+5}

test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
    update
    return $x
} -cleanup {
    destroy .f
    place forget .t
    pack .t
} -result {no configures}

test textWind-11.4 {EmbWinDisplayProc procedure, horizontal scrolling} -constraints {
    fonts
} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
................................................................................
    .t insert end " with junk after it."
    .t xview moveto 0
    .t xview scroll 5 units
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] [winfo ismapped .f2]
} -cleanup {
    destroy .f .f2
} -result {1 30x20+103+18 {103 18 30 20} 0}




test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} -constraints {
    fonts
} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
................................................................................
    .t insert end " with junk after it."
    update
    .t xview moveto 0
    .t xview scroll 25 units
    update
    list [winfo ismapped .f] [winfo ismapped .f2] [winfo geom .f2] [.t bbox .f2]
} -cleanup {
    destroy .f .f2
} -result {0 1 40x10+119+23 {119 23 40 10}}
.t configure -wrap char





test textWind-12.1 {EmbWinUndisplayProc procedure, mapping/unmapping} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
................................................................................
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x5+21+6 {21 6 5 5}}



test textWind-13.2 {EmbWinBboxProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x5+21+9 {21 9 5 5}}



test textWind-13.3 {EmbWinBboxProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x5+21+10 {21 10 5 5}}



test textWind-13.4 {EmbWinBboxProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x5+21+12 {21 12 5 5}}



test textWind-13.5 {EmbWinBboxProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x11+21+6 {21 6 5 11}}



test textWind-13.6 {EmbWinBboxProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x11+21+6 {21 6 5 11}}



test textWind-13.7 {EmbWinBboxProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x9+21+6 {21 6 5 9}}



test textWind-13.8 {EmbWinBboxProc procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result {5x11+21+6 {21 6 5 11}}
test textWind-13.9 {EmbWinBboxProc procedure, spacing options} -constraints {
    fonts
} -setup {

    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 5 -spacing3 2
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {

    destroy .f
} -result {5x5+21+14 {21 14 5 5}}




test textWind-14.1 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
    .t window configure .f -window {}
    lappend x updated
    update
    return $x
} -cleanup {
    destroy .f
} -result {modified removed unmapped updated}

test textWind-14.2 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
................................................................................
    .t delete .f
    lappend x updated
    update
    return $x
} -cleanup {
    destroy .f
} -result {modified deleted updated}

test textWind-14.3 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
................................................................................
    .t yview 2.0
    set result [winfo ismapped .f]
    update ; after 10
    list $result [winfo ismapped .f]
} -cleanup {
    destroy .f
} -result {1 0}

test textWind-14.4 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .t.f
................................................................................
    set result [winfo ismapped .t.f]
    update
    list $result [winfo ismapped .t.f]
} -cleanup {
    destroy .t.f
} -result {1 0}


test textWind-15.1 {TkTextWindowIndex procedure} -setup {
    .t delete 1.0 end
} -body {
    .t index .foo
} -returnCodes error -result {bad text index ".foo"}

test textWind-15.2 {TkTextWindowIndex procedure} -constraints fonts -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    .t tag add a 1.1
    .t tag add a 1.3
    list [.t index .f] [.t bbox 1.7]
} -cleanup {
    destroy .f
} -result {1.6 {77 8 7 13}}



test textWind-16.1 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
................................................................................
    update
    pack forget .t
    update
    winfo ismapped .f
} -cleanup {
    pack .t
} -result 0

test textWind-16.2 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
................................................................................
    lappend result [winfo geom .f] [.t bbox .f]
    frame .f2 -width 150 -height 30 -bd 2 -relief raised
    pack .f2 -before .t
    update
    lappend result [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f .f2
} -result {30x20+47+5 {47 5 30 20} 30x20+47+35 {47 5 30 20}}





test textWind-16.3 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    .t window create 1.6
    update
    pack forget .t
    update
} -cleanup {
    pack .t
} -result {}

test textWind-16.4 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
    frame .t.f -width 30 -height 20 -bg $color
................................................................................
    .t window create 1.6 -window .t.f
    update
    pack forget .t
    update
    list [winfo ismapped .t.f] [.t bbox .t.f]
} -cleanup {
    pack .t
} -result {1 {47 5 30 20}}


test textWind-17.1 {peer widgets and embedded windows} -setup {
    destroy .t .tt .f
} -body {
    pack [text .t]
    .t insert end "Line 1"








|
<

>
|
|
|

<
<
|
>
>
|
>




<
<
<



|








>
>
>
>
>
>
>


|









>
>
>
>
|
>
|









>
>
>
>
|
>








>
|




>




>
>
|
>
>
|








>
>
|
>
>
|








>
>
|







 







>
|












>
|












|
>
>
|












>
|












|
>
>
|











|
>
>







 







<
|










>
|










|
>
>
>
|











>
|










|
>
>
>
|










|
>
>


|












|
>
>
>
>


|
<
<












|
|
|
|
>












|
>
>

<
|










|
>
>
>
>
|







 







>
|
<
<







|







|
|
|
|
>







 







>
|
>
>
>




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







 







|
|
|
|
>
>




<
|
<







 







<
>
|
<
<









>








|
|
|
|
>




<
|
<













>
|
>
>





<
|
<







 







>
|
<
<










|
|
|
|
>











|
|
|
|
>











|
>
>
>












|
|
|
|
>











|
|
|
|
>











|
|
>







 







|
>







 







|
>







 







>
|
<
<







 







|
>
>
>
>
|
<
<







 







|
<
|
<
>
>
>







 







|
>
>
>
|










|
>
>
>
|










|
>
>
>
|










|
>
>
>
|










|
>
>
>
|










|
>
>
>
|










|
>
>
>
|










|
|
|
|
>











>

|
>
>







 







>







 







>







 







>







 







<





>
|













|
>







 







>







 







|
>
>
>
>
>












>







 







|







6
7
8
9
10
11
12
13
14

15
16
17
18
19
20


21
22
23
24
25
26
27
28
29



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
...
482
483
484
485
486
487
488

489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580


581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613

614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
...
664
665
666
667
668
669
670
671
672


673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
...
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716

717













718
719
720
721
722
723
724
...
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748

749

750
751
752
753
754
755
756
...
757
758
759
760
761
762
763

764
765


766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792

793

794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815

816

817
818
819
820
821
822
823
...
842
843
844
845
846
847
848
849
850


851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
...
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
...
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
...
996
997
998
999
1000
1001
1002
1003
1004


1005
1006
1007
1008
1009
1010
1011
....
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027


1028
1029
1030
1031
1032
1033
1034
....
1038
1039
1040
1041
1042
1043
1044
1045

1046

1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
....
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
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
....
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
....
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
....
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
....
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
....
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
....
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
# Copyright (c) 1998-1999 by Scriptics Corporation.
# All rights reserved.

package require tcltest 2.2
namespace import ::tcltest::*
tcltest::configure {*}$argv
tcltest::loadTestedCommands

deleteWindows


set fixedFont {"Courier New" -12}
set fixedHeight [font metrics $fixedFont -linespace]
set fixedWidth [font measure $fixedFont m]
set fixedAscent [font metrics $fixedFont -ascent]



# Widget used in almost all tests
set tWidth 30
set tHeight 6
text .t -width $tWidth -height $tHeight -bd 2 -highlightthickness 2 \
        -font $fixedFont
pack .t -expand 1 -fill both
update
.t debug on




set color [expr {[winfo depth .t] > 1 ? "green" : "black"}]

wm geometry . {}

# The statements below reset the main window;  it's needed if the window
# manager is mwm to make mwm forget about a previous minimum size setting.

wm withdraw .
wm minsize . 1 1
wm positionfrom . user
wm deiconify .

set bw [.t cget -borderwidth]
set px [.t cget -padx]
set py [.t cget -pady]
set hlth [.t cget -highlightthickness]
set padx [expr {$bw+$px+$hlth}]
set pady [expr {$bw+$py+$hlth}]

# ----------------------------------------------------------------------

test textWind-1.1 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -window]
} -result [list \
    1 \
    3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] 3 3] \
    {-window {} {} {} .f}]

test textWind-1.2 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 3 -height 3 -bg $color
    .t window create 2.2 -window .f -align top
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \
        [.t window configure .f -align]
} -result [list \
    1 \
    3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 3 3] \
    {-align {} {} center top}]

test textWind-1.3 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    .t window create 2.2 -create "Test script"
    .t window configure 2.2 -create
} -result {-create {} {} {} {Test script}}

test textWind-1.4 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    # the window .f should be wider than the fixed width
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -padx 5
    update
    list [winfo geom .f] [.t window configure .f -padx] [.t bbox 2.3]
} -result [list \
    10x20+[expr {$padx+2*$fixedWidth+5}]+[expr {$pady+$fixedHeight}] \
    {-padx {} {} 0 5} \
    [list [expr {$padx+2*$fixedWidth+10+2*5}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-1.5 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 10 -height 20 -bg $color
    .t window create 2.2 -window .f -pady 4
    update
    list [winfo geom .f] [.t window configure .f -pady] [.t bbox 2.31]
} -result [list \
    10x20+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+4}] \
    {-pady {} {} 0 4} \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+20+2*4}] $fixedWidth $fixedHeight]]

test textWind-1.6 {basic tests of options} -setup {
    .t delete 1.0 end
} -body {
    .t insert end "This is the first line"
    .t insert end "\nAnd this is a second line, which wraps around"
    frame .f -width 5 -height 5 -bg $color
    .t window create 2.2 -window .f -stretch 1
    update
    list [winfo geom .f] [.t window configure .f -stretch]
} -result [list \
    5x$fixedHeight+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    {-stretch {} {} 0 1}]


.t delete 1.0 end
.t insert end "This is the first line"
test textWind-2.1 {TkTextWindowCmd procedure} -body {
    .t window
} -returnCodes error -result {wrong # args: should be ".t window option ?arg ...?"}
................................................................................
} -body {
    frame .f -width 10 -height 6 -bg $color
    .t window create 1.0 -window .f
    .t window configure 1.0 -foo bar
} -cleanup {
    destroy .f
} -returnCodes error -result {unknown option "-foo"}

test textWind-3.2 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    .t window configure 1.3 -window {}
    update
    .t index .f
} -cleanup {
    destroy .f
} -returnCodes error -result {bad text index ".f"}

test textWind-3.3 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .f
    update
    .t window configure 1.3 -window {}
    update
    catch {.t index .f}
    list [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-3.4 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    .t window configure 1.3 -window {}
    update
    .t index .t.f
} -cleanup {
    destroy .t.f
} -returnCodes error -result {bad text index ".t.f"}

test textWind-3.5 {EmbWinConfigure procedure} -setup {
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.3 -window .t.f
    update
    .t window configure 1.3 -window {}
    update
    catch {.t index .t.f}
    list [winfo ismapped .t.f] [.t bbox 1.4]
} -cleanup {
    destroy .t.f
} -result [list 0 \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-3.6 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.3
    update
    .t window configure 1.3 -window .f
    update
    list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4]
} -cleanup {
    destroy .f
} -result [list 0 1.3 1 \
    [list [expr {$padx+3*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-3.7 {EmbWinConfigure procedure} -setup {
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f
    frame .f.f -width 15 -height 20 -bg $color
    pack .f.f
................................................................................
} -returnCodes error -result {bad align "gorp": must be baseline, bottom, center, or top}
test textWind-4.6 {AlignParseProc and AlignPrintProc procedures} -body {
    .t window configure 1.0 -align top
    catch {.t window configure 1.0 -align gorp}
    .t window configure 1.0 -align
} -result {-align {} {} center top}


test textWind-5.1 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    .t index .f
} -returnCodes error -result {bad text index ".f"}

test textWind-5.2 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-5.3 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    .t index .f
} -returnCodes error -result {bad text index ".f"}

test textWind-5.4 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -align bottom
    .t window configure 1.2 -window .f
    update
    destroy .f
    catch {.t index .f}
    list [.t bbox 1.2] [.t bbox 1.3]
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 0 0] \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]]

test textWind-5.5 {EmbWinStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.2 -create {frame .f -width 10 -height 20 -bg $color}
    update
    .t window configure 1.2 -create {frame .f -width 20 -height 10 -bg $color}
    destroy .f
    update
    list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3]
} -result [list 0 1.2 \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+(($fixedHeight-10)/2)}] 20 10] \
    [list [expr {$padx+2*$fixedWidth+20}] $pady $fixedWidth $fixedHeight]]


test textWind-6.1 {EmbWinRequestProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
    set result {}
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    lappend result [.t bbox 1.2] [.t bbox 1.3]
    .f configure -width 25 -height 30
    lappend result [.t bbox 1.2] [.t bbox 1.3]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+2*$fixedWidth}] $pady 10 20] \
    [list [expr {$padx+2*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight] \
    [list [expr {$padx+2*$fixedWidth}] $pady 25 30] \
    [list [expr {$padx+2*$fixedWidth+25}] [expr {$pady+((30-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]


test textWind-7.1 {EmbWinLostSlaveProc procedure} -setup {


    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    update
    place .f -in .t -x 100 -y 50
    update
    list [winfo geom .f] [.t bbox 1.2]
} -cleanup {
    destroy .f
} -result [list \
    10x20+[expr {$padx+100}]+[expr {$pady+50}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-7.2 {EmbWinLostSlaveProc procedure} -setup {
    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text"
    frame .t.f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .t.f
    update
    place .t.f -x 100 -y 50
    update
    list [winfo geom .t.f] [.t bbox 1.2]
} -cleanup {
    destroy .t.f
} -result [list \
    10x20+[expr {$padx+100}]+[expr {$pady+50}] \
    [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]


test textWind-8.1 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
    set x XXX
    .t delete 1.2
    list $x [.t bbox 1.2] [.t bbox 1.3] [winfo exists .f]
} -result [list destroyed \
    [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight] \
    [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight] \
    0]

test textWind-8.2 {EmbWinDeleteProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 10 -height 20 -bg $color
    .t window create 1.2 -window .f
    bind .f <Destroy> {set x destroyed}
................................................................................
        frame .f -width 10 -height 20 -bg $color
    }
    update
    list [winfo exists .f] [winfo width .f] [winfo height .f] [.t index .f]
} -cleanup {
    destroy .f
} -result {1 10 20 1.5}

test textWind-10.2 {EmbWinLayoutProc procedure, error in creating window} -setup {


    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        error "couldn't create window"
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{couldn't create window}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    proc bgerror args {
        global msg
        set msg $args
    }
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
        concat gorp
    }
    set msg xyzzy
    update
    list $msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{bad window path name "gorp"}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg

	lappend msg $args













    }
} -body {
    .t insert 1.0 "Some sample text"
    set msg {}
    after idle {
        .t window create 1.5 -create {
            frame .t.f
................................................................................
        .t bbox 1.5
        after 10
    }
    lappend msg [.t bbox 1.5] [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result [list \
    {{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \
    1]

test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t.f
    proc bgerror args {
        global msg

	lappend msg $args

    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        frame .t.f
        frame .t.f.f -width 10 -height 20 -bg $color
    }
................................................................................
    set msg {}
    update idletasks
    lappend msg [winfo exists .t.f.f]
} -cleanup {
    destroy .t.f
    rename bgerror {}
} -result {{{can't embed .t.f.f relative to .t}} 1}


test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} -setup {


    .t delete 1.0 end
    proc bgerror args {
        global msg
        if {[lsearch -exact $msg $args] == -1} {
            lappend msg $args
        }
    }
} -body {
    .t insert 1.0 "Some sample text"
    update
    .t window create 1.5 -create {
        concat .t
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t relative to .t}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg

	lappend msg $args

    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
    }
    set msg {}
    update
    lappend msg [.t bbox 1.5]
} -cleanup {
    rename bgerror {}
} -result [list \
    {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} \
    [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]]

test textWind-10.8 {EmbWinLayoutProc procedure, error in creating window} -setup {
    .t delete 1.0 end
    destroy .t2
    proc bgerror args {
        global msg

	lappend msg $args

    }
} -body {
    .t insert 1.0 "Some sample text"
    .t window create 1.5 -create {
        toplevel .t2 -width 100 -height 150
        wm geom .t2 +0+0
        concat .t2
................................................................................
    update
    .t window create 1.3 -create {concat .t.b}
    update
    .t index .t.b
} -cleanup {
    destroy .t.b
} -result {1.3}

test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {


    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 125 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 126 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]]

test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 127 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list $padx [expr {$pady+$fixedHeight}] 127 20] \
    [list [expr {$padx+127}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]

test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 20 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \
    {}]

test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 130 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] [expr {$tHeight*$fixedHeight}]] \
    {}]

test textWind-10.15 {EmbWinLayoutProc procedure, doesn't fit on line} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap char
    .t insert 1.0 "Some sample text"
    frame .f -width 250 -height 220 -bg $color -bd 2 -relief raised
    .t window create 1.12 -window .f
    update
    list [.t bbox .f] [.t bbox 1.13]
} -cleanup {
    destroy .f
} -result [list \
    [list $padx [expr {$pady+$fixedHeight}] [expr {$tWidth*$fixedWidth}] [expr {($tHeight-1)*$fixedHeight}]] \
    {}]

test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
} -body {
................................................................................
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.12 -window .f
    update
    winfo geom .f
} -cleanup {
    destroy .f
    place forget .t
} -result [list 30x20+[expr {$padx+30+12*$fixedWidth}]+[expr {$pady+50}]]

test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup {
    .t delete 1.0 end
    destroy .t.f
    place forget .t
    pack .t
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
    .t window create 1.12 -window .t.f
    update
    winfo geom .t.f
} -cleanup {
    destroy .t.f
    place forget .t
    pack .t
} -result [list 30x20+[expr {$padx+12*$fixedWidth}]+$pady]

test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup {
    .t delete 1.0 end
    destroy .f
    place forget .t
    pack .t
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
    update
    return $x
} -cleanup {
    destroy .f
    place forget .t
    pack .t
} -result {no configures}

test textWind-11.4 {EmbWinDisplayProc procedure, horizontal scrolling} -setup {


    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
................................................................................
    .t insert end " with junk after it."
    .t xview moveto 0
    .t xview scroll 5 units
    update
    list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] [winfo ismapped .f2]
} -cleanup {
    destroy .f .f2
} -result [list 1 \
    30x20+[expr {$padx+14*$fixedWidth}]+[expr {$pady+$fixedHeight}] \
    [list [expr {$padx+14*$fixedWidth}] [expr {$pady+$fixedHeight}] 30 20] \
    0]

test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} -setup {


    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t insert 1.0 "xyzzy\nFirst window here: "
    .t configure -wrap none
    frame .f -width 30 -height 20 -bg $color
    .t window create end -window .f
................................................................................
    .t insert end " with junk after it."
    update
    .t xview moveto 0
    .t xview scroll 25 units
    update
    list [winfo ismapped .f] [winfo ismapped .f2] [winfo geom .f2] [.t bbox .f2]
} -cleanup {
  destroy .f .f2

  .t configure -wrap char

} -result [list 0 1 \
    40x10+[expr {$padx+37*$fixedWidth+30-25*$fixedWidth}]+[expr {$pady+$fixedHeight+((20-10)/2)}] \
    [list [expr {$padx+37*$fixedWidth+30-25*$fixedWidth}] [expr {$pady+$fixedHeight+((20-10)/2)}] 40 10]]

test textWind-12.1 {EmbWinUndisplayProc procedure, mapping/unmapping} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
................................................................................
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 5]]

test textWind-13.2 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+(($fixedHeight-7)/2)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+(($fixedHeight-7)/2)}] 5 5]]

test textWind-13.3 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedAscent-6)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedAscent-6)}] 5 5]]

test textWind-13.4 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedHeight-7)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedHeight-7)}] 5 5]]

test textWind-13.5 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align top -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.6 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.7 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align baseline -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedAscent-1}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedAscent-1}]]]

test textWind-13.8 {EmbWinBboxProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align bottom -padx 2 -pady 1 -stretch 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f
} -result [list \
    5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]]

test textWind-13.9 {EmbWinBboxProc procedure, spacing options} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 5 -spacing3 2
    .t delete 1.0 end
    .t insert 1.0 "Some sample text"
    frame .f -width 5 -height 5 -bg $color
    .t window create 1.2 -window .f -align center -padx 2 -pady 1
    update
    list [winfo geom .f] [.t bbox .f]
} -cleanup {
    .t configure -spacing1 0 -spacing3 0
    destroy .f
} -result [list \
    5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+5+(($fixedHeight-5)/2)}] \
    [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+5+(($fixedHeight-5)/2)}] 5 5]]


test textWind-14.1 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
................................................................................
    .t window configure .f -window {}
    lappend x updated
    update
    return $x
} -cleanup {
    destroy .f
} -result {modified removed unmapped updated}

test textWind-14.2 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
................................................................................
    .t delete .f
    lappend x updated
    update
    return $x
} -cleanup {
    destroy .f
} -result {modified deleted updated}

test textWind-14.3 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .f
................................................................................
    .t yview 2.0
    set result [winfo ismapped .f]
    update ; after 10
    list $result [winfo ismapped .f]
} -cleanup {
    destroy .f
} -result {1 0}

test textWind-14.4 {EmbWinDelayedUnmap procedure} -setup {
    .t delete 1.0 end
    destroy .t.f
} -body {
    .t insert 1.0 "Some sample text\nAnother line\n3\n4\n5\n6\n7\n8\n9"
    frame .t.f -width 30 -height 20 -bg $color
    .t window create 1.2 -window .t.f
................................................................................
    set result [winfo ismapped .t.f]
    update
    list $result [winfo ismapped .t.f]
} -cleanup {
    destroy .t.f
} -result {1 0}


test textWind-15.1 {TkTextWindowIndex procedure} -setup {
    .t delete 1.0 end
} -body {
    .t index .foo
} -returnCodes error -result {bad text index ".foo"}

test textWind-15.2 {TkTextWindowIndex procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
    frame .f -width 30 -height 20 -bg $color
    .t window create 1.6 -window .f
    .t tag add a 1.1
    .t tag add a 1.3
    list [.t index .f] [.t bbox 1.7]
} -cleanup {
    destroy .f
} -result [list 1.6 \
    [list [expr {$padx+6*$fixedWidth+30}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]]


test textWind-16.1 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f
} -body {
    .t configure -wrap none
................................................................................
    update
    pack forget .t
    update
    winfo ismapped .f
} -cleanup {
    pack .t
} -result 0

test textWind-16.2 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
    destroy .f .f2
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
................................................................................
    lappend result [winfo geom .f] [.t bbox .f]
    frame .f2 -width 150 -height 30 -bd 2 -relief raised
    pack .f2 -before .t
    update
    lappend result [winfo geom .f] [.t bbox .f]
} -cleanup {
    destroy .f .f2
} -result [list \
    30x20+[expr {$padx+6*$fixedWidth}]+$pady \
    [list [expr {$padx+6*$fixedWidth}] $pady 30 20] \
    30x20+[expr {$padx+6*$fixedWidth}]+[expr {$pady+30}] \
    [list [expr {$padx+6*$fixedWidth}] $pady 30 20]]

test textWind-16.3 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t configure -wrap none
    .t insert 1.0 "Some sample text"
    .t window create 1.6
    update
    pack forget .t
    update
} -cleanup {
    pack .t
} -result {}

test textWind-16.4 {EmbWinTextStructureProc procedure} -setup {
    .t delete 1.0 end
} -body {
    .t configure -spacing1 0 -spacing2 0 -spacing3 0 \
        -wrap none
    .t insert 1.0 "Some sample text"
    frame .t.f -width 30 -height 20 -bg $color
................................................................................
    .t window create 1.6 -window .t.f
    update
    pack forget .t
    update
    list [winfo ismapped .t.f] [.t bbox .t.f]
} -cleanup {
    pack .t
} -result [list 1 [list [expr {$padx+6*$fixedWidth}] $pady 30 20]]


test textWind-17.1 {peer widgets and embedded windows} -setup {
    destroy .t .tt .f
} -body {
    pack [text .t]
    .t insert end "Line 1"

Changes to tests/ttk/layout.test.

17
18
19
20
21
22
23



24
25

    pack .b -expand true -fill both

    list [winfo reqwidth .b] [winfo reqheight .b]

} -cleanup { destroy .b } -result [list 24 24]





tcltest::cleanupTests







>
>
>


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

    pack .b -expand true -fill both

    list [winfo reqwidth .b] [winfo reqheight .b]

} -cleanup { destroy .b } -result [list 24 24]

test layout-2 "Empty -children not allowed" -body {
    ttk::style layout Test.Tentry {Entry.field -children {}}
} -returnCodes error -result {Invalid -children value}

tcltest::cleanupTests

Changes to tests/unixSelect.test.

104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
...
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

# ----------------------------------------------------------------------

test unixSelect-1.1 {TkSelGetSelection procedure: simple i18n text} -constraints {
    unix
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 \u00fcber
................................................................................
    dobg {string length [selection get]}
} -cleanup {
    cleanupbg
    destroy .e
} -result {4}

test unixSelect-1.2 {TkSelGetSelection procedure: simple i18n text, iso8859-1} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc\u0444
................................................................................
    }
    selection get
} -cleanup {
    cleanupbg
} -result \u00fc?

test unixSelect-1.3 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    unix
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
................................................................................
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 2 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.4 {TkSelGetSelection procedure: INCR i18n text, iso2022} -constraints {
    unix
} -setup {
    setupbg
    setup
} -body {
    # This test is subtle.  The selection ends up getting fetched twice by
    # Tk:  once to compute the length, and again to actually send the data.
    # The first time through, we don't convert the data to ISO2022, so the
................................................................................
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 8000 {COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3999 COMPOUND_TEXT 7998 4000 COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3998 COMPOUND_TEXT 7997 4000}}

test unixSelect-1.5 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    unix
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
................................................................................
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 2 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.6 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg [subst -nobackslashes {entry .e; pack .e; update
    .e insert 0 \u00fcber$longValue
    .e selection range 0 end}]
    string length [selection get]
} -cleanup {
    cleanupbg
} -result [expr {4 + [string length $longValue]}]

test unixSelect-1.7 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc
................................................................................
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc

test unixSelect-1.8 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc[string repeat x 3999]
................................................................................
    }
    selection get
} -cleanup {
    cleanupbg
} -result \u00fc[string repeat x 3999]

test unixSelect-1.9 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
................................................................................
    cleanupbg
} -result [string repeat x 3999]\u00fc[string repeat x 4000]
# Now some tests to make sure that the right thing is done when
# transferring UTF8 selections, to prevent [Bug 614650] and its ilk
# from rearing its ugly head again.

test unixSelect-1.10 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc

test unixSelect-1.11 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc[string repeat x 3999]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result \u00fc[string repeat x 3999]

test unixSelect-1.12 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc[string repeat x 4000]

test unixSelect-1.13 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    unix
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 \u00fcber\u0444
................................................................................
    dobg {string length [selection get -type UTF8_STRING]}
} -cleanup {
    destroy .e
    cleanupbg
} -result {5}

test unixSelect-1.14 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc\u0444
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result \u00fc\u0444

test unixSelect-1.15 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat \u00c4\u00e4 50]\n 21]

test unixSelect-1.16 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat \u00c4\u00e4 50]\n 21]

test unixSelect-1.17 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
................................................................................
    after 10
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat \u00c4\u00e4 50]\n 21]

test unixSelect-1.18 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    unix
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]







|







 







|







 







|







 







|







 







|







 







|












|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







 







|







104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
...
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
...
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
...
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
...
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
...
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
...
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
...
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
...
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
...
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
...
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
...
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
...
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
    set j $i.1$i.2$i.3$i.4$i.5$i.6$i.7$i.8$i.9$i.10$i.11$i.12$i.13$i.14
    append longValue A$j B$j C$j D$j E$j F$j G$j H$j I$j K$j L$j M$j N$j
}

# ----------------------------------------------------------------------

test unixSelect-1.1 {TkSelGetSelection procedure: simple i18n text} -constraints {
    x11
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 \u00fcber
................................................................................
    dobg {string length [selection get]}
} -cleanup {
    cleanupbg
    destroy .e
} -result {4}

test unixSelect-1.2 {TkSelGetSelection procedure: simple i18n text, iso8859-1} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc\u0444
................................................................................
    }
    selection get
} -cleanup {
    cleanupbg
} -result \u00fc?

test unixSelect-1.3 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
................................................................................
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 2 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.4 {TkSelGetSelection procedure: INCR i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    # This test is subtle.  The selection ends up getting fetched twice by
    # Tk:  once to compute the length, and again to actually send the data.
    # The first time through, we don't convert the data to ISO2022, so the
................................................................................
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 8000 {COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3999 COMPOUND_TEXT 7998 4000 COMPOUND_TEXT 0 4000 COMPOUND_TEXT 4000 3998 COMPOUND_TEXT 7997 4000}}

test unixSelect-1.5 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints {
    x11
} -setup {
    setupbg
    setup
} -body {
    selection handle -type COMPOUND_TEXT -format COMPOUND_TEXT . \
        {handler COMPOUND_TEXT}
    selection own .
................................................................................
    }]
    lappend result $selInfo
} -cleanup {
    cleanupbg
} -result {1 2 {COMPOUND_TEXT 0 4000}}

test unixSelect-1.6 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg [subst -nobackslashes {entry .e; pack .e; update
    .e insert 0 \u00fcber$longValue
    .e selection range 0 end}]
    string length [selection get]
} -cleanup {
    cleanupbg
} -result [expr {4 + [string length $longValue]}]

test unixSelect-1.7 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc
................................................................................
    }
    selection get
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc

test unixSelect-1.8 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc[string repeat x 3999]
................................................................................
    }
    selection get
} -cleanup {
    cleanupbg
} -result \u00fc[string repeat x 3999]

test unixSelect-1.9 {TkSelGetSelection procedure: INCR i18n text} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
................................................................................
    cleanupbg
} -result [string repeat x 3999]\u00fc[string repeat x 4000]
# Now some tests to make sure that the right thing is done when
# transferring UTF8 selections, to prevent [Bug 614650] and its ilk
# from rearing its ugly head again.

test unixSelect-1.10 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc

test unixSelect-1.11 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc[string repeat x 3999]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result \u00fc[string repeat x 3999]

test unixSelect-1.12 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat x 3999]\u00fc[string repeat x 4000]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat x 3999]\u00fc[string repeat x 4000]

test unixSelect-1.13 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    x11
} -setup {
    destroy .e
    setupbg
} -body {
    pack [entry .e]
    update
    .e insert 0 \u00fcber\u0444
................................................................................
    dobg {string length [selection get -type UTF8_STRING]}
} -cleanup {
    destroy .e
    cleanupbg
} -result {5}

test unixSelect-1.14 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 \u00fc\u0444
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result \u00fc\u0444

test unixSelect-1.15 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat \u00c4\u00e4 50]\n 21]

test unixSelect-1.16 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [entry .e]
        update
        .e insert 0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]
................................................................................
    }
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result i[string repeat [string repeat \u00c4\u00e4 50]\n 21]

test unixSelect-1.17 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 [string repeat [string repeat \u00c4\u00e4 50]\n 21]
................................................................................
    after 10
    selection get -type UTF8_STRING
} -cleanup {
    cleanupbg
} -result [string repeat [string repeat \u00c4\u00e4 50]\n 21]

test unixSelect-1.18 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints {
    x11
} -setup {
    setupbg
} -body {
    dobg {
        pack [text .t]
        update
        .t insert 1.0 i[string repeat [string repeat \u00c4\u00e4 50]\n 21]

Changes to tests/wm.test.

136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
....
1238
1239
1240
1241
1242
1243
1244
1245
1246


1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
    wm attributes . -to
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type}
test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -modified, -notify, or -titlepath}


### wm client ###
test wm-client-1.1 {usage} -returnCodes error -body {
    wm client
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-client-1.2 {usage} -returnCodes error -body {
................................................................................
} -result {wrong # args: should be "wm iconbitmap window ?bitmap?"}
test wm-iconbitmap-1.2.2 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13 14
} -result {wrong # args: should be "wm iconbitmap window ?-default? ?image?"}
test wm-iconbitmap-1.3 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13
} -result {illegal option "12" must be "-default"}
test wm-iconbitmap-1.4 {usage} -returnCodes error -body {
    wm iconbitmap .t bad-bitmap
} -result {bitmap "bad-bitmap" not defined}

test wm-iconbitmap-2.1 {setting and reading values} -setup {
    set result {}
} -body {
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t hourglass
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t {}
    lappend result [wm iconbitmap .t]
................................................................................
    wm resizable .t bad 0
} -result {expected boolean value but got "bad"}
test wm-resizable-1.5 {usage} -returnCodes error -body {
    wm resizable .t 1 bad
} -result {expected boolean value but got "bad"}

test wm-resizable-2.1 {setting and reading values} {
    wm resizable .t 0 1
    set result [wm resizable .t]


    wm resizable .t 1 0
    lappend result [wm resizable .t]
    wm resizable .t 1 1
    lappend result [wm resizable .t]
} {0 1 {1 0} {1 1}}


### wm sizefrom ###
test wm-sizefrom-1.1 {usage} -returnCodes error -body {
    wm sizefrom
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-sizefrom-1.2 {usage} -returnCodes error -body {







|







 







|



|







 







|

>
>




|







136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
...
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
....
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
    wm attributes . -to
} -result {wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"}
test wm-attributes-1.2.4 {usage} -constraints {unix notAqua} -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type}
test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body {
    wm attributes . _
} -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, or -transparent}


### wm client ###
test wm-client-1.1 {usage} -returnCodes error -body {
    wm client
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-client-1.2 {usage} -returnCodes error -body {
................................................................................
} -result {wrong # args: should be "wm iconbitmap window ?bitmap?"}
test wm-iconbitmap-1.2.2 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13 14
} -result {wrong # args: should be "wm iconbitmap window ?-default? ?image?"}
test wm-iconbitmap-1.3 {usage} -constraints win -returnCodes error -body {
    wm iconbitmap .t 12 13
} -result {illegal option "12" must be "-default"}
test wm-iconbitmap-1.4 {usage} -constraints notAqua -returnCodes error -body {
    wm iconbitmap .t bad-bitmap
} -result {bitmap "bad-bitmap" not defined}

test wm-iconbitmap-2.1 {setting and reading values} -constraints notAqua -setup {
    set result {}
} -body {
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t hourglass
    lappend result [wm iconbitmap .t]
    wm iconbitmap .t {}
    lappend result [wm iconbitmap .t]
................................................................................
    wm resizable .t bad 0
} -result {expected boolean value but got "bad"}
test wm-resizable-1.5 {usage} -returnCodes error -body {
    wm resizable .t 1 bad
} -result {expected boolean value but got "bad"}

test wm-resizable-2.1 {setting and reading values} {
    wm resizable .t 0 0
    set result [wm resizable .t]
    wm resizable .t 0 1
    lappend result [wm resizable .t]
    wm resizable .t 1 0
    lappend result [wm resizable .t]
    wm resizable .t 1 1
    lappend result [wm resizable .t]
} {0 0 {0 1} {1 0} {1 1}}


### wm sizefrom ###
test wm-sizefrom-1.1 {usage} -returnCodes error -body {
    wm sizefrom
} -result {wrong # args: should be "wm option window ?arg ...?"}
test wm-sizefrom-1.2 {usage} -returnCodes error -body {

Changes to unix/configure.

1425
1426
1427
1428
1429
1430
1431
1432
1433

1434
1435
1436


1437
1438
1439
1440
1441
1442
1443
....
4790
4791
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
....
5219
5220
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
....
5361
5362
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
....
5390
5391
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
....
5411
5412
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
....
6619
6620
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
....
7393
7394
7395
7396
7397
7398
7399
































































7400
7401
7402
7403
7404
7405
7406
....
8215
8216
8217
8218
8219
8220
8221
8222
8223
8224
8225
8226
8227
8228
8229
8230
8231
8232
8233
8234
8235
8236
8237
8238
8239
8240
8241
8242
8243
8244
8245
8246
8247
8248
8249
8250
8251
8252
8253
8254
8255
8256
8257
8258
8259
8260
8261
8262
8263
8264
8265
8266
8267
8268
8269
8270
8271
8272
8273
8274
8275
8276
8277
8278
8279
8280
8281
8282
8283
8284
8285
8286
8287
8288
8289
8290
8291
8292
8293
8294
8295
8296
8297
8298
8299
8300
8301
8302
8303
8304
8305
8306
8307
8308
8309
8310
8311
8312
8313
8314
8315
8316
8317
8318
8319
8320
8321
8322
8323
8324
8325
8326
8327
8328
8329
8330
8331
8332
8333
8334
8335
8336
8337
8338
8339
8340
8341
8342
8343
8344
8345
8346
8347
8348
8349
8350
8351
8352
8353
8354
8355
8356
8357
8358
8359
8360
8361
8362
8363
8364
8365
8366
8367
8368
8369
8370
8371
8372
8373
8374
8375
8376
8377
8378
8379
8380
8381
8382
8383
8384
8385
8386
8387
8388
8389
8390
8391
8392
8393
8394
8395
8396
8397
8398
8399
8400
8401
8402
8403
8404
8405
8406
8407
8408
8409
8410
8411
8412
8413
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \

			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \


			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
................................................................................
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	Haiku*)
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-lroot"
	    echo "$as_me:$LINENO: checking for inet_ntoa in -lnetwork" >&5
echo $ECHO_N "checking for inet_ntoa in -lnetwork... $ECHO_C" >&6
if test "${ac_cv_lib_network_inet_ntoa+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
................................................................................

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
................................................................................
	    alpha|sparc64)
		SHLIB_CFLAGS="-fPIC"
		;;
	    *)
		SHLIB_CFLAGS="-fpic"
		;;
	    esac
	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
................................................................................
	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	NetBSD-*)
	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
................................................................................
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"

fi

	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................
    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then

	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*|MINGW32_*) ;;
	    IRIX*) ;;
	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac
fi


................................................................................
echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then

cat >>confdefs.h <<\_ACEOF
#define HAVE_STRUCT_DIRENT64 1
_ACEOF

































































	fi

	echo "$as_me:$LINENO: checking for struct stat64" >&5
echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
if test "${tcl_cv_struct_stat64+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
................................................................................

cat >>confdefs.h <<\_ACEOF
#define TIME_WITH_SYS_TIME 1
_ACEOF

fi


#--------------------------------------------------------------------
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#--------------------------------------------------------------------


    echo "$as_me:$LINENO: checking for strtod" >&5
echo $ECHO_N "checking for strtod... $ECHO_C" >&6
if test "${ac_cv_func_strtod+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
/* Define strtod to an innocuous variant, in case <limits.h> declares strtod.
   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
#define strtod innocuous_strtod

/* System header to define __stub macros and hopefully few prototypes,
    which can conflict with char strtod (); below.
    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
    <limits.h> exists even on freestanding compilers.  */

#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif

#undef strtod

/* Override any gcc2 internal prototype to avoid an error.  */
#ifdef __cplusplus
extern "C"
{
#endif
/* We use char because int might match the return type of a gcc2
   builtin and then its argument prototype would still apply.  */
char strtod ();
/* The GNU C library defines this for functions which it implements
    to always fail with ENOSYS.  Some functions are actually named
    something starting with __ and the normal name is an alias.  */
#if defined (__stub_strtod) || defined (__stub___strtod)
choke me
#else
char (*f) () = strtod;
#endif
#ifdef __cplusplus
}
#endif

int
main ()
{
return f != strtod;
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest$ac_exeext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  ac_cv_func_strtod=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

ac_cv_func_strtod=no
fi
rm -f conftest.err conftest.$ac_objext \
      conftest$ac_exeext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5
echo "${ECHO_T}$ac_cv_func_strtod" >&6
if test $ac_cv_func_strtod = yes; then
  tcl_strtod=1
else
  tcl_strtod=0
fi

    if test "$tcl_strtod" = 1; then
	echo "$as_me:$LINENO: checking for Solaris2.4/Tru64 strtod bugs" >&5
echo $ECHO_N "checking for Solaris2.4/Tru64 strtod bugs... $ECHO_C" >&6
if test "${tcl_cv_strtod_buggy+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else

	    if test "$cross_compiling" = yes; then
  tcl_cv_strtod_buggy=buggy
else
  cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */

		extern double strtod();
		int main() {
		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
		    char *term;
		    double value;
		    value = strtod(infString, &term);
		    if ((term != infString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(nanString, &term);
		    if ((term != nanString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(spaceString, &term);
		    if (term == (spaceString+1)) {
			exit(1);
		    }
		    exit(0);
		}
_ACEOF
rm -f conftest$ac_exeext
if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
  (eval $ac_link) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_cv_strtod_buggy=ok
else
  echo "$as_me: program exited with status $ac_status" >&5
echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

( exit $ac_status )
tcl_cv_strtod_buggy=buggy
fi
rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
fi
fi
echo "$as_me:$LINENO: result: $tcl_cv_strtod_buggy" >&5
echo "${ECHO_T}$tcl_cv_strtod_buggy" >&6
	if test "$tcl_cv_strtod_buggy" = buggy; then
	    case $LIBOBJS in
    "fixstrtod.$ac_objext"   | \
  *" fixstrtod.$ac_objext"   | \
    "fixstrtod.$ac_objext "* | \
  *" fixstrtod.$ac_objext "* ) ;;
  *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" ;;
esac

	    USE_COMPAT=1

cat >>confdefs.h <<\_ACEOF
#define strtod fixstrtod
_ACEOF

	fi
    fi


#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

echo "$as_me:$LINENO: checking for mode_t" >&5







<

>



>
>







 







|







 







|







 







|







 







|







 







|







 







|







 







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







 







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







1425
1426
1427
1428
1429
1430
1431

1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
....
4792
4793
4794
4795
4796
4797
4798
4799
4800
4801
4802
4803
4804
4805
4806
....
5221
5222
5223
5224
5225
5226
5227
5228
5229
5230
5231
5232
5233
5234
5235
....
5363
5364
5365
5366
5367
5368
5369
5370
5371
5372
5373
5374
5375
5376
5377
....
5392
5393
5394
5395
5396
5397
5398
5399
5400
5401
5402
5403
5404
5405
5406
....
5413
5414
5415
5416
5417
5418
5419
5420
5421
5422
5423
5424
5425
5426
5427
....
6621
6622
6623
6624
6625
6626
6627
6628
6629
6630
6631
6632
6633
6634
6635
....
7395
7396
7397
7398
7399
7400
7401
7402
7403
7404
7405
7406
7407
7408
7409
7410
7411
7412
7413
7414
7415
7416
7417
7418
7419
7420
7421
7422
7423
7424
7425
7426
7427
7428
7429
7430
7431
7432
7433
7434
7435
7436
7437
7438
7439
7440
7441
7442
7443
7444
7445
7446
7447
7448
7449
7450
7451
7452
7453
7454
7455
7456
7457
7458
7459
7460
7461
7462
7463
7464
7465
7466
7467
7468
7469
7470
7471
7472
....
8281
8282
8283
8284
8285
8286
8287

























































































































































































8288
8289
8290
8291
8292
8293
8294
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \

			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
................................................................................
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	Haiku*)
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-lroot"
	    echo "$as_me:$LINENO: checking for inet_ntoa in -lnetwork" >&5
echo $ECHO_N "checking for inet_ntoa in -lnetwork... $ECHO_C" >&6
if test "${ac_cv_lib_network_inet_ntoa+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
................................................................................

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
................................................................................
	    alpha|sparc64)
		SHLIB_CFLAGS="-fPIC"
		;;
	    *)
		SHLIB_CFLAGS="-fpic"
		;;
	    esac
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
fi
................................................................................
	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	NetBSD-*)
	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    if test $doRpath = yes; then

		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'
................................................................................
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"

fi

	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$@"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................
    if test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes; then

	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*|MINGW32_*) ;;
	    IRIX*) ;;
	    NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac
fi


................................................................................
echo "${ECHO_T}$tcl_cv_struct_dirent64" >&6
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then

cat >>confdefs.h <<\_ACEOF
#define HAVE_STRUCT_DIRENT64 1
_ACEOF

	fi

	echo "$as_me:$LINENO: checking for DIR64" >&5
echo $ECHO_N "checking for DIR64... $ECHO_C" >&6
if test "${tcl_cv_DIR64+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else

	    cat >conftest.$ac_ext <<_ACEOF
/* confdefs.h.  */
_ACEOF
cat confdefs.h >>conftest.$ac_ext
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h.  */
#include <sys/types.h>
#include <dirent.h>
int
main ()
{
struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);
  ;
  return 0;
}
_ACEOF
rm -f conftest.$ac_objext
if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
  (eval $ac_compile) 2>conftest.er1
  ac_status=$?
  grep -v '^ *+' conftest.er1 >conftest.err
  rm -f conftest.er1
  cat conftest.err >&5
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); } &&
	 { ac_try='test -z "$ac_c_werror_flag"
			 || test ! -s conftest.err'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; } &&
	 { ac_try='test -s conftest.$ac_objext'
  { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
  (eval $ac_try) 2>&5
  ac_status=$?
  echo "$as_me:$LINENO: \$? = $ac_status" >&5
  (exit $ac_status); }; }; then
  tcl_cv_DIR64=yes
else
  echo "$as_me: failed program was:" >&5
sed 's/^/| /' conftest.$ac_ext >&5

tcl_cv_DIR64=no
fi
rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
fi
echo "$as_me:$LINENO: result: $tcl_cv_DIR64" >&5
echo "${ECHO_T}$tcl_cv_DIR64" >&6
	if test "x${tcl_cv_DIR64}" = "xyes" ; then

cat >>confdefs.h <<\_ACEOF
#define HAVE_DIR64 1
_ACEOF

	fi

	echo "$as_me:$LINENO: checking for struct stat64" >&5
echo $ECHO_N "checking for struct stat64... $ECHO_C" >&6
if test "${tcl_cv_struct_stat64+set}" = set; then
  echo $ECHO_N "(cached) $ECHO_C" >&6
else
................................................................................

cat >>confdefs.h <<\_ACEOF
#define TIME_WITH_SYS_TIME 1
_ACEOF

fi



























































































































































































#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

echo "$as_me:$LINENO: checking for mode_t" >&5

Changes to unix/configure.in.

192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME

#--------------------------------------------------------------------
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#--------------------------------------------------------------------

SC_BUGGY_STRTOD

#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T







<
<
<
<
<
<
<
<
<







192
193
194
195
196
197
198









199
200
201
202
203
204
205
#------------------------------------------------------------------------------
#       Find out all about time handling differences.
#------------------------------------------------------------------------------

AC_CHECK_HEADERS(sys/time.h)
AC_HEADER_TIME










#--------------------------------------------------------------------
#	Check for various typedefs and provide substitutes if
#	they don't exist.
#--------------------------------------------------------------------

AC_TYPE_MODE_T
AC_TYPE_PID_T

Changes to unix/tcl.m4.

87
88
89
90
91
92
93
94
95

96
97
98


99
100
101
102
103
104
105
...
220
221
222
223
224
225
226

227
228


229
230
231
232
233
234
235
....
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
....
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
....
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
....
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
....
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
....
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
....
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
....
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
....
2610
2611
2612
2613
2614
2615
2616









2617
2618
2619
2620
2621
2622
2623
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \

			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \


			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
................................................................................
	    # check in a few common install locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \

			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \


			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
................................................................................
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	Haiku*)
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-lroot"
	    AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
	    ;;
	HP-UX-*.11.*)
	    # Use updated header definitions where possible
	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
................................................................................

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
................................................................................
	    alpha|sparc64)
		SHLIB_CFLAGS="-fPIC"
		;;
	    *)
		SHLIB_CFLAGS="-fpic"
		;;
	    esac
	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
................................................................................
	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	NetBSD-*)
	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
................................................................................
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    ])
	    ;;
	FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*|MINGW32_*) ;;
	    IRIX*) ;;
	    NetBSD-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
................................................................................
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_BUGGY_STRTOD
#
#	Under Solaris 2.4, strtod returns the wrong value for the
#	terminating character under some conditions.  Check for this
#	and if the problem exists use a substitute procedure
#	"fixstrtod" (provided by Tcl) that corrects the error.
#	Also, on Compaq's Tru64 Unix 5.0,
#	strtod(" ") returns 0.0 instead of a failure to convert.
#
# Arguments:
#	none
#
# Results:
#
#	Might defines some of the following vars:
#		strtod (=fixstrtod)
#
#--------------------------------------------------------------------

AC_DEFUN([SC_BUGGY_STRTOD], [
    AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0)
    if test "$tcl_strtod" = 1; then
	AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[
	    AC_TRY_RUN([
		extern double strtod();
		int main() {
		    char *infString="Inf", *nanString="NaN", *spaceString=" ";
		    char *term;
		    double value;
		    value = strtod(infString, &term);
		    if ((term != infString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(nanString, &term);
		    if ((term != nanString) && (term[-1] == 0)) {
			exit(1);
		    }
		    value = strtod(spaceString, &term);
		    if (term == (spaceString+1)) {
			exit(1);
		    }
		    exit(0);
		}], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy,
		    tcl_cv_strtod_buggy=buggy)])
	if test "$tcl_cv_strtod_buggy" = buggy; then
	    AC_LIBOBJ([fixstrtod])
	    USE_COMPAT=1
	    AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?])
	fi
    fi
])

#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm) and socket stuff (-lsocket vs.
#	-lnsl) are dealt with here.
#
................................................................................
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_LINK_LIBS], [
    #--------------------------------------------------------------------
    # On a few very rare systems, all of the libm.a stuff is
    # already in libc.a.  Set compiler flags accordingly.
    # Also, Linux requires the "ieee" library for math to work
    # right (and it must appear before "-lm").
    #--------------------------------------------------------------------

    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")
    AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"])

    #--------------------------------------------------------------------
    # Interactive UNIX requires -linet instead of -lsocket, plus it
    # needs net/errno.h to define the socket-related error codes.
    #--------------------------------------------------------------------

    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
................................................................................
#	None
#
# Results:
#
#	Might define the following vars:
#		TCL_WIDE_INT_IS_LONG
#		TCL_WIDE_INT_TYPE
#		HAVE_STRUCT_DIRENT64
#		HAVE_STRUCT_STAT64
#		HAVE_TYPE_OFF64_T
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
................................................................................
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi










	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
],
		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])







<

>



>
>







 







>


>
>







 







|







 







|







 







|







 







|







 







|







 







|







 







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







 







<
<



<







 







|







 







>
>
>
>
>
>
>
>
>







87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
...
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
....
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
....
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
....
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
....
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
....
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
....
2393
2394
2395
2396
2397
2398
2399





















































2400
2401
2402
2403
2404
2405
2406
....
2418
2419
2420
2421
2422
2423
2424


2425
2426
2427

2428
2429
2430
2431
2432
2433
2434
....
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
....
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
	    fi

	    # check in a few common install locations
	    if test x"${ac_cv_c_tclconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \

			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tcl8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \
			; do
		    if test -f "$i/tclConfig.sh" ; then
			ac_cv_c_tclconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
................................................................................
	    # check in a few common install locations
	    if test x"${ac_cv_c_tkconfig}" = x ; then
		for i in `ls -d ${libdir} 2>/dev/null` \
			`ls -d ${exec_prefix}/lib 2>/dev/null` \
			`ls -d ${prefix}/lib 2>/dev/null` \
			`ls -d /usr/local/lib 2>/dev/null` \
			`ls -d /usr/contrib/lib 2>/dev/null` \
			`ls -d /usr/pkg/lib 2>/dev/null` \
			`ls -d /usr/lib 2>/dev/null` \
			`ls -d /usr/lib64 2>/dev/null` \
			`ls -d /usr/local/lib/tk8.6 2>/dev/null` \
			`ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \
			; do
		    if test -f "$i/tkConfig.sh" ; then
			ac_cv_c_tkconfig="`(cd $i; pwd)`"
			break
		    fi
		done
	    fi
................................................................................
	    CC_SEARCH_FLAGS=""
	    LD_SEARCH_FLAGS=""
	    ;;
	Haiku*)
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_SUFFIX=".so"
	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-lroot"
	    AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"])
	    ;;
	HP-UX-*.11.*)
	    # Use updated header definitions where possible
	    AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?])
................................................................................

	    CFLAGS_OPTIMIZE="-O2"
	    # egcs-2.91.66 on Redhat Linux 6.0 generates lots of warnings
	    # when you inline the string and math operations.  Turn this off to
	    # get rid of the warnings.
	    #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES"

	    SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared'
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS="-ldl"
	    LDFLAGS="$LDFLAGS -Wl,--export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"])
................................................................................
	    alpha|sparc64)
		SHLIB_CFLAGS="-fPIC"
		;;
	    *)
		SHLIB_CFLAGS="-fpic"
		;;
	    esac
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
	    SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}'
................................................................................
	    # OpenBSD doesn't do version numbers with dots.
	    UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a'
	    TCL_LIB_VERSIONS_OK=nodots
	    ;;
	NetBSD-*)
	    # NetBSD has ELF and can use 'cc -shared' to build shared libs
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared'
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
	    LDFLAGS="$LDFLAGS -export-dynamic"
	    AS_IF([test $doRpath = yes], [
		CC_SEARCH_FLAGS='-Wl,-rpath,${LIB_RUNTIME_DIR}'])
	    LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS}
................................................................................
	    AS_IF([test "${TCL_THREADS}" = "1"], [
		# The -pthread needs to go in the CFLAGS, not LIBS
		LIBS=`echo $LIBS | sed s/-pthread//`
		CFLAGS="$CFLAGS -pthread"
	    	LDFLAGS="$LDFLAGS -pthread"
	    ])
	    ;;
	DragonFly-*|FreeBSD-*)
	    # This configuration from FreeBSD Ports.
	    SHLIB_CFLAGS="-fPIC"
	    SHLIB_LD="${CC} -shared"
	    SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,-soname,\$[@]"
	    SHLIB_SUFFIX=".so"
	    DL_OBJS="tclLoadDl.o"
	    DL_LIBS=""
................................................................................

    AS_IF([test "$DL_OBJS" != "tclLoadNone.o" -a "$GCC" = yes], [
	case $system in
	    AIX-*) ;;
	    BSD/OS*) ;;
	    CYGWIN_*|MINGW32_*) ;;
	    IRIX*) ;;
	    NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;;
	    Darwin-*) ;;
	    SCO_SV-3.2*) ;;
	    *) SHLIB_CFLAGS="-fPIC" ;;
	esac])

    AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [
	AC_DEFINE(MODULE_SCOPE, [extern],
................................................................................
		tcl_cv_timezone_time=yes, tcl_cv_timezone_time=no)])
	if test $tcl_cv_timezone_time = yes ; then
	    AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?])
	fi
    fi
])






















































#--------------------------------------------------------------------
# SC_TCL_LINK_LIBS
#
#	Search for the libraries needed to link the Tcl shell.
#	Things like the math library (-lm) and socket stuff (-lsocket vs.
#	-lnsl) are dealt with here.
#
................................................................................
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_LINK_LIBS], [
    #--------------------------------------------------------------------
    # On a few very rare systems, all of the libm.a stuff is
    # already in libc.a.  Set compiler flags accordingly.


    #--------------------------------------------------------------------

    AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm")


    #--------------------------------------------------------------------
    # Interactive UNIX requires -linet instead of -lsocket, plus it
    # needs net/errno.h to define the socket-related error codes.
    #--------------------------------------------------------------------

    AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"])
................................................................................
#	None
#
# Results:
#
#	Might define the following vars:
#		TCL_WIDE_INT_IS_LONG
#		TCL_WIDE_INT_TYPE
#		HAVE_STRUCT_DIRENT64, HAVE_DIR64
#		HAVE_STRUCT_STAT64
#		HAVE_TYPE_OFF64_T
#
#--------------------------------------------------------------------

AC_DEFUN([SC_TCL_64BIT_FLAGS], [
    AC_MSG_CHECKING([for 64-bit integer type])
................................................................................
	AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 p;],
		tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)])
	if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[
	    AC_TRY_COMPILE([#include <sys/types.h>
#include <dirent.h>],[struct dirent64 *p; DIR64 d = opendir64(".");
            p = readdir64(d); rewinddir64(d); closedir64(d);],
		tcl_cv_DIR64=yes,tcl_cv_DIR64=no)])
	if test "x${tcl_cv_DIR64}" = "xyes" ; then
	    AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?])
	fi

	AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[
	    AC_TRY_COMPILE([#include <sys/stat.h>],[struct stat64 p;
],
		tcl_cv_struct_stat64=yes,tcl_cv_struct_stat64=no)])
	if test "x${tcl_cv_struct_stat64}" = "xyes" ; then
	    AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in <sys/stat.h>?])

Changes to unix/tkUnixFont.c.

402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
...
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
....
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
....
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
....
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
....
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
....
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
....
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
....
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
....
1845
1846
1847
1848
1849
1850
1851

1852

1853
1854
1855
1856
1857
1858
1859
....
1919
1920
1921
1922
1923
1924
1925

1926

1927
1928
1929
1930
1931
1932
1933
....
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
....
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
....
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
....
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    char *dstStart, *dstEnd;
    int ch;
    int result;
    static char hexChars[] = "0123456789abcdef";
    static char mapChars[] = {
	0, 0, 0, 0, 0, 0, 0,
	'a', 'b', 't', 'n', 'v', 'f', 'r'
    };

    result = TCL_OK;
................................................................................
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,			/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    FontAttributes atts;
    UnixFont *fontPtr = (UnixFont *) tkfont;
				/* Structure describing the logical font */
    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
				/* Pointer to subfont array in case
................................................................................
				 * means return at least one character even if
				 * no characters fit. */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFont *fontPtr;
    SubFont *lastSubFontPtr;
    int curX, curByte;

    /*
     * Unix does not use kerning or fractional character widths when
     * displaying text on the screen. So that means we can safely measure
     * individual characters or spans of characters and add up the widths w/o
     * any "off-by-one-pixel" errors.
     */
................................................................................
    lastSubFontPtr = &fontPtr->subFontArray[0];

    if (numBytes == 0) {
	curX = 0;
	curByte = 0;
    } else if (maxLength < 0) {
	const char *p, *end, *next;
	int ch;
	SubFont *thisSubFontPtr;
	FontFamily *familyPtr;
	Tcl_DString runString;

	/*
	 * A three step process:
	 * 1. Find a contiguous range of characters that can all be
................................................................................
		    Tcl_DStringLength(&runString));
	}
	Tcl_DStringFree(&runString);
	curByte = numBytes;
    } else {
	const char *p, *end, *next, *term;
	int newX, termX, sawNonSpace, dstWrote;
	Tcl_UniChar ch;
	FontFamily *familyPtr;
	XChar2b buf[8];

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + Tcl_UtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;
................................................................................
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += Tcl_UtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {
................................................................................
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += Tcl_UtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += Tcl_UtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}

................................................................................
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr = (UnixFont *) tkfont;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    int xStart, needWidth, window_width, do_width;
    Tcl_UniChar ch;
    FontFamily *familyPtr;
#ifdef TK_DRAW_CHAR_XWINDOW_CHECK
    int rx, ry;
    unsigned width, height, border_width, depth;
    Drawable root;
#endif

................................................................................
    window_width = 32768;
#endif

    end = source + numBytes;
    needWidth = fontPtr->font.fa.underline + fontPtr->font.fa.overstrike;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + Tcl_UtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {
................................................................................
    encoding = Tcl_GetEncoding(NULL, GetEncodingAlias(fa.xa.charset));

    familyPtr = tsdPtr->fontFamilyList;
    for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if ((familyPtr->faceName == fa.fa.family)
		&& (familyPtr->foundry == fa.xa.foundry)
		&& (familyPtr->encoding == encoding)) {

	    Tcl_FreeEncoding(encoding);

	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));
................................................................................
    if (familyPtr == NULL) {
	return;
    }
    familyPtr->refCount--;
    if (familyPtr->refCount > 0) {
	return;
    }

    Tcl_FreeEncoding(familyPtr->encoding);

    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }

    /*
................................................................................
static void
FontMapLoadPage(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int row)			/* Index of the page to be loaded into the
				 * cache. */
{
    char buf[16], src[TCL_UTF_MAX];
    int minHi, maxHi, minLo, maxLo, scale, checkLo;
    int i, end, bitOffset, isTwoByteFont, n;
    Tcl_Encoding encoding;
    XFontStruct *fontStructPtr;
    XCharStruct *widths;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
................................................................................
	}
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	int hi, lo;

	if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i, src),
		TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (isTwoByteFont) {
	    hi = ((unsigned char *) buf)[0];
	    lo = ((unsigned char *) buf)[1];
................................................................................
{
    int i, nameIdx, numNames, srcLen, numEncodings, bestIdx[2];
    Tk_Uid hateFoundry;
    const char *charset, *hateCharset;
    unsigned bestScore[2];
    char **nameList;
    char **nameListOrig;
    char src[TCL_UTF_MAX];
    FontAttributes want, got;
    Display *display;
    SubFont subFont;
    XFontStruct *fontStructPtr;
    Tcl_DString dsEncodings;
    Tcl_Encoding *encodingCachePtr;

................................................................................
    display = fontPtr->display;
    nameList = ListFonts(display, faceName, &numNames);
    if (numNames == 0) {
	return NULL;
    }
    nameListOrig = nameList;

    srcLen = Tcl_UniCharToUtf(ch, src);

    want.fa = fontPtr->font.fa;
    want.xa = fontPtr->xa;

    want.fa.family = Tk_GetUid(faceName);
    want.fa.size = (double)-fontPtr->pixelSize;








|
<







 







|







 







|







 







<







 







<









|







 







|







 







|





|







 







|
<







 







|







 







>
|
>







 







>
|
>







 







|







 







|







 







|







 







|







402
403
404
405
406
407
408
409

410
411
412
413
414
415
416
...
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
....
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
....
1031
1032
1033
1034
1035
1036
1037

1038
1039
1040
1041
1042
1043
1044
....
1084
1085
1086
1087
1088
1089
1090

1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
....
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
....
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
....
1271
1272
1273
1274
1275
1276
1277
1278

1279
1280
1281
1282
1283
1284
1285
....
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
....
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
....
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
....
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
....
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
....
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
....
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
				 * the conversion. */
    int *dstCharsPtr)		/* Filled with the number of characters that
				 * correspond to the bytes stored in the
				 * output buffer. */
{
    const char *srcStart, *srcEnd;
    char *dstStart, *dstEnd;
    int ch, result;

    static char hexChars[] = "0123456789abcdef";
    static char mapChars[] = {
	0, 0, 0, 0, 0, 0, 0,
	'a', 'b', 't', 'n', 'v', 'f', 'r'
    };

    result = TCL_OK;
................................................................................
 *----------------------------------------------------------------------
 */

void
TkpGetFontAttrsForChar(
    Tk_Window tkwin,		/* Window on the font's display */
    Tk_Font tkfont,		/* Font to query */
    int c,         		/* Character of interest */
    TkFontAttributes *faPtr)	/* Output: Font attributes */
{
    FontAttributes atts;
    UnixFont *fontPtr = (UnixFont *) tkfont;
				/* Structure describing the logical font */
    SubFont *lastSubFontPtr = &fontPtr->subFontArray[0];
				/* Pointer to subfont array in case
................................................................................
				 * means return at least one character even if
				 * no characters fit. */
    int *lengthPtr)		/* Filled with x-location just after the
				 * terminating character. */
{
    UnixFont *fontPtr;
    SubFont *lastSubFontPtr;
    int curX, curByte, ch;

    /*
     * Unix does not use kerning or fractional character widths when
     * displaying text on the screen. So that means we can safely measure
     * individual characters or spans of characters and add up the widths w/o
     * any "off-by-one-pixel" errors.
     */
................................................................................
    lastSubFontPtr = &fontPtr->subFontArray[0];

    if (numBytes == 0) {
	curX = 0;
	curByte = 0;
    } else if (maxLength < 0) {
	const char *p, *end, *next;

	SubFont *thisSubFontPtr;
	FontFamily *familyPtr;
	Tcl_DString runString;

	/*
	 * A three step process:
	 * 1. Find a contiguous range of characters that can all be
................................................................................
		    Tcl_DStringLength(&runString));
	}
	Tcl_DStringFree(&runString);
	curByte = numBytes;
    } else {
	const char *p, *end, *next, *term;
	int newX, termX, sawNonSpace, dstWrote;

	FontFamily *familyPtr;
	XChar2b buf[8];

	/*
	 * How many chars will fit in the space allotted? This first version
	 * may be inefficient because it measures every character
	 * individually.
	 */

	next = source + TkUtfToUniChar(source, &ch);
	newX = curX = termX = 0;

	term = source;
	end = source + numBytes;

	sawNonSpace = (ch > 255) || !isspace(ch);
	familyPtr = lastSubFontPtr->familyPtr;
................................................................................
	    p = next;
	    if (p >= end) {
		term = end;
		termX = curX;
		break;
	    }

	    next += TkUtfToUniChar(next, &ch);
	    if ((ch < 256) && isspace(ch)) {
		if (sawNonSpace) {
		    term = p;
		    termX = curX;
		    sawNonSpace = 0;
		}
	    } else {
................................................................................
	    /*
	     * Include the first character that didn't quite fit in the
	     * desired span. The width returned will include the width of that
	     * extra character.
	     */

	    curX = newX;
	    p += TkUtfToUniChar(p, &ch);
	}
	if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) {
	    term = p;
	    termX = curX;
	    if (term == source) {
		term += TkUtfToUniChar(term, &ch);
		termX = newX;
	    }
	} else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) {
	    term = p;
	    termX = curX;
	}

................................................................................
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    UnixFont *fontPtr = (UnixFont *) tkfont;
    SubFont *thisSubFontPtr, *lastSubFontPtr;
    Tcl_DString runString;
    const char *p, *end, *next;
    int xStart, needWidth, window_width, do_width, ch;

    FontFamily *familyPtr;
#ifdef TK_DRAW_CHAR_XWINDOW_CHECK
    int rx, ry;
    unsigned width, height, border_width, depth;
    Drawable root;
#endif

................................................................................
    window_width = 32768;
#endif

    end = source + numBytes;
    needWidth = fontPtr->font.fa.underline + fontPtr->font.fa.overstrike;
    for (p = source; p <= end; ) {
	if (p < end) {
	    next = p + TkUtfToUniChar(p, &ch);
	    thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr);
	} else {
	    next = p + 1;
	    thisSubFontPtr = lastSubFontPtr;
	}
	if ((thisSubFontPtr != lastSubFontPtr)
		|| (p == end) || (p-source > 200)) {
................................................................................
    encoding = Tcl_GetEncoding(NULL, GetEncodingAlias(fa.xa.charset));

    familyPtr = tsdPtr->fontFamilyList;
    for (; familyPtr != NULL; familyPtr = familyPtr->nextPtr) {
	if ((familyPtr->faceName == fa.fa.family)
		&& (familyPtr->foundry == fa.xa.foundry)
		&& (familyPtr->encoding == encoding)) {
	    if (encoding) {
		Tcl_FreeEncoding(encoding);
	    }
	    familyPtr->refCount++;
	    return familyPtr;
	}
    }

    familyPtr = ckalloc(sizeof(FontFamily));
    memset(familyPtr, 0, sizeof(FontFamily));
................................................................................
    if (familyPtr == NULL) {
	return;
    }
    familyPtr->refCount--;
    if (familyPtr->refCount > 0) {
	return;
    }
    if (familyPtr->encoding) {
	Tcl_FreeEncoding(familyPtr->encoding);
    }
    for (i = 0; i < FONTMAP_PAGES; i++) {
	if (familyPtr->fontMap[i] != NULL) {
	    ckfree(familyPtr->fontMap[i]);
	}
    }

    /*
................................................................................
static void
FontMapLoadPage(
    SubFont *subFontPtr,	/* Contains font mapping cache to be
				 * updated. */
    int row)			/* Index of the page to be loaded into the
				 * cache. */
{
    char buf[16], src[6];
    int minHi, maxHi, minLo, maxLo, scale, checkLo;
    int i, end, bitOffset, isTwoByteFont, n;
    Tcl_Encoding encoding;
    XFontStruct *fontStructPtr;
    XCharStruct *widths;
    ThreadSpecificData *tsdPtr =
	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
................................................................................
	}
    }

    end = (row + 1) << FONTMAP_SHIFT;
    for (i = row << FONTMAP_SHIFT; i < end; i++) {
	int hi, lo;

	if (Tcl_UtfToExternal(NULL, encoding, src, TkUniCharToUtf(i, src),
		TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL,
		NULL, NULL) != TCL_OK) {
	    continue;
	}
	if (isTwoByteFont) {
	    hi = ((unsigned char *) buf)[0];
	    lo = ((unsigned char *) buf)[1];
................................................................................
{
    int i, nameIdx, numNames, srcLen, numEncodings, bestIdx[2];
    Tk_Uid hateFoundry;
    const char *charset, *hateCharset;
    unsigned bestScore[2];
    char **nameList;
    char **nameListOrig;
    char src[6];
    FontAttributes want, got;
    Display *display;
    SubFont subFont;
    XFontStruct *fontStructPtr;
    Tcl_DString dsEncodings;
    Tcl_Encoding *encodingCachePtr;

................................................................................
    display = fontPtr->display;
    nameList = ListFonts(display, faceName, &numNames);
    if (numNames == 0) {
	return NULL;
    }
    nameListOrig = nameList;

    srcLen = TkUniCharToUtf(ch, src);

    want.fa = fontPtr->font.fa;
    want.xa = fontPtr->xa;

    want.fa.family = Tk_GetUid(faceName);
    want.fa.size = (double)-fontPtr->pixelSize;

Changes to unix/tkUnixKey.c.

106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
...
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
...
281
282
283
284
285
286
287















288
289
290
291
292
293
294

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Initialized, empty string to hold result. */
{
    int len, mincode, maxcode;
    Tcl_DString buf;
    TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

    /*
     * If we have the value cached already, use it now. [Bug 1373712]
     */

................................................................................
    /*
     * Only do this for KeyPress events, otherwise
     * further Xlib function behavior might be undefined.
     */

    if (eventPtr->type != KeyPress) {
	len = 0;
	Tcl_DStringSetLength(dsPtr, len);
	goto done;
    }

    /*
     * Filter keycodes out of range, otherwise
     * further Xlib function behavior might be undefined.
     */

    mincode = 0;
    maxcode = -1;
    XDisplayKeycodes(winPtr->dispPtr->display, &mincode, &maxcode);
    if ((eventPtr->xkey.keycode < mincode) ||
	(eventPtr->xkey.keycode > maxcode)) {
	len = 0;
	Tcl_DStringSetLength(dsPtr, len);
	goto done;
    }

#ifdef TK_USE_INPUT_METHODS
    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)
	    && (winPtr->inputContext != NULL)
................................................................................
void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keySym,
    XEvent *eventPtr)
{
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    int state;
    KeyCode keycode;

    if (keySym == NoSymbol) {
	keycode = 0;
    } else {
	keycode = XKeysymToKeycode(dispPtr->display, keySym);
    }
................................................................................
		if (state & 2) {
		    eventPtr->xkey.state |= dispPtr->modeModMask;
		}
		break;
	    }
	}
    }















    eventPtr->xkey.keycode = keycode;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpGetKeySym --







|







 







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







 







|







 







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







106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
...
128
129
130
131
132
133
134















135
136
137
138
139
140
141
...
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
...
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294

const char *
TkpGetString(
    TkWindow *winPtr,		/* Window where event occurred */
    XEvent *eventPtr,		/* X keyboard event. */
    Tcl_DString *dsPtr)		/* Initialized, empty string to hold result. */
{
    int len;
    Tcl_DString buf;
    TkKeyEvent *kePtr = (TkKeyEvent *) eventPtr;

    /*
     * If we have the value cached already, use it now. [Bug 1373712]
     */

................................................................................
    /*
     * Only do this for KeyPress events, otherwise
     * further Xlib function behavior might be undefined.
     */

    if (eventPtr->type != KeyPress) {
	len = 0;















	Tcl_DStringSetLength(dsPtr, len);
	goto done;
    }

#ifdef TK_USE_INPUT_METHODS
    if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)
	    && (winPtr->inputContext != NULL)
................................................................................
void
TkpSetKeycodeAndState(
    Tk_Window tkwin,
    KeySym keySym,
    XEvent *eventPtr)
{
    TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr;
    int state, mincode, maxcode;
    KeyCode keycode;

    if (keySym == NoSymbol) {
	keycode = 0;
    } else {
	keycode = XKeysymToKeycode(dispPtr->display, keySym);
    }
................................................................................
		if (state & 2) {
		    eventPtr->xkey.state |= dispPtr->modeModMask;
		}
		break;
	    }
	}
    }

    /*
     * Filter keycodes out of range, otherwise further Xlib function
     * behavior might be undefined, in particular XIM could cause crashes.
     */

    mincode = 0;
    maxcode = -1;
    XDisplayKeycodes(dispPtr->display, &mincode, &maxcode);
    if (keycode < mincode) {
	keycode = mincode;
    } else if (keycode > maxcode) {
	keycode = maxcode;
    }

    eventPtr->xkey.keycode = keycode;
}
 
/*
 *----------------------------------------------------------------------
 *
 * TkpGetKeySym --

Changes to unix/tkUnixMenu.c.

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
...
477
478
479
480
481
482
483

484
485
486
487
488
489
490
...
506
507
508
509
510
511
512
513

514
515
516
517
518
519
520
521
...
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
....
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
....
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
....
1431
1432
1433
1434
1435
1436
1437
1438

1439
1440
1441
1442
1443
1444
1445
....
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
 * Procedures used internally.
 */

static void		SetHelpMenu(TkMenu *menuPtr);
static void		DrawMenuEntryAccelerator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    Tk_3DBorder activeBorder, int x, int y,
			    int width, int height, int drawArrow);
static void		DrawMenuEntryBackground(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder activeBorder, Tk_3DBorder bgBorder,
			    int x, int y, int width, int heigth);
static void		DrawMenuEntryIndicator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder border, XColor *indicatorColor,
................................................................................
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    GC gc,			/* The precalculated gc to draw with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    Tk_3DBorder activeBorder,	/* The border for an active item */

    int x,			/* Left coordinate of entry rect */
    int y,			/* Top coordinate of entry rect */
    int width,			/* Width of entry */
    int height,			/* Height of entry */
    int drawArrow)		/* Whether or not to draw arrow. */
{
    XPoint points[3];
................................................................................
    	points[0].x = x + width - borderWidth - activeBorderWidth
		- CASCADE_ARROW_WIDTH;
    	points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2;
    	points[1].x = points[0].x;
    	points[1].y = points[0].y + CASCADE_ARROW_HEIGHT;
    	points[2].x = points[0].x + CASCADE_ARROW_WIDTH;
    	points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2;
    	Tk_Fill3DPolygon(menuPtr->tkwin, d, activeBorder, points, 3,

		DECORATION_BORDER_WIDTH,
	    	(menuPtr->postedCascade == mePtr)
	    	? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
    } else if (mePtr->accelPtr != NULL) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);
	int left = x + mePtr->labelWidth + activeBorderWidth
		+ mePtr->indicatorSpace;

................................................................................

    if (menuPtr->menuType == MENUBAR) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].x = width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
	    TK_RELIEF_RAISED);
}
 
/*
................................................................................
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
    maxX = width - 1;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);

    while (points[0].x < maxX) {
	points[1].x = points[0].x + segmentWidth;
	if (points[1].x > maxX) {
	    points[1].x = maxX;
	}
................................................................................
				/* Precalculated metrics for menu */
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawArrow)		/* Whether or not to draw the cascade arrow
				 * for cascade items. Only applies to
				 * Windows. */
{
    GC gc, indicatorGC;
    XColor *indicatorColor, *disableColor = NULL;
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_3DBorder bgBorder, activeBorder;
    const Tk_FontMetrics *fmPtr;
    Tk_FontMetrics entryMetrics;
................................................................................
    } else if (mePtr->type == TEAROFF_ENTRY) {
	DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
    } else {
	DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
	DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
		activeBorder, x, adjustedY, width, adjustedHeight, drawArrow);

	if (!mePtr->hideMargin) {
	    if (mePtr->state == ENTRY_ACTIVE) {
		bgBorder = activeBorder;
	    }
	    DrawMenuEntryIndicator(menuPtr, mePtr, d, bgBorder, indicatorColor,
		    disableColor, tkfont, fmPtr, x, adjustedY, width,
		    adjustedHeight);
................................................................................
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + indicatorSpace + labelWidth + accelWidth
	    + 2 * activeBorderWidth + 2 * borderWidth;

    windowHeight += borderWidth;

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */







|
|







 







>







 







|
>
|







 







|







 







|







 







|
<







 







|
>







 







|







48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
...
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
...
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
...
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
....
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
....
1324
1325
1326
1327
1328
1329
1330
1331

1332
1333
1334
1335
1336
1337
1338
....
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
....
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
 * Procedures used internally.
 */

static void		SetHelpMenu(TkMenu *menuPtr);
static void		DrawMenuEntryAccelerator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d, GC gc,
			    Tk_Font tkfont, const Tk_FontMetrics *fmPtr,
			    Tk_3DBorder activeBorder, Tk_3DBorder bgBorder,
			    int x, int y, int width, int height, int drawArrow);
static void		DrawMenuEntryBackground(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder activeBorder, Tk_3DBorder bgBorder,
			    int x, int y, int width, int heigth);
static void		DrawMenuEntryIndicator(TkMenu *menuPtr,
			    TkMenuEntry *mePtr, Drawable d,
			    Tk_3DBorder border, XColor *indicatorColor,
................................................................................
    TkMenu *menuPtr,		/* The menu we are drawing */
    TkMenuEntry *mePtr,		/* The entry we are drawing */
    Drawable d,			/* The drawable we are drawing into */
    GC gc,			/* The precalculated gc to draw with */
    Tk_Font tkfont,		/* The precalculated font */
    const Tk_FontMetrics *fmPtr,/* The precalculated metrics */
    Tk_3DBorder activeBorder,	/* The border for an active item */
    Tk_3DBorder bgBorder,	/* The background border */
    int x,			/* Left coordinate of entry rect */
    int y,			/* Top coordinate of entry rect */
    int width,			/* Width of entry */
    int height,			/* Height of entry */
    int drawArrow)		/* Whether or not to draw arrow. */
{
    XPoint points[3];
................................................................................
    	points[0].x = x + width - borderWidth - activeBorderWidth
		- CASCADE_ARROW_WIDTH;
    	points[0].y = y + (height - CASCADE_ARROW_HEIGHT)/2;
    	points[1].x = points[0].x;
    	points[1].y = points[0].y + CASCADE_ARROW_HEIGHT;
    	points[2].x = points[0].x + CASCADE_ARROW_WIDTH;
    	points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2;
    	Tk_Fill3DPolygon(menuPtr->tkwin, d,
		(mePtr->state == ENTRY_ACTIVE) ? activeBorder : bgBorder,
		points, 3, DECORATION_BORDER_WIDTH,
	    	(menuPtr->postedCascade == mePtr)
	    	? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED);
    } else if (mePtr->accelPtr != NULL) {
	const char *accel = Tcl_GetString(mePtr->accelPtr);
	int left = x + mePtr->labelWidth + activeBorderWidth
		+ mePtr->indicatorSpace;

................................................................................

    if (menuPtr->menuType == MENUBAR) {
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].x = x + width - 1;
    points[1].y = points[0].y;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);
    Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1,
	    TK_RELIEF_RAISED);
}
 
/*
................................................................................
	return;
    }

    points[0].x = x;
    points[0].y = y + height/2;
    points[1].y = points[0].y;
    segmentWidth = 6;
    maxX = x + width - 1;
    border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr);

    while (points[0].x < maxX) {
	points[1].x = points[0].x + segmentWidth;
	if (points[1].x > maxX) {
	    points[1].x = maxX;
	}
................................................................................
				/* Precalculated metrics for menu */
    int x,			/* X-coordinate of topleft of entry */
    int y,			/* Y-coordinate of topleft of entry */
    int width,			/* Width of the entry rectangle */
    int height,			/* Height of the current rectangle */
    int strictMotif,		/* Boolean flag */
    int drawArrow)		/* Whether or not to draw the cascade arrow
				 * for cascade items. */

{
    GC gc, indicatorGC;
    XColor *indicatorColor, *disableColor = NULL;
    TkMenu *menuPtr = mePtr->menuPtr;
    Tk_3DBorder bgBorder, activeBorder;
    const Tk_FontMetrics *fmPtr;
    Tk_FontMetrics entryMetrics;
................................................................................
    } else if (mePtr->type == TEAROFF_ENTRY) {
	DrawTearoffEntry(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
    } else {
	DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY,
		width, adjustedHeight);
	DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr,
		activeBorder, bgBorder, x, adjustedY, width, adjustedHeight,
		drawArrow);
	if (!mePtr->hideMargin) {
	    if (mePtr->state == ENTRY_ACTIVE) {
		bgBorder = activeBorder;
	    }
	    DrawMenuEntryIndicator(menuPtr, mePtr, d, bgBorder, indicatorColor,
		    disableColor, tkfont, fmPtr, x, adjustedY, width,
		    adjustedHeight);
................................................................................
	menuPtr->entries[j]->labelWidth = labelWidth;
	menuPtr->entries[j]->width = indicatorSpace + labelWidth
		+ accelWidth + 2 * activeBorderWidth;
	menuPtr->entries[j]->x = x;
	menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN;
    }
    windowWidth = x + indicatorSpace + labelWidth + accelWidth
	    + 2 * activeBorderWidth + borderWidth;

    windowHeight += borderWidth;

    /*
     * The X server doesn't like zero dimensions, so round up to at least 1 (a
     * zero-sized menu should never really occur, anyway).
     */

Changes to unix/tkUnixRFont.c.

707
708
709
710
711
712
713
714









715
716

717
718
719
720
721
722
723
...
846
847
848
849
850
851
852

853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
...
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912






913
914
915
916
917
918
919
920
921
922


923
924
925
926
927
928
929
...
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
....
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
....
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
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
....
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
....
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131



1132
1133
1134
1135






1136
1137
1138
1139
1140



1141
1142
1143
1144
1145
1146
1147
	newX = curX + extents.xOff;
	newByte = curByte + clen;
	if (maxLength >= 0 && newX > maxLength) {
	    if (flags & TK_PARTIAL_OK ||
		    (flags & TK_AT_LEAST_ONE && curByte == 0)) {
		curX = newX;
		curByte = newByte;
	    } else if (flags & TK_WHOLE_WORDS && termX != 0) {









		curX = termX;
		curByte = termByte;

	    }
	    break;
	}

	curX = newX;
	curByte = newByte;
    }
................................................................................
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */

    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));

   if (maxCoord <= y) {
      return; /* nothing to draw */
   }

    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
................................................................................
	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {
            int cx = x;
            int cy = y;

	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);
            if ((x += metrics.xOff) >= maxCoord
                  || (y += metrics.yOff) >= maxCoord) {
               break;
            }






            if (metrics.xOff > 0 && cx >= 0 && cy >= 0) {
               specs[nspec].font = ftFont;
               specs[nspec].x = cx;
               specs[nspec].y = cy;
               if (++nspec == NUM_SPEC) {
                   XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
                           specs, nspec);
                   nspec = 0;
               }
	    }


	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }

  doUnderlineStrikeout:
................................................................................
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -1000;	/* Should be good enough... */
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int xStart = x, yStart = y;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
#ifdef XFT_HAS_FIXED_ROTATED_PLACEMENT
................................................................................
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }

    nglyph = 0;
    currentFtFont = NULL;
    originX = originY = 0;		/* lint */

    while (numBytes > 0 && x >= minCoord && y >= minCoord) {
	XftFont *ftFont;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
................................................................................
		/*
		 * We pass multiple glyphs at once to enable the code to
		 * perform better rendering of sub-pixel inter-glyph spacing.
		 * If only the current Xft implementation could make use of
		 * this information... but we'll be ready when it does!
		 */

		XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
			originX, originY, glyphs, nglyph);
	    }
	    originX = ROUND16(x);
	    originY = ROUND16(y);
	    if (nglyph) {
		XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
			nglyph, &metrics);
		nglyph = 0;
                /*
                 * Breaking at this place is sub-optimal, but the whole algorithm
                 * has a design problem, the choice of NUM_SPEC is arbitrary, and so
                 * the inter-glyph spacing will look arbitrary. This algorithm
                 * has to draw the whole string at once (or whole blocks with same
                 * font), this requires a dynamic 'glyphs' array. In case of overflow
                 * the array has to be divided until the maximal string will fit. (GC)
                 */
                if ((x += metrics.xOff) >= maxCoord || (y += metrics.yOff) >= maxCoord) {
                   break;
                }
	    }









	    currentFtFont = ftFont;
	}
	glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
    }
    if (nglyph) {










	XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
		originX, originY, glyphs, nglyph);

    }
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

................................................................................
    }
    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0 && x >= minCoord && y >= minCoord) {
	XftFont *ftFont, *ft0Font;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
................................................................................
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {
	    specs[nspec].font = ftFont;
	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    specs[nspec].x = ROUND16(x);
	    specs[nspec].y = ROUND16(y);
	    XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
		    &metrics);



            if ((x += metrics.xOff*cosA + metrics.yOff*sinA) > maxCoord
                                 || (y += metrics.yOff*cosA - metrics.xOff*sinA) > maxCoord) {
               break;
            }






            if (++nspec == NUM_SPEC) {
		XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			specs, nspec);
		nspec = 0;
	    }



	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */








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







 







>









<
<
<
<







 







<
<
<



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

>
>







 







|







 







|







 







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





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







 







|







 







<

<
<


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







707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
...
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872




873
874
875
876
877
878
879
...
903
904
905
906
907
908
909



910
911
912



913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
...
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
....
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
....
1055
1056
1057
1058
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
....
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
....
1148
1149
1150
1151
1152
1153
1154

1155


1156
1157
1158
1159
1160
1161


1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
	newX = curX + extents.xOff;
	newByte = curByte + clen;
	if (maxLength >= 0 && newX > maxLength) {
	    if (flags & TK_PARTIAL_OK ||
		    (flags & TK_AT_LEAST_ONE && curByte == 0)) {
		curX = newX;
		curByte = newByte;
	    } else if (flags & TK_WHOLE_WORDS) {
		if ((flags & TK_AT_LEAST_ONE) && (termX == 0)) {
		    /*
		     * No space was seen before reaching the right
		     * of the allotted maxLength space, i.e. no word
		     * boundary. Return the string that fills the
		     * allotted space, without overfill.
		     * curX and curByte are already the right ones:
		     */
		} else {
		    curX = termX;
		    curByte = termByte;
		}
	    }
	    break;
	}

	curX = newX;
	curByte = newByte;
    }
................................................................................
				 * stripped out, they will be displayed as
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    int x, int y)		/* Coordinates at which to place origin of
				 * string when drawing. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int clen, nspec, xStart = x;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));





    if (fontPtr->ftDraw == 0) {
#if DEBUG_FONTSEL
	printf("Switch to drawable 0x%x\n", drawable);
#endif /* DEBUG_FONTSEL */
	fontPtr->ftDraw = XftDrawCreate(display, drawable,
		DefaultVisual(display, fontPtr->screen),
		DefaultColormap(display, fontPtr->screen));
................................................................................
	    goto doUnderlineStrikeout;
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, 0.0);
	if (ftFont) {



	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);
	    XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1,
		    &metrics);




	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */

	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = x;
		specs[nspec].y = y;
		if (++nspec == NUM_SPEC) {
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    nspec = 0;
		}
	    }
	    x += metrics.xOff;
	    y += metrics.yOff;
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }

  doUnderlineStrikeout:
................................................................................
				 * regular printing characters. */
    int numBytes,		/* Number of bytes in string. */
    double x, double y,		/* Coordinates at which to place origin of
				 * string when drawing. */
    double angle)		/* What angle to put text at, in degrees. */
{
    const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */
    const int minCoord = -maxCoord-1;
    UnixFtFont *fontPtr = (UnixFtFont *) tkfont;
    XGCValues values;
    XftColor *xftcolor;
    int xStart = x, yStart = y;
    ThreadSpecificData *tsdPtr = (ThreadSpecificData *)
            Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
#ifdef XFT_HAS_FIXED_ROTATED_PLACEMENT
................................................................................
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }

    nglyph = 0;
    currentFtFont = NULL;
    originX = originY = 0;		/* lint */

    while (numBytes > 0) {
	XftFont *ftFont;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
................................................................................
		/*
		 * We pass multiple glyphs at once to enable the code to
		 * perform better rendering of sub-pixel inter-glyph spacing.
		 * If only the current Xft implementation could make use of
		 * this information... but we'll be ready when it does!
		 */

		XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
			nglyph, &metrics);
		/*
		 * Draw glyph only when it fits entirely into 16 bit coords.
		 */

		if (x >= minCoord && y >= minCoord &&
		    x <= maxCoord - metrics.width &&
		    y <= maxCoord - metrics.height) {

		    /*
		     * NOTE:
		     * The whole algorithm has a design problem, the choice of
		     * NUM_SPEC is arbitrary, and so the inter-glyph spacing could
		     * look arbitrary. This algorithm has to draw the whole string
		     * at once (or whole blocks with same font), this requires a
		     * dynamic 'glyphs' array. In case of overflow the array has to
		     * be divided until the maximal string will fit. (GC)
                     * Given the resolution of current displays though, this should
                     * not be a huge issue since NUM_SPEC is 1024 and thus able to
                     * cover about 6000 pixels for a 6 pixel wide font (which is
                     * a very small barely readable font)
		     */

		    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
			    originX, originY, glyphs, nglyph);
		}
	    }
	    originX = ROUND16(x);
	    originY = ROUND16(y);
	    currentFtFont = ftFont;
	}
	glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c);
    }
    if (nglyph) {
	XftGlyphExtents(fontPtr->display, currentFtFont, glyphs,
		nglyph, &metrics);

	/*
	 * Draw glyph only when it fits entirely into 16 bit coords.
	 */

	if (x >= minCoord && y >= minCoord &&
	    x <= maxCoord - metrics.width &&
	    y <= maxCoord - metrics.height) {
	    XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont,
		    originX, originY, glyphs, nglyph);
	}
    }
#else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */
    int clen, nspec;
    XftGlyphFontSpec specs[NUM_SPEC];
    XGlyphInfo metrics;
    double sinA = sin(angle * PI/180.0), cosA = cos(angle * PI/180.0);

................................................................................
    }
    XGetGCValues(display, gc, GCForeground, &values);
    xftcolor = LookUpColor(display, fontPtr, values.foreground);
    if (tsdPtr->clipRegion != None) {
	XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion);
    }
    nspec = 0;
    while (numBytes > 0) {
	XftFont *ftFont, *ft0Font;
	FcChar32 c;

	clen = FcUtf8ToUcs4((FcChar8 *) source, &c, numBytes);
	if (clen <= 0) {
	    /*
	     * This should not happen, but it can.
................................................................................
	}
	source += clen;
	numBytes -= clen;

	ftFont = GetFont(fontPtr, c, angle);
	ft0Font = GetFont(fontPtr, c, 0.0);
	if (ftFont && ft0Font) {

	    specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c);


	    XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1,
		    &metrics);

	    /*
	     * Draw glyph only when it fits entirely into 16 bit coords.
	     */



	    if (x >= minCoord && y >= minCoord &&
		x <= maxCoord - metrics.width &&
		y <= maxCoord - metrics.height) {
		specs[nspec].font = ftFont;
		specs[nspec].x = ROUND16(x);
		specs[nspec].y = ROUND16(y);
		if (++nspec == NUM_SPEC) {
		    XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor,
			    specs, nspec);
		    nspec = 0;
		}
	    }
	    x += metrics.xOff*cosA + metrics.yOff*sinA;
	    y += metrics.yOff*cosA - metrics.xOff*sinA;
	}
    }
    if (nspec) {
	XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, specs, nspec);
    }
#endif /* XFT_HAS_FIXED_ROTATED_PLACEMENT */

Changes to unix/tkUnixScrlbr.c.

285
286
287
288
289
290
291





292
293
294
295
296
297
298

    if (scrollPtr->highlightWidth < 0) {
	scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin)
	    : Tk_Height(scrollPtr->tkwin);





    scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1;
    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
	    : Tk_Width(scrollPtr->tkwin))
	    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
	fieldLength = 0;
    }







>
>
>
>
>







285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303

    if (scrollPtr->highlightWidth < 0) {
	scrollPtr->highlightWidth = 0;
    }
    scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth;
    width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin)
	    : Tk_Height(scrollPtr->tkwin);

    /*
     * Next line assumes that the arrow area is a square.
     */

    scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1;
    fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin)
	    : Tk_Width(scrollPtr->tkwin))
	    - 2*(scrollPtr->arrowLength + scrollPtr->inset);
    if (fieldLength < 0) {
	fieldLength = 0;
    }

Changes to win/nmakehlp.c.

735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
...
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
    strncpy(path, dir, dirlen);
    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
    keylen = strlen(keypath);

#if 0 /* This function is not available in Visual C++ 6 */
    /*
     * Use numerics 0 -> FindExInfoStandard,
     * 1 -> FindExSearchLimitToDirectories, 
     * as these are not defined in Visual C++ 6
     */
    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
    hSearch = FindFirstFile(path, &finfo);
#endif
    if (hSearch == INVALID_HANDLE_VALUE)
................................................................................
	return 1; /* Not found */

    /* Loop through all subdirs checking if the keypath is under there */
    ret = 1; /* Assume not found */
    do {
	int sublen;
	/*
	 * We need to check it is a directory despite the 
	 * FindExSearchLimitToDirectories in the above call. See SDK docs
	 */
	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
................................................................................
 * LocateDependency --
 *
 *	Locates a dependency for a package.
 *        keypath - a relative path within the package directory
 *          that is used to confirm it is the correct directory.
 *	The search path for the package directory is currently only
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints 
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{
    int i, ret;
    static char *paths[] = {"..", "..\\..", "..\\..\\.."};
    
    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;
}







|







 







|







 







|







|







735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
...
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
...
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
    strncpy(path, dir, dirlen);
    strncpy(path+dirlen, "\\*", 3);	/* Including terminating \0 */
    keylen = strlen(keypath);

#if 0 /* This function is not available in Visual C++ 6 */
    /*
     * Use numerics 0 -> FindExInfoStandard,
     * 1 -> FindExSearchLimitToDirectories,
     * as these are not defined in Visual C++ 6
     */
    hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0);
#else
    hSearch = FindFirstFile(path, &finfo);
#endif
    if (hSearch == INVALID_HANDLE_VALUE)
................................................................................
	return 1; /* Not found */

    /* Loop through all subdirs checking if the keypath is under there */
    ret = 1; /* Assume not found */
    do {
	int sublen;
	/*
	 * We need to check it is a directory despite the
	 * FindExSearchLimitToDirectories in the above call. See SDK docs
	 */
	if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0)
	    continue;
	sublen = strlen(finfo.cFileName);
	if ((dirlen+1+sublen+1+keylen+1) > sizeof(path))
	    continue;		/* Path does not fit, assume not matched */
................................................................................
 * LocateDependency --
 *
 *	Locates a dependency for a package.
 *        keypath - a relative path within the package directory
 *          that is used to confirm it is the correct directory.
 *	The search path for the package directory is currently only
 *      the parent and grandparent of the current working directory.
 *      If found, the command prints
 *         name_DIRPATH=<full path of located directory>
 *      and returns 0. If not found, does not print anything and returns 1.
 */
static int LocateDependency(const char *keypath)
{
    int i, ret;
    static char *paths[] = {"..", "..\\..", "..\\..\\.."};

    for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) {
	ret = LocateDependencyHelper(paths[i], keypath);
	if (ret == 0)
	    return ret;
    }
    return ret;
}

Changes to win/tkWinDialog.c.

3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
....
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
	    }
	    Tcl_IncrRefCount(hdPtr->titleObj);
	    break;
	case FontchooserFont:
	    if (hdPtr->fontObj) {
		Tcl_DecrRefCount(hdPtr->fontObj);
	    }
	    (void)Tcl_GetString(objv[i+1]);
	    if (objv[i+1]->length) {
		hdPtr->fontObj = objv[i+1];
		if (Tcl_IsShared(hdPtr->fontObj)) {
		    hdPtr->fontObj = Tcl_DuplicateObj(hdPtr->fontObj);
		}
		Tcl_IncrRefCount(hdPtr->fontObj);
	    } else {
................................................................................
		hdPtr->fontObj = NULL;
	    }
	    break;
	case FontchooserCmd:
	    if (hdPtr->cmdObj) {
		Tcl_DecrRefCount(hdPtr->cmdObj);
	    }
	    (void)Tcl_GetString(objv[i+1]);
	    if (objv[i+1]->length) {
		hdPtr->cmdObj = objv[i+1];
		if (Tcl_IsShared(hdPtr->cmdObj)) {
		    hdPtr->cmdObj = Tcl_DuplicateObj(hdPtr->cmdObj);
		}
		Tcl_IncrRefCount(hdPtr->cmdObj);
	    } else {







|







 







|







3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
....
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
	    }
	    Tcl_IncrRefCount(hdPtr->titleObj);
	    break;
	case FontchooserFont:
	    if (hdPtr->fontObj) {
		Tcl_DecrRefCount(hdPtr->fontObj);
	    }
	    Tcl_GetString(objv[i+1]);
	    if (objv[i+1]->length) {
		hdPtr->fontObj = objv[i+1];
		if (Tcl_IsShared(hdPtr->fontObj)) {
		    hdPtr->fontObj = Tcl_DuplicateObj(hdPtr->fontObj);
		}
		Tcl_IncrRefCount(hdPtr->fontObj);
	    } else {
................................................................................
		hdPtr->fontObj = NULL;
	    }
	    break;
	case FontchooserCmd:
	    if (hdPtr->cmdObj) {
		Tcl_DecrRefCount(hdPtr->cmdObj);
	    }
	    Tcl_GetString(objv[i+1]);
	    if (objv[i+1]->length) {
		hdPtr->cmdObj = objv[i+1];
		if (Tcl_IsShared(hdPtr->cmdObj)) {
		    hdPtr->cmdObj = Tcl_DuplicateObj(hdPtr->cmdObj);
		}
		Tcl_IncrRefCount(hdPtr->cmdObj);
	    } else {

Changes to win/tkWinEmbed.c.

196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
 *	    TK_CONTAINER_ISAVAILABLE - a container window should return either
 *		a TRUE (non-zero) if it is available for use or a FALSE (zero)
 *		othersize.
 *
 *	The TK_INFO messages are required in order to verify if the window to
 *	use is a valid container. Without an id verification, an invalid
 *	window attachment may cause unexpected crashes/panics (bug 1096074).
 *	Additional sub messages may be definded/used in future for other
 *	needs.
 *
 *	We do not enforce the above protocol for the reason of backward
 *	compatibility. If the window to use is unable to handle TK_INFO
 *	messages (e.g., legacy Tk container applications before 8.5), a dialog
 *	box with a warning message pops up and the user is asked to confirm if
 *	the attachment should proceed. However, we may have to enforce it in
................................................................................
    } else {
	/*
	 * Proceed if the user decide to do so because it can be a legacy
	 * container application. However we may have to return a TCL_ERROR in
	 * order to avoid bug 1096074 in future.
	 */

	char msg[256];

	sprintf(msg, "Unable to get information of window \"%.80s\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching.", string);
	if (IDCANCEL == MessageBoxA(hwnd, msg, "Tk Warning",
		MB_OKCANCEL | MB_ICONWARNING)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Operation has been canceled", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "CANCEL", NULL);
	    return TCL_ERROR;
	}
    }







|







 







|

|
|







196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
...
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
 *	    TK_CONTAINER_ISAVAILABLE - a container window should return either
 *		a TRUE (non-zero) if it is available for use or a FALSE (zero)
 *		othersize.
 *
 *	The TK_INFO messages are required in order to verify if the window to
 *	use is a valid container. Without an id verification, an invalid
 *	window attachment may cause unexpected crashes/panics (bug 1096074).
 *	Additional sub messages may be defined/used in future for other
 *	needs.
 *
 *	We do not enforce the above protocol for the reason of backward
 *	compatibility. If the window to use is unable to handle TK_INFO
 *	messages (e.g., legacy Tk container applications before 8.5), a dialog
 *	box with a warning message pops up and the user is asked to confirm if
 *	the attachment should proceed. However, we may have to enforce it in
................................................................................
    } else {
	/*
	 * Proceed if the user decide to do so because it can be a legacy
	 * container application. However we may have to return a TCL_ERROR in
	 * order to avoid bug 1096074 in future.
	 */

	TCHAR msg[256];

	wsprintf(msg, TEXT("Unable to get information of window \"%.40hs\".  Attach to this\nwindow may have unpredictable results if it is not a valid container.\n\nPress Ok to proceed or Cancel to abort attaching."), string);
	if (IDCANCEL == MessageBox(hwnd, msg, TEXT("Tk Warning"),
		MB_OKCANCEL | MB_ICONWARNING)) {
    	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
		    "Operation has been canceled", -1));
	    Tcl_SetErrorCode(interp, "TK", "EMBED", "CANCEL", NULL);
	    return TCL_ERROR;
	}
    }

Changes to win/tkWinMenu.c.

1478
1479
1480
1481
1482
1483
1484









1485
1486
1487
1488
1489
1490
1491
....
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
....
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
....
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
...