New upstream version 8.6.9
Sergei Golovan
5 years ago
0 | 0 | A NOTE ON THE CHANGELOG: |
1 | 1 | Starting in early 2011, Tk source code has been under the management of |
2 | fossil, hosted at http://core.tcl.tk/tk/ . Fossil presents a "Timeline" | |
2 | fossil, hosted at http://core.tcl-lang.org/tk/ . Fossil presents a "Timeline" | |
3 | 3 | view of changes made that is superior in every way to a hand edited log file. |
4 | 4 | Because of this, many Tk developers are now out of the habit of maintaining |
5 | 5 | this log file. You may still find useful things in it, but the Timeline is |
0 | 0 | README: Tk |
1 | This is the Tk 8.6.8 source distribution. | |
1 | This is the Tk 8.6.9 source distribution. | |
2 | 2 | http://sourceforge.net/projects/tcl/files/Tcl/ |
3 | 3 | You can get any source release of Tk from the URL above. |
4 | 4 | |
11 | 11 | For details on features, incompatibilities, and potential problems with |
12 | 12 | this release, see the Tcl/Tk 8.6 Web page at |
13 | 13 | |
14 | http://www.tcl.tk/software/tcltk/8.6.html | |
14 | http://www.tcl-lang.org/software/tcltk/8.6.html | |
15 | 15 | |
16 | 16 | or refer to the "changes" file in this directory, which contains a |
17 | 17 | historical record of all changes to Tk. |
20 | 20 | Source code development and tracking of bug reports and feature requests |
21 | 21 | takes place at: |
22 | 22 | |
23 | http://core.tcl.tk/tk/ | |
23 | http://core.tcl-lang.org/tk/ | |
24 | 24 | |
25 | 25 | with the Tcl Developer Xchange at: |
26 | 26 | |
27 | http://www.tcl.tk/ | |
27 | http://www.tcl-lang.org/ | |
28 | 28 | |
29 | 29 | Tk is a freely available open source package. You can do virtually |
30 | 30 | anything you like with it, such as modifying it, redistributing it, |
1314 | 1314 | result across the execution of binding scripts. Otherwise if an event |
1315 | 1315 | triggers in the middle of some other script (e.g. a destroy event during |
1316 | 1316 | window creation, because there was an error in the creation command), |
1317 | the intepreter's result gets lost. | |
1317 | the interpreter's result gets lost. | |
1318 | 1318 | |
1319 | 1319 | 2/19/94 (bug fix) Fixed bug in dealing with results of sent command |
1320 | 1320 | that could cause them to get lost in some situations. |
7369 | 7369 | |
7370 | 7370 | 2017-03-11 (bug)[775273] artifacts on Ubuntu 16.10+ (nemethi) |
7371 | 7371 | |
7372 | 2n017-03-26 (TIP 464) Win multimedia keys support (fassel,vogel) | |
7372 | 2017-03-26 (TIP 464) Win multimedia keys support (fassel,vogel) | |
7373 | 7373 | |
7374 | 7374 | 2017-03-29 (bug)[28a3c3] test BTree memleaks plugged (anonymous) |
7375 | 7375 | |
7494 | 7494 | 2017-12-18 (bug)[b77626] Make [tk busy -cursor] silent no-op on macOS (vogel) |
7495 | 7495 | |
7496 | 7496 | --- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tk/ for details |
7497 | ||
7498 | 2017-12-31 (bug)[aa7679] crash using window after master destroyed (vogel) | |
7499 | ||
7500 | 2017-12-31 (bug)[6525e1] encoding leak in tkMacOSXProcessFiles (werner) | |
7501 | ||
7502 | 2018-01-07 (bug)[925262] New option -state for ttk::scale (vogel) | |
7503 | ||
7504 | 2018-01-07 (bug)[fa8de7] Crash [ttk::checkbutton .x -variable {}] (werner) | |
7505 | ||
7506 | 2018-01-16 (bug)[382712] Crash in [event generate . <KeyPress>] (werner) | |
7507 | ||
7508 | 2018-01-19 (bug)[657c38] Crash in menu destroy with checkbutton entry (werner) | |
7509 | ||
7510 | 2018-01-25 (bug)[de156e] Deny PRIMARY selection access in safe interps (nash) | |
7511 | ||
7512 | 2018-01-28 (bug)[b68710] Fixes in [text] bindings (nash) | |
7513 | ||
7514 | 2018-01-28 (bug)[e20d5c] Stop failures of textTag-18.1 (vogel) | |
7515 | ||
7516 | 2018-02-04 (bug)[5d991b] Fortify var traces against deleted vars (vogel) | |
7517 | ||
7518 | 2018-02-10 (bug)[1821174] Stop RenderBadPicture X error (werner) | |
7519 | ||
7520 | 2018-02-11 (bug)[502e74] Stop X errors on untrusted connections (werner) | |
7521 | ||
7522 | 2018-03-07 (bug)[71b131] Regression in Tk_DrawChars() (werner,cramer) | |
7523 | ||
7524 | 2018-04-03 (bug)[59fccb] menu flaws when empty menubar clicked (vogel,mcdonald) | |
7525 | ||
7526 | 2018-04-28 (bug)[7423f9] improved legacy support for [tk_setPalette] (bll) | |
7527 | ||
7528 | 2018-04-30 (bug)[6d5042] enable [tk inactive] on Mac OSX (culler) | |
7529 | ||
7530 | 2018-05-03 (bug)[75d38f] fix touchpad scroll of listbox on win notebook (vogel) | |
7531 | ||
7532 | 2018-06-16 (bug)[de01e2] Crash in [$text replace] (vogel) | |
7533 | ||
7534 | 2018-07-04 (bug)[6ca257] Fix [wm resizable] on Mac OSX (culler) | |
7535 | ||
7536 | 2018-07-04 (bug)[135696] Crash in [wm transient] (culler) | |
7537 | ||
7538 | 2018-07-04 (bug)[309b42] Improve ttk high-contrast-mode support (lemburg,vogel) | |
7539 | ||
7540 | 2018-07-17 (bug)[1088825] fix frame-2.17,3.9,3.10 on Mac (vogel) | |
7541 | ||
7542 | 2018-07-27 (bug)[fabed1] GIF photo support for "deferred clear code" (vogel) | |
7543 | ||
7544 | 2018-08-08 (feature) Modern full-screen support on Mac OSX (walzer) | |
7545 | ||
7546 | 2018-08-12 (bug)[1875c1] scrollbar on Mac OSX (walzer) | |
7547 | ||
7548 | 2018-08-14 (bug)[1ba71a] KeyRelease events on Mac OSX(walzer) | |
7549 | ||
7550 | 2018-09-02 (bug)[3441086] error message in layout-2 (vogel) | |
7551 | ||
7552 | 2018-09-07 (bug)[05bd7f] vista theme for combobox (vogel) | |
7553 | ||
7554 | 2018-09-08 (bug)[382712] crash in KeyPress event handling (vogel,werner) | |
7555 | ||
7556 | 2018-09-08 (bug)[6fcaaa] insertion cursor visibility in ttk::entry (nemethi) | |
7557 | ||
7558 | 2018-09-30 (bug)[822923] cascade menu indicator color (mcdonald) | |
7559 | ||
7560 | 2018-10-06 (bug)[9658bc] borderwidth calculations on menu items (vogel) | |
7561 | ||
7562 | 2018-10-17 (bug)[ca403f] treeview border drawing (vogel) | |
7563 | ||
7564 | 2018-10-17 (bug)[4b555a] hang in [$text search -all] (vogel,danckaert) | |
7565 | ||
7566 | 2018-10-30 (new platform) port to system changes in Mac OSX 10.14 (culler) | |
7567 | ||
7568 | 2018-11-04 (bug)[6b22d4] [treeview] binding fix (ohagan) | |
7569 | ||
7570 | - Released 8.6.9, November 16, 2018 - http://core.tcl-lang.org/tk/ for details - |
28 | 28 | extern void qsort(void *base, int n, int size, int (*compar)( |
29 | 29 | const void *element1, const void *element2)); |
30 | 30 | extern char * realloc(char *ptr, unsigned int numBytes); |
31 | extern double strtod(const char *string, char **endPtr); | |
32 | 31 | extern long strtol(const char *string, char **endPtr, int base); |
33 | 32 | extern unsigned long strtoul(const char *string, char **endPtr, int base); |
34 | 33 |
13 | 13 | long |
14 | 14 | \fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR |
15 | 15 | .sp |
16 | \fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR | |
16 | \fBTk_ResetUserInactiveTime(\fIdisplay\fB)\fR | |
17 | 17 | .SH ARGUMENTS |
18 | 18 | .AS Display *display |
19 | 19 | .AP Display *display in |
25 | 25 | \fBTk_GetUserInactiveTime\fR returns the number of milliseconds that |
26 | 26 | have passed since the last user interaction (usually via keyboard or |
27 | 27 | mouse) with the respective display. On systems and displays that do not |
28 | support querying the user inactiviy time, \fB\-1\fR is returned. | |
29 | \fBTk_GetUserInactiveTime\fR resets the user inactivity timer of the | |
28 | support querying the user inactivity time, \fB\-1\fR is returned. | |
29 | \fBTk_ResetUserInactiveTime\fR resets the user inactivity timer of the | |
30 | 30 | given display to zero. On windowing systems that do not support |
31 | 31 | multiple displays \fIdisplay\fR can be passed as \fBNULL\fR. |
32 | 32 | .SH KEYWORDS |
16 | 16 | user to select a directory. The following \fIoption\-value\fR pairs are |
17 | 17 | possible as command line arguments: |
18 | 18 | .TP |
19 | \fB\-command\fR \fIstring\fR | |
20 | Specifies the prefix of a Tcl command to invoke when the user closes the | |
21 | dialog after having selected an item. This callback is not called if the | |
22 | user cancelled the dialog. The actual command consists of \fIstring\fR | |
23 | followed by a space and the value selected by the user in the dialog. This | |
24 | is only available on Mac OS X. | |
25 | .TP | |
19 | 26 | \fB\-initialdir\fR \fIdirname\fR |
20 | 27 | Specifies that the directories in \fIdirectory\fR should be displayed |
21 | 28 | when the dialog pops up. If this parameter is not specified, |
25 | 32 | user-selected directory for the application. If the |
26 | 33 | parameter specifies a relative path, the return value will convert the |
27 | 34 | relative path to an absolute path. |
35 | .TP | |
36 | \fB\-message\fR \fIstring\fR | |
37 | Specifies a message to include in the client area of the dialog. | |
38 | This is only available on Mac OS X. | |
28 | 39 | .TP |
29 | 40 | \fB\-mustexist\fR \fIboolean\fR |
30 | 41 | Specifies whether the user may specify non-existent directories. If |
337 | 337 | changed. |
338 | 338 | .TP |
339 | 339 | \fB<<ThemeChanged>>\fR |
340 | This is sent to a text widget when the ttk (Tile) theme changed. | |
340 | This is sent to all widgets when the ttk theme changed. The ttk | |
341 | widgets listen to this event and redisplay themselves when it fires. | |
342 | The legacy widgets ignore this event. | |
341 | 343 | .TP |
342 | 344 | \fB<<TraverseIn>>\fR |
343 | 345 | This is sent to a widget when the focus enters the widget because of a |
33 | 33 | .PP |
34 | 34 | The following \fIoption\-value\fR pairs are possible as command line |
35 | 35 | arguments to these two commands: |
36 | .TP | |
37 | \fB\-command\fR \fIstring\fR | |
38 | Specifies the prefix of a Tcl command to invoke when the user closes the | |
39 | dialog after having selected an item. This callback is not called if the | |
40 | user cancelled the dialog. The actual command consists of \fIstring\fR | |
41 | followed by a space and the value selected by the user in the dialog. This | |
42 | is only available on Mac OS X. | |
36 | 43 | .TP |
37 | 44 | \fB\-confirmoverwrite\fR \fIboolean\fR |
38 | 45 | Configures how the Save dialog reacts when the selected file already |
22 | 22 | buttons. Then it returns the symbolic name of the selected button. |
23 | 23 | .PP |
24 | 24 | The following option-value pairs are supported: |
25 | .TP | |
26 | \fB\-command\fR \fIstring\fR | |
27 | Specifies the prefix of a Tcl command to invoke when the user closes the | |
28 | dialog. The actual command consists of \fIstring\fR followed by a space | |
29 | and the name of the button clicked by the user to close the dialog. This | |
30 | is only available on Mac OS X. | |
25 | 31 | .TP |
26 | 32 | \fB\-default\fR \fIname\fR |
27 | 33 | . |
28 | 28 | Specifies a desired height for the overall panedwindow widget. May be any |
29 | 29 | value accepted by \fBTk_GetPixels\fR. If an empty string, the widget will be |
30 | 30 | made high enough to allow all contained widgets to have their natural height. |
31 | .OP \-opaqueresize opaqueResize OpaqueResize | |
32 | Specifies whether panes should be resized as a sash is moved (true), | |
33 | or if resizing should be deferred until the sash is placed (false). | |
34 | In the latter case, a | |
35 | .QW ghost | |
36 | version of the sash is displayed during the resizing to show where the | |
37 | panes will be resized to when releasing the mouse button. This | |
38 | .QW ghost | |
39 | version of the sash is the proxy. It's rendering can be configured | |
40 | using the \fB-proxybackground\fR, \fB-proxyborderwidth\fR and | |
41 | \fB-proxyrelief\fR options. | |
31 | 42 | .OP \-proxybackground proxyBackground ProxyBackground |
32 | 43 | Background color to use when drawing the proxy. If an empty string, the |
33 | 44 | value of the \fB-background\fR option will be used. |
38 | 49 | Relief to use when drawing the proxy. May be any of the standard Tk |
39 | 50 | relief values. If an empty string, the value of the \fB-sashrelief\fR |
40 | 51 | option will be used. |
41 | .OP \-opaqueresize opaqueResize OpaqueResize | |
42 | Specifies whether panes should be resized as a sash is moved (true), | |
43 | or if resizing should be deferred until the sash is placed (false). | |
44 | 52 | .OP \-sashcursor sashCursor SashCursor |
45 | 53 | Mouse cursor to use when over a sash. If null, |
46 | 54 | \fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and |
132 | 140 | a sash or a handle, such as {0 sash} or {2 handle}. If the point is |
133 | 141 | over any other part of the panedwindow, the result is an empty list. |
134 | 142 | .TP |
135 | \fIpathName \fBproxy \fR?\fIargs\fR? | |
136 | . | |
137 | This command is used to query and change the position of the sash | |
138 | proxy, used for rubberband-style pane resizing. It can take any of | |
139 | the following forms: | |
140 | .RS | |
141 | .TP | |
142 | \fIpathName \fBproxy coord\fR | |
143 | . | |
144 | Return a list containing the x and y coordinates of the most recent | |
145 | proxy location. | |
146 | .TP | |
147 | \fIpathName \fBproxy forget\fR | |
148 | . | |
149 | Remove the proxy from the display. | |
150 | .TP | |
151 | \fIpathName \fBproxy place \fIx y\fR | |
152 | . | |
153 | Place the proxy at the given \fIx\fR and \fIy\fR coordinates. | |
154 | .RE | |
155 | .TP | |
156 | \fIpathName \fBsash \fR?\fIargs\fR? | |
157 | This command is used to query and change the position of sashes in the | |
158 | panedwindow. It can take any of the following forms: | |
159 | .RS | |
160 | .TP | |
161 | \fIpathName \fBsash coord \fIindex\fR | |
162 | . | |
163 | Return the current x and y coordinate pair for the sash given by | |
164 | \fIindex\fR. \fIIndex\fR must be an integer between 0 and 1 less than | |
165 | the number of panes in the panedwindow. The coordinates given are | |
166 | those of the top left corner of the region containing the sash. | |
167 | .TP | |
168 | \fIpathName \fBsash dragto \fIindex x y\fR | |
169 | . | |
170 | This command computes the difference between the given coordinates and the | |
171 | coordinates given to the last \fBsash mark\fR command for the given | |
172 | sash. It then moves that sash the computed difference. The return | |
173 | value is the empty string. | |
174 | .TP | |
175 | \fIpathName \fBsash mark \fIindex x y\fR | |
176 | . | |
177 | Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in | |
178 | conjunction with later \fBsash dragto\fR commands to move the sash. | |
179 | .TP | |
180 | \fIpathName \fBsash place \fIindex x y\fR | |
181 | . | |
182 | Place the sash given by \fIindex\fR at the given coordinates. | |
183 | .RE | |
184 | .TP | |
185 | 143 | \fIpathName \fBpanecget \fIwindow option\fR |
186 | 144 | . |
187 | 145 | Query a management option for \fIwindow\fR. \fIOption\fR may be any |
309 | 267 | \fIpathName \fBpanes\fR |
310 | 268 | . |
311 | 269 | Returns an ordered list of the widgets managed by \fIpathName\fR. |
270 | .TP | |
271 | \fIpathName \fBproxy \fR?\fIargs\fR? | |
272 | . | |
273 | This command is used to query and change the position of the sash | |
274 | proxy, used for rubberband-style pane resizing. It can take any of | |
275 | the following forms: | |
276 | .RS | |
277 | .TP | |
278 | \fIpathName \fBproxy coord\fR | |
279 | . | |
280 | Return a list containing the x and y coordinates of the most recent | |
281 | proxy location. | |
282 | .TP | |
283 | \fIpathName \fBproxy forget\fR | |
284 | . | |
285 | Remove the proxy from the display. | |
286 | .TP | |
287 | \fIpathName \fBproxy place \fIx y\fR | |
288 | . | |
289 | Place the proxy at the given \fIx\fR and \fIy\fR coordinates. | |
290 | .RE | |
291 | .TP | |
292 | \fIpathName \fBsash \fR?\fIargs\fR? | |
293 | This command is used to query and change the position of sashes in the | |
294 | panedwindow. It can take any of the following forms: | |
295 | .RS | |
296 | .TP | |
297 | \fIpathName \fBsash coord \fIindex\fR | |
298 | . | |
299 | Return the current x and y coordinate pair for the sash given by | |
300 | \fIindex\fR. \fIIndex\fR must be an integer between 0 and 1 less than | |
301 | the number of panes in the panedwindow. The coordinates given are | |
302 | those of the top left corner of the region containing the sash. | |
303 | .TP | |
304 | \fIpathName \fBsash dragto \fIindex x y\fR | |
305 | . | |
306 | This command computes the difference between the given coordinates and the | |
307 | coordinates given to the last \fBsash mark\fR command for the given | |
308 | sash. It then moves that sash the computed difference. The return | |
309 | value is the empty string. | |
310 | .TP | |
311 | \fIpathName \fBsash mark \fIindex x y\fR | |
312 | . | |
313 | Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in | |
314 | conjunction with later \fBsash dragto\fR commands to move the sash. | |
315 | .TP | |
316 | \fIpathName \fBsash place \fIindex x y\fR | |
317 | . | |
318 | Place the sash given by \fIindex\fR at the given coordinates. | |
319 | .RE | |
312 | 320 | .SH "RESIZING PANES" |
313 | 321 | .PP |
314 | 322 | A pane is resized by grabbing the sash (or sash handle if present) and |
62 | 62 | The empty string is the default value. |
63 | 63 | .OP \-selectcolor selectColor Background |
64 | 64 | Specifies a background color to use when the button is selected. |
65 | If \fB\-indicatoron\fR is true then the color applies to the indicator. | |
66 | Under Windows, this color is used as the background for the indicator | |
67 | regardless of the select state. | |
65 | If \fBindicatorOn\fR is true then the color is used as the background for | |
66 | the indicator regardless of the select state. | |
68 | 67 | If \fB\-indicatoron\fR is false, this color is used as the background |
69 | 68 | for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR, |
70 | 69 | whenever the widget is selected. |
139 | 139 | some other window claims ownership of the selection away from |
140 | 140 | \fIwindow\fR. \fISelection\fR defaults to PRIMARY. |
141 | 141 | .RE |
142 | .SH WIDGET FACILITIES | |
143 | .PP | |
144 | The \fBtext\fR, \fBentry\fR, \fBttk::entry\fR, \fBlistbox\fR, \fBspinbox\fR and \fBttk::spinbox\fR widgets have the option \fB\-exportselection\fR. If a widget has this option set to boolean \fBtrue\fR, then (in an unsafe interpreter) a selection made in the widget is automatically written to the \fBPRIMARY\fR selection. | |
145 | .PP | |
146 | A GUI event, for example \fB<<PasteSelection>>\fR, can copy the \fBPRIMARY\fR selection to certain widgets. This copy is implemented by a widget binding to the event. The binding script makes appropriate calls to the \fBselection\fR command. | |
147 | .PP | |
148 | .SH PORTABILITY ISSUES | |
149 | .PP | |
150 | On X11, the \fBPRIMARY\fR selection is a system-wide feature of the X server, allowing communication between different processes that are X11 clients. | |
151 | .PP | |
152 | On Windows, the \fBPRIMARY\fR selection is not provided by the system, but only by Tk, and so it is shared only between windows of a master interpreter and its unsafe slave interpreters. It is not shared between interpreters in different processes or different threads. Each master interpreter has a separate \fBPRIMARY\fR selection that is shared only with its unsafe slaves. | |
153 | .PP | |
154 | .SH SECURITY | |
155 | .PP | |
156 | A safe interpreter cannot read from the \fBPRIMARY\fR selection because its \fBselection\fR command is hidden. For this reason the \fBPRIMARY\fR selection cannot be written to the Tk widgets of a safe interpreter. | |
157 | .PP | |
158 | A Tk widget can have its option \fB\-exportselection\fR set to boolean \fBtrue\fR, but in a safe interpreter this option has no effect: writing from the widget to the \fBPRIMARY\fR selection is disabled. | |
159 | .PP | |
160 | These are security features. A safe interpreter may run untrusted code, and it is a security risk if this untrusted code can read or write the \fBPRIMARY\fR selection used by other interpreters. | |
161 | .PP | |
142 | 162 | .SH EXAMPLES |
143 | 163 | .PP |
144 | 164 | On X11 platforms, one of the standard selections available is the |
38 | 38 | Depending on the theme, the default button may be displayed |
39 | 39 | with an extra highlight ring, or with a different border color. |
40 | 40 | .RE |
41 | .OP \-width width Width | |
42 | If greater than zero, specifies how much space, in character widths, | |
43 | to allocate for the text label. | |
44 | If less than zero, specifies a minimum width. | |
45 | If zero or unspecified, the natural width of the text label is used. | |
46 | Note that some themes may specify a non-zero \fB\-width\fR | |
47 | in the style. | |
48 | 41 | .\" Not documented -- may go away |
49 | 42 | .\" .OP \-padding padding Padding |
50 | 43 | .\" .OP \-foreground foreground Foreground |
63 | 56 | .PP |
64 | 57 | \fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard |
65 | 58 | themes, which is useful for creating widgets for toolbars. |
66 | .SH "COMPATIBILITY OPTIONS" | |
67 | .OP \-state state State | |
68 | May be set to \fBnormal\fR or \fBdisabled\fR to control the | |
69 | \fBdisabled\fR state bit. This is a | |
70 | .QW write-only | |
71 | option: setting it changes the widget state, but the \fBstate\fR | |
72 | widget command does not affect the state option. | |
59 | .SH "STYLING OPTIONS" | |
60 | .PP | |
61 | The class name for a \fBttk::button\fP is \fBTButton\fP. | |
62 | .PP | |
63 | Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBpressed\fP, \fBreadonly\fP. | |
64 | .PP | |
65 | \fBTButton\fP styling options configurable with \fBttk::style\fP | |
66 | are: | |
67 | .PP | |
68 | \fB\-anchor\fP \fIanchor\fP | |
69 | .br | |
70 | \fB\-background\fP \fIcolor\fP | |
71 | .br | |
72 | \fB\-bordercolor\fP \fIcolor\fP | |
73 | .br | |
74 | \fB\-darkcolor\fP \fIcolor\fP | |
75 | .br | |
76 | \fB\-foreground\fP \fIcolor\fP | |
77 | .br | |
78 | \fB\-font\fP \fIfont\fP | |
79 | .br | |
80 | \fB\-highlightcolor\fP \fIcolor\fP | |
81 | .br | |
82 | \fB\-highlightthickness\fP \fIamount\fP | |
83 | .br | |
84 | \fB\-lightcolor\fP \fIcolor\fP | |
85 | .br | |
86 | \fB\-padding\fP \fIpadding\fP | |
87 | .br | |
88 | \fB\-relief\fP \fIrelief\fP | |
89 | .br | |
90 | \fB\-shiftrelief\fP \fIamount\fP | |
91 | .RS | |
92 | \fB\-shiftrelief\fP specifies how far the button contents are | |
93 | shifted down and right in the \fIpressed\fP state. | |
94 | This action provides additional skeumorphic feedback. | |
95 | .RE | |
96 | \fB\-width\fP \fIamount\fP | |
97 | .PP | |
98 | Some options are only available for specific themes. | |
99 | .PP | |
100 | See the \fBttk::style\fP manual page for information on how to configure | |
101 | ttk styles. | |
73 | 102 | .SH "SEE ALSO" |
74 | 103 | ttk::widget(n), button(n) |
75 | 104 | .SH "KEYWORDS" |
67 | 67 | .PP |
68 | 68 | \fBTtk::checkbutton\fR widgets support the \fBToolbutton\fR style in all |
69 | 69 | standard themes, which is useful for creating widgets for toolbars. |
70 | .SH "STYLING OPTIONS" | |
71 | .PP | |
72 | The class name for a \fBttk::checkbutton\fP is \fBTCheckbutton\fP. | |
73 | .PP | |
74 | Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP, | |
75 | \fBpressed\fP, \fBselected\fP, \fBreadonly\fP. | |
76 | .PP | |
77 | \fBTCheckbutton\fP styling options configurable with \fBttk::style\fP | |
78 | are: | |
79 | .PP | |
80 | \fB\-background\fP \fIcolor\fP | |
81 | .br | |
82 | \fB\-foreground\fP \fIcolor\fP | |
83 | .br | |
84 | \fB\-indicatorbackground\fP \fIcolor\fP | |
85 | .br | |
86 | \fB\-indicatorcolor\fP \fIcolor\fP | |
87 | .br | |
88 | \fB\-indicatormargin\fP \fIpadding\fP | |
89 | .br | |
90 | \fB\-indicatorrelief\fP \fIrelief\fP | |
91 | .br | |
92 | \fB\-padding\fP \fIpadding\fP | |
93 | .PP | |
94 | Some options are only available for specific themes. | |
95 | .PP | |
96 | See the \fBttk::style\fP manual page for information on how to configure | |
97 | ttk styles. | |
70 | 98 | .SH "SEE ALSO" |
71 | 99 | ttk::widget(n), ttk::radiobutton(n), checkbutton(n) |
72 | 100 | .SH "KEYWORDS" |
109 | 109 | when the user selects an element from the list of values. |
110 | 110 | If the selection action unposts the listbox, |
111 | 111 | this event is delivered after the listbox is unposted. |
112 | .SH "STYLING OPTIONS" | |
113 | .PP | |
114 | The class name for a \fBttk::combobox\fP is \fBTCombobox\fP. | |
115 | The \fBttk::combobox\fP uses the \fBentry\fP and | |
116 | \fBlistbox\fP widgets internally. | |
117 | The listbox frame has a class name of \fBComboboxPopdownFrame\fP. | |
118 | .PP | |
119 | Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBpressed\fP, \fBreadonly\fP. | |
120 | .PP | |
121 | \fBTCombobox\fP styling options configurable with \fBttk::style\fP | |
122 | are: | |
123 | .PP | |
124 | \fB\-arrowcolor\fP \fIcolor\fP | |
125 | .br | |
126 | \fB\-background\fP \fIcolor\fP | |
127 | .br | |
128 | \fB\-bordercolor\fP \fIcolor\fP | |
129 | .br | |
130 | \fB\-darkcolor\fP \fIcolor\fP | |
131 | .br | |
132 | \fB\-focusfill\fP \fIcolor\fP | |
133 | .br | |
134 | \fB\-foreground\fP \fIcolor\fP | |
135 | .br | |
136 | \fB\-fieldbackground\fP \fIcolor\fP | |
137 | .RS | |
138 | Can only be changed when using non-native and non-graphical themes. | |
139 | .RE | |
140 | \fB\-insertwidth\fP \fIamount\fP | |
141 | .br | |
142 | \fB\-lightcolor\fP \fIcolor\fP | |
143 | .br | |
144 | \fB\-padding\fP \fIpadding\fP | |
145 | .br | |
146 | \fB\-postoffset\fP \fIpadding\fP | |
147 | .br | |
148 | \fB\-selectbackground\fP \fIcolor\fP | |
149 | .RS | |
150 | Text entry select background. | |
151 | .RE | |
152 | \fB\-selectforeground\fP \fIcolor\fP | |
153 | .RS | |
154 | Text entry select foreground. | |
155 | .RE | |
156 | .PP | |
157 | The \fBttk::combobox\fP popdown listbox cannot be configured using | |
158 | \fBttk::style\fP nor via the widget \fBconfigure\fP command. The listbox | |
159 | can be configured using the option database. | |
160 | .PP | |
161 | option add *TCombobox*Listbox.background \fIcolor\fP | |
162 | .br | |
163 | option add *TCombobox*Listbox.font \fIfont\fP | |
164 | .br | |
165 | option add *TCombobox*Listbox.foreground \fIcolor\fP | |
166 | .br | |
167 | option add *TCombobox*Listbox.selectBackground \fIcolor\fP | |
168 | .br | |
169 | option add *TCombobox*Listbox.selectForeground \fIcolor\fP | |
170 | .PP | |
171 | To configure a specific listbox (subject to future change): | |
172 | .CS | |
173 | set popdown [ttk::combobox::PopdownWindow .mycombobox] | |
174 | $popdown.f.l configure \-font \fIfont\fP | |
175 | .CE | |
176 | .PP | |
177 | \fBComboboxPopdownFrame\fP | |
178 | styling options configurable with \fBttk::style\fP | |
179 | are: | |
180 | .PP | |
181 | \fB\-borderwidth\fP \fIamount\fP | |
182 | .br | |
183 | \fB\-relief\fP \fIrelief\fP | |
184 | .PP | |
185 | Some options are only available for specific themes. | |
186 | .PP | |
187 | See the \fBttk::style\fP manual page for information on how to configure | |
188 | ttk styles. | |
112 | 189 | .SH "SEE ALSO" |
113 | 190 | ttk::widget(n), ttk::entry(n) |
114 | 191 | .SH KEYWORDS |
460 | 460 | .PP |
461 | 461 | The entry widget sets the \fBinvalid\fR state if revalidation fails, |
462 | 462 | and clears it whenever validation succeeds. |
463 | .SH "STYLING OPTIONS" | |
464 | .PP | |
465 | The class name for a \fBttk::entry\fP is \fBTEntry\fP. | |
466 | .PP | |
467 | Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP. | |
468 | .PP | |
469 | \fBTEntry\fP styling options configurable with \fBttk::style\fP | |
470 | are: | |
471 | .PP | |
472 | \fB\-background\fP \fIcolor\fP | |
473 | .RS | |
474 | When using the aqua theme (Mac OS X), changes the \fB\-fieldbackground\fP. | |
475 | .RE | |
476 | \fB\-bordercolor\fP \fIcolor\fP | |
477 | .br | |
478 | \fB\-darkcolor\fP \fIcolor\fP | |
479 | .br | |
480 | \fB\-fieldbackground\fP \fIcolor\fP | |
481 | .RS | |
482 | Does not work with the aqua theme (Mac OS X). | |
483 | .br | |
484 | Some themes use a graphical background and their field background colors cannot be changed. | |
485 | .RE | |
486 | \fB\-foreground\fP \fIcolor\fP | |
487 | .br | |
488 | \fB\-insertwidth\fP \fIamount\fP | |
489 | .br | |
490 | \fB\-lightcolor\fP \fIcolor\fP | |
491 | .br | |
492 | \fB\-padding\fP \fIpadding\fP | |
493 | .br | |
494 | \fB\-relief\fP \fIrelief\fP | |
495 | .br | |
496 | \fB\-selectbackground\fP \fIcolor\fP | |
497 | .br | |
498 | \fB\-selectborderwidth\fP \fIamount\fP | |
499 | .br | |
500 | \fB\-selectforeground\fP \fIcolor\fP | |
501 | .PP | |
502 | See the \fBttk::style\fP manual page for information on how to configure | |
503 | ttk styles. | |
463 | 504 | .SH "SEE ALSO" |
464 | 505 | ttk::widget(n), entry(n) |
465 | 506 | .SH KEYWORDS |
44 | 44 | over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options. |
45 | 45 | \fBpack propagate\fR and \fBgrid propagate\fR can be used |
46 | 46 | to change this. |
47 | .SH "STYLING OPTIONS" | |
48 | .PP | |
49 | The class name for a \fBttk::frame\fP is \fBTFrame\fP. | |
50 | .PP | |
51 | \fBTFrame\fP styling options configurable with \fBttk::style\fP | |
52 | are: | |
53 | .PP | |
54 | \fB\-background\fP \fIcolor\fP | |
55 | .PP | |
56 | Some options are only available for specific themes. | |
57 | .PP | |
58 | See the \fBttk::style\fP manual page for information on how to configure | |
59 | ttk styles. | |
47 | 60 | .SH "SEE ALSO" |
48 | 61 | ttk::widget(n), ttk::labelframe(n), frame(n) |
49 | 62 | .SH "KEYWORDS" |
18 | 18 | to automatically change the displayed text. |
19 | 19 | .SO ttk_widget |
20 | 20 | \-class \-compound \-cursor |
21 | \-image \-padding \-style \-takefocus | |
21 | \-image \-padding \-state \-style \-takefocus | |
22 | 22 | \-text \-textvariable \-underline |
23 | 23 | \-width |
24 | 24 | .SE |
62 | 62 | Supports the standard widget commands |
63 | 63 | \fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR; |
64 | 64 | see \fIttk::widget(n)\fR. |
65 | .SH "STYLING OPTIONS" | |
66 | .PP | |
67 | The class name for a \fBttk::label\fP is \fBTLabel\fP. | |
68 | .PP | |
69 | Dynamic states: \fBdisabled\fP, \fBreadonly\fP. | |
70 | .PP | |
71 | \fBTLabel\fP styling options configurable with \fBttk::style\fP | |
72 | are: | |
73 | .PP | |
74 | \fB\-background\fP \fIcolor\fP | |
75 | .br | |
76 | \fB\-foreground\fP \fIcolor\fP | |
77 | .br | |
78 | \fB\-font\fP \fIfont\fP | |
79 | .PP | |
80 | Some options are only available for specific themes. | |
81 | .PP | |
82 | See the \fBttk::style\fP manual page for information on how to configure | |
83 | ttk styles. | |
65 | 84 | .SH "SEE ALSO" |
66 | 85 | ttk::widget(n), label(n) |
67 | 86 | '\" Local Variables: |
64 | 64 | Supports the standard widget commands |
65 | 65 | \fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR; |
66 | 66 | see \fIttk::widget(n)\fR. |
67 | .SH "STYLING OPTIONS" | |
68 | .PP | |
69 | The class name for a \fBttk::labelframe\fP is \fBTLabelframe\fP. | |
70 | The text label | |
71 | has a class of \fBTLabelframe.Label\fP. | |
72 | .PP | |
73 | Dynamic states: \fBdisabled\fP, \fBreadonly\fP. | |
74 | .PP | |
75 | \fBTLabelframe\fP styling options configurable with \fBttk::style\fP | |
76 | are: | |
77 | .PP | |
78 | \fB\-background\fP \fIcolor\fP | |
79 | .br | |
80 | \fB\-bordercolor\fP \fIcolor\fP | |
81 | .br | |
82 | \fB\-borderwidth\fP \fIamount\fP | |
83 | .br | |
84 | \fB\-darkcolor\fP \fIcolor\fP | |
85 | .br | |
86 | \fB\-labelmargins\fP \fIamount\fP | |
87 | .br | |
88 | \fB\-labeloutside\fP \fIboolean\fP | |
89 | .br | |
90 | \fB\-lightcolor\fP \fIcolor\fP | |
91 | .br | |
92 | \fB\-relief\fP \fIrelief\fP | |
93 | .PP | |
94 | \fBTLabelframe.Label\fP styling options configurable with \fBttk::style\fP | |
95 | are: | |
96 | .PP | |
97 | \fB\-background\fP \fIcolor\fP | |
98 | .br | |
99 | \fB\-font\fP \fIfont\fP | |
100 | .br | |
101 | \fB\-foreground\fP \fIcolor\fP | |
102 | .PP | |
103 | Some options are only available for specific themes. | |
104 | .PP | |
105 | See the \fBttk::style\fP manual page for information on how to configure | |
106 | ttk styles. | |
67 | 107 | .SH "SEE ALSO" |
68 | 108 | ttk::widget(n), ttk::frame(n), labelframe(n) |
69 | 109 | .SH "KEYWORDS" |
44 | 44 | .PP |
45 | 45 | \fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all |
46 | 46 | standard themes, which is useful for creating widgets for toolbars. |
47 | .SH "STYLING OPTIONS" | |
48 | .PP | |
49 | The class name for a \fBttk::menubutton\fP is \fBTMenubutton\fP. | |
50 | .PP | |
51 | Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBreadonly\fP. | |
52 | .PP | |
53 | \fBTMenubutton\fP styling options configurable with \fBttk::style\fP | |
54 | are: | |
55 | .PP | |
56 | \fB\-arrowsize\fP \fIamount\fP | |
57 | .br | |
58 | \fB\-background\fP \fIcolor\fP | |
59 | .br | |
60 | \fB\-foreground\fP \fIcolor\fP | |
61 | .br | |
62 | \fB\-font\fP \fIfont\fP | |
63 | .br | |
64 | \fB\-padding\fP \fIpadding\fP | |
65 | .br | |
66 | \fB\-relief\fP \fIrelief\fP | |
67 | .br | |
68 | \fB\-width\fP \fIamount\fP | |
69 | .PP | |
70 | Some options are only available for specific themes. | |
71 | .PP | |
72 | See the \fBttk::style\fP manual page for information on how to configure | |
73 | ttk styles. | |
47 | 74 | .SH "SEE ALSO" |
48 | 75 | ttk::widget(n), menu(n), menubutton(n) |
49 | 76 | .SH "KEYWORDS" |
207 | 207 | \&.nb select .nb.f2 |
208 | 208 | ttk::notebook::enableTraversal .nb |
209 | 209 | .CE |
210 | .SH "STYLING OPTIONS" | |
211 | .PP | |
212 | The class name for a \fBttk::notebook\fP is \fBTNotebook\fP. The tab has | |
213 | a class name of \fBTNotebook.Tab\fP | |
214 | .PP | |
215 | Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBselected\fP. | |
216 | .PP | |
217 | \fBTNotebook\fP styling options configurable with \fBttk::style\fP | |
218 | are: | |
219 | .PP | |
220 | \fB\-background\fP \fIcolor\fP | |
221 | .br | |
222 | \fB\-bordercolor\fP \fIcolor\fP | |
223 | .br | |
224 | \fB\-darkcolor\fP \fIcolor\fP | |
225 | .br | |
226 | \fB\-foreground\fP \fIcolor\fP | |
227 | .br | |
228 | \fB\-lightcolor\fP \fIcolor\fP | |
229 | .br | |
230 | \fB\-padding\fP \fIpadding\fP | |
231 | .br | |
232 | \fB\-tabmargins\fP \fIpadding\fP | |
233 | .br | |
234 | \fB\-tabposition\fP \fIside\fP | |
235 | .br | |
236 | .PP | |
237 | \fBTNotebook.Tab\fP styling options configurable with \fBttk::style\fP | |
238 | are: | |
239 | .PP | |
240 | \fB\-background\fP \fIcolor\fP | |
241 | .br | |
242 | \fB\-bordercolor\fP \fIcolor\fP | |
243 | .br | |
244 | \fB\-expand\fP \fIpadding\fP | |
245 | .RS | |
246 | Defines how much the tab grows in size. Usually used with the | |
247 | \fBselected\fP dynamic state. \fB\-tabmargins\fP should be | |
248 | set appropriately so that there is room for the tab growth. | |
249 | .RE | |
250 | \fB\-font\fP \fIfont\fP | |
251 | .br | |
252 | \fB\-foreground\fP \fIcolor\fP | |
253 | .br | |
254 | \fB\-padding\fP \fIpadding\fP | |
255 | .PP | |
256 | Some options are only available for specific themes. | |
257 | .PP | |
258 | See the \fBttk::style\fP manual page for information on how to configure | |
259 | ttk styles. | |
210 | 260 | .SH "SEE ALSO" |
211 | 261 | ttk::widget(n), grid(n) |
212 | 262 | .SH "KEYWORDS" |
105 | 105 | .\" depending on which changed most recently. |
106 | 106 | Returns the new position of sash number \fIindex\fR. |
107 | 107 | .\" Full story: new position may be different than the requested position. |
108 | .PP | |
109 | The panedwindow widget also supports the following generic \fBttk::widget\fR | |
110 | widget subcommands (see \fIttk::widget(n)\fR for details): | |
111 | .DS | |
112 | .ta 5.5c 11c | |
113 | \fBcget\fR \fBconfigure\fR | |
114 | \fBinstate\fR \fBstate\fR | |
115 | .DE | |
108 | 116 | .SH "VIRTUAL EVENTS" |
109 | 117 | .PP |
110 | 118 | The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on |
111 | 119 | LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts |
112 | 120 | for <Leave> events when the pointer crosses from a parent to a child. The |
113 | 121 | panedwindow widget needs to know when that happens. |
122 | .SH "STYLING OPTIONS" | |
123 | .PP | |
124 | The class name for a \fBttk::panedwindow\fP is \fBTPanedwindow\fP. The | |
125 | sash has a class name of \fBSash\fP. | |
126 | .PP | |
127 | \fBTPanedwindow\fP styling options configurable with \fBttk::style\fP | |
128 | are: | |
129 | .PP | |
130 | \fB\-background\fP \fIcolor\fP | |
131 | .PP | |
132 | \fBSash\fP styling options configurable with \fBttk::style\fP | |
133 | are: | |
134 | .PP | |
135 | \fB\-background\fP \fIcolor\fP | |
136 | .br | |
137 | \fB\-bordercolor\fP \fIcolor\fP | |
138 | .br | |
139 | \fB\-gripcount\fP \fIcount\fP | |
140 | .br | |
141 | \fB\-handlepad\fP \fIamount\fP | |
142 | .br | |
143 | \fB\-handlesize\fP \fIamount\fP | |
144 | .br | |
145 | \fB\-lightcolor\fP \fIcolor\fP | |
146 | .br | |
147 | \fB\-sashpad\fP \fIamount\fP | |
148 | .br | |
149 | \fB\-sashrelief\fP \fIrelief\fP | |
150 | .br | |
151 | \fB\-sashthickness\fP \fIamount\fP | |
152 | .PP | |
153 | Some options are only available for specific themes. | |
154 | .PP | |
155 | See the \fBttk::style\fP manual page for information on how to configure | |
156 | ttk styles. | |
114 | 157 | .SH "SEE ALSO" |
115 | 158 | ttk::widget(n), ttk::notebook(n), panedwindow(n) |
116 | 159 | '\" Local Variables: |
23 | 23 | \-style |
24 | 24 | .SE |
25 | 25 | .SH "WIDGET-SPECIFIC OPTIONS" |
26 | .OP \-length length Length | |
27 | Specifies the length of the long axis of the progress bar | |
28 | (width if horizontal, height if vertical). | |
29 | .OP \-maximum maximum Maximum | |
30 | A floating point number specifying the maximum \fB\-value\fR. | |
31 | Defaults to 100. | |
32 | .OP \-mode mode Mode | |
33 | One of \fBdeterminate\fR or \fBindeterminate\fR. | |
26 | 34 | .OP \-orient orient Orient |
27 | 35 | One of \fBhorizontal\fR or \fBvertical\fR. |
28 | 36 | Specifies the orientation of the progress bar. |
29 | .OP \-length length Length | |
30 | Specifies the length of the long axis of the progress bar | |
31 | (width if horizontal, height if vertical). | |
32 | .OP \-mode mode Mode | |
33 | One of \fBdeterminate\fR or \fBindeterminate\fR. | |
34 | .OP \-maximum maximum Maximum | |
35 | A floating point number specifying the maximum \fB\-value\fR. | |
36 | Defaults to 100. | |
37 | .OP \-phase phase Phase | |
38 | Read-only option. | |
39 | The widget periodically increments the value of this option | |
40 | whenever the \fB\-value\fR is greater than 0 and, | |
41 | in \fIdeterminate\fR mode, less than \fB\-maximum\fR. | |
42 | This option may be used by the current theme | |
43 | to provide additional animation effects. | |
37 | 44 | .OP \-value value Value |
38 | 45 | The current value of the progress bar. |
39 | 46 | In \fIdeterminate\fR mode, this represents the amount of work completed. |
46 | 53 | If specified, the \fB\-value\fR of the progress bar is |
47 | 54 | automatically set to the value of the variable whenever |
48 | 55 | the latter is modified. |
49 | .OP \-phase phase Phase | |
50 | Read-only option. | |
51 | The widget periodically increments the value of this option | |
52 | whenever the \fB\-value\fR is greater than 0 and, | |
53 | in \fIdeterminate\fR mode, less than \fB\-maximum\fR. | |
54 | This option may be used by the current theme | |
55 | to provide additional animation effects. | |
56 | 56 | .SH "WIDGET COMMAND" |
57 | 57 | .PP |
58 | 58 | .TP |
85 | 85 | \fIpathName \fBstop\fR |
86 | 86 | Stop autoincrement mode: |
87 | 87 | cancels any recurring timer event initiated by \fIpathName \fBstart\fR. |
88 | .SH "STYLING OPTIONS" | |
89 | .PP | |
90 | The class name for a \fBttk::progressbar\fP is \fBTProgressbar\fP. | |
91 | .PP | |
92 | \fBTProgressbar\fP styling options configurable with \fBttk::style\fP | |
93 | are: | |
94 | .PP | |
95 | \fB\-background\fP \fIcolor\fP | |
96 | .br | |
97 | \fB\-bordercolor\fP \fIcolor\fP | |
98 | .br | |
99 | \fB\-darkcolor\fP \fIcolor\fP | |
100 | .br | |
101 | \fB\-lightcolor\fP \fIcolor\fP | |
102 | .br | |
103 | \fB\-maxphase\fP | |
104 | .RS | |
105 | For the aqua theme. | |
106 | .RE | |
107 | \fB\-period\fP | |
108 | .RS | |
109 | For the aqua theme. | |
110 | .RE | |
111 | \fB\-troughcolor\fP \fIcolor\fP | |
112 | .PP | |
113 | Some options are only available for specific themes. | |
114 | .PP | |
115 | See the \fBttk::style\fP manual page for information on how to configure | |
116 | ttk styles. | |
88 | 117 | .SH "SEE ALSO" |
89 | 118 | ttk::widget(n) |
90 | 119 | '\" Local Variables: |
64 | 64 | .PP |
65 | 65 | \fBTtk::radiobutton\fR widgets support the \fBToolbutton\fR style in all |
66 | 66 | standard themes, which is useful for creating widgets for toolbars. |
67 | .SH "STYLING OPTIONS" | |
68 | .PP | |
69 | The class name for a \fBttk::radiobutton\fP is \fBTRadiobutton\fP. | |
70 | .PP | |
71 | Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP, | |
72 | \fBpressed\fP, \fBreadonly\fP, \fBselected\fP. | |
73 | .PP | |
74 | \fBTRadiobutton\fP styling options configurable with \fBttk::style\fP | |
75 | are: | |
76 | .PP | |
77 | \fB\-background\fP \fIcolor\fP | |
78 | .br | |
79 | \fB\-foreground\fP \fIcolor\fP | |
80 | .br | |
81 | \fB\-indicatorbackground\fP \fIcolor\fP | |
82 | .br | |
83 | \fB\-indicatorcolor\fP \fIcolor\fP | |
84 | .br | |
85 | \fB\-indicatormargin\fP \fIpadding\fP | |
86 | .br | |
87 | \fB\-indicatorrelief\fP \fIrelief\fP | |
88 | .br | |
89 | \fB\-padding\fP \fIpadding\fP | |
90 | .PP | |
91 | Some options are only available for specific themes. | |
92 | .PP | |
93 | See the \fBttk::style\fP manual page for information on how to configure | |
94 | ttk styles. | |
67 | 95 | .SH "SEE ALSO" |
68 | 96 | ttk::widget(n), ttk::checkbutton(n), radiobutton(n) |
69 | 97 | .SH "KEYWORDS" |
90 | 90 | Get the coordinates corresponding to \fIvalue\fR, or the coordinates |
91 | 91 | corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR |
92 | 92 | is omitted. |
93 | .SH "STYLING OPTIONS" | |
94 | .PP | |
95 | The class name for a \fBttk::scale\fP is \fBTProgressbar\fP. | |
96 | .PP | |
97 | Dynamic states: \fBactive\fP. | |
98 | .PP | |
99 | \fBTProgressbar\fP styling options configurable with \fBttk::style\fP | |
100 | are: | |
101 | .PP | |
102 | \fB\-background\fP \fIcolor\fP | |
103 | .br | |
104 | \fB\-borderwidth\fP \fIamount\fP | |
105 | .br | |
106 | \fB\-darkcolor\fP \fIcolor\fP | |
107 | .br | |
108 | \fB\-groovewidth\fP \fIamount\fP | |
109 | .br | |
110 | \fB\-lightcolor\fP \fIcolor\fP | |
111 | .br | |
112 | \fB\-sliderwidth\fP \fIamount\fP | |
113 | .br | |
114 | \fB\-troughcolor\fP \fIcolor\fP | |
115 | .br | |
116 | \fB\-troughrelief\fP \fIrelief\fP | |
117 | .PP | |
118 | Some options are only available for specific themes. | |
119 | .PP | |
120 | See the \fBttk::style\fP manual page for information on how to configure | |
121 | ttk styles. | |
93 | 122 | .SH "SEE ALSO" |
94 | 123 | ttk::widget(n), scale(n) |
95 | 124 | .SH KEYWORDS |
153 | 153 | grid columnconfigure $f 0 \-weight 1 |
154 | 154 | grid rowconfigure $f 0 \-weight 1 |
155 | 155 | .CE |
156 | .SH "STYLING OPTIONS" | |
157 | .PP | |
158 | The class name for a \fBttk::scrollbar\fP is \fBTScrollbar\fP. | |
159 | .PP | |
160 | Dynamic states: \fBactive\fP, \fBdisabled\fP. | |
161 | .PP | |
162 | \fBTScrollbar\fP styling options configurable with \fBttk::style\fP | |
163 | are: | |
164 | .PP | |
165 | \fB\-arrowcolor\fP \fIcolor\fP | |
166 | .br | |
167 | \fB\-background\fP \fIcolor\fP | |
168 | .br | |
169 | \fB\-bordercolor\fP \fIcolor\fP | |
170 | .br | |
171 | \fB\-darkcolor\fP \fIcolor\fP | |
172 | .br | |
173 | \fB\-foreground\fP \fIcolor\fP | |
174 | .br | |
175 | \fB\-lightcolor\fP \fIcolor\fP | |
176 | .br | |
177 | \fB\-troughcolor\fP \fIcolor\fP | |
178 | .PP | |
179 | Some options are only available for specific themes. | |
180 | .PP | |
181 | See the \fBttk::style\fP manual page for information on how to configure | |
182 | ttk styles. | |
156 | 183 | .SH "SEE ALSO" |
157 | 184 | ttk::widget(n), scrollbar(n) |
158 | 185 | .SH KEYWORDS |
16 | 16 | A \fBttk::separator\fR widget displays a horizontal or vertical separator |
17 | 17 | bar. |
18 | 18 | .SO ttk_widget |
19 | \-class \-cursor \-state | |
19 | \-class \-cursor | |
20 | 20 | \-style \-takefocus |
21 | 21 | .SE |
22 | 22 | .SH "WIDGET-SPECIFIC OPTIONS" |
28 | 28 | Separator widgets support the standard |
29 | 29 | \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR |
30 | 30 | methods. No other widget methods are used. |
31 | .PP | |
32 | .SH "STYLING OPTIONS" | |
33 | .PP | |
34 | The class name for a \fBttk::separator\fP is \fBTSeparator\fP. | |
35 | .PP | |
36 | \fBTSeparator\fP styling options configurable with \fBttk::style\fP | |
37 | are: | |
38 | .PP | |
39 | \fB\-background\fP \fIcolor\fP | |
40 | .PP | |
41 | Some options are only available for specific themes. | |
42 | .PP | |
43 | See the \fBttk::style\fP manual page for information on how to configure | |
44 | ttk styles. | |
31 | 45 | .SH "SEE ALSO" |
32 | 46 | ttk::widget(n) |
33 | 47 | .SH "KEYWORDS" |
2 | 2 | '\" |
3 | 3 | '\" See the file "license.terms" for information on usage and redistribution |
4 | 4 | '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
5 | '\" | |
5 | '\" | |
6 | 6 | .TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget" |
7 | 7 | .so man.macros |
8 | 8 | .BS |
17 | 17 | allows the user to resize the containing toplevel window |
18 | 18 | by pressing and dragging the grip. |
19 | 19 | .SO ttk_widget |
20 | \-class \-cursor \-state | |
20 | \-class \-cursor | |
21 | 21 | \-style \-takefocus |
22 | 22 | .SE |
23 | 23 | .SH "WIDGET COMMAND" |
59 | 59 | \fBttk::sizegrip\fR widgets only support |
60 | 60 | .QW southeast |
61 | 61 | resizing. |
62 | .SH "STYLING OPTIONS" | |
63 | .PP | |
64 | The class name for a \fBttk::sizegrip\fP is \fBTSizegrip\fP. | |
65 | .PP | |
66 | \fBTSizegrip\fP styling options configurable with \fBttk::style\fP | |
67 | are: | |
68 | .PP | |
69 | \fB\-background\fP \fIcolor\fP | |
70 | .PP | |
71 | Some options are only available for specific themes. | |
72 | .PP | |
73 | See the \fBttk::style\fP manual page for information on how to configure | |
74 | ttk styles. | |
62 | 75 | .SH "SEE ALSO" |
63 | 76 | ttk::widget(n) |
64 | 77 | .SH "KEYWORDS" |
20 | 20 | \fB\-textvariable\fR option to link the value displayed by the widget |
21 | 21 | to a Tcl variable. |
22 | 22 | .SO ttk_widget |
23 | \-class \-cursor \-style | |
23 | \-class \-cursor \-state \-style | |
24 | 24 | \-takefocus \-xscrollcommand |
25 | 25 | .SE |
26 | 26 | .SO ttk_entry |
27 | 27 | \-validate \-validatecommand |
28 | 28 | .SE |
29 | 29 | .SH "WIDGET-SPECIFIC OPTIONS" |
30 | .OP \-command command Command | |
31 | Specifies a Tcl command to be invoked whenever a spinbutton is invoked. | |
32 | .OP \-format format Format | |
33 | Specifies an alternate format to use when setting the string value | |
34 | when using the \fB\-from\fR and \fB\-to\fR range. | |
35 | This must be a format specifier of the form \fB%<pad>.<pad>f\fR, | |
36 | as it will format a floating-point number. | |
30 | 37 | .OP \-from from From |
31 | 38 | A floating\-point value specifying the lowest value for the spinbox. This is |
32 | 39 | used in conjunction with \fB\-to\fR and \fB\-increment\fR to set a numerical |
33 | range. | |
34 | .OP \-to to To | |
35 | A floating\-point value specifying the highest permissible value for the | |
36 | widget. See also \fB\-from\fR and \fB\-increment\fR. | |
37 | 40 | range. |
38 | 41 | .OP \-increment increment Increment |
39 | 42 | A floating\-point value specifying the change in value to be applied each |
40 | 43 | time one of the widget spin buttons is pressed. The up button applies a |
41 | 44 | positive increment, the down button applies a negative increment. |
45 | .OP \-to to To | |
46 | A floating\-point value specifying the highest permissible value for the | |
47 | widget. See also \fB\-from\fR and \fB\-increment\fR. | |
48 | range. | |
42 | 49 | .OP \-values values Values |
43 | 50 | This must be a Tcl list of values. If this option is set then this will |
44 | 51 | override any range set using the \fB\-from\fR, \fB\-to\fR and |
47 | 54 | .OP \-wrap wrap Wrap |
48 | 55 | Must be a proper boolean value. If on, the spinbox will wrap around the |
49 | 56 | values of data in the widget. |
50 | .OP \-format format Format | |
51 | Specifies an alternate format to use when setting the string value | |
52 | when using the \fB\-from\fR and \fB\-to\fR range. | |
53 | This must be a format specifier of the form \fB%<pad>.<pad>f\fR, | |
54 | as it will format a floating-point number. | |
55 | .OP \-command command Command | |
56 | Specifies a Tcl command to be invoked whenever a spinbutton is invoked. | |
57 | 57 | .SH "INDICES" |
58 | 58 | .PP |
59 | 59 | See the \fBttk::entry\fR manual for information about indexing characters. |
65 | 65 | .PP |
66 | 66 | The following subcommands are possible for spinbox widgets in addition to |
67 | 67 | the commands described for the \fBttk::entry\fR widget: |
68 | .TP | |
69 | \fIpathName \fBcurrent \fIindex\fR | |
70 | 68 | .TP |
71 | 69 | \fIpathName \fBget\fR |
72 | 70 | Returns the spinbox's current value. |
81 | 79 | The spinbox widget generates a \fB<<Increment>>\fR virtual event when |
82 | 80 | the user presses <Up>, and a \fB<<Decrement>>\fR virtual event when the |
83 | 81 | user presses <Down>. |
82 | .SH "STYLING OPTIONS" | |
83 | .PP | |
84 | The class name for a \fBttk::spinbox\fP is \fBTSpinbox\fP. | |
85 | .PP | |
86 | Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP. | |
87 | .PP | |
88 | \fBTSpinbox\fP styling options configurable with \fBttk::style\fP | |
89 | are: | |
90 | .PP | |
91 | \fB\-arrowcolor\fP \fIcolor\fP | |
92 | .br | |
93 | \fB\-arrowsize\fP \fIamount\fP | |
94 | .br | |
95 | \fB\-background\fP \fIcolor\fP | |
96 | .RS | |
97 | When using the aqua theme (Mac OS X), changes the \fB\-fieldbackground\fP. | |
98 | .RE | |
99 | \fB\-bordercolor\fP \fIcolor\fP | |
100 | .br | |
101 | \fB\-darkcolor\fP \fIcolor\fP | |
102 | .br | |
103 | \fB\-fieldbackground\fP \fIcolor\fP | |
104 | .RS | |
105 | Does not work with the aqua theme (Mac OS X). | |
106 | .RE | |
107 | \fB\-foreground\fP \fIcolor\fP | |
108 | .br | |
109 | \fB\-lightcolor\fP \fIcolor\fP | |
110 | .br | |
111 | \fB\-padding\fP \fIpadding\fP | |
112 | .br | |
113 | \fB\-selectbackground\fP \fIcolor\fP | |
114 | .br | |
115 | \fB\-selectforeground\fP \fIcolor\fP | |
116 | .PP | |
117 | Some options are only available for specific themes. | |
118 | .PP | |
119 | See the \fBttk::style\fP manual page for information on how to configure | |
120 | ttk styles. | |
84 | 121 | .SH "SEE ALSO" |
85 | 122 | ttk::widget(n), ttk::entry(n), spinbox(n) |
86 | 123 | .SH KEYWORDS |
473 | 473 | '\" Not yet: |
474 | 474 | '\" In Tk 8.5, the affected item is also passed as the \fB\-detail\fR field |
475 | 475 | '\" of the virtual event. |
476 | .SH "STYLING OPTIONS" | |
477 | .PP | |
478 | The class name for a \fBttk::treeview\fP is \fBTreeview\fP. | |
479 | The treeview header class name is \fBHeading\fP. | |
480 | The treeview item class name is \fBItem\fP. | |
481 | The treeview cell class name is \fBCell\fP. | |
482 | .PP | |
483 | Dynamic states: \fBdisabled\fP, \fBselected\fP. | |
484 | .PP | |
485 | \fBTreeview\fP styling options configurable with \fBttk::style\fP | |
486 | are: | |
487 | .PP | |
488 | \fB\-background\fP \fIcolor\fP | |
489 | .br | |
490 | \fB\-fieldbackground\fP \fIcolor\fP | |
491 | .br | |
492 | \fB\-font\fP \fIfont\fP | |
493 | .br | |
494 | \fB\-foreground\fP \fIcolor\fP | |
495 | .br | |
496 | \fB\-rowheight\fP \fIamount\fP | |
497 | .RS | |
498 | The \fB\-rowheight\fP value is not corrected by the \fBtk scaling\fP | |
499 | value or by the configured font size and must always be set. Also make | |
500 | sure that the \fB\-rowheight\fP is large enough to contain any images. | |
501 | .PP | |
502 | To adjust the \fB\-rowheight\fP for the Treeview style, use the following code | |
503 | after \fBtk scaling\fP has been applied. | |
504 | Note that even if you do not support or change \fBtk scaling\fP | |
505 | in your program, your users may have it set in their .wishrc. | |
506 | .RE | |
507 | .PP | |
508 | .CS | |
509 | ttk::style configure Treeview \\ | |
510 | \-rowheight [expr {[font metrics \fIfont\fP \-linespace] + 2}] | |
511 | .CE | |
512 | .PP | |
513 | \fBHeading\fP styling options configurable with \fBttk::style\fP | |
514 | are: | |
515 | .PP | |
516 | \fB\-background\fP \fIcolor\fP | |
517 | .br | |
518 | \fB\-font\fP \fIfont\fP | |
519 | .br | |
520 | \fB\-relief\fP \fIrelief\fP | |
521 | .PP | |
522 | \fBItem\fP styling options configurable with \fBttk::style\fP | |
523 | are: | |
524 | .PP | |
525 | \fB\-foreground\fP \fIcolor\fP | |
526 | .br | |
527 | \fB\-indicatormargins\fP \fIpadding\fP | |
528 | .br | |
529 | \fB\-indicatorsize\fP \fIamount\fP | |
530 | .br | |
531 | \fB\-padding\fP \fIpadding\fP | |
532 | .PP | |
533 | \fBCell\fP styling options configurable with \fBttk::style\fP | |
534 | are: | |
535 | .PP | |
536 | \fB\-padding\fP \fIpadding\fP | |
537 | .PP | |
538 | Some options are only available for specific themes. | |
539 | .PP | |
540 | See the \fBttk::style\fP manual page for information on how to configure | |
541 | ttk styles. | |
476 | 542 | .SH "SEE ALSO" |
477 | 543 | ttk::widget(n), listbox(n), image(n), bind(n) |
478 | 544 | '\" Local Variables: |
124 | 124 | If less than zero, specifies a minimum width. |
125 | 125 | If zero or unspecified, the natural width of the text label is used. |
126 | 126 | .SH "COMPATIBILITY OPTIONS" |
127 | This option is only available for themed widgets that have | |
128 | .QW corresponding | |
129 | traditional Tk widgets. | |
127 | 130 | .OP \-state state State |
128 | 131 | May be set to \fBnormal\fR or \fBdisabled\fR |
129 | 132 | to control the \fBdisabled\fR state bit. |
74 | 74 | #define TK_MAJOR_VERSION 8 |
75 | 75 | #define TK_MINOR_VERSION 6 |
76 | 76 | #define TK_RELEASE_LEVEL TCL_FINAL_RELEASE |
77 | #define TK_RELEASE_SERIAL 8 | |
77 | #define TK_RELEASE_SERIAL 9 | |
78 | 78 | |
79 | 79 | #define TK_VERSION "8.6" |
80 | #define TK_PATCH_LEVEL "8.6.8" | |
80 | #define TK_PATCH_LEVEL "8.6.9" | |
81 | 81 | |
82 | 82 | /* |
83 | 83 | * A special definition used to allow this header file to be included from |
1173 | 1173 | } Tk_TSOffset; |
1174 | 1174 | |
1175 | 1175 | /* |
1176 | * Bit fields in Tk_Offset->flags: | |
1176 | * Bit fields in Tk_TSOffset->flags: | |
1177 | 1177 | */ |
1178 | 1178 | |
1179 | 1179 | #define TK_OFFSET_INDEX 1 |
74 | 74 | * EVENT_BUFFER_SIZE too much, shift multi-clicks will be lost. |
75 | 75 | */ |
76 | 76 | |
77 | #define EVENT_BUFFER_SIZE 30 | |
77 | /* | |
78 | * NOTE: The changes which were needed to make Tk work on OSX 10.14 (Mojave) | |
79 | * also demand that the event ring be a bit bigger. It might be wise to | |
80 | * augment the current double-click pattern matching by adding a new | |
81 | * DoubleClick modifier bit which could be set based on the clickCount of the | |
82 | * Apple NSEvent object. | |
83 | */ | |
84 | ||
85 | #ifndef TK_MAC_OSX | |
86 | #define EVENT_BUFFER_SIZE 45 | |
87 | #else | |
88 | #define EVENT_BUFFER_SIZE 30 | |
89 | #endif | |
90 | ||
78 | 91 | typedef struct Tk_BindingTable_ { |
79 | 92 | XEvent eventRing[EVENT_BUFFER_SIZE]; |
80 | 93 | /* Circular queue of recent events (higher |
3466 | 3479 | if ((warp != 0) && Tk_IsMapped(tkwin)) { |
3467 | 3480 | TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display); |
3468 | 3481 | |
3469 | Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, | |
3482 | Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, | |
3470 | 3483 | event.general.xmotion.window); |
3471 | 3484 | |
3472 | 3485 | if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) { |
878 | 878 | |
879 | 879 | Tcl_CancelIdleCall(TkpDisplayButton, butPtr); |
880 | 880 | XFlush(butPtr->display); |
881 | #ifndef MAC_OSX_TK | |
882 | /* | |
883 | * On the mac you can not sleep in a display proc, and the | |
884 | * flash command doesn't do anything anyway. | |
885 | */ | |
881 | 886 | Tcl_Sleep(50); |
887 | #endif | |
882 | 888 | } |
883 | 889 | } |
884 | 890 | break; |
1610 | 1616 | Tcl_Obj *valuePtr; |
1611 | 1617 | |
1612 | 1618 | /* |
1619 | * See ticket [5d991b82]. | |
1620 | */ | |
1621 | ||
1622 | if (butPtr->selVarNamePtr == NULL) { | |
1623 | if (!(flags & TCL_INTERP_DESTROYED)) { | |
1624 | Tcl_UntraceVar2(interp, name1, name2, | |
1625 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
1626 | ButtonVarProc, clientData); | |
1627 | } | |
1628 | return NULL; | |
1629 | } | |
1630 | ||
1631 | /* | |
1613 | 1632 | * If the variable is being unset, then just re-establish the trace unless |
1614 | 1633 | * the whole interpreter is going away. |
1615 | 1634 | */ |
1691 | 1710 | ButtonTextVarProc( |
1692 | 1711 | ClientData clientData, /* Information about button. */ |
1693 | 1712 | Tcl_Interp *interp, /* Interpreter containing variable. */ |
1694 | const char *name1, /* Not used. */ | |
1695 | const char *name2, /* Not used. */ | |
1713 | const char *name1, /* Name of variable. */ | |
1714 | const char *name2, /* Second part of variable name. */ | |
1696 | 1715 | int flags) /* Information about what happened. */ |
1697 | 1716 | { |
1698 | 1717 | TkButton *butPtr = clientData; |
1701 | 1720 | if (butPtr->flags & BUTTON_DELETED) { |
1702 | 1721 | return NULL; |
1703 | 1722 | } |
1723 | ||
1724 | /* | |
1725 | * See ticket [5d991b82]. | |
1726 | */ | |
1727 | ||
1728 | if (butPtr->textVarNamePtr == NULL) { | |
1729 | if (!(flags & TCL_INTERP_DESTROYED)) { | |
1730 | Tcl_UntraceVar2(interp, name1, name2, | |
1731 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
1732 | ButtonTextVarProc, clientData); | |
1733 | } | |
1734 | return NULL; | |
1735 | } | |
1704 | 1736 | |
1705 | 1737 | /* |
1706 | 1738 | * If the variable is unset, then immediately recreate it unless the whole |
100 | 100 | enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE }; |
101 | 101 | Tk_Window tkwin = clientData; |
102 | 102 | int i, index, nice = 0; |
103 | Tk_ErrorHandler handler; | |
103 | 104 | |
104 | 105 | if (objc > 4) { |
105 | 106 | wrongArgs: |
127 | 128 | break; |
128 | 129 | } |
129 | 130 | } |
131 | handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, NULL, NULL); | |
130 | 132 | XBell(Tk_Display(tkwin), 0); |
131 | 133 | if (!nice) { |
132 | 134 | XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset); |
133 | 135 | } |
134 | 136 | XFlush(Tk_Display(tkwin)); |
137 | Tk_DeleteErrorHandler(handler); | |
135 | 138 | return TCL_OK; |
136 | 139 | } |
137 | 140 |
936 | 936 | ObjectIsEmpty( |
937 | 937 | Tcl_Obj *objPtr) /* Object to test. May be NULL. */ |
938 | 938 | { |
939 | int length; | |
940 | ||
941 | 939 | if (objPtr == NULL) { |
942 | 940 | return 1; |
943 | 941 | } |
944 | if (objPtr->bytes != NULL) { | |
945 | return (objPtr->length == 0); | |
946 | } | |
947 | (void)Tcl_GetStringFromObj(objPtr, &length); | |
948 | return (length == 0); | |
942 | if (objPtr->bytes == NULL) { | |
943 | Tcl_GetString(objPtr); | |
944 | } | |
945 | return (objPtr->length == 0); | |
949 | 946 | } |
950 | 947 | |
951 | 948 | /* |
886 | 886 | entryPtr->selectLast = index2; |
887 | 887 | } |
888 | 888 | if (!(entryPtr->flags & GOT_SELECTION) |
889 | && (entryPtr->exportSelection)) { | |
889 | && (entryPtr->exportSelection) | |
890 | && (!Tcl_IsSafe(entryPtr->interp))) { | |
890 | 891 | Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, |
891 | 892 | EntryLostSelection, entryPtr); |
892 | 893 | entryPtr->flags |= GOT_SELECTION; |
1121 | 1122 | * value. |
1122 | 1123 | */ |
1123 | 1124 | |
1124 | oldExport = entryPtr->exportSelection; | |
1125 | oldExport = (entryPtr->exportSelection) && (!Tcl_IsSafe(entryPtr->interp)); | |
1125 | 1126 | if (entryPtr->type == TK_SPINBOX) { |
1126 | 1127 | oldValues = sbPtr->valueStr; |
1127 | 1128 | oldFormat = sbPtr->reqFormat; |
1275 | 1276 | */ |
1276 | 1277 | |
1277 | 1278 | if (entryPtr->exportSelection && (!oldExport) |
1279 | && (!Tcl_IsSafe(entryPtr->interp)) | |
1278 | 1280 | && (entryPtr->selectFirst != -1) |
1279 | 1281 | && !(entryPtr->flags & GOT_SELECTION)) { |
1280 | 1282 | Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, |
2744 | 2746 | * Grab the selection if we don't own it already. |
2745 | 2747 | */ |
2746 | 2748 | |
2747 | if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)) { | |
2749 | if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection) | |
2750 | && (!Tcl_IsSafe(entryPtr->interp))) { | |
2748 | 2751 | Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, |
2749 | 2752 | entryPtr); |
2750 | 2753 | entryPtr->flags |= GOT_SELECTION; |
2811 | 2814 | const char *string; |
2812 | 2815 | const char *selStart, *selEnd; |
2813 | 2816 | |
2814 | if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) { | |
2817 | if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection) | |
2818 | || Tcl_IsSafe(entryPtr->interp)) { | |
2815 | 2819 | return -1; |
2816 | 2820 | } |
2817 | 2821 | string = entryPtr->displayString; |
2864 | 2868 | */ |
2865 | 2869 | |
2866 | 2870 | if (TkpAlwaysShowSelection(entryPtr->tkwin) |
2867 | && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection) { | |
2871 | && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection | |
2872 | && (!Tcl_IsSafe(entryPtr->interp))) { | |
2868 | 2873 | entryPtr->selectFirst = -1; |
2869 | 2874 | entryPtr->selectLast = -1; |
2870 | 2875 | EventuallyRedraw(entryPtr); |
3129 | 3134 | EntryTextVarProc( |
3130 | 3135 | ClientData clientData, /* Information about button. */ |
3131 | 3136 | Tcl_Interp *interp, /* Interpreter containing variable. */ |
3132 | const char *name1, /* Not used. */ | |
3133 | const char *name2, /* Not used. */ | |
3137 | const char *name1, /* Name of variable. */ | |
3138 | const char *name2, /* Second part of variable name. */ | |
3134 | 3139 | int flags) /* Information about what happened. */ |
3135 | 3140 | { |
3136 | 3141 | Entry *entryPtr = clientData; |
3142 | 3147 | */ |
3143 | 3148 | return NULL; |
3144 | 3149 | } |
3150 | ||
3151 | /* | |
3152 | * See ticket [5d991b82]. | |
3153 | */ | |
3154 | ||
3155 | if (entryPtr->textVarName == NULL) { | |
3156 | if (!(flags & TCL_INTERP_DESTROYED)) { | |
3157 | Tcl_UntraceVar2(interp, name1, name2, | |
3158 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
3159 | EntryTextVarProc, clientData); | |
3160 | } | |
3161 | return NULL; | |
3162 | } | |
3145 | 3163 | |
3146 | 3164 | /* |
3147 | 3165 | * If the variable is unset, then immediately recreate it unless the whole |
4033 | 4051 | entryPtr->selectLast = index2; |
4034 | 4052 | } |
4035 | 4053 | if (!(entryPtr->flags & GOT_SELECTION) |
4036 | && entryPtr->exportSelection) { | |
4054 | && entryPtr->exportSelection | |
4055 | && (!Tcl_IsSafe(entryPtr->interp))) { | |
4037 | 4056 | Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, |
4038 | 4057 | EntryLostSelection, entryPtr); |
4039 | 4058 | entryPtr->flags |= GOT_SELECTION; |
220 | 220 | * value that the users requests. Malloc'ed */ |
221 | 221 | char *valueFormat; /* Sprintf conversion specifier used for the |
222 | 222 | * value. */ |
223 | char digitFormat[10]; /* Sprintf conversion specifier computed from | |
223 | char digitFormat[16]; /* Sprintf conversion specifier computed from | |
224 | 224 | * digits and other information; used for the |
225 | 225 | * value. */ |
226 | 226 |
81 | 81 | * errors. */ |
82 | 82 | ClientData clientData) /* Arbitrary value to pass to errorProc. */ |
83 | 83 | { |
84 | register TkErrorHandler *errorPtr; | |
85 | register TkDisplay *dispPtr; | |
84 | TkErrorHandler *errorPtr; | |
85 | TkDisplay *dispPtr; | |
86 | 86 | |
87 | 87 | /* |
88 | 88 | * Find the display. If Tk doesn't know about this display then it's an |
146 | 146 | Tk_ErrorHandler handler) /* Token for handler to delete; was previous |
147 | 147 | * return value from Tk_CreateErrorHandler. */ |
148 | 148 | { |
149 | register TkErrorHandler *errorPtr = (TkErrorHandler *) handler; | |
150 | register TkDisplay *dispPtr = errorPtr->dispPtr; | |
149 | TkErrorHandler *errorPtr = (TkErrorHandler *) handler; | |
150 | TkDisplay *dispPtr = errorPtr->dispPtr; | |
151 | 151 | |
152 | 152 | errorPtr->lastRequest = NextRequest(dispPtr->display) - 1; |
153 | 153 | |
165 | 165 | |
166 | 166 | dispPtr->deleteCount += 1; |
167 | 167 | if (dispPtr->deleteCount >= 10) { |
168 | register TkErrorHandler *prevPtr; | |
168 | TkErrorHandler *prevPtr; | |
169 | 169 | TkErrorHandler *nextPtr; |
170 | int lastSerial; | |
171 | ||
170 | int lastSerial = LastKnownRequestProcessed(dispPtr->display); | |
171 | ||
172 | /* | |
173 | * Last chance to catch errors for this handler: if no event/error | |
174 | * processing took place to follow up the end of this error handler | |
175 | * we need a round trip with the X server now. | |
176 | */ | |
177 | ||
178 | if (errorPtr->lastRequest > (unsigned long) lastSerial) { | |
179 | XSync(dispPtr->display, False); | |
180 | } | |
172 | 181 | dispPtr->deleteCount = 0; |
173 | lastSerial = LastKnownRequestProcessed(dispPtr->display); | |
174 | 182 | errorPtr = dispPtr->errorPtr; |
175 | 183 | for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) { |
176 | 184 | nextPtr = errorPtr->nextPtr; |
212 | 220 | static int |
213 | 221 | ErrorProc( |
214 | 222 | Display *display, /* Display for which error occurred. */ |
215 | register XErrorEvent *errEventPtr) | |
223 | XErrorEvent *errEventPtr) | |
216 | 224 | /* Information about error. */ |
217 | 225 | { |
218 | register TkDisplay *dispPtr; | |
219 | register TkErrorHandler *errorPtr; | |
226 | TkDisplay *dispPtr; | |
227 | TkErrorHandler *errorPtr; | |
220 | 228 | |
221 | 229 | /* |
222 | 230 | * See if we know anything about the display. If not, then invoke the |
2867 | 2867 | } |
2868 | 2868 | } |
2869 | 2869 | } else if (eventPtr->type == DestroyNotify) { |
2870 | register Gridder *gridPtr2, *nextPtr; | |
2870 | register Gridder *slavePtr, *nextPtr; | |
2871 | 2871 | |
2872 | 2872 | if (gridPtr->masterPtr != NULL) { |
2873 | 2873 | Unlink(gridPtr); |
2874 | 2874 | } |
2875 | for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL; | |
2876 | gridPtr2 = nextPtr) { | |
2877 | Tk_UnmapWindow(gridPtr2->tkwin); | |
2878 | gridPtr2->masterPtr = NULL; | |
2879 | nextPtr = gridPtr2->nextPtr; | |
2880 | gridPtr2->nextPtr = NULL; | |
2875 | for (slavePtr = gridPtr->slavePtr; slavePtr != NULL; | |
2876 | slavePtr = nextPtr) { | |
2877 | Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL); | |
2878 | Tk_UnmapWindow(slavePtr->tkwin); | |
2879 | slavePtr->masterPtr = NULL; | |
2880 | nextPtr = slavePtr->nextPtr; | |
2881 | slavePtr->nextPtr = NULL; | |
2881 | 2882 | } |
2882 | 2883 | Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable, |
2883 | 2884 | (char *) gridPtr->tkwin)); |
2893 | 2894 | Tcl_DoWhenIdle(ArrangeGrid, gridPtr); |
2894 | 2895 | } |
2895 | 2896 | } else if (eventPtr->type == UnmapNotify) { |
2896 | register Gridder *gridPtr2; | |
2897 | ||
2898 | for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL; | |
2899 | gridPtr2 = gridPtr2->nextPtr) { | |
2900 | Tk_UnmapWindow(gridPtr2->tkwin); | |
2897 | register Gridder *slavePtr; | |
2898 | ||
2899 | for (slavePtr = gridPtr->slavePtr; slavePtr != NULL; | |
2900 | slavePtr = slavePtr->nextPtr) { | |
2901 | Tk_UnmapWindow(slavePtr->tkwin); | |
2901 | 2902 | } |
2902 | 2903 | } |
2903 | 2904 | } |
1140 | 1140 | * Last pass reset the decoder, so the first code we see |
1141 | 1141 | * must be a singleton. Seed the stack with it, and set up |
1142 | 1142 | * the old/first code pointers for insertion into the |
1143 | * string table. We can't just roll this into the | |
1144 | * clearCode test above, because at that point we have not | |
1145 | * yet read the next code. | |
1143 | * codes table. We can't just roll this into the clearCode | |
1144 | * test above, because at that point we have not yet read | |
1145 | * the next code. | |
1146 | 1146 | */ |
1147 | 1147 | |
1148 | 1148 | *top++ = append[code]; |
1153 | 1153 | |
1154 | 1154 | inCode = code; |
1155 | 1155 | |
1156 | if (code == maxCode) { | |
1156 | if ((code == maxCode) && (maxCode < (1 << MAX_LWZ_BITS))) { | |
1157 | 1157 | /* |
1158 | 1158 | * maxCode is always one bigger than our highest assigned |
1159 | 1159 | * code. If the code we see is equal to maxCode, then we |
1160 | * are about to add a new string to the table. ??? | |
1160 | * are about to add a new entry to the codes table. | |
1161 | 1161 | */ |
1162 | 1162 | |
1163 | 1163 | *top++ = firstCode; |
1166 | 1166 | |
1167 | 1167 | while (code > clearCode) { |
1168 | 1168 | /* |
1169 | * Populate the stack by tracing the string in the string | |
1169 | * Populate the stack by tracing the code in the codes | |
1170 | 1170 | * table from its tail to its head |
1171 | 1171 | */ |
1172 | 1172 | |
1175 | 1175 | } |
1176 | 1176 | firstCode = append[code]; |
1177 | 1177 | |
1178 | /* | |
1179 | * If there's no more room in our string table, quit. | |
1180 | * Otherwise, add a new string to the table | |
1181 | */ | |
1182 | ||
1183 | if (maxCode >= (1 << MAX_LWZ_BITS)) { | |
1184 | return TCL_OK; | |
1185 | } | |
1186 | ||
1187 | /* | |
1188 | * Push the head of the string onto the stack. | |
1189 | */ | |
1190 | ||
1191 | *top++ = firstCode; | |
1192 | ||
1193 | /* | |
1194 | * Add a new string to the string table | |
1195 | */ | |
1196 | ||
1197 | prefix[maxCode] = oldCode; | |
1198 | append[maxCode] = firstCode; | |
1199 | maxCode++; | |
1178 | /* | |
1179 | * Push the head of the code onto the stack. | |
1180 | */ | |
1181 | ||
1182 | *top++ = firstCode; | |
1183 | ||
1184 | if (maxCode < (1 << MAX_LWZ_BITS)) { | |
1185 | /* | |
1186 | * If there's still room in our codes table, add a new entry. | |
1187 | * Otherwise don't, and keep using the current table. | |
1188 | * See DEFERRED CLEAR CODE IN LZW COMPRESSION in the GIF89a | |
1189 | * specification. | |
1190 | */ | |
1191 | ||
1192 | prefix[maxCode] = oldCode; | |
1193 | append[maxCode] = firstCode; | |
1194 | maxCode++; | |
1195 | } | |
1200 | 1196 | |
1201 | 1197 | /* |
1202 | 1198 | * maxCode tells us the maximum code value we can accept. If |
29 | 29 | * Forward declarations |
30 | 30 | */ |
31 | 31 | |
32 | #ifndef MAC_OSX_TK | |
32 | 33 | static void BlendComplexAlpha(XImage *bgImg, PhotoInstance *iPtr, |
33 | 34 | int xOffset, int yOffset, int width, int height); |
35 | #endif | |
34 | 36 | static int IsValidPalette(PhotoInstance *instancePtr, |
35 | 37 | const char *palette); |
36 | 38 | static int CountBits(pixel mask); |
408 | 410 | * |
409 | 411 | *---------------------------------------------------------------------- |
410 | 412 | */ |
411 | ||
413 | #ifndef MAC_OSX_TK | |
412 | 414 | #ifndef _WIN32 |
413 | 415 | #define GetRValue(rgb) (UCHAR(((rgb) & red_mask) >> red_shift)) |
414 | 416 | #define GetGValue(rgb) (UCHAR(((rgb) & green_mask) >> green_shift)) |
417 | 419 | (UCHAR(r) << red_shift) | \ |
418 | 420 | (UCHAR(g) << green_shift) | \ |
419 | 421 | (UCHAR(b) << blue_shift) )) |
420 | #ifdef MAC_OSX_TK | |
421 | #define RGBA(r, g, b, a) ((unsigned)( \ | |
422 | (UCHAR(r) << red_shift) | \ | |
423 | (UCHAR(g) << green_shift) | \ | |
424 | (UCHAR(b) << blue_shift) | \ | |
425 | (UCHAR(a) << alpha_shift) )) | |
426 | #endif | |
427 | 422 | #define RGB15(r, g, b) ((unsigned)( \ |
428 | 423 | (((r) * red_mask / 255) & red_mask) | \ |
429 | 424 | (((g) * green_mask / 255) & green_mask) | \ |
442 | 437 | unsigned long pixel; |
443 | 438 | unsigned char r, g, b, alpha, unalpha, *masterPtr; |
444 | 439 | unsigned char *alphaAr = iPtr->masterPtr->pix32; |
445 | #if defined(MAC_OSX_TK) | |
446 | /* Background "pixels" are actually 2^pp x 2^pp blocks of subpixels. Each | |
447 | * block gets blended with the color of one image pixel. Since we iterate | |
448 | * over the background subpixels, we reset the width and height to the | |
449 | * subpixel dimensions of the background image we are using. | |
450 | */ | |
451 | int pp = bgImg->pixelpower; | |
452 | width = width << pp; | |
453 | height = height << pp; | |
454 | #endif | |
440 | ||
455 | 441 | /* |
456 | 442 | * This blending is an integer version of the Source-Over compositing rule |
457 | 443 | * (see Porter&Duff, "Compositing Digital Images", proceedings of SIGGRAPH |
491 | 477 | while ((0x0001 & (blue_mask >> blue_shift)) == 0) { |
492 | 478 | blue_shift++; |
493 | 479 | } |
494 | #ifdef MAC_OSX_TK | |
495 | unsigned long alpha_mask = visual->alpha_mask; | |
496 | unsigned long alpha_shift = 0; | |
497 | while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) { | |
498 | alpha_shift++; | |
499 | } | |
500 | #endif | |
501 | 480 | #endif /* !_WIN32 */ |
502 | 481 | |
503 | 482 | /* |
557 | 536 | #endif /* !_WIN32 && !MAC_OSX_TK */ |
558 | 537 | |
559 | 538 | for (y = 0; y < height; y++) { |
560 | # if !defined(MAC_OSX_TK) | |
561 | 539 | line = (y + yOffset) * iPtr->masterPtr->width; |
562 | 540 | for (x = 0; x < width; x++) { |
563 | 541 | masterPtr = alphaAr + ((line + x + xOffset) * 4); |
564 | #else | |
565 | /* Repeat each image row and column 2^pp times. */ | |
566 | line = ((y>>pp) + yOffset) * iPtr->masterPtr->width; | |
567 | for (x = 0; x < width; x++) { | |
568 | masterPtr = alphaAr + ((line + (x>>pp) + xOffset) * 4); | |
569 | #endif | |
570 | 542 | alpha = masterPtr[3]; |
571 | 543 | |
572 | 544 | /* |
598 | 570 | g = ALPHA_BLEND(ga, g, alpha, unalpha); |
599 | 571 | b = ALPHA_BLEND(ba, b, alpha, unalpha); |
600 | 572 | } |
601 | #ifndef MAC_OSX_TK | |
602 | 573 | XPutPixel(bgImg, x, y, RGB(r, g, b)); |
603 | #else | |
604 | XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha)); | |
605 | #endif | |
606 | 574 | } |
607 | 575 | } |
608 | 576 | } |
609 | 577 | #undef ALPHA_BLEND |
610 | 578 | } |
579 | #endif /* MAC_OSX_TK */ | |
611 | 580 | |
612 | 581 | /* |
613 | 582 | *---------------------------------------------------------------------- |
650 | 619 | return; |
651 | 620 | } |
652 | 621 | |
622 | #ifdef MAC_OSX_TK | |
623 | /* | |
624 | * The Mac version of TkPutImage handles RGBA images directly. There is | |
625 | * no need to call XGetImage or to do the Porter-Duff compositing by hand. | |
626 | * We just let the CG graphics library do it, using the graphics hardware. | |
627 | */ | |
628 | unsigned char *rgbaPixels = instancePtr->masterPtr->pix32; | |
629 | ||
630 | XImage *photo = XCreateImage(display, NULL, 32, ZPixmap, 0, (char*)rgbaPixels, | |
631 | (unsigned int)instancePtr->width, | |
632 | (unsigned int)instancePtr->height, | |
633 | 0, (unsigned int)(4 * instancePtr->width)); | |
634 | TkPutImage(NULL, 0, display, drawable, instancePtr->gc, | |
635 | photo, imageX, imageY, drawableX, drawableY, | |
636 | (unsigned int) width, (unsigned int) height); | |
637 | photo->data = NULL; | |
638 | XDestroyImage(photo); | |
639 | #else | |
653 | 640 | if ((instancePtr->masterPtr->flags & COMPLEX_ALPHA) |
654 | 641 | && visInfo.depth >= 15 |
655 | 642 | && (visInfo.class == DirectColor || visInfo.class == TrueColor)) { |
708 | 695 | XSetClipOrigin(display, instancePtr->gc, 0, 0); |
709 | 696 | } |
710 | 697 | XFlush(display); |
698 | #endif | |
711 | 699 | } |
712 | 700 | |
713 | 701 | /* |
982 | 982 | declare 39 aqua { |
983 | 983 | void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid) |
984 | 984 | } |
985 | declare 40 aqua { | |
986 | void TkSuspendClipboard(void) | |
987 | } | |
985 | # | |
986 | # Slot 40 unused (WAS: TkSuspendClipboard) | |
987 | # | |
988 | 988 | declare 41 aqua { |
989 | 989 | int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart) |
990 | 990 | } |
223 | 223 | EXTERN int TkSetMacColor(unsigned long pixel, void *macColor); |
224 | 224 | /* 39 */ |
225 | 225 | EXTERN void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid); |
226 | /* 40 */ | |
227 | EXTERN void TkSuspendClipboard(void); | |
226 | /* Slot 40 is reserved */ | |
228 | 227 | /* 41 */ |
229 | 228 | EXTERN int TkMacOSXZoomToplevel(void *whichWindow, |
230 | 229 | short zoomPart); |
383 | 382 | void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */ |
384 | 383 | int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */ |
385 | 384 | void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */ |
386 | void (*tkSuspendClipboard) (void); /* 40 */ | |
385 | void (*reserved40)(void); | |
387 | 386 | int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */ |
388 | 387 | Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */ |
389 | 388 | MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */ |
598 | 597 | (tkIntPlatStubsPtr->tkSetMacColor) /* 38 */ |
599 | 598 | #define TkSetWMName \ |
600 | 599 | (tkIntPlatStubsPtr->tkSetWMName) /* 39 */ |
601 | #define TkSuspendClipboard \ | |
602 | (tkIntPlatStubsPtr->tkSuspendClipboard) /* 40 */ | |
600 | /* Slot 40 is reserved */ | |
603 | 601 | #define TkMacOSXZoomToplevel \ |
604 | 602 | (tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */ |
605 | 603 | #define Tk_TopCoordsToWindow \ |
1564 | 1564 | Tcl_Obj *errorResult = NULL; |
1565 | 1565 | int oldExport, error; |
1566 | 1566 | |
1567 | oldExport = listPtr->exportSelection; | |
1567 | oldExport = (listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp)); | |
1568 | 1568 | if (listPtr->listVarName != NULL) { |
1569 | 1569 | Tcl_UntraceVar2(interp, listPtr->listVarName, NULL, |
1570 | 1570 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, |
1606 | 1606 | |
1607 | 1607 | /* |
1608 | 1608 | * Claim the selection if we've suddenly started exporting it and |
1609 | * there is a selection to export. | |
1609 | * there is a selection to export and this interp is unsafe. | |
1610 | 1610 | */ |
1611 | 1611 | |
1612 | if (listPtr->exportSelection && !oldExport | |
1612 | if (listPtr->exportSelection && (!oldExport) | |
1613 | && (!Tcl_IsSafe(listPtr->interp)) | |
1613 | 1614 | && (listPtr->numSelected != 0)) { |
1614 | 1615 | Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, |
1615 | 1616 | ListboxLostSelection, listPtr); |
3078 | 3079 | EventuallyRedrawRange(listPtr, first, last); |
3079 | 3080 | } |
3080 | 3081 | if ((oldCount == 0) && (listPtr->numSelected > 0) |
3081 | && listPtr->exportSelection) { | |
3082 | && (listPtr->exportSelection) | |
3083 | && (!Tcl_IsSafe(listPtr->interp))) { | |
3082 | 3084 | Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, |
3083 | 3085 | ListboxLostSelection, listPtr); |
3084 | 3086 | } |
3124 | 3126 | const char *stringRep; |
3125 | 3127 | Tcl_HashEntry *entry; |
3126 | 3128 | |
3127 | if (!listPtr->exportSelection) { | |
3129 | if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) { | |
3128 | 3130 | return -1; |
3129 | 3131 | } |
3130 | 3132 | |
3195 | 3197 | { |
3196 | 3198 | register Listbox *listPtr = clientData; |
3197 | 3199 | |
3198 | if ((listPtr->exportSelection) && (listPtr->nElements > 0)) { | |
3200 | if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp)) | |
3201 | && (listPtr->nElements > 0)) { | |
3199 | 3202 | ListboxSelect(listPtr, 0, listPtr->nElements-1, 0); |
3200 | 3203 | GenerateListboxSelectEvent(listPtr); |
3201 | 3204 | } |
3427 | 3430 | ListboxListVarProc( |
3428 | 3431 | ClientData clientData, /* Information about button. */ |
3429 | 3432 | Tcl_Interp *interp, /* Interpreter containing variable. */ |
3430 | const char *name1, /* Not used. */ | |
3431 | const char *name2, /* Not used. */ | |
3433 | const char *name1, /* Name of variable. */ | |
3434 | const char *name2, /* Second part of variable name. */ | |
3432 | 3435 | int flags) /* Information about what happened. */ |
3433 | 3436 | { |
3434 | 3437 | Listbox *listPtr = clientData; |
3435 | 3438 | Tcl_Obj *oldListObj, *varListObj; |
3436 | 3439 | int oldLength, i; |
3437 | 3440 | Tcl_HashEntry *entry; |
3441 | ||
3442 | /* | |
3443 | * See ticket [5d991b82]. | |
3444 | */ | |
3445 | ||
3446 | if (listPtr->listVarName == NULL) { | |
3447 | if (!(flags & TCL_INTERP_DESTROYED)) { | |
3448 | Tcl_UntraceVar2(interp, name1, name2, | |
3449 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
3450 | ListboxListVarProc, clientData); | |
3451 | } | |
3452 | return NULL; | |
3453 | } | |
3438 | 3454 | |
3439 | 3455 | /* |
3440 | 3456 | * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable! |
235 | 235 | Tcl_Preserve(interp); |
236 | 236 | |
237 | 237 | #if defined(_WIN32) && !defined(__CYGWIN__) |
238 | #if !defined(STATIC_BUILD) | |
239 | /* If compiled for Win32 but running on Cygwin, don't use console */ | |
240 | if (!tclStubsPtr->reserved9) | |
241 | #endif | |
238 | 242 | Tk_InitConsoleChannels(interp); |
239 | 243 | #endif |
240 | 244 |
1699 | 1699 | if (mePtr->labelPtr == NULL) { |
1700 | 1700 | mePtr->labelLength = 0; |
1701 | 1701 | } else { |
1702 | (void)Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength); | |
1702 | Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength); | |
1703 | 1703 | } |
1704 | 1704 | if (mePtr->accelPtr == NULL) { |
1705 | 1705 | mePtr->accelLength = 0; |
1706 | 1706 | } else { |
1707 | (void)Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength); | |
1707 | Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength); | |
1708 | 1708 | } |
1709 | 1709 | |
1710 | 1710 | /* |
2494 | 2494 | } |
2495 | 2495 | |
2496 | 2496 | menuPtr = mePtr->menuPtr; |
2497 | ||
2498 | if (menuPtr->menuFlags & MENU_DELETION_PENDING) { | |
2499 | return NULL; | |
2500 | } | |
2501 | ||
2502 | /* | |
2503 | * See ticket [5d991b82]. | |
2504 | */ | |
2505 | ||
2506 | if (mePtr->namePtr == NULL) { | |
2507 | Tcl_UntraceVar2(interp, name1, name2, | |
2508 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
2509 | MenuVarProc, clientData); | |
2510 | return NULL; | |
2511 | } | |
2512 | ||
2497 | 2513 | name = Tcl_GetString(mePtr->namePtr); |
2498 | 2514 | |
2499 | 2515 | /* |
623 | 623 | int width; |
624 | 624 | int borderWidth; |
625 | 625 | Tk_3DBorder border; |
626 | int activeBorderWidth; | |
627 | 626 | int relief; |
628 | 627 | |
629 | 628 | |
635 | 634 | Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, |
636 | 635 | &borderWidth); |
637 | 636 | border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); |
638 | Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, | |
639 | menuPtr->activeBorderWidthPtr, &activeBorderWidth); | |
640 | 637 | |
641 | 638 | if (menuPtr->menuType == MENUBAR) { |
642 | 639 | Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth, |
667 | 664 | } |
668 | 665 | mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY; |
669 | 666 | |
670 | if (menuPtr->menuType == MENUBAR) { | |
671 | width = mePtr->width; | |
672 | } else { | |
673 | if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { | |
674 | width = Tk_Width(menuPtr->tkwin) - mePtr->x | |
675 | - activeBorderWidth; | |
676 | } else { | |
677 | width = mePtr->width + borderWidth; | |
678 | } | |
679 | } | |
680 | 667 | TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont, |
681 | &menuMetrics, mePtr->x, mePtr->y, width, | |
668 | &menuMetrics, mePtr->x, mePtr->y, mePtr->width, | |
682 | 669 | mePtr->height, strictMotif, 1); |
683 | 670 | if ((index > 0) && (menuPtr->menuType != MENUBAR) |
684 | 671 | && mePtr->columnBreak) { |
685 | 672 | mePtr = menuPtr->entries[index - 1]; |
686 | 673 | Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, |
687 | mePtr->x, mePtr->y + mePtr->height, | |
688 | mePtr->width, | |
689 | Tk_Height(tkwin) - mePtr->y - mePtr->height - | |
690 | activeBorderWidth, 0, | |
691 | TK_RELIEF_FLAT); | |
674 | mePtr->x, mePtr->y + mePtr->height, mePtr->width, | |
675 | Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth, | |
676 | 0, TK_RELIEF_FLAT); | |
692 | 677 | } |
693 | 678 | } |
694 | 679 | |
697 | 682 | |
698 | 683 | if (menuPtr->numEntries == 0) { |
699 | 684 | x = y = borderWidth; |
700 | width = Tk_Width(tkwin) - 2 * activeBorderWidth; | |
701 | height = Tk_Height(tkwin) - 2 * activeBorderWidth; | |
685 | width = Tk_Width(tkwin) - 2 * borderWidth; | |
686 | height = Tk_Height(tkwin) - 2 * borderWidth; | |
702 | 687 | } else { |
703 | 688 | mePtr = menuPtr->entries[menuPtr->numEntries - 1]; |
704 | 689 | Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), |
705 | 690 | border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, |
706 | Tk_Height(tkwin) - mePtr->y - mePtr->height | |
707 | - activeBorderWidth, 0, | |
708 | TK_RELIEF_FLAT); | |
691 | Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth, | |
692 | 0, TK_RELIEF_FLAT); | |
709 | 693 | x = mePtr->x + mePtr->width; |
710 | 694 | y = mePtr->y + mePtr->height; |
711 | width = Tk_Width(tkwin) - x - activeBorderWidth; | |
712 | height = Tk_Height(tkwin) - y - activeBorderWidth; | |
695 | width = Tk_Width(tkwin) - x - borderWidth; | |
696 | height = Tk_Height(tkwin) - y - borderWidth; | |
713 | 697 | } |
714 | 698 | Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y, |
715 | 699 | width, height, 0, TK_RELIEF_FLAT); |
881 | 881 | unsigned len; |
882 | 882 | |
883 | 883 | /* |
884 | * See ticket [5d991b82]. | |
885 | */ | |
886 | ||
887 | if (mbPtr->textVarName == NULL) { | |
888 | if (!(flags & TCL_INTERP_DESTROYED)) { | |
889 | Tcl_UntraceVar2(interp, name1, name2, | |
890 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
891 | MenuButtonTextVarProc, clientData); | |
892 | } | |
893 | return NULL; | |
894 | } | |
895 | ||
896 | /* | |
884 | 897 | * If the variable is unset, then immediately recreate it unless the whole |
885 | 898 | * interpreter is going away. |
886 | 899 | */ |
838 | 838 | const char *value; |
839 | 839 | |
840 | 840 | /* |
841 | * See ticket [5d991b82]. | |
842 | */ | |
843 | ||
844 | if (msgPtr->textVarName == NULL) { | |
845 | if (!(flags & TCL_INTERP_DESTROYED)) { | |
846 | Tcl_UntraceVar2(interp, name1, name2, | |
847 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
848 | MessageTextVarProc, clientData); | |
849 | } | |
850 | return NULL; | |
851 | } | |
852 | ||
853 | /* | |
841 | 854 | * If the variable is unset, then immediately recreate it unless the whole |
842 | 855 | * interpreter is going away. |
843 | 856 | */ |
152 | 152 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
153 | 153 | |
154 | 154 | if (tsdPtr->doubleTypePtr == NULL) { |
155 | tsdPtr->doubleTypePtr = Tcl_GetObjType("double"); | |
156 | tsdPtr->intTypePtr = Tcl_GetObjType("int"); | |
155 | /* Smart initialization of doubleTypePtr/intTypePtr without | |
156 | * hash-table lookup or creating complete Tcl_Obj's */ | |
157 | Tcl_Obj obj; | |
158 | obj.length = 3; | |
159 | obj.bytes = (char *)"0.0"; | |
160 | obj.typePtr = NULL; | |
161 | Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue); | |
162 | tsdPtr->doubleTypePtr = obj.typePtr; | |
163 | obj.bytes += 2; | |
164 | obj.length = 1; | |
165 | obj.typePtr = NULL; | |
166 | Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue); | |
167 | tsdPtr->intTypePtr = obj.typePtr; | |
157 | 168 | } |
158 | 169 | return tsdPtr; |
159 | 170 | } |
656 | 667 | { |
657 | 668 | MMRep *mmPtr; |
658 | 669 | char buffer[TCL_DOUBLE_SPACE]; |
659 | register int len; | |
670 | size_t len; | |
660 | 671 | |
661 | 672 | mmPtr = objPtr->internalRep.twoPtrValue.ptr1; |
662 | 673 | /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */ |
665 | 676 | } |
666 | 677 | |
667 | 678 | Tcl_PrintDouble(NULL, mmPtr->value, buffer); |
668 | len = (int)strlen(buffer); | |
679 | len = strlen(buffer); | |
669 | 680 | |
670 | 681 | objPtr->bytes = ckalloc(len + 1); |
671 | 682 | strcpy(objPtr->bytes, buffer); |
880 | 891 | * Free the old internalRep before setting the new one. |
881 | 892 | */ |
882 | 893 | |
883 | (void)Tcl_GetString(objPtr); | |
894 | Tcl_GetString(objPtr); | |
884 | 895 | typePtr = objPtr->typePtr; |
885 | 896 | if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { |
886 | 897 | typePtr->freeIntRepProc(objPtr); |
171 | 171 | timPtr->interp = interp; |
172 | 172 | timPtr->width = 30; |
173 | 173 | timPtr->height = 15; |
174 | timPtr->imageName = ckalloc((unsigned) (strlen(name) + 1)); | |
174 | timPtr->imageName = ckalloc(strlen(name) + 1); | |
175 | 175 | strcpy(timPtr->imageName, name); |
176 | timPtr->varName = ckalloc((unsigned) (strlen(varName) + 1)); | |
176 | timPtr->varName = ckalloc(strlen(varName) + 1); | |
177 | 177 | strcpy(timPtr->varName, varName); |
178 | 178 | Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL); |
179 | 179 | *clientDataPtr = timPtr; |
995 | 995 | while ((*src == ' ') || (*src == '\t')) { |
996 | 996 | src++; |
997 | 997 | } |
998 | if (*src == '\\' && (src[1] == '\t' || src[1] == ' ')) { | |
999 | src++; | |
1000 | } | |
998 | 1001 | if (*src == '\0') { |
999 | 1002 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
1000 | 1003 | "missing value on line %d", lineNum)); |
1024 | 1027 | src += 2; |
1025 | 1028 | *dst++ = '\n'; |
1026 | 1029 | continue; |
1027 | } else if (src[1] == '\t' || src[1] == ' ' || src[1] == '\\') { | |
1030 | } else if (src[1] == '\\') { | |
1028 | 1031 | ++src; |
1029 | 1032 | } else if (src[1] >= '0' && src[1] <= '3' && src[2] >= '0' && |
1030 | 1033 | src[2] <= '9' && src[3] >= '0' && src[3] <= '9') { |
1361 | 1361 | * handling it and should mark it as free. |
1362 | 1362 | */ |
1363 | 1363 | |
1364 | if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) { | |
1364 | if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) { | |
1365 | 1365 | TkFreeGeometryMaster(masterPtr->tkwin, "pack"); |
1366 | 1366 | masterPtr->flags &= ~ALLOCED_MASTER; |
1367 | 1367 | } |
2991 | 2991 | ObjectIsEmpty( |
2992 | 2992 | Tcl_Obj *objPtr) /* Object to test. May be NULL. */ |
2993 | 2993 | { |
2994 | int length; | |
2995 | ||
2996 | 2994 | if (objPtr == NULL) { |
2997 | 2995 | return 1; |
2998 | 2996 | } |
2999 | if (objPtr->bytes != NULL) { | |
3000 | return (objPtr->length == 0); | |
3001 | } | |
3002 | (void)Tcl_GetStringFromObj(objPtr, &length); | |
3003 | return (length == 0); | |
2997 | if (objPtr->bytes == NULL) { | |
2998 | Tcl_GetString(objPtr); | |
2999 | } | |
3000 | return (objPtr->length == 0); | |
3004 | 3001 | } |
3005 | 3002 | |
3006 | 3003 | /* |
1192 | 1192 | int result; |
1193 | 1193 | |
1194 | 1194 | /* |
1195 | * See ticket [5d991b82]. | |
1196 | */ | |
1197 | ||
1198 | if (scalePtr->varNamePtr == NULL) { | |
1199 | if (!(flags & TCL_INTERP_DESTROYED)) { | |
1200 | Tcl_UntraceVar2(interp, name1, name2, | |
1201 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
1202 | ScaleVarProc, clientData); | |
1203 | } | |
1204 | return NULL; | |
1205 | } | |
1206 | ||
1207 | /* | |
1195 | 1208 | * If the variable is unset, then immediately recreate it unless the whole |
1196 | 1209 | * interpreter is going away. |
1197 | 1210 | */ |
72 | 72 | * values. 0 means we get to choose the number |
73 | 73 | * based on resolution and/or the range of the |
74 | 74 | * scale. */ |
75 | char format[10]; /* Sprintf conversion specifier computed from | |
75 | char format[16]; /* Sprintf conversion specifier computed from | |
76 | 76 | * digits and other information. */ |
77 | 77 | double bigIncrement; /* Amount to use for large increments to scale |
78 | 78 | * value. (0 means we pick a value). */ |
546 | 546 | TkMacOSXWindowOffset, /* 37 */ |
547 | 547 | TkSetMacColor, /* 38 */ |
548 | 548 | TkSetWMName, /* 39 */ |
549 | TkSuspendClipboard, /* 40 */ | |
549 | 0, /* 40 */ | |
550 | 550 | TkMacOSXZoomToplevel, /* 41 */ |
551 | 551 | Tk_TopCoordsToWindow, /* 42 */ |
552 | 552 | TkMacOSXContainerId, /* 43 */ |
30 | 30 | #if defined(MAC_OSX_TK) |
31 | 31 | #include "tkMacOSXInt.h" |
32 | 32 | #include "tkScrollbar.h" |
33 | #define SIMULATE_DRAWING TkTestSimulateDrawing(true); | |
34 | #else | |
35 | #define SIMULATE_DRAWING | |
33 | 36 | #endif |
34 | 37 | |
35 | 38 | #ifdef __UNIX__ |
167 | 170 | Tcl_Interp *interp, int objc, |
168 | 171 | Tcl_Obj *const objv[]); |
169 | 172 | #endif |
170 | #if defined(_WIN32) || defined(MAC_OSX_TK) | |
173 | #if defined(_WIN32) | |
171 | 174 | static int TestmetricsObjCmd(ClientData dummy, |
172 | 175 | Tcl_Interp *interp, int objc, |
173 | 176 | Tcl_Obj * const objv[]); |
265 | 268 | Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd, |
266 | 269 | (ClientData) Tk_MainWindow(interp), NULL); |
267 | 270 | |
268 | #if defined(_WIN32) || defined(MAC_OSX_TK) | |
271 | #if defined(_WIN32) | |
269 | 272 | Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd, |
270 | 273 | (ClientData) Tk_MainWindow(interp), NULL); |
271 | #elif !defined(__CYGWIN__) | |
274 | #elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK) | |
272 | 275 | Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd, |
273 | 276 | (ClientData) Tk_MainWindow(interp), NULL); |
274 | 277 | Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd, |
275 | 278 | (ClientData) Tk_MainWindow(interp), NULL); |
276 | 279 | Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd, |
277 | 280 | (ClientData) Tk_MainWindow(interp), NULL); |
278 | #endif /* _WIN32 || MAC_OSX_TK */ | |
281 | #endif /* _WIN32 */ | |
279 | 282 | |
280 | 283 | /* |
281 | 284 | * Create test image type. |
1549 | 1552 | TImageInstance *instPtr = (TImageInstance *) clientData; |
1550 | 1553 | char buffer[200 + TCL_INTEGER_SPACE * 6]; |
1551 | 1554 | |
1552 | sprintf(buffer, "%s display %d %d %d %d %d %d", | |
1553 | instPtr->masterPtr->imageName, imageX, imageY, width, height, | |
1554 | drawableX, drawableY); | |
1555 | /* | |
1556 | * The purpose of the test image type is to track the calls to an image | |
1557 | * display proc and record the parameters passed in each call. On macOS | |
1558 | * these tests will fail because of the asynchronous drawing. The low | |
1559 | * level graphics calls below which are supposed to draw a rectangle will | |
1560 | * not draw anything to the screen because the idle task will not be | |
1561 | * processed inside of the drawRect method and hence will not be able to | |
1562 | * obtain a valid graphics context. Instead, the window will be marked as | |
1563 | * needing display, and will be redrawn during a future asynchronous call | |
1564 | * to drawRect. This will generate an other call to this display proc, | |
1565 | * and the recorded data will show extra calls, causing the test to fail. | |
1566 | * To avoid this, we can set the [NSApp simulateDrawing] flag, which will | |
1567 | * cause all low level drawing routines to return immediately and not | |
1568 | * schedule the window for drawing later. This flag is cleared by the | |
1569 | * next call to XSync, which is called by the update command. | |
1570 | */ | |
1571 | ||
1572 | sprintf(buffer, "%s display %d %d %d %d", | |
1573 | instPtr->masterPtr->imageName, imageX, imageY, width, height); | |
1555 | 1574 | Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL, |
1556 | buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); | |
1575 | buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); | |
1557 | 1576 | if (width > (instPtr->masterPtr->width - imageX)) { |
1558 | 1577 | width = instPtr->masterPtr->width - imageX; |
1559 | 1578 | } |
1560 | 1579 | if (height > (instPtr->masterPtr->height - imageY)) { |
1561 | 1580 | height = instPtr->masterPtr->height - imageY; |
1562 | 1581 | } |
1582 | ||
1583 | SIMULATE_DRAWING | |
1563 | 1584 | XDrawRectangle(display, drawable, instPtr->gc, drawableX, drawableY, |
1564 | 1585 | (unsigned) (width-1), (unsigned) (height-1)); |
1565 | 1586 | XDrawLine(display, drawable, instPtr->gc, drawableX, drawableY, |
1764 | 1785 | *---------------------------------------------------------------------- |
1765 | 1786 | */ |
1766 | 1787 | |
1767 | #if defined(_WIN32) || defined(MAC_OSX_TK) | |
1788 | #if defined(_WIN32) | |
1768 | 1789 | static int |
1769 | 1790 | TestmetricsObjCmd( |
1770 | 1791 | ClientData clientData, /* Main window for application. */ |
1775 | 1796 | char buf[TCL_INTEGER_SPACE]; |
1776 | 1797 | int val; |
1777 | 1798 | |
1778 | #ifdef _WIN32 | |
1779 | 1799 | if (objc < 2) { |
1780 | 1800 | Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); |
1781 | 1801 | return TCL_ERROR; |
1782 | 1802 | } |
1783 | #else | |
1784 | Tk_Window tkwin = (Tk_Window) clientData; | |
1785 | TkWindow *winPtr; | |
1786 | ||
1787 | if (objc != 3) { | |
1788 | Tcl_WrongNumArgs(interp, 1, objv, "option window"); | |
1789 | return TCL_ERROR; | |
1790 | } | |
1791 | ||
1792 | winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); | |
1793 | if (winPtr == NULL) { | |
1794 | return TCL_ERROR; | |
1795 | } | |
1796 | #endif | |
1797 | 1803 | |
1798 | 1804 | if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) { |
1799 | #ifdef _WIN32 | |
1800 | 1805 | val = GetSystemMetrics(SM_CYVSCROLL); |
1801 | #else | |
1802 | val = ((TkScrollbar *) winPtr->instanceData)->width; | |
1803 | #endif | |
1804 | 1806 | } else if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) { |
1805 | #ifdef _WIN32 | |
1806 | 1807 | val = GetSystemMetrics(SM_CXHSCROLL); |
1807 | #else | |
1808 | val = ((TkScrollbar *) winPtr->instanceData)->width; | |
1809 | #endif | |
1810 | 1808 | } else { |
1811 | 1809 | Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), |
1812 | 1810 | "\": must be cxhscroll or cyvscroll", NULL); |
863 | 863 | } |
864 | 864 | |
865 | 865 | for (i = 2; i < objc-2; i++) { |
866 | int value, length; | |
866 | int value; | |
867 | size_t length; | |
867 | 868 | const char *option = Tcl_GetString(objv[i]); |
868 | 869 | char c; |
869 | 870 | |
872 | 873 | goto badOption; |
873 | 874 | } |
874 | 875 | c = option[1]; |
875 | if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) { | |
876 | if (c == 'c' && !strncmp("-chars", option, length)) { | |
876 | 877 | value = CountIndices(textPtr, indexFromPtr, indexToPtr, |
877 | 878 | COUNT_CHARS); |
878 | 879 | } else if (c == 'd' && (length > 8) |
879 | && !strncmp("-displaychars", option, (unsigned) length)) { | |
880 | && !strncmp("-displaychars", option, length)) { | |
880 | 881 | value = CountIndices(textPtr, indexFromPtr, indexToPtr, |
881 | 882 | COUNT_DISPLAY_CHARS); |
882 | 883 | } else if (c == 'd' && (length > 8) |
883 | && !strncmp("-displayindices", option,(unsigned)length)) { | |
884 | && !strncmp("-displayindices", option,length)) { | |
884 | 885 | value = CountIndices(textPtr, indexFromPtr, indexToPtr, |
885 | 886 | COUNT_DISPLAY_INDICES); |
886 | 887 | } else if (c == 'd' && (length > 8) |
887 | && !strncmp("-displaylines", option, (unsigned) length)) { | |
888 | && !strncmp("-displaylines", option, length)) { | |
888 | 889 | TkTextLine *fromPtr, *lastPtr; |
889 | 890 | TkTextIndex index, index2; |
890 | 891 | |
982 | 983 | value = -value; |
983 | 984 | } |
984 | 985 | } else if (c == 'i' |
985 | && !strncmp("-indices", option, (unsigned) length)) { | |
986 | && !strncmp("-indices", option, length)) { | |
986 | 987 | value = CountIndices(textPtr, indexFromPtr, indexToPtr, |
987 | 988 | COUNT_INDICES); |
988 | 989 | } else if (c == 'l' |
989 | && !strncmp("-lines", option, (unsigned) length)) { | |
990 | && !strncmp("-lines", option, length)) { | |
990 | 991 | value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr) |
991 | 992 | - TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); |
992 | 993 | } else if (c == 'u' |
993 | && !strncmp("-update", option, (unsigned) length)) { | |
994 | && !strncmp("-update", option, length)) { | |
994 | 995 | update = 1; |
995 | 996 | continue; |
996 | 997 | } else if (c == 'x' |
997 | && !strncmp("-xpixels", option, (unsigned) length)) { | |
998 | && !strncmp("-xpixels", option, length)) { | |
998 | 999 | int x1, x2; |
999 | 1000 | TkTextIndex index; |
1000 | 1001 | |
1004 | 1005 | TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2); |
1005 | 1006 | value = x2 - x1; |
1006 | 1007 | } else if (c == 'y' |
1007 | && !strncmp("-ypixels", option, (unsigned) length)) { | |
1008 | && !strncmp("-ypixels", option, length)) { | |
1008 | 1009 | if (update) { |
1009 | 1010 | TkTextUpdateLineMetrics(textPtr, |
1010 | 1011 | TkBTreeLinesTo(textPtr, indexFromPtr->linePtr), |
1154 | 1155 | objc++; |
1155 | 1156 | } |
1156 | 1157 | useIdx = ckalloc(objc); |
1157 | memset(useIdx, 0, (unsigned) objc); | |
1158 | memset(useIdx, 0, (size_t) objc); | |
1158 | 1159 | |
1159 | 1160 | /* |
1160 | 1161 | * Do a decreasing order sort so that we delete the end ranges |
1161 | 1162 | * first to maintain index consistency. |
1162 | 1163 | */ |
1163 | 1164 | |
1164 | qsort(indices, (unsigned) objc / 2, | |
1165 | qsort(indices, (size_t) objc / 2, | |
1165 | 1166 | 2 * sizeof(TkTextIndex), TextIndexSortProc); |
1166 | 1167 | lastStart = NULL; |
1167 | 1168 | |
1259 | 1260 | Tcl_Obj *objPtr = NULL; |
1260 | 1261 | int i, found = 0, visible = 0; |
1261 | 1262 | const char *name; |
1262 | int length; | |
1263 | size_t length; | |
1263 | 1264 | |
1264 | 1265 | if (objc < 3) { |
1265 | 1266 | Tcl_WrongNumArgs(interp, 2, objv, |
1278 | 1279 | name = Tcl_GetString(objv[i]); |
1279 | 1280 | length = objv[i]->length; |
1280 | 1281 | if (length > 1 && name[0] == '-') { |
1281 | if (strncmp("-displaychars", name, (unsigned) length) == 0) { | |
1282 | if (strncmp("-displaychars", name, length) == 0) { | |
1282 | 1283 | i++; |
1283 | 1284 | visible = 1; |
1284 | 1285 | name = Tcl_GetString(objv[i]); |
1464 | 1465 | * unnecessarily. |
1465 | 1466 | */ |
1466 | 1467 | |
1467 | int deleteInsertOffset, insertLength, j; | |
1468 | int deleteInsertOffset, insertLength, j, indexFromLine, indexFromByteOffset; | |
1468 | 1469 | |
1469 | 1470 | insertLength = 0; |
1470 | 1471 | for (j = 4; j < objc; j += 2) { |
1482 | 1483 | deleteInsertOffset = insertLength; |
1483 | 1484 | } |
1484 | 1485 | |
1486 | indexFromLine = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); | |
1487 | indexFromByteOffset = indexFromPtr->byteIndex; | |
1488 | ||
1485 | 1489 | result = TextReplaceCmd(textPtr, interp, indexFromPtr, |
1486 | 1490 | indexToPtr, objc, objv, 0); |
1487 | 1491 | |
1490 | 1494 | * Move the insertion position to the correct place. |
1491 | 1495 | */ |
1492 | 1496 | |
1493 | indexFromPtr = TkTextGetIndexFromObj(interp, textPtr, objv[2]); | |
1494 | TkTextIndexForwChars(NULL, indexFromPtr, | |
1497 | TkTextIndex indexTmp; | |
1498 | ||
1499 | TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, indexFromLine, | |
1500 | indexFromByteOffset, &indexTmp); | |
1501 | TkTextIndexForwChars(NULL, &indexTmp, | |
1495 | 1502 | deleteInsertOffset, &index, COUNT_INDICES); |
1496 | 1503 | TkBTreeUnlinkSegment(textPtr->insertMarkPtr, |
1497 | 1504 | textPtr->insertMarkPtr->body.mark.linePtr); |
2077 | 2084 | Tcl_Obj *const objv[]) /* Argument objects. */ |
2078 | 2085 | { |
2079 | 2086 | Tk_SavedOptions savedOptions; |
2080 | int oldExport = textPtr->exportSelection; | |
2087 | int oldExport = (textPtr->exportSelection) && (!Tcl_IsSafe(textPtr->interp)); | |
2081 | 2088 | int mask = 0; |
2082 | 2089 | |
2083 | 2090 | if (Tk_SetOptions(interp, (char *) textPtr, textPtr->optionTable, |
2306 | 2313 | * are tagged characters. |
2307 | 2314 | */ |
2308 | 2315 | |
2309 | if (textPtr->exportSelection && (!oldExport)) { | |
2316 | if (textPtr->exportSelection && (!oldExport) && (!Tcl_IsSafe(textPtr->interp))) { | |
2310 | 2317 | TkTextSearch search; |
2311 | 2318 | TkTextIndex first, last; |
2312 | 2319 | |
2626 | 2633 | * information to add to text. */ |
2627 | 2634 | int viewUpdate) /* Update the view if set. */ |
2628 | 2635 | { |
2629 | int lineIndex, length; | |
2636 | int lineIndex; | |
2637 | size_t length; | |
2630 | 2638 | TkText *tPtr; |
2631 | 2639 | int *lineAndByteIndex; |
2632 | 2640 | int resetViewCount; |
2725 | 2733 | } |
2726 | 2734 | |
2727 | 2735 | /* |
2728 | * Invalidate any selection retrievals in progress. | |
2736 | * Invalidate any selection retrievals in progress, and send an event | |
2737 | * that the selection changed if that is the case. | |
2729 | 2738 | */ |
2730 | 2739 | |
2731 | 2740 | for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { |
2741 | if (TkBTreeCharTagged(indexPtr, tPtr->selTagPtr)) { | |
2742 | TkTextSelectionEvent(tPtr); | |
2743 | } | |
2732 | 2744 | tPtr->abortSelections = 1; |
2733 | 2745 | } |
2734 | 2746 | |
3068 | 3080 | int *lineAndByteIndex; |
3069 | 3081 | int resetViewCount; |
3070 | 3082 | int pixels[2*PIXEL_CLIENTS]; |
3083 | Tcl_HashSearch search; | |
3084 | Tcl_HashEntry *hPtr; | |
3085 | int i; | |
3071 | 3086 | |
3072 | 3087 | if (sharedTextPtr == NULL) { |
3073 | 3088 | sharedTextPtr = textPtr->sharedTextPtr; |
3132 | 3147 | } |
3133 | 3148 | } |
3134 | 3149 | |
3135 | if (line1 < line2) { | |
3136 | /* | |
3137 | * We are deleting more than one line. For speed, we remove all tags | |
3138 | * from the range first. If we don't do this, the code below can (when | |
3139 | * there are many tags) grow non-linearly in execution time. | |
3140 | */ | |
3141 | ||
3142 | Tcl_HashSearch search; | |
3143 | Tcl_HashEntry *hPtr; | |
3144 | int i; | |
3145 | ||
3146 | for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); | |
3147 | hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { | |
3148 | TkTextTag *tagPtr = Tcl_GetHashValue(hPtr); | |
3149 | ||
3150 | TkBTreeTag(&index1, &index2, tagPtr, 0); | |
3151 | } | |
3152 | ||
3153 | /* | |
3154 | * Special case for the sel tag which is not in the hash table. We | |
3155 | * need to do this once for each peer text widget. | |
3156 | */ | |
3157 | ||
3158 | for (tPtr = sharedTextPtr->peers; tPtr != NULL ; | |
3159 | tPtr = tPtr->next) { | |
3160 | if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) { | |
3161 | /* | |
3162 | * Send an event that the selection changed. This is | |
3163 | * equivalent to: | |
3164 | * event generate $textWidget <<Selection>> | |
3165 | */ | |
3166 | ||
3167 | TkTextSelectionEvent(textPtr); | |
3168 | tPtr->abortSelections = 1; | |
3169 | } | |
3170 | } | |
3150 | /* | |
3151 | * For speed, we remove all tags from the range first. If we don't | |
3152 | * do this, the code below can (when there are many tags) grow | |
3153 | * non-linearly in execution time. | |
3154 | */ | |
3155 | ||
3156 | for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); | |
3157 | hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { | |
3158 | TkTextTag *tagPtr = Tcl_GetHashValue(hPtr); | |
3159 | ||
3160 | TkBTreeTag(&index1, &index2, tagPtr, 0); | |
3161 | } | |
3162 | ||
3163 | /* | |
3164 | * Special case for the sel tag which is not in the hash table. We | |
3165 | * need to do this once for each peer text widget. | |
3166 | */ | |
3167 | ||
3168 | for (tPtr = sharedTextPtr->peers; tPtr != NULL ; | |
3169 | tPtr = tPtr->next) { | |
3170 | if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) { | |
3171 | /* | |
3172 | * Send an event that the selection changed. This is | |
3173 | * equivalent to: | |
3174 | * event generate $textWidget <<Selection>> | |
3175 | */ | |
3176 | ||
3177 | TkTextSelectionEvent(textPtr); | |
3178 | tPtr->abortSelections = 1; | |
3179 | } | |
3171 | 3180 | } |
3172 | 3181 | |
3173 | 3182 | /* |
3377 | 3386 | TkTextSearch search; |
3378 | 3387 | TkTextSegment *segPtr; |
3379 | 3388 | |
3380 | if (!textPtr->exportSelection) { | |
3389 | if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) { | |
3381 | 3390 | return -1; |
3382 | 3391 | } |
3383 | 3392 | |
3507 | 3516 | if (TkpAlwaysShowSelection(textPtr->tkwin)) { |
3508 | 3517 | TkTextIndex start, end; |
3509 | 3518 | |
3510 | if (!textPtr->exportSelection) { | |
3519 | if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) { | |
3511 | 3520 | return; |
3512 | 3521 | } |
3513 | 3522 | |
4174 | 4183 | |
4175 | 4184 | if (lenPtr != NULL) { |
4176 | 4185 | if (searchSpecPtr->exact) { |
4177 | (void)Tcl_GetString(theLine); | |
4186 | Tcl_GetString(theLine); | |
4178 | 4187 | *lenPtr = theLine->length; |
4179 | 4188 | } else { |
4180 | 4189 | *lenPtr = Tcl_GetCharLength(theLine); |
4699 | 4708 | if (objc == arg) { |
4700 | 4709 | TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES); |
4701 | 4710 | } else { |
4702 | int length; | |
4711 | size_t length; | |
4703 | 4712 | const char *str; |
4704 | 4713 | |
4705 | 4714 | if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) { |
4707 | 4716 | } |
4708 | 4717 | str = Tcl_GetString(objv[arg]); |
4709 | 4718 | length = objv[arg]->length; |
4710 | if (strncmp(str, "end", (unsigned) length) == 0) { | |
4719 | if (strncmp(str, "end", length) == 0) { | |
4711 | 4720 | atEnd = 1; |
4712 | 4721 | } |
4713 | 4722 | } |
5813 | 5822 | firstOffset = 0; |
5814 | 5823 | } |
5815 | 5824 | |
5816 | if (alreadySearchOffset != -1) { | |
5825 | if (alreadySearchOffset >= 0) { | |
5817 | 5826 | if (searchSpecPtr->backwards) { |
5818 | 5827 | if (alreadySearchOffset < lastOffset) { |
5819 | 5828 | lastOffset = alreadySearchOffset; |
5902 | 5911 | * match. |
5903 | 5912 | */ |
5904 | 5913 | |
5905 | const char c = pattern[0]; | |
5906 | ||
5907 | if (alreadySearchOffset != -1) { | |
5914 | const char c = matchLength ? pattern[0] : '\0'; | |
5915 | ||
5916 | if (alreadySearchOffset >= 0) { | |
5908 | 5917 | p = startOfLine + alreadySearchOffset; |
5909 | 5918 | alreadySearchOffset = -1; |
5910 | 5919 | } else { |
5911 | 5920 | p = startOfLine + lastOffset -1; |
5912 | 5921 | } |
5913 | 5922 | while (p >= startOfLine + firstOffset) { |
5914 | if (p[0] == c && !strncmp(p, pattern, | |
5915 | (unsigned) matchLength)) { | |
5923 | if (matchLength == 0 || (p[0] == c && !strncmp( | |
5924 | p, pattern, (size_t) matchLength))) { | |
5916 | 5925 | goto backwardsMatch; |
5917 | 5926 | } |
5918 | 5927 | p--; |
6007 | 6016 | * result. |
6008 | 6017 | */ |
6009 | 6018 | |
6010 | if (strncmp(p,pattern,(unsigned)matchLength)) { | |
6019 | if (strncmp(p,pattern,(size_t)matchLength)) { | |
6011 | 6020 | p = NULL; |
6012 | 6021 | } |
6013 | 6022 | break; |
6075 | 6084 | if (firstNewLine != -1) { |
6076 | 6085 | break; |
6077 | 6086 | } else { |
6078 | alreadySearchOffset -= matchLength; | |
6087 | alreadySearchOffset -= (matchLength ? matchLength : 1); | |
6088 | if (alreadySearchOffset < 0) { | |
6089 | break; | |
6090 | } | |
6079 | 6091 | } |
6080 | 6092 | } else { |
6081 | firstOffset = p - startOfLine + matchLength; | |
6093 | firstOffset = matchLength ? p - startOfLine + matchLength | |
6094 | : p - startOfLine + 1; | |
6082 | 6095 | if (firstOffset >= lastOffset) { |
6083 | 6096 | /* |
6084 | 6097 | * Now, we have to be careful not to find |
6814 | 6827 | if (objPtr == NULL) { |
6815 | 6828 | return 1; |
6816 | 6829 | } |
6817 | if (objPtr->bytes != NULL) { | |
6818 | return (objPtr->length == 0); | |
6819 | } | |
6820 | (void)Tcl_GetString(objPtr); | |
6830 | if (objPtr->bytes == NULL) { | |
6831 | Tcl_GetString(objPtr); | |
6832 | } | |
6821 | 6833 | return (objPtr->length == 0); |
6822 | 6834 | } |
6823 | 6835 |
23 | 23 | |
24 | 24 | #ifdef MAC_OSX_TK |
25 | 25 | #include "tkMacOSXInt.h" |
26 | #define OK_TO_LOG (!TkpAppIsDrawing()) | |
27 | #define FORCE_DISPLAY(winPtr) TkpDisplayWindow(winPtr) | |
28 | #else | |
29 | #define OK_TO_LOG 1 | |
30 | #define FORCE_DISPLAY(winPtr) | |
26 | 31 | #endif |
27 | 32 | |
28 | 33 | /* |
202 | 207 | (fabs((double1)-(double2))*((scaleFactor)+1.0) < 0.3) |
203 | 208 | |
204 | 209 | /* |
205 | * Macro to make debugging/testing logging a little easier. | |
210 | * Macros to make debugging/testing logging a little easier. | |
211 | * | |
212 | * On OSX 10.14 Drawing procedures are sometimes run because the system has | |
213 | * decided to redraw the window. This can corrupt the data that a test is | |
214 | * trying to collect. So we don't write to the logging variables when the | |
215 | * drawing procedure is being run that way. Other systems can always log. | |
206 | 216 | */ |
207 | 217 | |
208 | #define LOG(toVar,what) \ | |
209 | Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \ | |
210 | TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT) | |
218 | #define LOG(toVar,what) \ | |
219 | if (OK_TO_LOG) \ | |
220 | Tcl_SetVar2(textPtr->interp, toVar, NULL, (what), \ | |
221 | TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT) | |
222 | #define CLEAR(var) \ | |
223 | if (OK_TO_LOG) \ | |
224 | Tcl_SetVar2(interp, var, NULL, "", TCL_GLOBAL_ONLY) | |
211 | 225 | |
212 | 226 | /* |
213 | 227 | * The following structure describes one line of the display, which may be |
3120 | 3134 | TkText *textPtr, /* Information about text widget. */ |
3121 | 3135 | Bool InSync) /* true if in sync, false otherwise */ |
3122 | 3136 | { |
3137 | /* | |
3138 | * OSX 10.14 needs to be told to display the window when the Text Widget | |
3139 | * is in sync. (That is, to run DisplayText inside of the drawRect | |
3140 | * method.) Otherwise the screen might not get updated until an event | |
3141 | * like a mouse click is received. But that extra drawing corrupts the | |
3142 | * data that the test suite is trying to collect. | |
3143 | */ | |
3144 | ||
3145 | if (!tkTextDebug) { | |
3146 | FORCE_DISPLAY(textPtr->tkwin); | |
3147 | } | |
3148 | ||
3123 | 3149 | TkSendVirtualEvent(textPtr->tkwin, "WidgetViewSync", |
3124 | 3150 | Tcl_NewBooleanObj(InSync)); |
3125 | 3151 | } |
4135 | 4161 | Tcl_Preserve(interp); |
4136 | 4162 | |
4137 | 4163 | if (tkTextDebug) { |
4138 | Tcl_SetVar2(interp, "tk_textRelayout", NULL, "", TCL_GLOBAL_ONLY); | |
4164 | CLEAR("tk_textRelayout"); | |
4139 | 4165 | } |
4140 | 4166 | |
4141 | 4167 | if (!Tk_IsMapped(textPtr->tkwin) || (dInfoPtr->maxX <= dInfoPtr->x) |
4146 | 4172 | } |
4147 | 4173 | numRedisplays++; |
4148 | 4174 | if (tkTextDebug) { |
4149 | Tcl_SetVar2(interp, "tk_textRedraw", NULL, "", TCL_GLOBAL_ONLY); | |
4175 | CLEAR("tk_textRedraw"); | |
4150 | 4176 | } |
4151 | 4177 | |
4152 | 4178 | /* |
5133 | 5159 | TextDInfo *dInfoPtr = textPtr->dInfoPtr; |
5134 | 5160 | GC newGC; |
5135 | 5161 | XGCValues gcValues; |
5162 | Bool inSync = 1; | |
5136 | 5163 | |
5137 | 5164 | /* |
5138 | 5165 | * Schedule the window redisplay. See TkTextChanged for the reason why |
5141 | 5168 | |
5142 | 5169 | if (!(dInfoPtr->flags & REDRAW_PENDING)) { |
5143 | 5170 | Tcl_DoWhenIdle(DisplayText, textPtr); |
5171 | inSync = 0; | |
5144 | 5172 | } |
5145 | 5173 | dInfoPtr->flags |= REDRAW_PENDING|REDRAW_BORDERS|DINFO_OUT_OF_DATE |
5146 | 5174 | |REPICK_NEEDED; |
5212 | 5240 | dInfoPtr->yScrollFirst = dInfoPtr->yScrollLast = -1; |
5213 | 5241 | |
5214 | 5242 | if (mask & TK_TEXT_LINE_GEOMETRY) { |
5243 | ||
5215 | 5244 | /* |
5216 | 5245 | * Set up line metric recalculation. |
5217 | 5246 | * |
5236 | 5265 | textPtr->refCount++; |
5237 | 5266 | dInfoPtr->lineUpdateTimer = Tcl_CreateTimerHandler(1, |
5238 | 5267 | AsyncUpdateLineMetrics, textPtr); |
5239 | GenerateWidgetViewSyncEvent(textPtr, 0); | |
5268 | inSync = 0; | |
5269 | } | |
5270 | ||
5271 | if (!inSync) { | |
5272 | GenerateWidgetViewSyncEvent(textPtr, 0); | |
5240 | 5273 | } |
5241 | 5274 | } |
5242 | 5275 | } |
133 | 133 | Tcl_Obj *objPtr) |
134 | 134 | { |
135 | 135 | char buffer[TK_POS_CHARS]; |
136 | register int len; | |
136 | size_t len; | |
137 | 137 | const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr); |
138 | 138 | |
139 | 139 | len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer); |
386 | 386 | TkTextSegment *segPtr; |
387 | 387 | int index; |
388 | 388 | const char *p, *start; |
389 | Tcl_UniChar ch; | |
389 | int ch; | |
390 | 390 | |
391 | 391 | indexPtr->tree = tree; |
392 | 392 | if (lineIndex < 0) { |
436 | 436 | |
437 | 437 | start = segPtr->body.chars + (byteIndex - index); |
438 | 438 | p = Tcl_UtfPrev(start, segPtr->body.chars); |
439 | p += Tcl_UtfToUniChar(p, &ch); | |
439 | p += TkUtfToUniChar(p, &ch); | |
440 | 440 | indexPtr->byteIndex += p - start; |
441 | 441 | } |
442 | 442 | break; |
479 | 479 | register TkTextSegment *segPtr; |
480 | 480 | char *p, *start, *end; |
481 | 481 | int index, offset; |
482 | Tcl_UniChar ch; | |
482 | int ch; | |
483 | 483 | |
484 | 484 | indexPtr->tree = tree; |
485 | 485 | if (lineIndex < 0) { |
526 | 526 | return indexPtr; |
527 | 527 | } |
528 | 528 | charIndex--; |
529 | offset = Tcl_UtfToUniChar(p, &ch); | |
529 | offset = TkUtfToUniChar(p, &ch); | |
530 | 530 | index += offset; |
531 | 531 | } |
532 | 532 | } else { |
1474 | 1474 | TkTextElideInfo *infoPtr = NULL; |
1475 | 1475 | int byteOffset; |
1476 | 1476 | char *start, *end, *p; |
1477 | Tcl_UniChar ch; | |
1477 | int ch; | |
1478 | 1478 | int elide = 0; |
1479 | 1479 | int checkElided = (type & COUNT_DISPLAY); |
1480 | 1480 | |
1573 | 1573 | if (segPtr->typePtr == &tkTextCharType) { |
1574 | 1574 | start = segPtr->body.chars + byteOffset; |
1575 | 1575 | end = segPtr->body.chars + segPtr->size; |
1576 | for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) { | |
1576 | for (p = start; p < end; p += TkUtfToUniChar(p, &ch)) { | |
1577 | 1577 | if (charCount == 0) { |
1578 | 1578 | dstPtr->byteIndex += (p - start); |
1579 | 1579 | goto forwardCharDone; |
242 | 242 | TkTextSelectionEvent(textPtr); |
243 | 243 | |
244 | 244 | if (addTag && textPtr->exportSelection |
245 | && (!Tcl_IsSafe(textPtr->interp)) | |
245 | 246 | && !(textPtr->flags & GOT_SELECTION)) { |
246 | 247 | Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, |
247 | 248 | TkTextLostSelection, textPtr); |
732 | 732 | size_t length = objv[2]->length; |
733 | 733 | |
734 | 734 | #define ArgPfxEq(str) \ |
735 | ((arg[0] == str[0]) && !strncmp(arg, str, (unsigned)length)) | |
735 | ((arg[0] == str[0]) && !strncmp(arg, str, length)) | |
736 | 736 | |
737 | 737 | if (ArgPfxEq("moveto")) { |
738 | 738 | if (objc != 4) { |
1259 | 1259 | int TkUniCharToUtf(int ch, char *buf) |
1260 | 1260 | { |
1261 | 1261 | int size = Tcl_UniCharToUtf(ch, buf); |
1262 | if ((ch > 0xffff) && (ch <= 0x10ffff) && (size < 4)) { | |
1262 | if ((((unsigned)(ch - 0x10000) <= 0xFFFFF)) && (size < 4)) { | |
1263 | 1263 | /* Hey, this is wrong, we must be running TCL_UTF_MAX==3 |
1264 | 1264 | * The best thing we can do is spit out 2 surrogates */ |
1265 | 1265 | ch -= 0x10000; |
2782 | 2782 | Tcl_Preserve(interp); |
2783 | 2783 | Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr); |
2784 | 2784 | Tcl_Release(interp); |
2785 | } | |
2786 | ||
2787 | /* | |
2788 | * Let error handlers catch up before actual close of displays. | |
2789 | * Must be done before tsdPtr->displayList is cleared, otherwise | |
2790 | * ErrorProc() in tkError.c cannot associate the pending X errors | |
2791 | * to the remaining error handlers. | |
2792 | */ | |
2793 | ||
2794 | for (dispPtr = tsdPtr->displayList; dispPtr != NULL; | |
2795 | dispPtr = dispPtr->nextPtr) { | |
2796 | XSync(dispPtr->display, False); | |
2785 | 2797 | } |
2786 | 2798 | |
2787 | 2799 | /* |
488 | 488 | CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask) |
489 | 489 | { |
490 | 490 | Checkbutton *checkPtr = recordPtr; |
491 | Ttk_TraceHandle *vt = Ttk_TraceVariable( | |
492 | interp, checkPtr->checkbutton.variableObj, | |
493 | CheckbuttonVariableChanged, checkPtr); | |
494 | ||
495 | if (!vt) { | |
496 | return TCL_ERROR; | |
491 | Tcl_Obj *varName = checkPtr->checkbutton.variableObj; | |
492 | Ttk_TraceHandle *vt = NULL; | |
493 | ||
494 | if (varName != NULL && *Tcl_GetString(varName) != '\0') { | |
495 | vt = Ttk_TraceVariable(interp, varName, | |
496 | CheckbuttonVariableChanged, checkPtr); | |
497 | if (!vt) { | |
498 | return TCL_ERROR; | |
499 | } | |
497 | 500 | } |
498 | 501 | |
499 | 502 | if (BaseConfigure(interp, recordPtr, mask) != TCL_OK){ |
501 | 504 | return TCL_ERROR; |
502 | 505 | } |
503 | 506 | |
504 | Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace); | |
507 | if (checkPtr->checkbutton.variableTrace) { | |
508 | Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace); | |
509 | } | |
505 | 510 | checkPtr->checkbutton.variableTrace = vt; |
506 | 511 | |
507 | 512 | return TCL_OK; |
547 | 552 | else |
548 | 553 | newValue = checkPtr->checkbutton.onValueObj; |
549 | 554 | |
550 | if (Tcl_ObjSetVar2(interp, | |
551 | checkPtr->checkbutton.variableObj, NULL, newValue, | |
552 | TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) | |
553 | == NULL) | |
555 | if (checkPtr->checkbutton.variableObj == NULL || | |
556 | *Tcl_GetString(checkPtr->checkbutton.variableObj) == '\0') | |
557 | CheckbuttonVariableChanged(checkPtr, Tcl_GetString(newValue)); | |
558 | else if (Tcl_ObjSetVar2(interp, | |
559 | checkPtr->checkbutton.variableObj, NULL, newValue, | |
560 | TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) | |
561 | == NULL) | |
554 | 562 | return TCL_ERROR; |
555 | 563 | |
556 | 564 | if (WidgetDestroyed(corePtr)) |
336 | 336 | const char *string; |
337 | 337 | const char *selStart, *selEnd; |
338 | 338 | |
339 | if (entryPtr->entry.selectFirst < 0 || !entryPtr->entry.exportSelection) { | |
339 | if (entryPtr->entry.selectFirst < 0 || (!entryPtr->entry.exportSelection) | |
340 | || Tcl_IsSafe(entryPtr->core.interp)) { | |
340 | 341 | return -1; |
341 | 342 | } |
342 | 343 | string = entryPtr->entry.displayString; |
371 | 372 | |
372 | 373 | /* EntryOwnSelection -- |
373 | 374 | * Assert ownership of the PRIMARY selection, |
374 | * if -exportselection set and selection is present. | |
375 | * if -exportselection set and selection is present and interp is unsafe. | |
375 | 376 | */ |
376 | 377 | static void EntryOwnSelection(Entry *entryPtr) |
377 | 378 | { |
378 | 379 | if (entryPtr->entry.exportSelection |
380 | && (!Tcl_IsSafe(entryPtr->core.interp)) | |
379 | 381 | && !(entryPtr->core.flags & GOT_SELECTION)) { |
380 | 382 | Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection, |
381 | 383 | (ClientData) entryPtr); |
998 | 1000 | |
999 | 1001 | /* Claim the selection, in case we've suddenly started exporting it. |
1000 | 1002 | */ |
1001 | if (entryPtr->entry.exportSelection && entryPtr->entry.selectFirst != -1) { | |
1003 | if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst != -1) | |
1004 | && (!Tcl_IsSafe(entryPtr->core.interp))) { | |
1002 | 1005 | EntryOwnSelection(entryPtr); |
1003 | 1006 | } |
1004 | 1007 | |
1240 | 1243 | /* Draw cursor: |
1241 | 1244 | */ |
1242 | 1245 | if (showCursor) { |
1246 | Ttk_Box field = Ttk_ClientRegion(entryPtr->core.layout, "field"); | |
1243 | 1247 | int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos), |
1244 | 1248 | cursorY = entryPtr->entry.layoutY, |
1245 | 1249 | cursorHeight = entryPtr->entry.layoutHeight, |
1253 | 1257 | /* @@@ should: maybe: SetCaretPos even when blinked off */ |
1254 | 1258 | Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight); |
1255 | 1259 | |
1256 | gc = EntryGetGC(entryPtr, es.insertColorObj, clipRegion); | |
1260 | cursorX -= cursorWidth/2; | |
1261 | if (cursorX < field.x) { | |
1262 | cursorX = field.x; | |
1263 | } else if (cursorX + cursorWidth > field.x + field.width) { | |
1264 | cursorX = field.x + field.width - cursorWidth; | |
1265 | } | |
1266 | ||
1267 | gc = EntryGetGC(entryPtr, es.insertColorObj, None); | |
1257 | 1268 | XFillRectangle(Tk_Display(tkwin), d, gc, |
1258 | cursorX-cursorWidth/2, cursorY, cursorWidth, cursorHeight); | |
1259 | XSetClipMask(Tk_Display(tkwin), gc, None); | |
1269 | cursorX, cursorY, cursorWidth, cursorHeight); | |
1260 | 1270 | Tk_FreeGC(Tk_Display(tkwin), gc); |
1261 | 1271 | } |
1262 | 1272 |
701 | 701 | if (childSpec) { |
702 | 702 | tail->child = Ttk_ParseLayoutTemplate(interp, childSpec); |
703 | 703 | if (!tail->child) { |
704 | Tcl_SetObjResult(interp, Tcl_ObjPrintf("Invalid -children value")); | |
705 | Tcl_SetErrorCode(interp, "TTK", "VALUE", "CHILDREN", NULL); | |
704 | 706 | goto error; |
705 | 707 | } |
706 | 708 | } |
420 | 420 | } |
421 | 421 | |
422 | 422 | newValueObj = Tcl_NewDoubleObj(value); |
423 | Tcl_IncrRefCount(newValueObj); | |
423 | 424 | |
424 | 425 | TtkRedisplayWidget(&pb->core); |
425 | 426 | |
426 | 427 | /* Update value by setting the linked -variable, if there is one: |
427 | 428 | */ |
428 | 429 | if (pb->progress.variableTrace) { |
429 | return Tcl_ObjSetVar2( | |
430 | interp, pb->progress.variableObj, 0, newValueObj, | |
431 | TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) | |
432 | ? TCL_OK : TCL_ERROR; | |
430 | int result = Tcl_ObjSetVar2( | |
431 | interp, pb->progress.variableObj, 0, newValueObj, | |
432 | TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) | |
433 | ? TCL_OK : TCL_ERROR; | |
434 | Tcl_DecrRefCount(newValueObj); | |
435 | return result; | |
433 | 436 | } |
434 | 437 | |
435 | 438 | /* Otherwise, change the -value directly: |
436 | 439 | */ |
437 | Tcl_IncrRefCount(newValueObj); | |
438 | 440 | Tcl_DecrRefCount(pb->progress.valueObj); |
439 | 441 | pb->progress.valueObj = newValueObj; |
440 | 442 | CheckAnimation(pb); |
13 | 13 | |
14 | 14 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
15 | 15 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
16 | ||
17 | /* Bit fields for OptionSpec mask field: | |
18 | */ | |
19 | #define STATE_CHANGED (0x100) /* -state option changed */ | |
16 | 20 | |
17 | 21 | /* |
18 | 22 | * Scale widget record |
33 | 37 | |
34 | 38 | /* internal state */ |
35 | 39 | Ttk_TraceHandle *variableTrace; |
40 | ||
41 | /* | |
42 | * Compatibility/legacy options: | |
43 | */ | |
44 | Tcl_Obj *stateObj; | |
36 | 45 | |
37 | 46 | } ScalePart; |
38 | 47 | |
65 | 74 | DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0, |
66 | 75 | GEOMETRY_CHANGED}, |
67 | 76 | |
77 | {TK_OPTION_STRING, "-state", "state", "State", | |
78 | "normal", Tk_Offset(Scale,scale.stateObj), -1, | |
79 | 0,0,STATE_CHANGED}, | |
80 | ||
68 | 81 | WIDGET_TAKEFOCUS_TRUE, |
69 | 82 | WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs) |
70 | 83 | }; |
137 | 150 | Ttk_UntraceVariable(scale->scale.variableTrace); |
138 | 151 | } |
139 | 152 | scale->scale.variableTrace = vt; |
153 | ||
154 | if (mask & STATE_CHANGED) { | |
155 | TtkCheckStateOption(&scale->core, scale->scale.stateObj); | |
156 | } | |
140 | 157 | |
141 | 158 | return TCL_OK; |
142 | 159 | } |
129 | 129 | unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF; |
130 | 130 | unsigned int mask = onbits | offbits; |
131 | 131 | Tcl_DString result; |
132 | int i, len; | |
132 | int i; | |
133 | size_t len; | |
133 | 134 | |
134 | 135 | Tcl_DStringInit(&result); |
135 | 136 | |
145 | 146 | len = Tcl_DStringLength(&result); |
146 | 147 | if (len) { |
147 | 148 | /* 'len' includes extra trailing ' ' */ |
148 | objPtr->bytes = Tcl_Alloc((unsigned)len); | |
149 | objPtr->bytes = Tcl_Alloc(len); | |
149 | 150 | objPtr->length = len-1; |
150 | strncpy(objPtr->bytes, Tcl_DStringValue(&result), (size_t)len-1); | |
151 | strncpy(objPtr->bytes, Tcl_DStringValue(&result), len-1); | |
151 | 152 | objPtr->bytes[len-1] = '\0'; |
152 | 153 | } else { |
153 | 154 | /* empty string */ |
25 | 25 | VarTraceProc( |
26 | 26 | ClientData clientData, /* Widget record pointer */ |
27 | 27 | Tcl_Interp *interp, /* Interpreter containing variable. */ |
28 | const char *name1, /* (unused) */ | |
29 | const char *name2, /* (unused) */ | |
28 | const char *name1, /* Name of variable. */ | |
29 | const char *name2, /* Second part of variable name. */ | |
30 | 30 | int flags) /* Information about what happened. */ |
31 | 31 | { |
32 | 32 | Ttk_TraceHandle *tracePtr = clientData; |
34 | 34 | Tcl_Obj *valuePtr; |
35 | 35 | |
36 | 36 | if (flags & TCL_INTERP_DESTROYED) { |
37 | return NULL; | |
38 | } | |
39 | ||
40 | /* | |
41 | * See ticket [5d991b82]. | |
42 | */ | |
43 | ||
44 | if (tracePtr->varnameObj == NULL) { | |
45 | Tcl_UntraceVar2(interp, name1, name2, | |
46 | TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, | |
47 | VarTraceProc, clientData); | |
37 | 48 | return NULL; |
38 | 49 | } |
39 | 50 |
1824 | 1824 | static int DrawForest( |
1825 | 1825 | Treeview *tv, TreeItem *item, Drawable d, int depth, int row) |
1826 | 1826 | { |
1827 | while (item && row <= tv->tree.yscroll.last) { | |
1827 | while (item && row < tv->tree.yscroll.last) { | |
1828 | 1828 | row = DrawSubtree(tv, item, d, depth, row); |
1829 | 1829 | item = item->next; |
1830 | 1830 | } |
13 | 13 | # tk::Priv elements used in this file: |
14 | 14 | # |
15 | 15 | # afterId - Token returned by "after" for autoscanning. |
16 | # listboxPrev - The last element to be selected or deselected | |
16 | # listboxPrev - The last element to be selected or deselected | |
17 | 17 | # during a selection operation. |
18 | 18 | # listboxSelection - All of the items that were selected before the |
19 | 19 | # current selection operation (such as a mouse |
608 | 608 | return |
609 | 609 | } |
610 | 610 | if {[$menu index active] eq "none"} { |
611 | set Priv(window) {} | |
611 | if {[$menu cget -type] ne "menubar" } { | |
612 | set Priv(window) {} | |
613 | } | |
612 | 614 | return |
613 | 615 | } |
614 | 616 | $menu postcascade active |
233 | 233 | } |
234 | 234 | if {!$valid} { |
235 | 235 | return -code error -errorcode {TK MSGBOX DEFAULT} \ |
236 | "invalid default button \"$data(-default)\"" | |
236 | "bad -default value \"$data(-default)\": must be\ | |
237 | abort, retry, ignore, ok, cancel, no, or yes" | |
237 | 238 | } |
238 | 239 | |
239 | 240 | # 2. Set the dialog to be a child window of $parent |
204 | 204 | # |
205 | 205 | # Arguments: |
206 | 206 | # color - Name of starting color. |
207 | # perecent - Integer telling how much to brighten or darken as a | |
207 | # percent - Integer telling how much to brighten or darken as a | |
208 | 208 | # percent: 50 means darken by 50%, 110 means brighten |
209 | 209 | # by 10%. |
210 | 210 | |
211 | 211 | proc ::tk::Darken {color percent} { |
212 | foreach {red green blue} [winfo rgb . $color] { | |
213 | set red [expr {($red/256)*$percent/100}] | |
214 | set green [expr {($green/256)*$percent/100}] | |
215 | set blue [expr {($blue/256)*$percent/100}] | |
216 | break | |
217 | } | |
218 | if {$red > 255} { | |
219 | set red 255 | |
220 | } | |
221 | if {$green > 255} { | |
222 | set green 255 | |
223 | } | |
224 | if {$blue > 255} { | |
225 | set blue 255 | |
226 | } | |
227 | return [format "#%02x%02x%02x" $red $green $blue] | |
212 | if {$percent < 0} { | |
213 | return #000000 | |
214 | } elseif {$percent > 200} { | |
215 | return #ffffff | |
216 | } elseif {$percent <= 100} { | |
217 | lassign [winfo rgb . $color] r g b | |
218 | set r [expr {($r/256)*$percent/100}] | |
219 | set g [expr {($g/256)*$percent/100}] | |
220 | set b [expr {($b/256)*$percent/100}] | |
221 | } elseif {$percent > 100} { | |
222 | lassign [winfo rgb . $color] r g b | |
223 | set r [expr {255 - ((65535-$r)/256)*(200-$percent)/100}] | |
224 | set g [expr {255 - ((65535-$g)/256)*(200-$percent)/100}] | |
225 | set b [expr {255 - ((65535-$b)/256)*(200-$percent)/100}] | |
226 | } | |
227 | return [format #%02x%02x%02x $r $g $b] | |
228 | 228 | } |
229 | 229 | |
230 | 230 | # ::tk_bisque -- |
1057 | 1057 | # make <<Cut>> an atomic operation on the Undo stack, |
1058 | 1058 | # i.e. separate it from other delete operations on either side |
1059 | 1059 | set oldSeparator [$w cget -autoseparators] |
1060 | if {$oldSeparator} { | |
1060 | if {([$w cget -state] eq "normal") && $oldSeparator} { | |
1061 | 1061 | $w edit separator |
1062 | 1062 | } |
1063 | 1063 | clipboard clear -displayof $w |
1064 | 1064 | clipboard append -displayof $w $data |
1065 | 1065 | $w delete sel.first sel.last |
1066 | if {$oldSeparator} { | |
1066 | if {([$w cget -state] eq "normal") && $oldSeparator} { | |
1067 | 1067 | $w edit separator |
1068 | 1068 | } |
1069 | 1069 | } |
10 | 10 | # this file, and for a DISCLAIMER OF ALL WARRANTIES. |
11 | 11 | |
12 | 12 | # Verify that we have Tk binary and script components from the same release |
13 | package require -exact Tk 8.6.8 | |
13 | package require -exact Tk 8.6.9 | |
14 | 14 | |
15 | 15 | # Create a ::tk namespace |
16 | 16 | namespace eval ::tk { |
94 | 94 | ttk::style configure Heading -font TkHeadingFont -relief raised |
95 | 95 | ttk::style configure Treeview -background $colors(-window) |
96 | 96 | ttk::style map Treeview \ |
97 | -background [list selected $colors(-selectbg)] \ | |
98 | -foreground [list selected $colors(-selectfg)] ; | |
97 | -background [list disabled $colors(-frame)\ | |
98 | {!disabled !selected} $colors(-window) \ | |
99 | selected $colors(-selectbg)] \ | |
100 | -foreground [list disabled $colors(-disabledfg) \ | |
101 | {!disabled !selected} black \ | |
102 | selected $colors(-selectfg)] | |
99 | 103 | |
100 | 104 | ttk::style configure TScale \ |
101 | 105 | -groovewidth 4 -troughrelief sunken \ |
40 | 40 | ttk::style configure Heading -font TkHeadingFont |
41 | 41 | ttk::style configure Treeview -rowheight 18 -background White |
42 | 42 | ttk::style map Treeview \ |
43 | -background {{selected background} systemHighlightSecondary | |
44 | selected systemHighlight} | |
43 | -background [list disabled systemDialogBackgroundInactive \ | |
44 | {!disabled !selected} systemWindowBody \ | |
45 | {selected background} systemHighlightSecondary \ | |
46 | selected systemHighlight] \ | |
47 | -foreground [list disabled systemModelessDialogInactiveText \ | |
48 | {!disabled !selected} black \ | |
49 | selected systemModelessDialogActiveText] | |
45 | 50 | |
46 | 51 | # Enable animation for ttk::progressbar widget: |
47 | 52 | ttk::style configure TProgressbar -period 100 -maxphase 255 |
130 | 130 | -font TkHeadingFont -relief raised -padding {3} |
131 | 131 | ttk::style configure Treeview -background $colors(-window) |
132 | 132 | ttk::style map Treeview \ |
133 | -background [list selected $colors(-selectbg)] \ | |
134 | -foreground [list selected $colors(-selectfg)] ; | |
133 | -background [list disabled $colors(-frame)\ | |
134 | {!disabled !selected} $colors(-window) \ | |
135 | selected $colors(-selectbg)] \ | |
136 | -foreground [list disabled $colors(-disabledfg) \ | |
137 | {!disabled !selected} black \ | |
138 | selected $colors(-selectfg)] | |
135 | 139 | |
136 | 140 | ttk::style configure TLabelframe \ |
137 | 141 | -labeloutside true -labelmargins {0 0 0 4} \ |
97 | 97 | ttk::style configure Heading -font TkHeadingFont -relief raised |
98 | 98 | ttk::style configure Treeview -background $colors(-window) |
99 | 99 | ttk::style map Treeview \ |
100 | -background [list selected $colors(-selectbg)] \ | |
101 | -foreground [list selected $colors(-selectfg)] ; | |
100 | -background [list disabled $colors(-frame)\ | |
101 | {!disabled !selected} $colors(-window) \ | |
102 | selected $colors(-selectbg)] \ | |
103 | -foreground [list disabled $colors(-disabledfg) \ | |
104 | {!disabled !selected} black \ | |
105 | selected $colors(-selectfg)] | |
102 | 106 | |
103 | 107 | # |
104 | 108 | # Toolbar buttons: |
87 | 87 | ### Option database settings. |
88 | 88 | # |
89 | 89 | |
90 | option add *TCombobox*Listbox.font TkTextFont | |
91 | option add *TCombobox*Listbox.relief flat | |
92 | option add *TCombobox*Listbox.highlightThickness 0 | |
90 | option add *TCombobox*Listbox.font TkTextFont widgetDefault | |
91 | option add *TCombobox*Listbox.relief flat widgetDefault | |
92 | option add *TCombobox*Listbox.highlightThickness 0 widgetDefault | |
93 | 93 | |
94 | 94 | ## Platform-specific settings. |
95 | 95 | # |
96 | 96 | switch -- [tk windowingsystem] { |
97 | 97 | x11 { |
98 | option add *TCombobox*Listbox.background white | |
98 | option add *TCombobox*Listbox.background white widgetDefault | |
99 | 99 | } |
100 | 100 | aqua { |
101 | option add *TCombobox*Listbox.borderWidth 0 | |
101 | option add *TCombobox*Listbox.borderWidth 0 widgetDefault | |
102 | 102 | } |
103 | 103 | } |
104 | 104 |
109 | 109 | -background $colors(-window) \ |
110 | 110 | -foreground $colors(-text) ; |
111 | 111 | ttk::style map Treeview \ |
112 | -background [list selected $colors(-selectbg)] \ | |
113 | -foreground [list selected $colors(-selectfg)] ; | |
112 | -background [list disabled $colors(-frame)\ | |
113 | {!disabled !selected} $colors(-window) \ | |
114 | selected $colors(-selectbg)] \ | |
115 | -foreground [list disabled $colors(-disabledfg) \ | |
116 | {!disabled !selected} black \ | |
117 | selected $colors(-selectfg)] | |
114 | 118 | |
115 | 119 | # Combobox popdown frame |
116 | 120 | ttk::style layout ComboboxPopdownFrame { |
33 | 33 | |
34 | 34 | ### Option database settings. |
35 | 35 | # |
36 | option add *TEntry.cursor [ttk::cursor text] | |
36 | option add *TEntry.cursor [ttk::cursor text] widgetDefault | |
37 | 37 | |
38 | 38 | ### Bindings. |
39 | 39 | # |
417 | 417 | # Suspend autoscroll. |
418 | 418 | # |
419 | 419 | proc ttk::entry::DragIn {w} { |
420 | ttk::CancelRepeat | |
420 | ttk::CancelRepeat | |
421 | 421 | } |
422 | 422 | |
423 | 423 | ## <ButtonRelease-1> binding |
431 | 431 | ## AutoScroll |
432 | 432 | # Called repeatedly when the mouse is outside an entry window |
433 | 433 | # with Button 1 down. Scroll the window left or right, |
434 | # depending on where the mouse left the window, and extend | |
434 | # depending on where the mouse left the window, and extend | |
435 | 435 | # the selection according to the current selection mode. |
436 | 436 | # |
437 | 437 | # TODO: AutoScroll should repeat faster (50ms) than normal autorepeat. |
8 | 8 | switch -- [tk windowingsystem] { |
9 | 9 | x11 - |
10 | 10 | win32 { |
11 | option add *TSizegrip.cursor [ttk::cursor seresize] | |
11 | option add *TSizegrip.cursor [ttk::cursor seresize] widgetDefault | |
12 | 12 | } |
13 | 13 | aqua { |
14 | 14 | # Aqua sizegrips use default Arrow cursor. |
119 | 119 | variable State |
120 | 120 | |
121 | 121 | if {$w != $State(activeWidget) || $heading != $State(activeHeading)} { |
122 | if {$State(activeHeading) != {}} { | |
122 | if {[winfo exists $State(activeWidget)] && $State(activeHeading) != {}} { | |
123 | 123 | $State(activeWidget) heading $State(activeHeading) state !active |
124 | 124 | } |
125 | 125 | if {$heading != {}} { |
20 | 20 | -foreground SystemWindowText \ |
21 | 21 | -selectforeground SystemHighlightText \ |
22 | 22 | -selectbackground SystemHighlight \ |
23 | -insertcolor SystemWindowText \ | |
23 | 24 | -font TkDefaultFont \ |
24 | 25 | ; |
25 | 26 | |
45 | 46 | ttk::style configure Heading -font TkHeadingFont |
46 | 47 | ttk::style configure Treeview -background SystemWindow |
47 | 48 | ttk::style map Treeview \ |
48 | -background [list selected SystemHighlight] \ | |
49 | -foreground [list selected SystemHighlightText] ; | |
49 | -background [list disabled SystemButtonFace \ | |
50 | {!disabled !selected} SystemWindow \ | |
51 | selected SystemHighlight] \ | |
52 | -foreground [list disabled SystemGrayText \ | |
53 | {!disabled !selected} SystemWindowText \ | |
54 | selected SystemHighlightText] | |
50 | 55 | |
51 | 56 | # Label and Toolbutton |
52 | ttk::style configure TLabelframe.Label -foreground "#0046d5" | |
57 | ttk::style configure TLabelframe.Label -foreground SystemButtonText | |
53 | 58 | |
54 | 59 | ttk::style configure Toolbutton -padding {4 4} |
55 | 60 | |
56 | 61 | # Combobox |
57 | 62 | ttk::style configure TCombobox -padding 2 |
58 | ttk::style element create Combobox.field vsapi \ | |
59 | COMBOBOX 2 {{} 1} | |
60 | 63 | ttk::style element create Combobox.border vsapi \ |
61 | 64 | COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1} |
65 | ttk::style element create Combobox.background vsapi \ | |
66 | EDIT 3 {disabled 3 readonly 5 focus 4 hover 2 {} 1} | |
62 | 67 | ttk::style element create Combobox.rightdownarrow vsapi \ |
63 | 68 | COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \ |
64 | 69 | -syssize {SM_CXVSCROLL SM_CYVSCROLL} |
66 | 71 | Combobox.border -sticky nswe -border 0 -children { |
67 | 72 | Combobox.rightdownarrow -side right -sticky ns |
68 | 73 | Combobox.padding -expand 1 -sticky nswe -children { |
69 | Combobox.focus -expand 1 -sticky nswe -children { | |
70 | Combobox.textarea -sticky nswe | |
74 | Combobox.background -sticky nswe -children { | |
75 | Combobox.focus -expand 1 -sticky nswe -children { | |
76 | Combobox.textarea -sticky nswe | |
77 | } | |
71 | 78 | } |
72 | 79 | } |
73 | 80 | } |
9 | 9 | -foreground SystemWindowText \ |
10 | 10 | -selectforeground SystemHighlightText \ |
11 | 11 | -selectbackground SystemHighlight \ |
12 | -fieldbackground SystemWindow \ | |
13 | -insertcolor SystemWindowText \ | |
12 | 14 | -troughcolor SystemScrollbar \ |
13 | 15 | -font TkDefaultFont \ |
14 | 16 | ; |
70 | 72 | ttk::style configure Heading -font TkHeadingFont -relief raised |
71 | 73 | ttk::style configure Treeview -background SystemWindow |
72 | 74 | ttk::style map Treeview \ |
73 | -background [list selected SystemHighlight] \ | |
74 | -foreground [list selected SystemHighlightText] ; | |
75 | -background [list disabled SystemButtonFace \ | |
76 | {!disabled !selected} SystemWindow \ | |
77 | selected SystemHighlight] \ | |
78 | -foreground [list disabled SystemGrayText \ | |
79 | {!disabled !selected} SystemWindowText \ | |
80 | selected SystemHighlightText] | |
75 | 81 | |
76 | 82 | ttk::style configure TProgressbar \ |
77 | 83 | -background SystemHighlight -borderwidth 0 ; |
10 | 10 | -foreground SystemWindowText \ |
11 | 11 | -selectforeground SystemHighlightText \ |
12 | 12 | -selectbackground SystemHighlight \ |
13 | -insertcolor SystemWindowText \ | |
13 | 14 | -font TkDefaultFont \ |
14 | 15 | ; |
15 | 16 | |
60 | 61 | |
61 | 62 | ttk::style configure Toolbutton -padding {4 4} |
62 | 63 | |
64 | # Treeview: | |
65 | ttk::style configure Heading -font TkHeadingFont -relief raised | |
66 | ttk::style configure Treeview -background SystemWindow | |
67 | ttk::style map Treeview \ | |
68 | -background [list disabled SystemButtonFace \ | |
69 | {!disabled !selected} SystemWindow \ | |
70 | selected SystemHighlight] \ | |
71 | -foreground [list disabled SystemGrayText \ | |
72 | {!disabled !selected} SystemWindowText \ | |
73 | selected SystemHighlightText]; | |
63 | 74 | } |
64 | 75 | } |
560 | 560 | windows are redrawn within the DisplayText function by some |
561 | 561 | conditional code which is only used for macOS. |
562 | 562 | |
563 | 5.0 Virtual events on 10.14 | |
564 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
565 | ||
566 | 10.14 supports system appearance changes, and has added a "Dark Mode" | |
567 | that casts all window frames and menus as black. Tk 8.6.9 has added two | |
568 | virtual events, <<LightAqua>> and <<DarkAqua>>, to allow you to update | |
569 | your Tk app's appearance when the system appearance changes. Just bind | |
570 | your appearance-updating code to these virtual events and you will see | |
571 | it triggered when the system appearance toggles between dark and light. |
41 | 41 | TCL_PACKAGE_PATH = "$(LIBDIR)" |
42 | 42 | TCL_DEFS = HAVE_TCL_CONFIG_H |
43 | 43 | TK_LIBRARY = $(LIBDIR)/tk$(VERSION) |
44 | TK_DEFS = HAVE_TK_CONFIG_H TCL_NO_DEPRECATED | |
44 | TK_DEFS = HAVE_TK_CONFIG_H | |
45 | 45 | VERSION = 8.6 |
2286 | 2286 | TK_VERSION=8.6 |
2287 | 2287 | TK_MAJOR_VERSION=8 |
2288 | 2288 | TK_MINOR_VERSION=6 |
2289 | TK_PATCH_LEVEL=".8" | |
2289 | TK_PATCH_LEVEL=".9" | |
2290 | 2290 | VERSION=${TK_VERSION} |
2291 | 2291 | LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv" |
2292 | 2292 | |
2375 | 2375 | for i in `ls -d ${libdir} 2>/dev/null` \ |
2376 | 2376 | `ls -d ${exec_prefix}/lib 2>/dev/null` \ |
2377 | 2377 | `ls -d ${prefix}/lib 2>/dev/null` \ |
2378 | `ls -d /usr/local/lib 2>/dev/null` \ | |
2378 | 2379 | `ls -d /usr/contrib/lib 2>/dev/null` \ |
2379 | `ls -d /usr/local/lib 2>/dev/null` \ | |
2380 | 2380 | `ls -d /usr/pkg/lib 2>/dev/null` \ |
2381 | 2381 | `ls -d /usr/lib 2>/dev/null` \ |
2382 | 2382 | `ls -d /usr/lib64 2>/dev/null` \ |
2383 | `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \ | |
2384 | `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \ | |
2383 | 2385 | ; do |
2384 | 2386 | if test -f "$i/tclConfig.sh" ; then |
2385 | 2387 | ac_cv_c_tclconfig="`(cd $i; pwd)`" |
4943 | 4945 | LDFLAGS="$LDFLAGS -Wl,--export-dynamic" |
4944 | 4946 | SHLIB_CFLAGS="-fPIC" |
4945 | 4947 | SHLIB_SUFFIX=".so" |
4946 | SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' | |
4948 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' | |
4947 | 4949 | DL_OBJS="tclLoadDl.o" |
4948 | 4950 | DL_LIBS="-lroot" |
4949 | 4951 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for inet_ntoa in -lnetwork" >&5 |
5265 | 5267 | # get rid of the warnings. |
5266 | 5268 | #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" |
5267 | 5269 | |
5268 | SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' | |
5270 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' | |
5269 | 5271 | DL_OBJS="tclLoadDl.o" |
5270 | 5272 | DL_LIBS="-ldl" |
5271 | 5273 | LDFLAGS="$LDFLAGS -Wl,--export-dynamic" |
5373 | 5375 | SHLIB_CFLAGS="-fpic" |
5374 | 5376 | ;; |
5375 | 5377 | esac |
5376 | SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' | |
5378 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' | |
5377 | 5379 | SHLIB_SUFFIX=".so" |
5378 | 5380 | DL_OBJS="tclLoadDl.o" |
5379 | 5381 | DL_LIBS="" |
5400 | 5402 | NetBSD-*) |
5401 | 5403 | # NetBSD has ELF and can use 'cc -shared' to build shared libs |
5402 | 5404 | SHLIB_CFLAGS="-fPIC" |
5403 | SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' | |
5405 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' | |
5404 | 5406 | SHLIB_SUFFIX=".so" |
5405 | 5407 | DL_OBJS="tclLoadDl.o" |
5406 | 5408 | DL_LIBS="" |
5419 | 5421 | |
5420 | 5422 | fi |
5421 | 5423 | ;; |
5422 | FreeBSD-*) | |
5424 | DragonFly-*|FreeBSD-*) | |
5423 | 5425 | # This configuration from FreeBSD Ports. |
5424 | 5426 | SHLIB_CFLAGS="-fPIC" |
5425 | 5427 | SHLIB_LD="${CC} -shared" |
6235 | 6237 | BSD/OS*) ;; |
6236 | 6238 | CYGWIN_*|MINGW32_*) ;; |
6237 | 6239 | IRIX*) ;; |
6238 | NetBSD-*|FreeBSD-*|OpenBSD-*) ;; | |
6240 | NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;; | |
6239 | 6241 | Darwin-*) ;; |
6240 | 6242 | SCO_SV-3.2*) ;; |
6241 | 6243 | *) SHLIB_CFLAGS="-fPIC" ;; |
6698 | 6700 | if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then |
6699 | 6701 | |
6700 | 6702 | $as_echo "#define HAVE_STRUCT_DIRENT64 1" >>confdefs.h |
6703 | ||
6704 | fi | |
6705 | ||
6706 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for DIR64" >&5 | |
6707 | $as_echo_n "checking for DIR64... " >&6; } | |
6708 | if ${tcl_cv_DIR64+:} false; then : | |
6709 | $as_echo_n "(cached) " >&6 | |
6710 | else | |
6711 | ||
6712 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
6713 | /* end confdefs.h. */ | |
6714 | #include <sys/types.h> | |
6715 | #include <dirent.h> | |
6716 | int | |
6717 | main () | |
6718 | { | |
6719 | struct dirent64 *p; DIR64 d = opendir64("."); | |
6720 | p = readdir64(d); rewinddir64(d); closedir64(d); | |
6721 | ; | |
6722 | return 0; | |
6723 | } | |
6724 | _ACEOF | |
6725 | if ac_fn_c_try_compile "$LINENO"; then : | |
6726 | tcl_cv_DIR64=yes | |
6727 | else | |
6728 | tcl_cv_DIR64=no | |
6729 | fi | |
6730 | rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext | |
6731 | fi | |
6732 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_DIR64" >&5 | |
6733 | $as_echo "$tcl_cv_DIR64" >&6; } | |
6734 | if test "x${tcl_cv_DIR64}" = "xyes" ; then | |
6735 | ||
6736 | $as_echo "#define HAVE_DIR64 1" >>confdefs.h | |
6701 | 6737 | |
6702 | 6738 | fi |
6703 | 6739 | |
7159 | 7195 | $as_echo "#define TIME_WITH_SYS_TIME 1" >>confdefs.h |
7160 | 7196 | |
7161 | 7197 | fi |
7162 | ||
7163 | ||
7164 | #-------------------------------------------------------------------- | |
7165 | # Under Solaris 2.4, strtod returns the wrong value for the | |
7166 | # terminating character under some conditions. Check for this | |
7167 | # and if the problem exists use a substitute procedure | |
7168 | # "fixstrtod" (provided by Tcl) that corrects the error. | |
7169 | #-------------------------------------------------------------------- | |
7170 | ||
7171 | ||
7172 | ac_fn_c_check_func "$LINENO" "strtod" "ac_cv_func_strtod" | |
7173 | if test "x$ac_cv_func_strtod" = xyes; then : | |
7174 | tcl_strtod=1 | |
7175 | else | |
7176 | tcl_strtod=0 | |
7177 | fi | |
7178 | ||
7179 | if test "$tcl_strtod" = 1; then | |
7180 | { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Solaris2.4/Tru64 strtod bugs" >&5 | |
7181 | $as_echo_n "checking for Solaris2.4/Tru64 strtod bugs... " >&6; } | |
7182 | if ${tcl_cv_strtod_buggy+:} false; then : | |
7183 | $as_echo_n "(cached) " >&6 | |
7184 | else | |
7185 | ||
7186 | if test "$cross_compiling" = yes; then : | |
7187 | tcl_cv_strtod_buggy=buggy | |
7188 | else | |
7189 | cat confdefs.h - <<_ACEOF >conftest.$ac_ext | |
7190 | /* end confdefs.h. */ | |
7191 | ||
7192 | extern double strtod(); | |
7193 | int main() { | |
7194 | char *infString="Inf", *nanString="NaN", *spaceString=" "; | |
7195 | char *term; | |
7196 | double value; | |
7197 | value = strtod(infString, &term); | |
7198 | if ((term != infString) && (term[-1] == 0)) { | |
7199 | exit(1); | |
7200 | } | |
7201 | value = strtod(nanString, &term); | |
7202 | if ((term != nanString) && (term[-1] == 0)) { | |
7203 | exit(1); | |
7204 | } | |
7205 | value = strtod(spaceString, &term); | |
7206 | if (term == (spaceString+1)) { | |
7207 | exit(1); | |
7208 | } | |
7209 | exit(0); | |
7210 | } | |
7211 | _ACEOF | |
7212 | if ac_fn_c_try_run "$LINENO"; then : | |
7213 | tcl_cv_strtod_buggy=ok | |
7214 | else | |
7215 | tcl_cv_strtod_buggy=buggy | |
7216 | fi | |
7217 | rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ | |
7218 | conftest.$ac_objext conftest.beam conftest.$ac_ext | |
7219 | fi | |
7220 | ||
7221 | fi | |
7222 | { $as_echo "$as_me:${as_lineno-$LINENO}: result: $tcl_cv_strtod_buggy" >&5 | |
7223 | $as_echo "$tcl_cv_strtod_buggy" >&6; } | |
7224 | if test "$tcl_cv_strtod_buggy" = buggy; then | |
7225 | case " $LIBOBJS " in | |
7226 | *" fixstrtod.$ac_objext "* ) ;; | |
7227 | *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" | |
7228 | ;; | |
7229 | esac | |
7230 | ||
7231 | USE_COMPAT=1 | |
7232 | ||
7233 | $as_echo "#define strtod fixstrtod" >>confdefs.h | |
7234 | ||
7235 | fi | |
7236 | fi | |
7237 | 7198 | |
7238 | 7199 | |
7239 | 7200 | #-------------------------------------------------------------------- |
20 | 20 | #include "tkMacOSXFont.h" |
21 | 21 | #include "tkMacOSXDebug.h" |
22 | 22 | |
23 | ||
24 | 23 | #define FIRST_DRAW 2 |
25 | 24 | #define ACTIVE 4 |
26 | 25 | |
27 | ||
28 | /* | |
29 | * Default insets for controls | |
30 | */ | |
31 | ||
32 | #define DEF_INSET_LEFT 12 | |
33 | #define DEF_INSET_RIGHT 12 | |
34 | #define DEF_INSET_TOP 1 | |
35 | #define DEF_INSET_BOTTOM 1 | |
26 | /* | |
27 | * Extra padding used for computing the content size that should | |
28 | * be allowed when drawing the HITheme button. | |
29 | */ | |
30 | ||
31 | #define HI_PADX 2 | |
32 | #define HI_PADY 1 | |
36 | 33 | |
37 | 34 | /* |
38 | 35 | * Some defines used to control what type of control is drawn. |
317 | 314 | Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength, |
318 | 315 | butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); |
319 | 316 | |
320 | /*Remove extraneous padding around label widgets.*/ | |
321 | 317 | txtWidth = butPtr->textWidth; |
322 | txtHeight = butPtr->textHeight + DEF_INSET_BOTTOM + DEF_INSET_TOP; | |
318 | txtHeight = butPtr->textHeight; | |
323 | 319 | charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); |
324 | 320 | Tk_GetFontMetrics(butPtr->tkfont, &fm); |
325 | 321 | haveText = (txtWidth != 0 && txtHeight != 0); |
363 | 359 | height = butPtr->height > 0 ? butPtr->height : height; |
364 | 360 | |
365 | 361 | } else { /* Text only */ |
366 | /*Add four pixels of padding to width for text-only buttons to improve appearance.*/ | |
367 | width = txtWidth + butPtr->indicatorSpace + 4; | |
362 | width = txtWidth + butPtr->indicatorSpace; | |
368 | 363 | height = txtHeight; |
369 | 364 | if (butPtr->width > 0) { |
370 | 365 | width = butPtr->width * charWidth; |
395 | 390 | int paddingx = 0; |
396 | 391 | int paddingy = 0; |
397 | 392 | |
398 | tmpRect = CGRectMake(0, 0, width, height); | |
393 | tmpRect = CGRectMake(0, 0, width + 2*HI_PADX, height + 2*HI_PADY); | |
399 | 394 | |
400 | 395 | HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds); |
401 | 396 | /* If the content region has a minimum height, match it. */ |
424 | 419 | |
425 | 420 | width += butPtr->inset*2; |
426 | 421 | height += butPtr->inset*2; |
422 | if ([NSApp macMinorVersion] == 6) { | |
423 | width += 12; | |
424 | } | |
427 | 425 | |
428 | 426 | Tk_GeometryRequest(butPtr->tkwin, width, height); |
429 | 427 | Tk_SetInternalBorder(butPtr->tkwin, butPtr->inset); |
648 | 646 | butPtr->textHeight, &x, &y); |
649 | 647 | x += butPtr->indicatorSpace; |
650 | 648 | Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout, |
651 | x, y - DEF_INSET_BOTTOM, 0, -1); | |
649 | x, y, 0, -1); | |
652 | 650 | } |
653 | 651 | |
654 | 652 | /* |
785 | 783 | return; |
786 | 784 | } |
787 | 785 | |
788 | ||
789 | if (mbPtr->btnkind == kThemePushButton) { | |
790 | /* | |
791 | * For some reason, pushbuttons get drawn a bit | |
792 | * too low, normally. Correct for this. | |
793 | */ | |
794 | if (cntrRect.size.height < 22) { | |
795 | cntrRect.origin.y -= 1; | |
796 | } else if (cntrRect.size.height < 23) { | |
797 | cntrRect.origin.y -= 2; | |
798 | } | |
799 | } | |
800 | ||
801 | 786 | hiinfo.version = 0; |
802 | 787 | hiinfo.state = mbPtr->drawinfo.state; |
803 | 788 | hiinfo.kind = mbPtr->btnkind; |
909 | 894 | return; |
910 | 895 | } |
911 | 896 | |
912 | /*Overlay Tk elements over button native region: drawing elements within button boundaries/native region causes unpredictable metrics.*/ | |
897 | /* | |
898 | * Overlay Tk elements over button native region: drawing elements | |
899 | * within button boundaries/native region causes unpredictable metrics. | |
900 | */ | |
913 | 901 | DrawButtonImageAndText( butPtr); |
914 | 902 | } |
915 | 903 | |
1212 | 1200 | PULSE_TIMER_MSECS, PulseDefaultButtonProc, clientData); |
1213 | 1201 | } |
1214 | 1202 | |
1203 | /* | |
1204 | * Local Variables: | |
1205 | * mode: objc | |
1206 | * c-basic-offset: 4 | |
1207 | * fill-column: 79 | |
1208 | * coding: utf-8 | |
1209 | * End: | |
1210 | */ |
11 | 11 | */ |
12 | 12 | |
13 | 13 | #include "tkMacOSXPrivate.h" |
14 | #include "tkMacOSXConstants.h" | |
14 | 15 | #include "tkSelect.h" |
15 | 16 | |
16 | 17 | static NSInteger changeCount = -1; |
69 | 70 | if (clipboardOwner && [[NSPasteboard generalPasteboard] changeCount] != |
70 | 71 | changeCount) { |
71 | 72 | TkDisplay *dispPtr = TkGetDisplayList(); |
72 | ||
73 | 73 | if (dispPtr) { |
74 | 74 | XEvent event; |
75 | ||
76 | 75 | event.xany.type = SelectionClear; |
77 | 76 | event.xany.serial = NextRequest(Tk_Display(clipboardOwner)); |
78 | 77 | event.xany.send_event = False; |
124 | 123 | int result = TCL_ERROR; |
125 | 124 | TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; |
126 | 125 | |
127 | if (dispPtr && selection == dispPtr->clipboardAtom && (target == XA_STRING | |
128 | || target == dispPtr->utf8Atom)) { | |
126 | int haveExternalClip = ([[NSPasteboard generalPasteboard] changeCount] != changeCount); | |
127 | if (dispPtr && (haveExternalClip || dispPtr->clipboardActive) | |
128 | && selection == dispPtr->clipboardAtom | |
129 | && (target == XA_STRING || target == dispPtr->utf8Atom)) { | |
129 | 130 | NSString *string = nil; |
130 | 131 | NSPasteboard *pb = [NSPasteboard generalPasteboard]; |
131 | 132 | NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject: |
175 | 176 | clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL; |
176 | 177 | if (!dispPtr->clipboardActive) { |
177 | 178 | NSPasteboard *pb = [NSPasteboard generalPasteboard]; |
178 | ||
179 | 179 | changeCount = [pb declareTypes:[NSArray array] owner:NSApp]; |
180 | 180 | } |
181 | 181 | } |
286 | 286 | TkSelPropProc( |
287 | 287 | register XEvent *eventPtr) /* X PropertyChange event. */ |
288 | 288 | { |
289 | } | |
290 | ||
291 | /* | |
292 | *---------------------------------------------------------------------- | |
293 | * | |
294 | * TkSuspendClipboard -- | |
295 | * | |
296 | * Handle clipboard conversion as required by the suppend event. | |
297 | * | |
298 | * Results: | |
299 | * None. | |
300 | * | |
301 | * Side effects: | |
302 | * The local scrap is moved to the global scrap. | |
303 | * | |
304 | *---------------------------------------------------------------------- | |
305 | */ | |
306 | ||
307 | void | |
308 | TkSuspendClipboard(void) | |
309 | { | |
310 | changeCount = [[NSPasteboard generalPasteboard] changeCount]; | |
311 | 289 | } |
312 | 290 | |
313 | 291 | /* |
40 | 40 | { |
41 | 41 | return NULL; |
42 | 42 | } |
43 | ||
44 | /* | |
45 | * Local Variables: | |
46 | * mode: objc | |
47 | * c-basic-offset: 4 | |
48 | * fill-column: 79 | |
49 | * coding: utf-8 | |
50 | * End: | |
51 | */ |
14 | 14 | #ifndef _TKMACCONSTANTS |
15 | 15 | #define _TKMACCONSTANTS |
16 | 16 | |
17 | #if MAC_OS_X_VERSION_MAX_ALLOWED < 1070 | |
18 | #define NSFullScreenWindowMask (1 << 14) | |
19 | #endif | |
20 | ||
17 | 21 | /* |
18 | 22 | * Let's raise a glass for the project manager who improves our lives by |
19 | 23 | * generating deprecation warnings about pointless changes of the names |
20 | 24 | * of constants. |
21 | 25 | */ |
22 | 26 | |
27 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 | |
28 | #define kCTFontDefaultOrientation kCTFontOrientationDefault | |
29 | #define kCTFontVerticalOrientation kCTFontOrientationVertical | |
30 | #endif | |
31 | ||
23 | 32 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 |
24 | 33 | #define NSOKButton NSModalResponseOK |
25 | 34 | #endif |
26 | 35 | |
36 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101100 | |
37 | #define kCTFontUserFixedPitchFontType kCTFontUIFontUserFixedPitch | |
38 | #endif | |
39 | ||
27 | 40 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 |
28 | 41 | #define NSAppKitDefined NSEventTypeAppKitDefined |
42 | #define NSApplicationDefined NSEventTypeApplicationDefined | |
29 | 43 | #define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated |
30 | 44 | #define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated |
31 | 45 | #define NSWindowExposedEventType NSEventSubtypeWindowExposed |
78 | 92 | #define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock |
79 | 93 | #define NSShiftKeyMask NSEventModifierFlagShift |
80 | 94 | #define NSAnyEventMask NSEventMaskAny |
95 | #define NSApplicationDefinedMask NSEventMaskApplicationDefined | |
81 | 96 | #define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground |
82 | 97 | #define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow |
83 | 98 | #define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel |
89 | 104 | #define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar |
90 | 105 | #define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable |
91 | 106 | #define NSBorderlessWindowMask NSWindowStyleMaskBorderless |
107 | #define NSFullScreenWindowMask NSWindowStyleMaskFullScreen | |
92 | 108 | #endif |
93 | 109 | |
110 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 | |
111 | #define NSStringPboardType NSPasteboardTypeString | |
112 | #define NSOnState NSControlStateValueOn | |
113 | #define NSOffState NSControlStateValueOff | |
114 | // Now we are also changing names of methods! | |
115 | #define graphicsContextWithGraphicsPort graphicsContextWithCGContext | |
94 | 116 | #endif |
117 | ||
118 | ||
119 | #endif | |
120 |
116 | 116 | ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING |
117 | 117 | }; |
118 | 118 | static const char *const alertButtonStrings[] = { |
119 | "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL | |
119 | "abort", "retry", "ignore", "ok", "cancel", "no", "yes", NULL | |
120 | 120 | }; |
121 | 121 | |
122 | 122 | static const NSString *const alertButtonNames[][3] = { |
146 | 146 | [TYPE_OK] = {0, 0, 0, 1, 0, 0, 0}, |
147 | 147 | [TYPE_OKCANCEL] = {0, 0, 0, 1, 2, 0, 0}, |
148 | 148 | [TYPE_RETRYCANCEL] = {0, 1, 0, 0, 2, 0, 0}, |
149 | [TYPE_YESNO] = {0, 0, 0, 0, 0, 1, 2}, | |
150 | [TYPE_YESNOCANCEL] = {0, 0, 0, 0, 3, 1, 2}, | |
149 | [TYPE_YESNO] = {0, 0, 0, 0, 0, 2, 1}, | |
150 | [TYPE_YESNOCANCEL] = {0, 0, 0, 0, 3, 2, 1}, | |
151 | 151 | }; |
152 | 152 | |
153 | 153 | /* |
160 | 160 | [TYPE_OK] = {3, 0, 0}, |
161 | 161 | [TYPE_OKCANCEL] = {3, 4, 0}, |
162 | 162 | [TYPE_RETRYCANCEL] = {1, 4, 0}, |
163 | [TYPE_YESNO] = {5, 6, 0}, | |
164 | [TYPE_YESNOCANCEL] = {5, 6, 4}, | |
163 | [TYPE_YESNO] = {6, 5, 0}, | |
164 | [TYPE_YESNOCANCEL] = {6, 5, 4}, | |
165 | 165 | }; |
166 | 166 | |
167 | 167 | /* |
745 | 745 | /* |
746 | 746 | * The -typevariable must be set to the selected file type, if the dialog was not cancelled |
747 | 747 | */ |
748 | NSInteger selectedFilterIndex = filterInfo.fileTypeIndex; | |
748 | NSUInteger selectedFilterIndex = filterInfo.fileTypeIndex; | |
749 | 749 | NSString *selectedFilter = NULL; |
750 | 750 | if (filterInfo.userHasSelectedFilter) { |
751 | 751 | selectedFilterIndex = filterInfo.fileTypeIndex; |
771 | 771 | selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex]; |
772 | 772 | } else { |
773 | 773 | // scan the list |
774 | int i; | |
774 | NSUInteger i; | |
775 | 775 | for (i = 0; i < [filterInfo.fileTypeNames count]; i++) { |
776 | 776 | if (filterCompatible(extension, i)) { |
777 | 777 | selectedFilterIndex = i; |
1197 | 1197 | NSString *year = [dateFormatter stringFromDate:[NSDate date]]; |
1198 | 1198 | |
1199 | 1199 | [dateFormatter release]; |
1200 | ||
1201 | NSMutableParagraphStyle *style = | |
1202 | [[[NSParagraphStyle defaultParagraphStyle] mutableCopy] | |
1203 | autorelease]; | |
1204 | ||
1205 | [style setAlignment:NSCenterTextAlignment]; | |
1206 | ||
1207 | NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: | |
1208 | @"Tcl & Tk", @"ApplicationName", | |
1209 | @"Tcl " TCL_VERSION " & Tk " TK_VERSION, @"ApplicationVersion", | |
1210 | @TK_PATCH_LEVEL, @"Version", | |
1211 | image, @"ApplicationIcon", | |
1212 | [NSString stringWithFormat:@"Copyright %1$C 1987-%2$@.", 0xA9, | |
1213 | year], @"Copyright", | |
1214 | [[[NSAttributedString alloc] initWithString: | |
1215 | [NSString stringWithFormat: | |
1216 | @"%1$C 1987-%2$@ Tcl Core Team." "\n\n" | |
1217 | "%1$C 1989-%2$@ Contributors." "\n\n" | |
1218 | "%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC." "\n\n" | |
1219 | "%1$C 2014-%2$@ Marc Culler." "\n\n" | |
1220 | "%1$C 2002-%2$@ Daniel A. Steffen." "\n\n" | |
1221 | "%1$C 2001-2009 Apple Inc." "\n\n" | |
1222 | "%1$C 2001-2002 Jim Ingham & Ian Reid" "\n\n" | |
1223 | "%1$C 1998-2000 Jim Ingham & Ray Johnson" "\n\n" | |
1224 | "%1$C 1998-2000 Scriptics Inc." "\n\n" | |
1225 | "%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] attributes: | |
1226 | [NSDictionary dictionaryWithObject:style | |
1227 | forKey:NSParagraphStyleAttributeName]] autorelease], @"Credits", | |
1228 | nil]; | |
1229 | [NSApp orderFrontStandardAboutPanelWithOptions:options]; | |
1200 | ||
1201 | /* | |
1202 | * This replaces the old about dialog with a standard alert that displays | |
1203 | * correctly on 10.14. | |
1204 | */ | |
1205 | ||
1206 | NSString *version = @"Tcl " TCL_PATCH_LEVEL " & Tk " TCL_PATCH_LEVEL; | |
1207 | NSString *url = @"www.tcl-lang.org"; | |
1208 | NSTextView *credits = [[NSTextView alloc] initWithFrame:NSMakeRect(0,0,300,300)]; | |
1209 | NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSize]]; | |
1210 | NSDictionary *textAttributes = [NSDictionary dictionaryWithObject:font | |
1211 | forKey:NSFontAttributeName]; | |
1212 | [credits insertText: [[NSAttributedString alloc] | |
1213 | initWithString:[NSString stringWithFormat: @"\n" | |
1214 | "Tcl and Tk are distributed under a modified BSD license: " | |
1215 | "www.tcl.tk/software/tcltk/license.html\n\n" | |
1216 | "%1$C 1987-%2$@ Tcl Core Team and Contributers.\n\n" | |
1217 | "%1$C 2011-%2$@ Kevin Walzer/WordTech Communications LLC.\n\n" | |
1218 | "%1$C 2014-%2$@ Marc Culler.\n\n" | |
1219 | "%1$C 2002-2012 Daniel A. Steffen.\n\n" | |
1220 | "%1$C 2001-2009 Apple Inc.\n\n" | |
1221 | "%1$C 2001-2002 Jim Ingham & Ian Reid\n\n" | |
1222 | "%1$C 1998-2000 Jim Ingham & Ray Johnson\n\n" | |
1223 | "%1$C 1998-2000 Scriptics Inc.\n\n" | |
1224 | "%1$C 1996-1997 Sun Microsystems Inc.", 0xA9, year] | |
1225 | attributes:textAttributes] | |
1226 | replacementRange:NSMakeRange(0,0)]; | |
1227 | [credits setDrawsBackground:NO]; | |
1228 | [credits setEditable:NO]; | |
1229 | NSAlert *about = [[NSAlert alloc] init]; | |
1230 | [[about window] setTitle:@"About Tcl & Tk"]; | |
1231 | [about setMessageText: version]; | |
1232 | [about setInformativeText:url]; | |
1233 | about.accessoryView = credits; | |
1234 | [about runModal]; | |
1235 | [about release]; | |
1230 | 1236 | } |
1231 | 1237 | |
1232 | 1238 | /* |
1256 | 1262 | Tcl_WrongNumArgs(interp, 1, objv, NULL); |
1257 | 1263 | return TCL_ERROR; |
1258 | 1264 | } |
1259 | [NSApp orderFrontStandardAboutPanelWithOptions:[NSDictionary dictionary]]; | |
1265 | TkAboutDlg(); | |
1260 | 1266 | return TCL_OK; |
1261 | 1267 | } |
1262 | 1268 | |
1329 | 1335 | |
1330 | 1336 | case ALERT_ICON: |
1331 | 1337 | if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings, |
1332 | sizeof(char *), "value", TCL_EXACT, &iconIndex) != TCL_OK) { | |
1338 | sizeof(char *), "-icon value", TCL_EXACT, &iconIndex) != TCL_OK) { | |
1333 | 1339 | goto end; |
1334 | 1340 | } |
1335 | 1341 | break; |
1359 | 1365 | |
1360 | 1366 | case ALERT_TYPE: |
1361 | 1367 | if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings, |
1362 | sizeof(char *), "value", TCL_EXACT, &typeIndex) != TCL_OK) { | |
1368 | sizeof(char *), "-type value", TCL_EXACT, &typeIndex) != TCL_OK) { | |
1363 | 1369 | goto end; |
1364 | 1370 | } |
1365 | 1371 | break; |
1375 | 1381 | */ |
1376 | 1382 | |
1377 | 1383 | if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1], |
1378 | alertButtonStrings, sizeof(char *), "value", TCL_EXACT, &index) != TCL_OK) { | |
1384 | alertButtonStrings, sizeof(char *), "-default value", TCL_EXACT, &index) != TCL_OK) { | |
1379 | 1385 | goto end; |
1380 | 1386 | } |
1381 | 1387 |
16 | 16 | #include "tkMacOSXPrivate.h" |
17 | 17 | #include "tkMacOSXDebug.h" |
18 | 18 | #include "tkButton.h" |
19 | ||
20 | #if MAC_OS_X_VERSION_MIN_REQUIRED >= 101400 | |
21 | #define GET_CGCONTEXT [[NSGraphicsContext currentContext] CGContext] | |
22 | #else | |
23 | #define GET_CGCONTEXT [[NSGraphicsContext currentContext] graphicsPort] | |
24 | #endif | |
19 | 25 | |
20 | 26 | /* |
21 | 27 | #ifdef TK_MAC_DEBUG |
103 | 109 | * TkMacOSXBitmapRepFromDrawableRect |
104 | 110 | * |
105 | 111 | * Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep. |
112 | * | |
113 | * This is only used by XGetImage, which is never called. And this | |
114 | * implementation does not work correctly. Originally it relied on | |
115 | * [NSBitmapImageRep initWithFocusedViewRect:view_rect] which was | |
116 | * deprecated by Apple in OSX 10.14 and also required the use of other | |
117 | * deprecated functions such as [NSView lockFocus]. Apple's suggested | |
118 | * replacement is [NSView cacheDisplayInRect: toBitmapImageRep:] and that | |
119 | * is what is being used here. However, that method only works when the | |
120 | * view has a valid CGContext, and a view is only guaranteed to have a | |
121 | * valid context during a call to [NSView drawRect]. To further | |
122 | * complicate matters, cacheDisplayInRect calls [NSView drawRect]. | |
123 | * Essentially it is asking the view to draw a subrectangle of itself into | |
124 | * a special graphics context which is linked to the BitmapImageRep. But | |
125 | * our implementation of [NSView drawRect] does not allow recursive calls. | |
126 | * If called recursively it returns immediately without doing any drawing. | |
127 | * So the bottom line is that this function either returns a NULL pointer | |
128 | * or a black image. To make it useful would require a significant amount | |
129 | * of rewriting of the drawRect method. Perhaps the next release of OSX | |
130 | * will include some more helpful ways of doing this. | |
106 | 131 | * |
107 | 132 | * Results: |
108 | 133 | * Returns an NSBitmapRep representing the image of the given |
127 | 152 | unsigned int height) |
128 | 153 | { |
129 | 154 | MacDrawable *mac_drawable = (MacDrawable *) drawable; |
130 | CGContextRef cg_context=NULL; | |
131 | CGImageRef cg_image=NULL, sub_cg_image=NULL; | |
132 | NSBitmapImageRep *bitmap_rep=NULL; | |
155 | CGContextRef cg_context = NULL; | |
156 | CGImageRef cg_image=NULL, sub_cg_image = NULL; | |
157 | NSBitmapImageRep *bitmap_rep = NULL; | |
133 | 158 | NSView *view=NULL; |
134 | 159 | if ( mac_drawable->flags & TK_IS_PIXMAP ) { |
160 | ||
135 | 161 | /* |
136 | * This means that the MacDrawable is functioning as a | |
137 | * Tk Pixmap, so its view field is NULL. | |
138 | */ | |
162 | * This MacDrawable is a bitmap, so its view is NULL. | |
163 | */ | |
164 | ||
139 | 165 | cg_context = TkMacOSXGetCGContextForDrawable(drawable); |
140 | 166 | CGRect image_rect = CGRectMake(x, y, width, height); |
141 | 167 | cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context); |
148 | 174 | CGImageRelease(cg_image); |
149 | 175 | } |
150 | 176 | } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) { |
177 | ||
151 | 178 | /* |
152 | 179 | * Convert Tk top-left to NSView bottom-left coordinates. |
153 | 180 | */ |
181 | ||
154 | 182 | int view_height = [view bounds].size.height; |
155 | 183 | NSRect view_rect = NSMakeRect(x + mac_drawable->xOff, |
156 | 184 | view_height - height - y - mac_drawable->yOff, |
157 | 185 | width, height); |
158 | 186 | |
159 | if ( [view lockFocusIfCanDraw] ) { | |
160 | bitmap_rep = [NSBitmapImageRep alloc]; | |
161 | bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect]; | |
162 | [view unlockFocus]; | |
187 | /* | |
188 | * Attempt to copy from the view to a bitmapImageRep. If the view does | |
189 | * not have a valid CGContext, doing this will silently corrupt memory | |
190 | * and make a big mess. So, in that case, we mark the view as needing | |
191 | * display and return NULL. | |
192 | */ | |
193 | ||
194 | if (view == [NSView focusView]) { | |
195 | bitmap_rep = [view bitmapImageRepForCachingDisplayInRect: view_rect]; | |
196 | [bitmap_rep retain]; | |
197 | [view cacheDisplayInRect:view_rect toBitmapImageRep:bitmap_rep]; | |
163 | 198 | } else { |
164 | TkMacOSXDbgMsg("Could not lock focus on view."); | |
165 | } | |
166 | ||
199 | TkMacOSXDbgMsg("No CGContext - cannot copy from screen to bitmap."); | |
200 | [view setNeedsDisplay:YES]; | |
201 | return NULL; | |
202 | } | |
167 | 203 | } else { |
168 | 204 | TkMacOSXDbgMsg("Invalid source drawable"); |
169 | 205 | } |
204 | 240 | MacDrawable *srcDraw = (MacDrawable *) src; |
205 | 241 | NSBitmapImageRep *bitmap_rep = NULL; |
206 | 242 | CGImageRef img = NULL; |
243 | CGRect bounds, srcRect, dstRect; | |
207 | 244 | |
208 | 245 | display->request++; |
209 | ||
210 | 246 | if (!width || !height) { |
211 | /* This happens all the time. | |
212 | TkMacOSXDbgMsg("Drawing of empty area requested"); | |
213 | */ | |
214 | 247 | return; |
215 | 248 | } |
216 | 249 | |
217 | 250 | if (!TkMacOSXSetupDrawingContext(dst, gc, 1, &dc)) { |
218 | 251 | return; |
219 | /*TkMacOSXDbgMsg("Failed to setup drawing context.");*/ | |
252 | TkMacOSXDbgMsg("Failed to setup drawing context."); | |
220 | 253 | } |
221 | 254 | |
222 | 255 | if ( dc.context ) { |
223 | 256 | if (srcDraw->flags & TK_IS_PIXMAP) { |
224 | 257 | img = TkMacOSXCreateCGImageWithDrawable(src); |
225 | 258 | }else if (TkMacOSXDrawableWindow(src)) { |
226 | bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(src, src_x, src_y, width, height); | |
259 | bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(src, | |
260 | src_x, src_y, width, height); | |
227 | 261 | if ( bitmap_rep ) { |
228 | 262 | img = [bitmap_rep CGImage]; |
229 | 263 | } |
232 | 266 | } |
233 | 267 | |
234 | 268 | if (img) { |
235 | TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background, | |
236 | CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), | |
237 | CGRectMake(src_x, src_y, width, height), | |
238 | CGRectMake(dest_x, dest_y, width, height)); | |
269 | bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height); | |
270 | srcRect = CGRectMake(src_x, src_y, width, height); | |
271 | dstRect = CGRectMake(dest_x, dest_y, width, height); | |
272 | TkMacOSXDrawCGImage(dst, gc, dc.context, img, | |
273 | gc->foreground, gc->background, bounds, srcRect, dstRect); | |
239 | 274 | CFRelease(img); |
240 | ||
241 | ||
242 | 275 | } else { |
243 | 276 | TkMacOSXDbgMsg("Failed to construct CGImage."); |
244 | 277 | } |
287 | 320 | TkMacOSXDrawingContext dc; |
288 | 321 | MacDrawable *srcDraw = (MacDrawable *) src; |
289 | 322 | MacDrawable *dstDraw = (MacDrawable *) dst; |
290 | ||
323 | CGRect bounds, srcRect, dstRect; | |
291 | 324 | display->request++; |
292 | 325 | if (!width || !height) { |
293 | 326 | /* TkMacOSXDbgMsg("Drawing of empty area requested"); */ |
307 | 340 | TkpClipMask *clipPtr = (TkpClipMask *) gc->clip_mask; |
308 | 341 | unsigned long imageBackground = gc->background; |
309 | 342 | if (clipPtr && clipPtr->type == TKP_CLIP_PIXMAP){ |
310 | CGRect srcRect = CGRectMake(src_x, src_y, width, height); | |
343 | srcRect = CGRectMake(src_x, src_y, width, height); | |
311 | 344 | CGImageRef mask = TkMacOSXCreateCGImageWithDrawable(clipPtr->value.pixmap); |
312 | 345 | CGImageRef submask = CGImageCreateWithImageInRect(img, srcRect); |
313 | 346 | CGRect rect = CGRectMake(dest_x, dest_y, width, height); |
332 | 365 | CGImageRelease(submask); |
333 | 366 | CGImageRelease(subimage); |
334 | 367 | } else { |
335 | TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground, | |
336 | CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), | |
337 | CGRectMake(src_x, src_y, width, height), | |
338 | CGRectMake(dest_x, dest_y, width, height)); | |
368 | bounds = CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height); | |
369 | srcRect = CGRectMake(src_x, src_y, width, height); | |
370 | dstRect = CGRectMake(dest_x, dest_y, width, height); | |
371 | TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, | |
372 | imageBackground, bounds, srcRect, dstRect); | |
339 | 373 | CGImageRelease(img); |
340 | 374 | } |
341 | 375 | } else { /* no image */ |
439 | 473 | int height) |
440 | 474 | { |
441 | 475 | Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0); |
442 | MacDrawable *macDraw = (MacDrawable *) pixmap; | |
443 | 476 | NSImage *nsImage; |
444 | 477 | |
445 | macDraw->flags |= TK_USE_XIMAGE_ALPHA; | |
446 | 478 | Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0); |
447 | 479 | nsImage = CreateNSImageWithPixmap(pixmap, width, height); |
448 | 480 | Tk_FreePixmap(display, pixmap); |
595 | 627 | } |
596 | 628 | } |
597 | 629 | dstBounds = CGRectOffset(dstBounds, macDraw->xOff, macDraw->yOff); |
598 | ||
599 | 630 | if (CGImageIsMask(image)) { |
600 | /*CGContextSaveGState(context);*/ | |
601 | 631 | if (macDraw->flags & TK_IS_BW_PIXMAP) { |
602 | /* Set fill color to black, background comes from the context, or is transparent. */ | |
632 | ||
633 | /* Set fill color to black; background comes from the context, | |
634 | * or is transparent. | |
635 | */ | |
636 | ||
603 | 637 | if (imageBackground != TRANSPARENT_PIXEL << 24) { |
604 | 638 | CGContextClearRect(context, dstBounds); |
605 | 639 | } |
1447 | 1481 | *---------------------------------------------------------------------- |
1448 | 1482 | */ |
1449 | 1483 | |
1450 | int | |
1484 | Bool | |
1451 | 1485 | TkMacOSXSetupDrawingContext( |
1452 | 1486 | Drawable d, |
1453 | 1487 | GC gc, |
1455 | 1489 | TkMacOSXDrawingContext *dcPtr) |
1456 | 1490 | { |
1457 | 1491 | MacDrawable *macDraw = ((MacDrawable*)d); |
1458 | int dontDraw = 0, isWin = 0; | |
1492 | Bool canDraw = true; | |
1493 | NSWindow *win = NULL; | |
1459 | 1494 | TkMacOSXDrawingContext dc = {}; |
1460 | 1495 | CGRect clipBounds; |
1461 | 1496 | |
1497 | /* | |
1498 | * If we are simulating drawing for tests, just return false. | |
1499 | */ | |
1500 | ||
1501 | if ([NSApp simulateDrawing]) { | |
1502 | return false; | |
1503 | } | |
1504 | ||
1505 | /* | |
1506 | * If the drawable is not a pixmap and it has an associated | |
1507 | * NSWindow then we know we are drawing to a window. | |
1508 | */ | |
1509 | ||
1510 | if (!(macDraw->flags & TK_IS_PIXMAP)) { | |
1511 | win = TkMacOSXDrawableWindow(d); | |
1512 | } | |
1513 | ||
1514 | /* | |
1515 | * Check that we have a non-empty clipping region. | |
1516 | */ | |
1517 | ||
1462 | 1518 | dc.clipRgn = TkMacOSXGetClipRgn(d); |
1463 | if (!dontDraw) { | |
1464 | ClipToGC(d, gc, &dc.clipRgn); | |
1465 | dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0; | |
1466 | } | |
1467 | if (dontDraw) { | |
1519 | ClipToGC(d, gc, &dc.clipRgn); | |
1520 | if (dc.clipRgn && HIShapeIsEmpty(dc.clipRgn)) { | |
1521 | canDraw = false; | |
1468 | 1522 | goto end; |
1469 | 1523 | } |
1470 | if (useCG) { | |
1471 | dc.context = TkMacOSXGetCGContextForDrawable(d); | |
1472 | } | |
1473 | if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) { | |
1474 | isWin = (TkMacOSXDrawableWindow(d) != nil); | |
1475 | } | |
1524 | ||
1525 | /* | |
1526 | * If we already have a CGContext, use it. Otherwise, if we | |
1527 | * are drawing to a window then we can get one from the | |
1528 | * window. | |
1529 | */ | |
1530 | ||
1531 | dc.context = TkMacOSXGetCGContextForDrawable(d); | |
1476 | 1532 | if (dc.context) { |
1477 | 1533 | dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context); |
1478 | } else if (isWin) { | |
1534 | } else if (win) { | |
1479 | 1535 | NSView *view = TkMacOSXDrawableView(macDraw); |
1480 | 1536 | if (view) { |
1481 | if (view != [NSView focusView]) { | |
1482 | dc.focusLocked = [view lockFocusIfCanDraw]; | |
1483 | dontDraw = !dc.focusLocked; | |
1484 | } else { | |
1485 | dontDraw = ![view canDraw]; | |
1486 | } | |
1487 | if (dontDraw) { | |
1488 | goto end; | |
1489 | } | |
1490 | [[view window] disableFlushWindow]; | |
1537 | ||
1538 | /* | |
1539 | * We can only draw into the view when the current CGContext is | |
1540 | * valid and belongs to the view. Validity can only be guaranteed | |
1541 | * inside of a view's drawRect or setFrame methods. The isDrawing | |
1542 | * attribute tells us whether we are being called from one of those | |
1543 | * methods. | |
1544 | * | |
1545 | * If the CGContext is not valid, or belongs to a different View, | |
1546 | * then we mark our view as needing display and return failure. | |
1547 | * It should get drawn in a later call to drawRect. | |
1548 | */ | |
1549 | ||
1550 | if (view != [NSView focusView]) { | |
1551 | [view setNeedsDisplay:YES]; | |
1552 | canDraw = false; | |
1553 | goto end; | |
1554 | } | |
1491 | 1555 | dc.view = view; |
1492 | dc.context = [[NSGraphicsContext currentContext] graphicsPort]; | |
1556 | dc.context = GET_CGCONTEXT; | |
1493 | 1557 | dc.portBounds = NSRectToCGRect([view bounds]); |
1494 | 1558 | if (dc.clipRgn) { |
1495 | 1559 | clipBounds = CGContextGetClipBoundingBox(dc.context); |
1502 | 1566 | Tcl_Panic("TkMacOSXSetupDrawingContext(): " |
1503 | 1567 | "no context to draw into !"); |
1504 | 1568 | } |
1569 | ||
1570 | /* | |
1571 | * Configure the drawing context. | |
1572 | */ | |
1573 | ||
1505 | 1574 | if (dc.context) { |
1506 | 1575 | CGAffineTransform t = { .a = 1, .b = 0, .c = 0, .d = -1, .tx = 0, |
1507 | 1576 | .ty = dc.portBounds.size.height}; |
1508 | 1577 | dc.portBounds.origin.x += macDraw->xOff; |
1509 | 1578 | dc.portBounds.origin.y += macDraw->yOff; |
1510 | if (!dc.focusLocked) { | |
1511 | CGContextSaveGState(dc.context); | |
1512 | } | |
1579 | CGContextSaveGState(dc.context); | |
1513 | 1580 | CGContextSetTextDrawingMode(dc.context, kCGTextFill); |
1514 | 1581 | CGContextConcatCTM(dc.context, t); |
1515 | 1582 | if (dc.clipRgn) { |
1544 | 1611 | double w = gc->line_width; |
1545 | 1612 | |
1546 | 1613 | TkMacOSXSetColorInContext(gc, gc->foreground, dc.context); |
1547 | if (isWin) { | |
1614 | if (win) { | |
1548 | 1615 | CGContextSetPatternPhase(dc.context, CGSizeMake( |
1549 | 1616 | dc.portBounds.size.width, dc.portBounds.size.height)); |
1550 | 1617 | } |
1582 | 1649 | } |
1583 | 1650 | } |
1584 | 1651 | } |
1652 | ||
1585 | 1653 | end: |
1586 | if (dontDraw && dc.clipRgn) { | |
1654 | #ifdef TK_MAC_DEBUG_DRAWING | |
1655 | if (!canDraw && win != NULL) { | |
1656 | TkWindow *winPtr = TkMacOSXGetTkWindow(win); | |
1657 | if (winPtr) fprintf(stderr, "Cannot draw in %s - postponing.\n", | |
1658 | Tk_PathName(winPtr)); | |
1659 | } | |
1660 | #endif | |
1661 | if (!canDraw && dc.clipRgn) { | |
1587 | 1662 | CFRelease(dc.clipRgn); |
1588 | 1663 | dc.clipRgn = NULL; |
1589 | 1664 | } |
1590 | 1665 | *dcPtr = dc; |
1591 | return !dontDraw; | |
1666 | return canDraw; | |
1592 | 1667 | } |
1593 | 1668 | |
1594 | 1669 | /* |
1613 | 1688 | { |
1614 | 1689 | if (dcPtr->context) { |
1615 | 1690 | CGContextSynchronize(dcPtr->context); |
1616 | [[dcPtr->view window] setViewsNeedDisplay:YES]; | |
1617 | [[dcPtr->view window] enableFlushWindow]; | |
1618 | if (dcPtr->focusLocked) { | |
1619 | [dcPtr->view unlockFocus]; | |
1620 | } else { | |
1621 | CGContextRestoreGState(dcPtr->context); | |
1622 | } | |
1691 | CGContextRestoreGState(dcPtr->context); | |
1623 | 1692 | } |
1624 | 1693 | if (dcPtr->clipRgn) { |
1625 | 1694 | CFRelease(dcPtr->clipRgn); |
1658 | 1727 | #ifdef TK_MAC_DEBUG_DRAWING |
1659 | 1728 | TkMacOSXDbgMsg("%s", macDraw->winPtr->pathName); |
1660 | 1729 | NSView *view = TkMacOSXDrawableView(macDraw); |
1661 | if ([view lockFocusIfCanDraw]) { | |
1662 | CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort]; | |
1663 | CGContextSaveGState(context); | |
1664 | CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0, | |
1665 | -1.0, 0.0, [view bounds].size.height)); | |
1666 | ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context); | |
1667 | CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1); | |
1668 | CGContextEOFillPath(context); | |
1669 | CGContextRestoreGState(context); | |
1670 | [view unlockFocus]; | |
1671 | } | |
1730 | CGContextSaveGState(context); | |
1731 | CGContextConcatCTM(context, CGAffineTransformMake(1.0, 0.0, 0.0, | |
1732 | -1.0, 0.0, [view bounds].size.height)); | |
1733 | ChkErr(HIShapeReplacePathInCGContext, macDraw->visRgn, context); | |
1734 | CGContextSetRGBFillColor(context, 0.0, 1.0, 0.0, 0.1); | |
1735 | CGContextEOFillPath(context); | |
1736 | CGContextRestoreGState(context); | |
1672 | 1737 | #endif /* TK_MAC_DEBUG_DRAWING */ |
1673 | 1738 | } |
1674 | 1739 | |
1728 | 1793 | int width, int height) |
1729 | 1794 | { |
1730 | 1795 | MacDrawable *macDraw = (MacDrawable *) d; |
1731 | NSView *view = TkMacOSXDrawableView(macDraw); | |
1732 | 1796 | |
1733 | 1797 | if (macDraw->drawRgn) { |
1734 | 1798 | CFRelease(macDraw->drawRgn); |
1735 | 1799 | macDraw->drawRgn = NULL; |
1736 | 1800 | } |
1737 | ||
1738 | 1801 | if (width >= 0 && height >= 0) { |
1739 | 1802 | CGRect clipRect = CGRectMake(x + macDraw->xOff, y + macDraw->yOff, |
1740 | 1803 | width, height); |
1749 | 1812 | CFRelease(drawRgn); |
1750 | 1813 | } else { |
1751 | 1814 | macDraw->drawRgn = drawRgn; |
1752 | } | |
1753 | if (view && view != [NSView focusView] && [view lockFocusIfCanDraw]) { | |
1754 | clipRect.origin.y = [view bounds].size.height - | |
1755 | (clipRect.origin.y + clipRect.size.height); | |
1756 | NSRectClip(NSRectFromCGRect(clipRect)); | |
1757 | macDraw->flags |= TK_FOCUSED_VIEW; | |
1758 | } | |
1759 | } else { | |
1760 | if (view && (macDraw->flags & TK_FOCUSED_VIEW)) { | |
1761 | [view unlockFocus]; | |
1762 | macDraw->flags &= ~TK_FOCUSED_VIEW; | |
1763 | 1815 | } |
1764 | 1816 | } |
1765 | 1817 | } |
804 | 804 | */ |
805 | 805 | return; |
806 | 806 | } |
807 | ||
807 | ||
808 | 808 | /* |
809 | 809 | * Ignore any X protocol errors that happen in this procedure (almost any |
810 | 810 | * operation could fail, for example, if the embedded application has |
111 | 111 | * |
112 | 112 | * TkMacOSXFlushWindows -- |
113 | 113 | * |
114 | * This routine flushes all the visible windows of the application. It is | |
115 | * called by XSync(). | |
114 | * This routine is a stub called by XSync, which is called during the Tk | |
115 | * update command. The language specification does not require that the | |
116 | * update command be synchronous but many of the tests assume that is the | |
117 | * case. It is not naturally the case on macOS since many idle tasks are | |
118 | * run inside of the drawRect method of a window's contentView, and that | |
119 | * method will not be called until after this function returns. To make | |
120 | * the tests work, we attempt to force this to be synchronous by waiting | |
121 | * until drawRect has been called for each window. The mechanism we use | |
122 | * for this is to have drawRect post an ApplicationDefined NSEvent on the | |
123 | * AppKit event queue when it finishes drawing, and wait for it here. | |
116 | 124 | * |
117 | 125 | * Results: |
118 | 126 | * None. |
119 | 127 | * |
120 | 128 | * Side effects: |
121 | * Flushes all visible Cocoa windows | |
129 | * Calls the drawRect method of the contentView of each visible | |
130 | * window. | |
122 | 131 | * |
123 | 132 | *---------------------------------------------------------------------- |
124 | 133 | */ |
127 | 136 | TkMacOSXFlushWindows(void) |
128 | 137 | { |
129 | 138 | NSArray *macWindows = [NSApp orderedWindows]; |
130 | ||
139 | if ([NSApp simulateDrawing]) { | |
140 | [NSApp setSimulateDrawing:NO]; | |
141 | return; | |
142 | } | |
131 | 143 | for (NSWindow *w in macWindows) { |
132 | if (TkMacOSXGetXWindow(w)) { | |
133 | [w flushWindow]; | |
134 | } | |
144 | if (TkMacOSXGetXWindow(w)) { | |
145 | [w displayIfNeeded]; | |
146 | } | |
135 | 147 | } |
136 | 148 | } |
137 | 149 |
13 | 13 | |
14 | 14 | #include "tkMacOSXPrivate.h" |
15 | 15 | #include "tkMacOSXFont.h" |
16 | ||
17 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 | |
16 | #include "tkMacOSXConstants.h" | |
17 | ||
18 | 18 | #define defaultOrientation kCTFontDefaultOrientation |
19 | 19 | #define verticalOrientation kCTFontVerticalOrientation |
20 | #else | |
21 | #define defaultOrientation kCTFontOrientationDefault | |
22 | #define verticalOrientation kCTFontOrientationVertical | |
23 | #endif | |
24 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 101100 | |
25 | 20 | #define fixedPitch kCTFontUserFixedPitchFontType |
26 | #else | |
27 | #define fixedPitch kCTFontUIFontUserFixedPitch | |
28 | #endif | |
29 | 21 | |
30 | 22 | /* |
31 | 23 | #ifdef TK_MAC_DEBUG |
258 | 250 | } |
259 | 251 | fontPtr->nsFont = nsFont; |
260 | 252 | // some don't like antialiasing on fixed-width even if bigger than limit |
261 | // dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10; | |
253 | // dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10; | |
262 | 254 | if (antialiasedTextEnabled >= 0/* || dontAA*/) { |
263 | 255 | renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ? |
264 | 256 | NSFontIntegerAdvancementsRenderingMode : |
818 | 810 | *lengthPtr = 0; |
819 | 811 | return 0; |
820 | 812 | } |
821 | #if 0 | |
822 | /* Back-compatibility with ATSUI renderer, appears not to be needed */ | |
823 | if (rangeStart == 0 && maxLength == 1 && (flags & TK_ISOLATE_END) && | |
824 | !(flags & TK_AT_LEAST_ONE)) { | |
825 | length = 0; | |
826 | fit = 0; | |
827 | goto done; | |
828 | } | |
829 | #endif | |
830 | 813 | if (maxLength > 32767) { |
831 | 814 | maxLength = 32767; |
832 | 815 | } |
859 | 842 | double maxWidth = maxLength + offset; |
860 | 843 | NSCharacterSet *cs; |
861 | 844 | |
845 | /* | |
846 | * Get a line breakpoint in the source string. | |
847 | */ | |
848 | ||
862 | 849 | index = start; |
863 | 850 | if (flags & TK_WHOLE_WORDS) { |
864 | 851 | index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth); |
869 | 856 | if (index <= start && !(flags & TK_WHOLE_WORDS)) { |
870 | 857 | index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth); |
871 | 858 | } |
859 | ||
860 | /* | |
861 | * Trim right whitespace/lineending characters. | |
862 | */ | |
863 | ||
872 | 864 | cs = (index <= len && (flags & TK_WHOLE_WORDS)) ? |
873 | 865 | whitespaceCharacterSet : lineendingCharacterSet; |
874 | 866 | while (index > start && |
875 | 867 | [cs characterIsMember:[string characterAtIndex:(index - 1)]]) { |
876 | 868 | index--; |
877 | 869 | } |
870 | ||
871 | /* | |
872 | * If there is no line breakpoint in the source string between | |
873 | * its start and the index position that fits in maxWidth, then | |
874 | * CTTypesetterSuggestLineBreak() returns that very last index. | |
875 | * However if the TK_WHOLE_WORDS flag is set, we want to break | |
876 | * at a word boundary. In this situation, unless TK_AT_LEAST_ONE | |
877 | * is set, we must report that zero chars actually fit (in other | |
878 | * words the smallest word of the source string is still larger | |
879 | * than maxWidth). | |
880 | */ | |
881 | ||
882 | if ((index >= start) && (index < len) && | |
883 | (flags & TK_WHOLE_WORDS) && !(flags & TK_AT_LEAST_ONE) && | |
884 | ![cs characterIsMember:[string characterAtIndex:index]]) { | |
885 | index = start; | |
886 | } | |
887 | ||
878 | 888 | if (index <= start && (flags & TK_AT_LEAST_ONE)) { |
879 | 889 | index = start + 1; |
880 | 890 | } |
891 | ||
892 | /* | |
893 | * Now measure the string width in pixels. | |
894 | */ | |
895 | ||
881 | 896 | if (index > 0) { |
882 | 897 | range.length = index; |
883 | 898 | line = CTTypesetterCreateLine(typesetter, range); |
920 | 935 | flags & TK_AT_LEAST_ONE ? "atLeastOne " : "", |
921 | 936 | flags & TK_ISOLATE_END ? "isolateEnd " : "", |
922 | 937 | length, fit); |
923 | //if (!(rangeLength==1 && rangeStart == 0)) fprintf(stderr, " measure len=%d (max=%d, w=%.0f) from %d (nb=%d): source=\"%s\": index=%d return %d\n",rangeLength,maxLength,width,rangeStart,numBytes, source+rangeStart, index, fit); | |
924 | 938 | #endif |
925 | 939 | *lengthPtr = length; |
926 | 940 | return fit; |
278 | 278 | Tcl_Interp *interp, |
279 | 279 | const char* procedure) |
280 | 280 | { |
281 | Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8"); | |
281 | Tcl_Encoding utf8; | |
282 | 282 | const AEDesc *fileSpecDesc = nil; |
283 | 283 | AEDesc contents; |
284 | 284 | char URLString[1 + URL_MAX_LENGTH]; |
330 | 330 | |
331 | 331 | Tcl_DStringInit(&command); |
332 | 332 | Tcl_DStringAppend(&command, procedure, -1); |
333 | utf8 = Tcl_GetEncoding(NULL, "utf-8"); | |
333 | 334 | |
334 | 335 | for (index = 1; index <= count; index++) { |
335 | 336 | if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword, |
348 | 349 | Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName)); |
349 | 350 | Tcl_DStringFree(&pathName); |
350 | 351 | } |
352 | ||
353 | Tcl_FreeEncoding(utf8); | |
351 | 354 | AEDisposeDesc(&contents); |
352 | 355 | |
353 | 356 | /* |
360 | 363 | Tcl_BackgroundException(interp, code); |
361 | 364 | } |
362 | 365 | Tcl_DStringFree(&command); |
363 | return; | |
364 | 366 | } |
365 | 367 | |
366 | 368 | /* |
5 | 5 | * Copyright (c) 1995-1997 Sun Microsystems, Inc. |
6 | 6 | * Copyright 2001-2009, Apple Inc. |
7 | 7 | * Copyright (c) 2005-2009 Daniel A. Steffen <das@users.sourceforge.net> |
8 | * Copyright 2017 Marc Culler. | |
8 | * Copyright 2017-2018 Marc Culler. | |
9 | 9 | * |
10 | 10 | * See the file "license.terms" for information on usage and redistribution |
11 | 11 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
28 | 28 | * |
29 | 29 | * TkMacOSXCreateCGImageWithXImage -- |
30 | 30 | * |
31 | * Create CGImage from XImage, copying the image data. | |
31 | * Create CGImage from XImage, copying the image data. Called | |
32 | * in Tk_PutImage and (currently) nowhere else. | |
32 | 33 | * |
33 | 34 | * Results: |
34 | 35 | * CGImage, release after use. |
45 | 46 | |
46 | 47 | CGImageRef |
47 | 48 | TkMacOSXCreateCGImageWithXImage( |
48 | XImage *image, | |
49 | int use_ximage_alpha) | |
49 | XImage *image) | |
50 | 50 | { |
51 | 51 | CGImageRef img = NULL; |
52 | 52 | size_t bitsPerComponent, bitsPerPixel; |
87 | 87 | bitsPerPixel, image->bytes_per_line, provider, decode, 0); |
88 | 88 | } |
89 | 89 | } else if (image->format == ZPixmap && image->bits_per_pixel == 32) { |
90 | ||
90 | 91 | /* |
91 | 92 | * Color image |
92 | 93 | */ |
93 | 94 | |
94 | 95 | CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); |
95 | ||
96 | 96 | bitsPerComponent = 8; |
97 | 97 | bitsPerPixel = 32; |
98 | 98 | bitmapInfo = (image->byte_order == MSBFirst ? |
99 | kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little); | |
100 | if (use_ximage_alpha) { | |
101 | bitmapInfo |= kCGImageAlphaPremultipliedFirst; | |
102 | } else { | |
103 | bitmapInfo |= kCGImageAlphaNoneSkipFirst; | |
104 | } | |
99 | kCGBitmapByteOrder32Little : kCGBitmapByteOrder32Big); | |
100 | bitmapInfo |= kCGImageAlphaLast; | |
105 | 101 | data = memcpy(ckalloc(len), image->data + image->xoffset, len); |
106 | 102 | if (data) { |
107 | 103 | provider = CGDataProviderCreateWithData(data, data, len, releaseData); |
127 | 123 | * |
128 | 124 | * XGetImage -- |
129 | 125 | * |
130 | * This function copies data from a pixmap or window into an XImage. | |
126 | * This function copies data from a pixmap or window into an XImage. It | |
127 | * is essentially never used. At one time it was called by | |
128 | * pTkImgPhotoDisplay, but that is no longer the case. Currently it is | |
129 | * called two places, one of which is requesting an XY image which we do | |
130 | * not support. It probably does not work correctly -- see the comments | |
131 | * for TkMacOSXBitmapRepFromDrawableRect. | |
131 | 132 | * |
132 | 133 | * Results: |
133 | 134 | * Returns a newly allocated XImage containing the data from the given |
164 | 165 | unsigned int bytes_per_row, size, row, n, m; |
165 | 166 | unsigned int scalefactor=1, scaled_height=height, scaled_width=width; |
166 | 167 | NSWindow *win = TkMacOSXDrawableWindow(drawable); |
167 | MacDrawable *macDraw = ((MacDrawable*)drawable); | |
168 | 168 | static enum {unknown, no, yes} has_retina = unknown; |
169 | 169 | |
170 | 170 | if (win && has_retina == unknown) { |
177 | 177 | } |
178 | 178 | |
179 | 179 | if (has_retina == yes) { |
180 | ||
180 | 181 | /* |
181 | 182 | * We only allow scale factors 1 or 2, as Apple currently does. |
182 | 183 | */ |
184 | ||
183 | 185 | #ifdef __clang__ |
184 | 186 | scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1; |
185 | 187 | #endif |
191 | 193 | if (width == 0 || height == 0) { |
192 | 194 | return NULL; |
193 | 195 | } |
196 | ||
194 | 197 | bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable, |
195 | x, y, width, height); | |
198 | x, y, width, height); | |
196 | 199 | if (!bitmap_rep) { |
197 | 200 | TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep"); |
198 | 201 | return NULL; |
205 | 208 | (bitmap_fmt != 0 && bitmap_fmt != 1) || |
206 | 209 | [bitmap_rep samplesPerPixel] != 4 || |
207 | 210 | [bitmap_rep isPlanar] != 0 || |
208 | bytes_per_row != 4 * scaled_width || | |
211 | bytes_per_row < 4 * scaled_width || | |
209 | 212 | size != bytes_per_row*scaled_height ) { |
210 | 213 | TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format"); |
211 | 214 | CFRelease(bitmap_rep); |
212 | 215 | return NULL; |
213 | 216 | } |
214 | ||
215 | if (macDraw->flags & TK_USE_XIMAGE_ALPHA) { | |
216 | /* | |
217 | * When called by TkImgPhotoDisplay we are being asked to return a | |
218 | * background image to be blended with the photoimage using its | |
219 | * alpha channel, if it has one. Returning a black pixmap here | |
220 | * makes TkImgPhotoDisplay create an XImage with a premultiplied | |
221 | * alpha channel, as favored by Apple. When TkImgPhotoDisplay | |
222 | * passes this XImage to TkPutImage, targeting a pixmap, it creates | |
223 | * an image with correct transparency. This is used, for example, | |
224 | * when creating an iconphoto or a menu image from a PNG | |
225 | * photoimage. | |
226 | */ | |
227 | bzero(bitmap, size); | |
228 | } else { | |
229 | memcpy(bitmap, (char *)[bitmap_rep bitmapData], size); | |
230 | } | |
217 | memcpy(bitmap, (char *)[bitmap_rep bitmapData], size); | |
231 | 218 | CFRelease(bitmap_rep); |
232 | 219 | |
233 | 220 | /* |
234 | 221 | * When Apple extracts a bitmap from an NSView, it may be in |
235 | 222 | * either BGRA or ABGR format. For an XImage we need RGBA. |
236 | 223 | */ |
224 | ||
237 | 225 | struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr; |
238 | 226 | |
239 | for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) { | |
240 | for (m=n; m<n+bytes_per_row; m+=4) { | |
227 | for (row = 0, n = 0; row < scaled_height; row++, n += bytes_per_row) { | |
228 | for (m = n; m < n + 4*scaled_width; m += 4) { | |
241 | 229 | R = *(bitmap + m + pixel.r); |
242 | 230 | G = *(bitmap + m + pixel.g); |
243 | 231 | B = *(bitmap + m + pixel.b); |
513 | 501 | * |
514 | 502 | * TkPutImage -- |
515 | 503 | * |
516 | * Copies a subimage from an in-memory image to a rectangle of | |
517 | * of the specified drawable. | |
504 | * Copies a rectangular subimage of an XImage into a drawable. | |
505 | * Currently this is only called by TkImgPhotoDisplay, using | |
506 | * a Window as the drawable. | |
518 | 507 | * |
519 | 508 | * Results: |
520 | 509 | * None. |
541 | 530 | unsigned int height) /* distination and source. */ |
542 | 531 | { |
543 | 532 | TkMacOSXDrawingContext dc; |
544 | MacDrawable *macDraw = ((MacDrawable*)drawable); | |
533 | MacDrawable *macDraw = (MacDrawable *) drawable; | |
545 | 534 | |
546 | 535 | display->request++; |
547 | 536 | if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) { |
548 | 537 | return BadDrawable; |
549 | 538 | } |
550 | 539 | if (dc.context) { |
551 | CGImageRef img = TkMacOSXCreateCGImageWithXImage(image, | |
552 | macDraw->flags & TK_USE_XIMAGE_ALPHA); | |
540 | CGRect bounds, srcRect, dstRect; | |
541 | CGImageRef img = TkMacOSXCreateCGImageWithXImage(image); | |
542 | ||
543 | /* | |
544 | * The CGContext for a pixmap is RGB only, with A = 0. | |
545 | */ | |
546 | ||
547 | if (!(macDraw->flags & TK_IS_PIXMAP)) { | |
548 | CGContextSetBlendMode(dc.context, kCGBlendModeSourceAtop); | |
549 | } | |
553 | 550 | if (img) { |
554 | /* If the XImage has big pixels, rescale the source dimensions.*/ | |
551 | ||
552 | /* If the XImage has big pixels, the source is rescaled to reflect | |
553 | * the actual pixel dimensions. This is not currently used, but | |
554 | * could arise if the image were copied from a retina monitor and | |
555 | * redrawn on an ordinary monitor. | |
556 | */ | |
557 | ||
555 | 558 | int pp = image->pixelpower; |
559 | bounds = CGRectMake(0, 0, image->width, image->height); | |
560 | srcRect = CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp); | |
561 | dstRect = CGRectMake(dest_x, dest_y, width, height); | |
556 | 562 | TkMacOSXDrawCGImage(drawable, gc, dc.context, |
557 | img, gc->foreground, gc->background, | |
558 | CGRectMake(0, 0, image->width<<pp, image->height<<pp), | |
559 | CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp), | |
560 | CGRectMake(dest_x, dest_y, width, height)); | |
563 | img, gc->foreground, gc->background, | |
564 | bounds, srcRect, dstRect); | |
561 | 565 | CFRelease(img); |
562 | 566 | } else { |
563 | 567 | TkMacOSXDbgMsg("Invalid source drawable"); |
15 | 15 | #include "tkMacOSXPrivate.h" |
16 | 16 | |
17 | 17 | #include <sys/stat.h> |
18 | #include <sys/utsname.h> | |
19 | 18 | #include <dlfcn.h> |
20 | 19 | #include <objc/objc-auto.h> |
21 | 20 | |
27 | 26 | */ |
28 | 27 | |
29 | 28 | static char scriptPath[PATH_MAX + 1] = ""; |
30 | ||
31 | long tkMacOSXMacOSXVersion = 0; | |
32 | 29 | |
33 | 30 | #pragma mark TKApplication(TKInit) |
34 | 31 | |
47 | 44 | |
48 | 45 | @implementation TKApplication |
49 | 46 | @synthesize poolLock = _poolLock; |
47 | @synthesize macMinorVersion = _macMinorVersion; | |
48 | @synthesize isDrawing = _isDrawing; | |
49 | @synthesize simulateDrawing = _simulateDrawing; | |
50 | 50 | @end |
51 | 51 | |
52 | 52 | /* |
152 | 152 | [NSApp setPoolLock:0]; |
153 | 153 | |
154 | 154 | /* |
155 | * Record the OS version we are running on. | |
156 | */ | |
157 | int minorVersion; | |
158 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 101000 | |
159 | Gestalt(gestaltSystemVersionMinor, (SInt32*)&minorVersion); | |
160 | #else | |
161 | NSOperatingSystemVersion systemVersion; | |
162 | systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; | |
163 | minorVersion = systemVersion.minorVersion; | |
164 | #endif | |
165 | [NSApp setMacMinorVersion: minorVersion]; | |
166 | ||
167 | /* | |
168 | * We are not drawing yet. | |
169 | */ | |
170 | ||
171 | [NSApp setIsDrawing:NO]; | |
172 | [NSApp setSimulateDrawing:NO]; | |
173 | ||
174 | /* | |
155 | 175 | * Be our own delegate. |
156 | 176 | */ |
157 | 177 | [self setDelegate:self]; |
159 | 179 | /* |
160 | 180 | * Make sure we are allowed to open windows. |
161 | 181 | */ |
182 | ||
162 | 183 | [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; |
163 | 184 | |
164 | 185 | /* |
254 | 275 | */ |
255 | 276 | |
256 | 277 | if (!initialized) { |
257 | struct utsname name; | |
258 | 278 | struct stat st; |
259 | 279 | |
260 | 280 | initialized = 1; |
266 | 286 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 |
267 | 287 | # error Mac OS X 10.6 required |
268 | 288 | #endif |
269 | ||
270 | if (!uname(&name)) { | |
271 | tkMacOSXMacOSXVersion = (strtod(name.release, NULL) + 96) * 10; | |
272 | } | |
273 | /*Check for new versioning scheme on Yosemite (10.10) and later.*/ | |
274 | if (MAC_OS_X_VERSION_MIN_REQUIRED > 100000) { | |
275 | tkMacOSXMacOSXVersion = MAC_OS_X_VERSION_MIN_REQUIRED/100; | |
276 | } | |
277 | if (tkMacOSXMacOSXVersion && MAC_OS_X_VERSION_MIN_REQUIRED < 100000 && | |
278 | tkMacOSXMacOSXVersion/10 < MAC_OS_X_VERSION_MIN_REQUIRED/10) { | |
279 | Tcl_Panic("Mac OS X 10.%d or later required !", | |
280 | (MAC_OS_X_VERSION_MIN_REQUIRED/10)-100); | |
281 | } | |
282 | ||
283 | 289 | |
284 | 290 | #ifdef TK_FRAMEWORK |
285 | 291 | /* |
82 | 82 | #define TK_CLIP_INVALID 0x02 |
83 | 83 | #define TK_HOST_EXISTS 0x04 |
84 | 84 | #define TK_DRAWN_UNDER_MENU 0x08 |
85 | #define TK_FOCUSED_VIEW 0x10 | |
86 | #define TK_IS_PIXMAP 0x20 | |
87 | #define TK_IS_BW_PIXMAP 0x40 | |
88 | #define TK_DO_NOT_DRAW 0x80 | |
89 | #define TK_USE_XIMAGE_ALPHA 0x100 | |
85 | #define TK_IS_PIXMAP 0x10 | |
86 | #define TK_IS_BW_PIXMAP 0x20 | |
87 | #define TK_DO_NOT_DRAW 0x40 | |
88 | ||
90 | 89 | /* |
91 | 90 | * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags |
92 | 91 | * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the |
198 | 197 | MODULE_SCOPE void TkpRetainRegion(TkRegion r); |
199 | 198 | MODULE_SCOPE void TkpReleaseRegion(TkRegion r); |
200 | 199 | MODULE_SCOPE void TkpShiftButton(NSButton *button, NSPoint delta); |
200 | MODULE_SCOPE Bool TkpAppIsDrawing(void); | |
201 | MODULE_SCOPE void TkpDisplayWindow(Tk_Window tkwin); | |
202 | MODULE_SCOPE void TkTestSimulateDrawing(Bool); | |
203 | ||
201 | 204 | /* |
202 | 205 | * Include the stubbed internal platform-specific API. |
203 | 206 | */ |
39 | 39 | |
40 | 40 | static void setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state); |
41 | 41 | static unsigned isFunctionKey(unsigned int code); |
42 | ||
43 | unsigned short releaseCode; | |
42 | 44 | |
43 | 45 | |
44 | 46 | #pragma mark TKApplication(TKKeyEvent) |
65 | 67 | processingCompose = NO; |
66 | 68 | } |
67 | 69 | |
70 | w = [theEvent window]; | |
71 | TkWindow *winPtr = TkMacOSXGetTkWindow(w); | |
72 | Tk_Window tkwin = (Tk_Window) winPtr; | |
73 | XEvent xEvent; | |
74 | ||
75 | if (!winPtr) { | |
76 | return theEvent; | |
77 | } | |
78 | ||
68 | 79 | switch (type) { |
69 | 80 | case NSKeyUp: |
70 | if (finishedCompose) | |
71 | { | |
72 | // if we were composing, swallow the last release since we already sent | |
73 | finishedCompose = NO; | |
74 | return theEvent; | |
75 | } | |
81 | /*Fix for bug #1ba71a86bb: key release firing on key press.*/ | |
82 | setupXEvent(&xEvent, w, 0); | |
83 | xEvent.xany.type = KeyRelease; | |
84 | xEvent.xkey.keycode = releaseCode; | |
85 | xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); | |
76 | 86 | case NSKeyDown: |
77 | 87 | repeat = [theEvent isARepeat]; |
78 | 88 | characters = [theEvent characters]; |
81 | 91 | case NSFlagsChanged: |
82 | 92 | modifiers = [theEvent modifierFlags]; |
83 | 93 | keyCode = [theEvent keyCode]; |
84 | // w = [self windowWithWindowNumber:[theEvent windowNumber]]; | |
85 | w = [theEvent window]; | |
94 | ||
86 | 95 | #if defined(TK_MAC_DEBUG_EVENTS) || NS_KEYLOG == 1 |
87 | 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); | |
96 | 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); | |
88 | 97 | #endif |
89 | 98 | break; |
90 | 99 | |
170 | 179 | xEvent.xkey.keycode = (modifiers ^ savedModifiers); |
171 | 180 | } else { |
172 | 181 | if (type == NSKeyUp || repeat) { |
173 | xEvent.xany.type = KeyRelease; | |
182 | xEvent.xany.type = KeyRelease; | |
174 | 183 | } else { |
175 | 184 | xEvent.xany.type = KeyPress; |
176 | 185 | } |
237 | 246 | { |
238 | 247 | int i, len = [(NSString *)aString length]; |
239 | 248 | XEvent xEvent; |
240 | TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); | |
241 | Tk_Window tkwin = (Tk_Window) winPtr; | |
242 | ||
243 | if (NS_KEYLOG) | |
244 | NSLog (@"insertText '%@'\tlen = %d", aString, len); | |
249 | ||
250 | if (NS_KEYLOG) | |
251 | TKLog (@"insertText '%@'\tlen = %d", aString, len); | |
245 | 252 | processingCompose = NO; |
246 | 253 | finishedCompose = YES; |
247 | 254 | |
254 | 261 | xEvent.xany.type = KeyPress; |
255 | 262 | |
256 | 263 | for (i =0; i<len; i++) |
257 | { | |
258 | xEvent.xkey.keycode = (UInt16) [aString characterAtIndex: i]; | |
259 | [[aString substringWithRange: NSMakeRange(i,1)] | |
260 | getCString: xEvent.xkey.trans_chars | |
261 | maxLength: XMaxTransChars encoding: NSUTF8StringEncoding]; | |
262 | xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars); | |
263 | xEvent.xany.type = KeyPress; | |
264 | Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); | |
265 | ||
266 | xEvent.xany.type = KeyRelease; | |
267 | xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); | |
268 | Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); | |
269 | xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); | |
270 | } | |
264 | { | |
265 | xEvent.xkey.keycode = (UInt16) [aString characterAtIndex: i]; | |
266 | [[aString substringWithRange: NSMakeRange(i,1)] | |
267 | getCString: xEvent.xkey.trans_chars | |
268 | maxLength: XMaxTransChars encoding: NSUTF8StringEncoding]; | |
269 | xEvent.xkey.nbytes = strlen(xEvent.xkey.trans_chars); | |
270 | xEvent.xany.type = KeyPress; | |
271 | releaseCode = (UInt16) [aString characterAtIndex: 0]; | |
272 | Tk_QueueWindowEvent(&xEvent, TCL_QUEUE_TAIL); | |
273 | } | |
274 | releaseCode = (UInt16) [aString characterAtIndex: 0]; | |
271 | 275 | } |
272 | 276 | |
273 | 277 | |
277 | 281 | NSString *str = [aString respondsToSelector: @selector (string)] ? |
278 | 282 | [aString string] : aString; |
279 | 283 | if (NS_KEYLOG) |
280 | NSLog (@"setMarkedText '%@' len =%lu range %lu from %lu", str, | |
284 | TKLog (@"setMarkedText '%@' len =%lu range %lu from %lu", str, | |
281 | 285 | (unsigned long) [str length], (unsigned long) selRange.length, |
282 | 286 | (unsigned long) selRange.location); |
283 | 287 | |
304 | 308 | NSRange rng = privateWorkingText != nil |
305 | 309 | ? NSMakeRange (0, [privateWorkingText length]) : NSMakeRange (NSNotFound, 0); |
306 | 310 | if (NS_KEYLOG) |
307 | NSLog (@"markedRange request"); | |
311 | TKLog (@"markedRange request"); | |
308 | 312 | return rng; |
309 | 313 | } |
310 | 314 | |
312 | 316 | - (void)unmarkText |
313 | 317 | { |
314 | 318 | if (NS_KEYLOG) |
315 | NSLog (@"unmark (accept) text"); | |
319 | TKLog (@"unmark (accept) text"); | |
316 | 320 | [self deleteWorkingText]; |
317 | 321 | processingCompose = NO; |
318 | 322 | } |
328 | 332 | pt.y = caret_y; |
329 | 333 | |
330 | 334 | pt = [self convertPoint: pt toView: nil]; |
331 | pt = [[self window] convertPointToScreen: pt]; | |
335 | pt = [[self window] tkConvertPointToScreen: pt]; | |
332 | 336 | pt.y -= caret_height; |
333 | 337 | |
334 | 338 | rect.origin = pt; |
347 | 351 | - (void)doCommandBySelector: (SEL)aSelector |
348 | 352 | { |
349 | 353 | if (NS_KEYLOG) |
350 | NSLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector)); | |
354 | TKLog (@"doCommandBySelector: %@", NSStringFromSelector (aSelector)); | |
351 | 355 | processingCompose = NO; |
352 | 356 | if (aSelector == @selector (deleteBackward:)) |
353 | 357 | { |
377 | 381 | - (NSRange)selectedRange |
378 | 382 | { |
379 | 383 | if (NS_KEYLOG) |
380 | NSLog (@"selectedRange request"); | |
384 | TKLog (@"selectedRange request"); | |
381 | 385 | return NSMakeRange (NSNotFound, 0); |
382 | 386 | } |
383 | 387 | |
385 | 389 | - (NSUInteger)characterIndexForPoint: (NSPoint)thePoint |
386 | 390 | { |
387 | 391 | if (NS_KEYLOG) |
388 | NSLog (@"characterIndexForPoint request"); | |
392 | TKLog (@"characterIndexForPoint request"); | |
389 | 393 | return 0; |
390 | 394 | } |
391 | 395 | |
395 | 399 | static NSAttributedString *str = nil; |
396 | 400 | if (str == nil) str = [NSAttributedString new]; |
397 | 401 | if (NS_KEYLOG) |
398 | NSLog (@"attributedSubstringFromRange request"); | |
402 | TKLog (@"attributedSubstringFromRange request"); | |
399 | 403 | return str; |
400 | 404 | } |
401 | 405 | /* End <NSTextInput> impl. */ |
409 | 413 | if (privateWorkingText == nil) |
410 | 414 | return; |
411 | 415 | if (NS_KEYLOG) |
412 | NSLog(@"deleteWorkingText len = %lu\n", | |
416 | TKLog(@"deleteWorkingText len = %lu\n", | |
413 | 417 | (unsigned long)[privateWorkingText length]); |
414 | 418 | [privateWorkingText release]; |
415 | 419 | privateWorkingText = nil; |
429 | 433 | { |
430 | 434 | TkWindow *winPtr = TkMacOSXGetTkWindow(w); |
431 | 435 | Tk_Window tkwin = (Tk_Window) winPtr; |
436 | if (!winPtr) { | |
437 | return; | |
438 | } | |
432 | 439 | |
433 | 440 | memset(xEvent, 0, sizeof(XEvent)); |
434 | 441 | xEvent->xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); |
689 | 689 | eventPtr->xkey.keycode = 0; |
690 | 690 | } else if ( modKeyArray[0] <= keysym && |
691 | 691 | keysym <= modKeyArray[NUM_MOD_KEYCODES - 1]) { |
692 | /* | |
692 | /* | |
693 | 693 | * Keysyms for pure modifiers only arise in generated events. |
694 | 694 | * We should just copy them to the keycode. |
695 | 695 | */ |
772 | 772 | int result; |
773 | 773 | |
774 | 774 | inPostMenu = 1; |
775 | ||
775 | ||
776 | 776 | result = TkPreprocessMenu(menuPtr); |
777 | 777 | if (result != TCL_OK) { |
778 | 778 | inPostMenu = 0; |
784 | 784 | NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1); |
785 | 785 | |
786 | 786 | frame.origin = [view convertPoint: |
787 | [win convertPointFromScreen:frame.origin] fromView:nil]; | |
787 | [win tkConvertPointFromScreen:frame.origin] fromView:nil]; | |
788 | 788 | |
789 | 789 | NSMenu *menu = (NSMenu *) menuPtr->platformData; |
790 | 790 | NSPopUpButtonCell *popUpButtonCell = [[NSPopUpButtonCell alloc] |
1138 | 1138 | columnEntryPtr->x = x; |
1139 | 1139 | columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN; |
1140 | 1140 | } |
1141 | x += maxIndicatorSpace + maxWidth + 2 * borderWidth; | |
1141 | x += maxIndicatorSpace + maxWidth + 2 * activeBorderWidth; | |
1142 | 1142 | maxWidth = maxIndicatorSpace = 0; |
1143 | 1143 | lastColumnBreak = i; |
1144 | 1144 | y = borderWidth; |
1624 | 1624 | int height, /* Height of the current rectangle */ |
1625 | 1625 | int strictMotif, /* Boolean flag */ |
1626 | 1626 | int drawArrow) /* Whether or not to draw the cascade arrow |
1627 | * for cascade items. Only applies to | |
1628 | * Windows. */ | |
1627 | * for cascade items. */ | |
1629 | 1628 | { |
1630 | 1629 | } |
1631 | 1630 |
842 | 842 | return 1; |
843 | 843 | } |
844 | 844 | |
845 | /* | |
846 | * Local Variables: | |
847 | * mode: objc | |
848 | * c-basic-offset: 4 | |
849 | * fill-column: 79 | |
850 | * coding: utf-8 | |
851 | * End: | |
852 | */ |
378 | 378 | XVirtualEvent event; |
379 | 379 | int x, y; |
380 | 380 | TkWindow *winPtr = TkMacOSXGetTkWindow([NSApp keyWindow]); |
381 | Tk_Window tkwin = (Tk_Window) winPtr; | |
382 | ||
383 | if (tkwin == NULL) { | |
381 | Tk_Window tkwin; | |
382 | ||
383 | if (!winPtr) { | |
384 | 384 | return; |
385 | 385 | } |
386 | 386 | tkwin = (Tk_Window) winPtr->dispPtr->focusPtr; |
387 | if (tkwin == NULL) { | |
387 | if (!tkwin) { | |
388 | 388 | return; |
389 | 389 | } |
390 | 390 | bzero(&event, sizeof(XVirtualEvent)); |
89 | 89 | /* Create an Xevent to add to the Tk queue. */ |
90 | 90 | NSPoint global, local = [theEvent locationInWindow]; |
91 | 91 | if (eventWindow) { /* local will be in window coordinates. */ |
92 | global = [eventWindow convertPointToScreen: local]; | |
92 | global = [eventWindow tkConvertPointToScreen: local]; | |
93 | 93 | local.y = [eventWindow frame].size.height - local.y; |
94 | 94 | global.y = tkMacOSXZeroScreenHeight - global.y; |
95 | 95 | } else { /* local will be in screen coordinates. */ |
96 | 96 | if (_windowWithMouse ) { |
97 | 97 | eventWindow = _windowWithMouse; |
98 | 98 | global = local; |
99 | local = [eventWindow convertPointFromScreen: local]; | |
99 | local = [eventWindow tkConvertPointFromScreen: local]; | |
100 | 100 | local.y = [eventWindow frame].size.height - local.y; |
101 | 101 | global.y = tkMacOSXZeroScreenHeight - global.y; |
102 | 102 | } else { /* We have no window. Use the screen???*/ |
372 | 372 | if (win) { |
373 | 373 | NSPoint local; |
374 | 374 | |
375 | local = [win convertPointFromScreen:global]; | |
375 | local = [win tkConvertPointFromScreen:global]; | |
376 | 376 | local.y = [win frame].size.height - local.y; |
377 | 377 | if (macWin->winPtr && macWin->winPtr->wmInfoPtr) { |
378 | 378 | local.x -= macWin->winPtr->wmInfoPtr->xInParent; |
470 | 470 | if (win) { |
471 | 471 | NSPoint local = NSMakePoint(x, tkMacOSXZeroScreenHeight - y); |
472 | 472 | |
473 | local = [win convertPointFromScreen:local]; | |
473 | local = [win tkConvertPointFromScreen:local]; | |
474 | 474 | local.y = [win frame].size.height - local.y; |
475 | 475 | if (macWin->winPtr && macWin->winPtr->wmInfoPtr) { |
476 | 476 | local.x -= macWin->winPtr->wmInfoPtr->xInParent; |
31 | 31 | static void TkMacOSXEventsSetupProc(ClientData clientData, int flags); |
32 | 32 | static void TkMacOSXEventsCheckProc(ClientData clientData, int flags); |
33 | 33 | |
34 | #ifdef TK_MAC_DEBUG_EVENTS | |
35 | static char* Tk_EventName[39] = { | |
36 | "", | |
37 | "", | |
38 | "KeyPress", /*2*/ | |
39 | "KeyRelease", /*3*/ | |
40 | "ButtonPress", /*4*/ | |
41 | "ButtonRelease", /*5*/ | |
42 | "MotionNotify", /*6*/ | |
43 | "EnterNotify", /*7*/ | |
44 | "LeaveNotify", /*8*/ | |
45 | "FocusIn", /*9*/ | |
46 | "FocusOut", /*10*/ | |
47 | "KeymapNotify", /*11*/ | |
48 | "Expose", /*12*/ | |
49 | "GraphicsExpose", /*13*/ | |
50 | "NoExpose", /*14*/ | |
51 | "VisibilityNotify", /*15*/ | |
52 | "CreateNotify", /*16*/ | |
53 | "DestroyNotify", /*17*/ | |
54 | "UnmapNotify", /*18*/ | |
55 | "MapNotify", /*19*/ | |
56 | "MapRequest", /*20*/ | |
57 | "ReparentNotify", /*21*/ | |
58 | "ConfigureNotify", /*22*/ | |
59 | "ConfigureRequest", /*23*/ | |
60 | "GravityNotify", /*24*/ | |
61 | "ResizeRequest", /*25*/ | |
62 | "CirculateNotify", /*26*/ | |
63 | "CirculateRequest", /*27*/ | |
64 | "PropertyNotify", /*28*/ | |
65 | "SelectionClear", /*29*/ | |
66 | "SelectionRequest", /*30*/ | |
67 | "SelectionNotify", /*31*/ | |
68 | "ColormapNotify", /*32*/ | |
69 | "ClientMessage", /*33*/ | |
70 | "MappingNotify", /*34*/ | |
71 | "VirtualEvent", /*35*/ | |
72 | "ActivateNotify", /*36*/ | |
73 | "DeactivateNotify", /*37*/ | |
74 | "MouseWheelEvent" /*38*/ | |
75 | }; | |
76 | ||
77 | static Tk_RestrictAction | |
78 | InspectQueueRestrictProc( | |
79 | ClientData arg, | |
80 | XEvent *eventPtr) | |
81 | { | |
82 | XVirtualEvent* ve = (XVirtualEvent*) eventPtr; | |
83 | const char *name; | |
84 | long serial = ve->serial; | |
85 | long time = eventPtr->xkey.time; | |
86 | ||
87 | if (eventPtr->type == VirtualEvent) { | |
88 | name = ve->name; | |
89 | } else { | |
90 | name = Tk_EventName[eventPtr->type]; | |
91 | } | |
92 | fprintf(stderr, " > %s;serial = %lu; time=%lu)\n", | |
93 | name, serial, time); | |
94 | return TK_DEFER_EVENT; | |
95 | } | |
96 | ||
97 | /* | |
98 | * Debugging tool which prints the current Tcl queue. | |
99 | */ | |
100 | ||
101 | void DebugPrintQueue(void) | |
102 | { | |
103 | ClientData oldArg; | |
104 | Tk_RestrictProc *oldProc; | |
105 | ||
106 | oldProc = Tk_RestrictEvents(InspectQueueRestrictProc, NULL, &oldArg); | |
107 | fprintf(stderr, "Current queue:\n"); | |
108 | while (Tcl_DoOneEvent(TCL_ALL_EVENTS|TCL_DONT_WAIT)) {}; | |
109 | Tk_RestrictEvents(oldProc, oldArg, &oldArg); | |
110 | } | |
111 | # endif | |
112 | ||
34 | 113 | #pragma mark TKApplication(TKNotify) |
35 | 114 | |
36 | 115 | @interface NSApplication(TKNotify) |
38 | 117 | - (void) _modalSession: (NSModalSession) session sendEvent: (NSEvent *) event; |
39 | 118 | @end |
40 | 119 | |
41 | @implementation NSWindow(TKNotify) | |
42 | - (id) tkDisplayIfNeeded | |
43 | { | |
44 | if (![self isAutodisplay]) { | |
45 | [self displayIfNeeded]; | |
46 | } | |
47 | return nil; | |
48 | } | |
49 | @end | |
50 | ||
51 | 120 | @implementation TKApplication(TKNotify) |
52 | /* Display all windows each time an event is removed from the queue.*/ | |
53 | - (NSEvent *) nextEventMatchingMask: (NSUInteger) mask | |
54 | untilDate: (NSDate *) expiration inMode: (NSString *) mode | |
55 | dequeue: (BOOL) deqFlag | |
56 | { | |
57 | NSEvent *event = [super nextEventMatchingMask:mask | |
58 | untilDate:expiration | |
59 | inMode:mode | |
60 | dequeue:deqFlag]; | |
61 | /* Retain this event for later use. Must be released.*/ | |
62 | [event retain]; | |
63 | [NSApp makeWindowsPerform:@selector(tkDisplayIfNeeded) inOrder:NO]; | |
64 | return event; | |
65 | } | |
121 | /* | |
122 | * Earlier versions of Tk would override nextEventMatchingMask here, adding a | |
123 | * call to displayIfNeeded on all windows after calling super. This would cause | |
124 | * windows to be redisplayed (if necessary) each time that an event was | |
125 | * received. This was intended to replace Apple's default autoDisplay | |
126 | * mechanism, which the earlier versions of Tk would disable. When autoDisplay | |
127 | * is set to the default value of YES, the Apple event loop will call | |
128 | * displayIfNeeded on all windows at the beginning of each iteration of their | |
129 | * event loop. Since Tk does not call the Apple event loop, it was thought | |
130 | * that the autoDisplay behavior needed to be replicated. | |
131 | * | |
132 | * However, as of OSX 10.14 (Mojave) the autoDisplay property became | |
133 | * deprecated. Luckily it turns out that, even though we don't ever start the | |
134 | * Apple event loop, the Apple window manager still calls displayIfNeeded on | |
135 | * all windows on a regular basis, perhaps each time the queue is empty. So we | |
136 | * no longer, and perhaps never did need to set autoDisplay to NO, nor call | |
137 | * displayIfNeeded on our windows. We can just leave all of that to the window | |
138 | * manager. | |
139 | */ | |
66 | 140 | |
67 | 141 | /* |
68 | 142 | * Call super then check the pasteboard. |
71 | 145 | { |
72 | 146 | [super sendEvent:theEvent]; |
73 | 147 | [NSApp tkCheckPasteboard]; |
148 | #ifdef TK_MAC_DEBUG_EVENTS | |
149 | fprintf(stderr, "Sending event of type %d\n", (int)[theEvent type]); | |
150 | DebugPrintQueue(); | |
151 | #endif | |
74 | 152 | } |
75 | 153 | @end |
76 | 154 | |
90 | 168 | *---------------------------------------------------------------------- |
91 | 169 | */ |
92 | 170 | |
93 | static NSString * | |
171 | NSString * | |
94 | 172 | GetRunLoopMode(NSModalSession modalSession) |
95 | 173 | { |
96 | 174 | NSString *runLoopMode = nil; |
228 | 306 | if (currentEvent.type > 0) { |
229 | 307 | Tcl_SetMaxBlockTime(&zeroBlockTime); |
230 | 308 | } |
231 | [currentEvent release]; | |
232 | 309 | } |
233 | 310 | } |
234 | 311 | } |
297 | 374 | [NSApp sendEvent:currentEvent]; |
298 | 375 | } |
299 | 376 | } |
300 | [currentEvent release]; | |
301 | 377 | } else { |
302 | 378 | break; |
303 | 379 | } |
130 | 130 | NSView *view; |
131 | 131 | HIShapeRef clipRgn; |
132 | 132 | CGRect portBounds; |
133 | int focusLocked; | |
134 | 133 | } TkMacOSXDrawingContext; |
135 | 134 | |
136 | 135 | /* |
189 | 188 | MODULE_SCOPE EventModifiers TkMacOSXModifierState(void); |
190 | 189 | MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable, |
191 | 190 | int x, int y, unsigned int width, unsigned int height); |
192 | MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image, | |
193 | int use_ximage_alpha); | |
191 | MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image); | |
194 | 192 | MODULE_SCOPE void TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context, |
195 | 193 | CGImageRef image, unsigned long imageForeground, |
196 | 194 | unsigned long imageBackground, CGRect imageBounds, |
264 | 262 | #ifdef __i386__ |
265 | 263 | /* The Objective C runtime used on i386 requires this. */ |
266 | 264 | int _poolLock; |
265 | int _macMinorVersion; | |
266 | Bool _isDrawing; | |
267 | Bool _simulateDrawing; | |
267 | 268 | #endif |
268 | 269 | } |
269 | 270 | @property int poolLock; |
271 | @property int macMinorVersion; | |
272 | @property Bool isDrawing; | |
273 | @property Bool simulateDrawing; | |
270 | 274 | |
271 | 275 | @end |
272 | 276 | @interface TKApplication(TKInit) |
328 | 332 | |
329 | 333 | @interface TKContentView(TKWindowEvent) |
330 | 334 | - (void) drawRect: (NSRect) rect; |
331 | - (void) generateExposeEvents: (HIShapeRef) shape; | |
332 | - (void) viewDidEndLiveResize; | |
335 | - (void) generateExposeEvents: (HIShapeRef) shape; | |
333 | 336 | - (void) tkToolbarButton: (id) sender; |
334 | 337 | - (BOOL) isOpaque; |
335 | 338 | - (BOOL) wantsDefaultClipping; |
342 | 345 | @end |
343 | 346 | |
344 | 347 | @interface NSWindow(TKWm) |
345 | - (NSPoint) convertPointToScreen:(NSPoint)point; | |
346 | - (NSPoint) convertPointFromScreen:(NSPoint)point; | |
348 | - (NSPoint) tkConvertPointToScreen:(NSPoint)point; | |
349 | - (NSPoint) tkConvertPointFromScreen:(NSPoint)point; | |
347 | 350 | @end |
348 | 351 | |
349 | 352 | #pragma mark NSMenu & NSMenuItem Utilities |
7 | 7 | * Copyright 2001-2009, Apple Inc. |
8 | 8 | * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net> |
9 | 9 | * Copyright (c) 2015 Kevin Walzer/WordTech Commununications LLC. |
10 | * Copyright (c) 2018 Marc Culler | |
10 | 11 | * See the file "license.terms" for information on usage and redistribution |
11 | 12 | * of this file, and for a DISCLAIMER OF ALL WARRANTIES. |
12 | 13 | */ |
25 | 26 | |
26 | 27 | #define MIN_SLIDER_LENGTH 5 |
27 | 28 | |
28 | /*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/ | |
29 | /*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling.*/ | |
29 | 30 | #ifdef __LP64__ |
30 | 31 | #define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum)) |
31 | 32 | #else |
32 | 33 | #define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum)) |
33 | 34 | #endif /* __LP64__ */ |
34 | 35 | |
35 | #define MOUNTAIN_LION_STYLE (NSAppKitVersionNumber < 1138) | |
36 | ||
37 | /* | |
38 | * Declaration of Mac specific scrollbar structure. | |
36 | /* | |
37 | * Apple reversed the scroll direction with the release of OSX 10.7 Lion. | |
38 | */ | |
39 | ||
40 | #define SNOW_LEOPARD_STYLE (NSAppKitVersionNumber < 1138) | |
41 | ||
42 | /* | |
43 | * Declaration of an extended scrollbar structure with Mac specific additions. | |
39 | 44 | */ |
40 | 45 | |
41 | 46 | typedef struct MacScrollbar { |
42 | TkScrollbar information; /* Generic scrollbar info. */ | |
47 | TkScrollbar information; /* Generic scrollbar info. */ | |
43 | 48 | GC troughGC; /* For drawing trough. */ |
44 | 49 | GC copyGC; /* Used for copying from pixmap onto screen. */ |
50 | Bool buttonDown; /* Is the mouse button down? */ | |
51 | Bool mouseOver; /* Is the pointer over the scrollbar. */ | |
52 | HIThemeTrackDrawInfo info; /* Controls how the scrollbar is drawn. */ | |
45 | 53 | } MacScrollbar; |
54 | ||
55 | /* Used to initialize a MacScrollbar's info field. */ | |
56 | HIThemeTrackDrawInfo defaultInfo = { | |
57 | .version = 0, | |
58 | .min = 0.0, | |
59 | .max = 100.0, | |
60 | .attributes = kThemeTrackShowThumb, | |
61 | }; | |
46 | 62 | |
47 | 63 | /* |
48 | 64 | * The class procedure table for the scrollbar widget. All fields except size |
58 | 74 | }; |
59 | 75 | |
60 | 76 | |
61 | /*Information on scrollbar layout, metrics, and draw info.*/ | |
77 | /* Information on scrollbar layout, metrics, and draw info.*/ | |
62 | 78 | typedef struct ScrollbarMetrics { |
63 | 79 | SInt32 width, minThumbHeight; |
64 | 80 | int minHeight, topArrowHeight, bottomArrowHeight; |
65 | 81 | NSControlSize controlSize; |
66 | 82 | } ScrollbarMetrics; |
67 | 83 | |
68 | static ScrollbarMetrics metrics[2] = { | |
69 | {15, 54, 26, 14, 14, kControlSizeNormal}, /* kThemeScrollBarMedium */ | |
70 | {11, 40, 20, 10, 10, kControlSizeSmall}, /* kThemeScrollBarSmall */ | |
84 | ||
85 | static ScrollbarMetrics metrics = { | |
86 | 15, 54, 26, 14, 14, kControlSizeNormal /* kThemeScrollBarMedium */ | |
71 | 87 | }; |
72 | HIThemeTrackDrawInfo info = { | |
73 | .version = 0, | |
74 | .min = 0.0, | |
75 | .max = 100.0, | |
76 | .attributes = kThemeTrackShowThumb, | |
77 | }; | |
78 | ||
79 | ||
80 | /* | |
81 | * Forward declarations for procedures defined later in this file: | |
88 | ||
89 | ||
90 | /* | |
91 | * Declarations of static functions defined later in this file: | |
82 | 92 | */ |
83 | 93 | |
84 | 94 | static void ScrollbarEventProc(ClientData clientData, XEvent *eventPtr); |
85 | static int ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr); | |
95 | static int ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr); | |
86 | 96 | static void UpdateControlValues(TkScrollbar *scrollPtr); |
87 | 97 | |
88 | 98 | /* |
110 | 120 | |
111 | 121 | scrollPtr->troughGC = None; |
112 | 122 | scrollPtr->copyGC = None; |
113 | ||
114 | Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); | |
123 | scrollPtr->info = defaultInfo; | |
124 | scrollPtr->buttonDown = false; | |
125 | ||
126 | Tk_CreateEventHandler(tkwin, | |
127 | ExposureMask | | |
128 | StructureNotifyMask | | |
129 | FocusChangeMask | | |
130 | ButtonPressMask | | |
131 | ButtonReleaseMask | | |
132 | EnterWindowMask | | |
133 | LeaveWindowMask | | |
134 | VisibilityChangeMask, | |
135 | ScrollbarEventProc, scrollPtr); | |
115 | 136 | |
116 | 137 | return (TkScrollbar *) scrollPtr; |
117 | 138 | } |
129 | 150 | * None. |
130 | 151 | * |
131 | 152 | * Side effects: |
132 | * Information appears on the screen. | |
153 | * Draws a scrollbar on the screen. | |
133 | 154 | * |
134 | 155 | *-------------------------------------------------------------- |
135 | 156 | */ |
139 | 160 | ClientData clientData) /* Information about window. */ |
140 | 161 | { |
141 | 162 | register TkScrollbar *scrollPtr = (TkScrollbar *) clientData; |
163 | MacScrollbar *msPtr = (MacScrollbar *) scrollPtr; | |
142 | 164 | register Tk_Window tkwin = scrollPtr->tkwin; |
143 | 165 | TkWindow *winPtr = (TkWindow *) tkwin; |
144 | 166 | TkMacOSXDrawingContext dc; |
162 | 184 | .ty = viewHeight}; |
163 | 185 | CGContextConcatCTM(dc.context, t); |
164 | 186 | |
165 | /*Draw Unix-style scroll trough to provide rect for native scrollbar.*/ | |
187 | /*Draw a 3D rectangle to provide a base for the native scrollbar.*/ | |
166 | 188 | if (scrollPtr->highlightWidth != 0) { |
167 | 189 | GC fgGC, bgGC; |
168 | 190 | |
186 | 208 | Tk_Width(tkwin) - 2*scrollPtr->inset, |
187 | 209 | Tk_Height(tkwin) - 2*scrollPtr->inset, 0, TK_RELIEF_FLAT); |
188 | 210 | |
189 | /*Update values and draw in native rect.*/ | |
211 | /* Update values and then draw the native scrollbar over the rectangle.*/ | |
190 | 212 | UpdateControlValues(scrollPtr); |
191 | if (MOUNTAIN_LION_STYLE) { | |
192 | HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationInverted); | |
213 | ||
214 | if (SNOW_LEOPARD_STYLE) { | |
215 | HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationInverted); | |
193 | 216 | } else { |
194 | HIThemeDrawTrack (&info, 0, dc.context, kHIThemeOrientationNormal); | |
217 | HIThemeDrawTrack (&(msPtr->info), 0, dc.context, kHIThemeOrientationNormal); | |
195 | 218 | } |
196 | 219 | TkMacOSXRestoreDrawingContext(&dc); |
197 | 220 | |
217 | 240 | */ |
218 | 241 | |
219 | 242 | |
220 | extern void | |
243 | ||
244 | extern void | |
221 | 245 | TkpComputeScrollbarGeometry( |
222 | register TkScrollbar *scrollPtr) | |
223 | /* Scrollbar whose geometry may have | |
224 | * changed. */ | |
225 | { | |
226 | ||
227 | int variant, fieldLength; | |
246 | register TkScrollbar *scrollPtr) | |
247 | /* Scrollbar whose geometry may have | |
248 | * changed. */ | |
249 | { | |
250 | ||
251 | /* | |
252 | * The code below is borrowed from tkUnixScrlbr.c but has been adjusted to | |
253 | * account for some differences between macOS and X11. The Unix scrollbar | |
254 | * has an arrow button on each end. On macOS 10.6 (Snow Leopard) the | |
255 | * scrollbars by default have both arrow buttons at the bottom or right. | |
256 | * (There is a preferences setting to use the Unix layout, but we are not | |
257 | * supporting that!) On more recent versions of macOS there are no arrow | |
258 | * buttons at all. The case of no arrow buttons can be handled as a special | |
259 | * case of having both buttons at the end, but where scrollPtr->arrowLength | |
260 | * happens to be zero. To adjust for having both arrows at the same end we | |
261 | * shift the scrollbar up by the arrowLength. | |
262 | */ | |
263 | ||
264 | int fieldLength; | |
228 | 265 | |
229 | 266 | if (scrollPtr->highlightWidth < 0) { |
230 | scrollPtr->highlightWidth = 0; | |
267 | scrollPtr->highlightWidth = 0; | |
231 | 268 | } |
232 | 269 | scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth; |
233 | variant = ((scrollPtr->vertical ? Tk_Width(scrollPtr->tkwin) : | |
234 | Tk_Height(scrollPtr->tkwin)) - 2 * scrollPtr->inset | |
235 | < metrics[0].width) ? 1 : 0; | |
236 | scrollPtr->arrowLength = (metrics[variant].topArrowHeight + | |
237 | metrics[variant].bottomArrowHeight) / 2; | |
270 | if ([NSApp macMinorVersion] == 6) { | |
271 | scrollPtr->arrowLength = scrollPtr->width; | |
272 | } else { | |
273 | scrollPtr->arrowLength = 0; | |
274 | } | |
238 | 275 | fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin) |
239 | : Tk_Width(scrollPtr->tkwin)) | |
240 | - 2 * (scrollPtr->arrowLength + scrollPtr->inset); | |
276 | : Tk_Width(scrollPtr->tkwin)) | |
277 | - 2*(scrollPtr->arrowLength + scrollPtr->inset); | |
241 | 278 | if (fieldLength < 0) { |
242 | fieldLength = 0; | |
243 | } | |
244 | scrollPtr->sliderFirst = fieldLength * scrollPtr->firstFraction; | |
245 | scrollPtr->sliderLast = fieldLength * scrollPtr->lastFraction; | |
279 | fieldLength = 0; | |
280 | } | |
281 | scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction; | |
282 | scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction; | |
246 | 283 | |
247 | 284 | /* |
248 | * Adjust the slider so that some piece of it is always | |
249 | * displayed in the scrollbar and so that it has at least | |
250 | * a minimal width (so it can be grabbed with the mouse). | |
285 | * Adjust the slider so that some piece of it is always displayed in the | |
286 | * scrollbar and so that it has at least a minimal width (so it can be | |
287 | * grabbed with the mouse). | |
251 | 288 | */ |
252 | 289 | |
253 | if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) { | |
254 | scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth; | |
290 | if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) { | |
291 | scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH; | |
255 | 292 | } |
256 | 293 | if (scrollPtr->sliderFirst < 0) { |
257 | scrollPtr->sliderFirst = 0; | |
258 | } | |
259 | if (scrollPtr->sliderLast < (scrollPtr->sliderFirst + | |
260 | metrics[variant].minThumbHeight)) { | |
261 | scrollPtr->sliderLast = scrollPtr->sliderFirst + | |
262 | metrics[variant].minThumbHeight; | |
294 | scrollPtr->sliderFirst = 0; | |
295 | } | |
296 | if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) { | |
297 | scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH; | |
263 | 298 | } |
264 | 299 | if (scrollPtr->sliderLast > fieldLength) { |
265 | scrollPtr->sliderLast = fieldLength; | |
266 | } | |
267 | ||
268 | scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; | |
269 | scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; | |
270 | ||
271 | ||
272 | /* Register the desired geometry for the window (leave enough space | |
273 | * for the two arrows plus a minimum-size slider, plus border around | |
274 | * the whole window, if any). Then arrange for the window to be | |
275 | * redisplayed. | |
300 | scrollPtr->sliderLast = fieldLength; | |
301 | } | |
302 | scrollPtr->sliderFirst += -scrollPtr->arrowLength + scrollPtr->inset; | |
303 | scrollPtr->sliderLast += scrollPtr->inset; | |
304 | ||
305 | /* | |
306 | * Register the desired geometry for the window. Leave enough space for the | |
307 | * two arrows, if there are any arrows, plus a minimum-size slider, plus | |
308 | * border around the whole window, if any. Then arrange for the window to | |
309 | * be redisplayed. | |
276 | 310 | */ |
277 | 311 | |
278 | if (scrollPtr->vertical) { | |
279 | Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width + 2 * scrollPtr->inset, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) + metrics[variant].minThumbHeight); | |
312 | if (scrollPtr->vertical) { | |
313 | Tk_GeometryRequest(scrollPtr->tkwin, | |
314 | scrollPtr->width + 2*scrollPtr->inset, | |
315 | 2*(scrollPtr->arrowLength + scrollPtr->borderWidth | |
316 | + scrollPtr->inset) + metrics.minThumbHeight); | |
280 | 317 | } else { |
281 | Tk_GeometryRequest(scrollPtr->tkwin, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) + metrics[variant].minThumbHeight, scrollPtr->width + 2 * scrollPtr->inset); | |
318 | Tk_GeometryRequest(scrollPtr->tkwin, | |
319 | 2*(scrollPtr->arrowLength + scrollPtr->borderWidth | |
320 | + scrollPtr->inset) + metrics.minThumbHeight, | |
321 | scrollPtr->width + 2*scrollPtr->inset); | |
282 | 322 | } |
283 | 323 | Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset); |
284 | ||
285 | } | |
286 | ||
287 | ||
288 | ||
324 | } | |
289 | 325 | |
290 | 326 | /* |
291 | 327 | *---------------------------------------------------------------------- |
315 | 351 | if (macScrollPtr->copyGC != None) { |
316 | 352 | Tk_FreeGC(scrollPtr->display, macScrollPtr->copyGC); |
317 | 353 | } |
318 | ||
319 | macScrollPtr=NULL; | |
320 | 354 | } |
321 | 355 | |
322 | 356 | /* |
326 | 360 | * |
327 | 361 | * This procedure is called after the generic code has finished |
328 | 362 | * processing configuration options, in order to configure platform |
329 | * specific options. | |
363 | * specific options. There are no such option on the Mac, however. | |
330 | 364 | * |
331 | 365 | * Results: |
332 | 366 | * None. |
333 | 367 | * |
334 | 368 | * Side effects: |
335 | * Configuration info may get changed. | |
369 | * Currently, none. | |
336 | 370 | * |
337 | 371 | *---------------------------------------------------------------------- |
338 | 372 | */ |
340 | 374 | void |
341 | 375 | TkpConfigureScrollbar( |
342 | 376 | register TkScrollbar *scrollPtr) |
343 | /* Information about widget; may or may not | |
344 | * already have values for some fields. */ | |
345 | 377 | { |
346 | 378 | |
347 | 379 | } |
371 | 403 | int x, int y) /* Coordinates within scrollPtr's window. */ |
372 | 404 | { |
373 | 405 | |
374 | /* | |
375 | * Using code from tkUnixScrlbr.c because Unix scroll bindings are | |
376 | * driving the display at the script level. All the Mac scrollbar | |
377 | * has to do is re-draw itself. | |
406 | /* | |
407 | * The code below is borrowed from tkUnixScrlbr.c and needs no adjustment | |
408 | * since it does not involve the arrow buttons. | |
378 | 409 | */ |
379 | 410 | |
380 | int length, fieldlength, width, tmp; | |
411 | int length, width, tmp; | |
381 | 412 | register const int inset = scrollPtr->inset; |
382 | register const int arrowSize = scrollPtr->arrowLength + inset; | |
383 | 413 | |
384 | 414 | if (scrollPtr->vertical) { |
385 | 415 | length = Tk_Height(scrollPtr->tkwin); |
386 | fieldlength = length - 2 * arrowSize; | |
387 | 416 | width = Tk_Width(scrollPtr->tkwin); |
388 | 417 | } else { |
389 | 418 | tmp = x; |
390 | 419 | x = y; |
391 | 420 | y = tmp; |
392 | 421 | length = Tk_Width(scrollPtr->tkwin); |
393 | fieldlength = length - 2 * arrowSize; | |
394 | 422 | width = Tk_Height(scrollPtr->tkwin); |
395 | 423 | } |
396 | 424 | |
397 | fieldlength = fieldlength < 0 ? 0 : fieldlength; | |
398 | ||
399 | if (x<inset || x>=width-inset || y<inset || y>=length-inset) { | |
425 | if (x < inset || x >= width - inset || | |
426 | y < inset || y >= length - inset) { | |
400 | 427 | return OUTSIDE; |
401 | 428 | } |
402 | 429 | |
403 | 430 | /* |
404 | * All of the calculations in this procedure mirror those in | |
405 | * TkpDisplayScrollbar. Be sure to keep the two consistent. | |
431 | * Here we assume that the scrollbar is layed out with both arrow buttons | |
432 | * at the bottom (or right). Except on 10.6, however, the arrows do not | |
433 | * actually exist, i.e. the arrowLength is 0. These are the same | |
434 | * assumptions which are being made in TkpComputeScrollbarGeometry. | |
406 | 435 | */ |
407 | 436 | |
408 | if (y < scrollPtr->sliderFirst) { | |
437 | if (y < scrollPtr->sliderFirst + scrollPtr->arrowLength) { | |
409 | 438 | return TOP_GAP; |
410 | } | |
411 | if (y < scrollPtr->sliderLast) { | |
439 | } | |
440 | if (y < scrollPtr->sliderLast) { | |
412 | 441 | return SLIDER; |
413 | } | |
414 | if (y < fieldlength){ | |
442 | } | |
443 | if (y < length - (2*scrollPtr->arrowLength + inset)) { | |
415 | 444 | return BOTTOM_GAP; |
416 | } | |
417 | if (y < fieldlength + arrowSize) { | |
445 | } | |
446 | /* On systems newer than 10.6 we have already returned. */ | |
447 | if (y < length - (scrollPtr->arrowLength + inset)) { | |
418 | 448 | return TOP_ARROW; |
419 | } | |
420 | return BOTTOM_ARROW; | |
421 | ||
449 | } | |
450 | return BOTTOM_ARROW; | |
422 | 451 | } |
423 | 452 | |
424 | 453 | /* |
428 | 457 | * |
429 | 458 | * This procedure updates the Macintosh scrollbar control to |
430 | 459 | * display the values defined by the Tk scrollbar. This is the |
431 | * key interface to the Mac-native * scrollbar; the Unix bindings | |
460 | * key interface to the Mac-native scrollbar; the Unix bindings | |
432 | 461 | * drive scrolling in the Tk window and all the Mac scrollbar has |
433 | 462 | * to do is redraw itself. |
434 | 463 | * |
445 | 474 | UpdateControlValues( |
446 | 475 | TkScrollbar *scrollPtr) /* Scrollbar data struct. */ |
447 | 476 | { |
477 | MacScrollbar *msPtr = (MacScrollbar *)scrollPtr; | |
448 | 478 | Tk_Window tkwin = scrollPtr->tkwin; |
449 | 479 | MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin); |
450 | 480 | double dViewSize; |
451 | 481 | HIRect contrlRect; |
452 | int variant; | |
453 | 482 | short width, height; |
454 | 483 | |
455 | 484 | NSView *view = TkMacOSXDrawableView(macWin); |
461 | 490 | frame.origin.y = viewHeight - (frame.origin.y + frame.size.height); |
462 | 491 | |
463 | 492 | contrlRect = NSRectToCGRect(frame); |
464 | info.bounds = contrlRect; | |
493 | msPtr->info.bounds = contrlRect; | |
465 | 494 | |
466 | 495 | width = contrlRect.size.width; |
467 | 496 | height = contrlRect.size.height; |
468 | ||
469 | variant = contrlRect.size.width < metrics[0].width ? 1 : 0; | |
470 | 497 | |
471 | 498 | /* |
472 | 499 | * Ensure we set scrollbar control bounds only once all size adjustments |
473 | 500 | * have been computed. |
474 | 501 | */ |
475 | 502 | |
476 | info.bounds = contrlRect; | |
503 | msPtr->info.bounds = contrlRect; | |
477 | 504 | if (scrollPtr->vertical) { |
478 | info.attributes &= ~kThemeTrackHorizontal; | |
505 | msPtr->info.attributes &= ~kThemeTrackHorizontal; | |
479 | 506 | } else { |
480 | info.attributes |= kThemeTrackHorizontal; | |
507 | msPtr->info.attributes |= kThemeTrackHorizontal; | |
481 | 508 | } |
482 | 509 | |
483 | 510 | /* |
494 | 521 | factor = RangeToFactor(maximum); |
495 | 522 | dViewSize = (scrollPtr->lastFraction - scrollPtr->firstFraction) |
496 | 523 | * factor; |
497 | info.max = MIN_SCROLLBAR_VALUE + | |
524 | msPtr->info.max = MIN_SCROLLBAR_VALUE + | |
498 | 525 | factor - dViewSize; |
499 | info.trackInfo.scrollbar.viewsize = dViewSize; | |
526 | msPtr->info.trackInfo.scrollbar.viewsize = dViewSize; | |
500 | 527 | if (scrollPtr->vertical) { |
501 | if (MOUNTAIN_LION_STYLE) { | |
502 | info.value = factor * scrollPtr->firstFraction; | |
528 | if (SNOW_LEOPARD_STYLE) { | |
529 | msPtr->info.value = factor * scrollPtr->firstFraction; | |
503 | 530 | } else { |
504 | info.value = info.max - factor * scrollPtr->firstFraction; | |
531 | msPtr->info.value = msPtr->info.max - factor * scrollPtr->firstFraction; | |
505 | 532 | } |
506 | 533 | } else { |
507 | info.value = MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction; | |
534 | msPtr->info.value = MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction; | |
508 | 535 | } |
509 | 536 | |
510 | 537 | if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0) |
511 | || height <= metrics[variant].minHeight) { | |
512 | info.enableState = kThemeTrackHideTrack; | |
538 | || height <= metrics.minHeight) { | |
539 | msPtr->info.enableState = kThemeTrackHideTrack; | |
513 | 540 | } else { |
514 | info.enableState = kThemeTrackActive; | |
515 | info.attributes = kThemeTrackShowThumb | kThemeTrackThumbRgnIsNotGhost; | |
516 | } | |
517 | ||
518 | } | |
519 | ||
520 | /* | |
521 | *-------------------------------------------------------------- | |
522 | * | |
523 | * ScrollbarPress -- | |
541 | msPtr->info.enableState = kThemeTrackActive; | |
542 | msPtr->info.attributes = kThemeTrackShowThumb | kThemeTrackThumbRgnIsNotGhost; | |
543 | } | |
544 | ||
545 | } | |
546 | ||
547 | /* | |
548 | *-------------------------------------------------------------- | |
549 | * | |
550 | * ScrollbarEvent -- | |
524 | 551 | * |
525 | 552 | * This procedure is invoked in response to <ButtonPress>, <ButtonRelease>, |
526 | * <EnterNotify>, and <LeaveNotify> events. Scrollbar appearance is modified. | |
553 | * <EnterNotify>, and <LeaveNotify> events. The Scrollbar appearance is | |
554 | * modified for each event. | |
527 | 555 | * |
528 | 556 | *-------------------------------------------------------------- |
529 | 557 | */ |
530 | 558 | |
531 | 559 | static int |
532 | ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr) | |
533 | { | |
534 | ||
535 | if (eventPtr->type == ButtonPress) { | |
536 | UpdateControlValues(scrollPtr); | |
537 | info.trackInfo.scrollbar.pressState = 1; | |
538 | } | |
539 | if (eventPtr->type == EnterNotify) { | |
540 | info.trackInfo.scrollbar.pressState = 1; | |
541 | } | |
542 | if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) { | |
543 | info.trackInfo.scrollbar.pressState = 0; | |
544 | } | |
545 | return TCL_OK; | |
560 | ScrollbarEvent(TkScrollbar *scrollPtr, XEvent *eventPtr) | |
561 | { | |
562 | MacScrollbar *msPtr = (MacScrollbar *)scrollPtr; | |
563 | ||
564 | /* The pressState does not indicate whether the moused button was | |
565 | * pressed at some location in the Scrollbar. Rather, it indicates | |
566 | * that the scrollbar should appear as if it were pressed in that | |
567 | * location. The standard Mac behavior is that once the button is | |
568 | * pressed inside the Scrollbar the appearance should not change until | |
569 | * the button is released, even if the mouse moves outside of the | |
570 | * scrollbar. However, if the mouse lies over the scrollbar but the | |
571 | * button is not pressed then the appearance should be the same as if | |
572 | * the button had been pressed on the slider, i.e. kThemeThumbPressed. | |
573 | * See the file Appearance.r, or HIToolbox.bridgesupport on 10.14. | |
574 | */ | |
575 | ||
576 | if (eventPtr->type == ButtonPress) { | |
577 | msPtr->buttonDown = true; | |
578 | UpdateControlValues(scrollPtr); | |
579 | int where = TkpScrollbarPosition(scrollPtr, | |
580 | eventPtr->xbutton.x, | |
581 | eventPtr->xbutton.y); | |
582 | switch(where) { | |
583 | case OUTSIDE: | |
584 | msPtr->info.trackInfo.scrollbar.pressState = 0; | |
585 | break; | |
586 | case TOP_GAP: | |
587 | msPtr->info.trackInfo.scrollbar.pressState = kThemeTopTrackPressed; | |
588 | break; | |
589 | case SLIDER: | |
590 | msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed; | |
591 | break; | |
592 | case BOTTOM_GAP: | |
593 | msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomTrackPressed; | |
594 | break; | |
595 | case TOP_ARROW: | |
596 | /* This looks wrong and the docs say it is wrong but it works. */ | |
597 | msPtr->info.trackInfo.scrollbar.pressState = kThemeTopInsideArrowPressed; | |
598 | break; | |
599 | case BOTTOM_ARROW: | |
600 | msPtr->info.trackInfo.scrollbar.pressState = kThemeBottomOutsideArrowPressed; | |
601 | break; | |
602 | } | |
603 | } | |
604 | if (eventPtr->type == ButtonRelease) { | |
605 | msPtr->buttonDown = false; | |
606 | if (!msPtr->mouseOver) { | |
607 | msPtr->info.trackInfo.scrollbar.pressState = 0; | |
608 | } | |
609 | } | |
610 | if (eventPtr->type == EnterNotify) { | |
611 | msPtr->mouseOver = true; | |
612 | if (!msPtr->buttonDown) { | |
613 | msPtr->info.trackInfo.scrollbar.pressState = kThemeThumbPressed; | |
614 | } | |
615 | } | |
616 | if (eventPtr->type == LeaveNotify) { | |
617 | msPtr->mouseOver = false; | |
618 | if (!msPtr->buttonDown) { | |
619 | msPtr->info.trackInfo.scrollbar.pressState = 0; | |
620 | } | |
621 | } | |
622 | return TCL_OK; | |
546 | 623 | } |
547 | 624 | |
548 | 625 | |
584 | 661 | case ButtonRelease: |
585 | 662 | case EnterNotify: |
586 | 663 | case LeaveNotify: |
587 | ScrollbarPress(clientData, eventPtr); | |
664 | ScrollbarEvent(clientData, eventPtr); | |
588 | 665 | break; |
589 | 666 | default: |
590 | 667 | TkScrollbarEventProc(clientData, eventPtr); |
591 | 668 | } |
592 | 669 | } |
670 | ||
671 | /* | |
672 | * Local Variables: | |
673 | * mode: objc | |
674 | * c-basic-offset: 4 | |
675 | * fill-column: 79 | |
676 | * coding: utf-8 | |
677 | * End: | |
678 | */ |
204 | 204 | event.xvisibility.type = VisibilityNotify; |
205 | 205 | event.xvisibility.state = VisibilityUnobscured; |
206 | 206 | NotifyVisibility(macWin->winPtr, &event); |
207 | ||
208 | /* | |
209 | * Make sure that subwindows get displayed. | |
210 | */ | |
211 | ||
212 | GenerateConfigureNotify(macWin->winPtr, 1); | |
213 | ||
207 | 214 | } |
208 | 215 | |
209 | 216 | /* |
294 | 301 | event.xunmap.from_configure = false; |
295 | 302 | Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); |
296 | 303 | } else { |
304 | ||
297 | 305 | /* |
298 | 306 | * Rebuild the visRgn clip region for the parent so it will be allowed |
299 | 307 | * to draw in the space from which this subwindow was removed. |
300 | 308 | */ |
309 | ||
301 | 310 | if (parentPtr && parentPtr->privatePtr->visRgn) { |
302 | 311 | TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(parentPtr->privatePtr), |
303 | 312 | parentPtr->privatePtr->visRgn); |
379 | 388 | if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { |
380 | 389 | NSWindow *w = macWin->winPtr->wmInfoPtr->window; |
381 | 390 | if (w) { |
391 | ||
382 | 392 | /* We explicitly convert everything to doubles so we don't get |
383 | 393 | * surprised (again) by what happens when you do arithmetic with |
384 | 394 | * unsigned ints. |
385 | 395 | */ |
396 | ||
386 | 397 | CGFloat X = (CGFloat)x; |
387 | 398 | CGFloat Y = (CGFloat)y; |
388 | 399 | CGFloat Width = (CGFloat)width; |
469 | 480 | if (contWinPtr) { |
470 | 481 | macParent = contWinPtr->privatePtr; |
471 | 482 | } else { |
483 | ||
472 | 484 | /* |
473 | 485 | * Here we should handle out of process embedding. At this point, |
474 | 486 | * we are assuming that the changes.x,y is not maintained, if you |
477 | 489 | */ |
478 | 490 | } |
479 | 491 | } else { |
492 | ||
480 | 493 | /* |
481 | 494 | * TODO: update all xOff & yOffs |
482 | 495 | */ |
568 | 581 | if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { |
569 | 582 | TkWmRestackToplevel(macWin->winPtr, Above, NULL); |
570 | 583 | } else { |
584 | ||
571 | 585 | /* |
572 | 586 | * TODO: this should generate damage |
573 | 587 | */ |
602 | 616 | if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { |
603 | 617 | TkWmRestackToplevel(macWin->winPtr, Below, NULL); |
604 | 618 | } else { |
605 | /* | |
619 | ||
620 | /* | |
606 | 621 | * TODO: this should generate damage |
607 | 622 | */ |
608 | 623 | } |
873 | 888 | } |
874 | 889 | CFRelease(rgn); |
875 | 890 | } else { |
891 | ||
876 | 892 | /* |
877 | 893 | * An unmapped window has empty clip regions to prevent any |
878 | 894 | * (erroneous) drawing into it or its children from becoming |
1133 | 1149 | TkMacOSXGetRootControl( |
1134 | 1150 | Drawable drawable) |
1135 | 1151 | { |
1152 | ||
1136 | 1153 | /* |
1137 | 1154 | * will probably need to fix this up for embedding |
1138 | 1155 | */ |
1313 | 1330 | TkWindow *childPtr; |
1314 | 1331 | |
1315 | 1332 | if (winPtr->privatePtr == NULL) { |
1333 | ||
1316 | 1334 | /* |
1317 | 1335 | * We haven't called Tk_MakeWindowExist for this window yet. The offset |
1318 | 1336 | * information will be postponed and calulated at that time. (This will |
79 | 79 | } |
80 | 80 | |
81 | 81 | /* |
82 | *---------------------------------------------------------------------- | |
83 | * | |
84 | * TkTestSimulateDrawing -- | |
85 | * | |
86 | * A test widget display procedure which records calls can use this to | |
87 | * avoid duplicate calls which would occur due to fact that no valid | |
88 | * graphics context is available to the idle task which is running the | |
89 | * display proc. Note that no actual drawing to the screen will take | |
90 | * place when this flag is set. This is just a wrapper for the NSApp | |
91 | * property. | |
92 | * | |
93 | * | |
94 | * Results: | |
95 | * Calls to low level drawing routines will return without actually | |
96 | * drawing anything to the screen. | |
97 | * | |
98 | * Side effects: | |
99 | * None | |
100 | * | |
101 | *---------------------------------------------------------------------- | |
102 | */ | |
103 | MODULE_SCOPE void | |
104 | TkTestSimulateDrawing(Bool yesno) { | |
105 | [NSApp setSimulateDrawing:yesno]; | |
106 | } | |
107 | ||
108 | ||
109 | ||
110 | /* | |
82 | 111 | * Local Variables: |
83 | 112 | * mode: objc |
84 | 113 | * c-basic-offset: 4 |
67 | 67 | TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); |
68 | 68 | #endif |
69 | 69 | BOOL movedOnly = [[notification name] |
70 | isEqualToString:NSWindowDidMoveNotification]; | |
71 | ||
72 | if (movedOnly) { | |
73 | /* constraining to screen after move not needed with AppKit */ | |
74 | } | |
70 | isEqualToString:NSWindowDidMoveNotification]; | |
75 | 71 | |
76 | 72 | NSWindow *w = [notification object]; |
77 | 73 | TkWindow *winPtr = TkMacOSXGetTkWindow(w); |
95 | 91 | flags |= TK_SIZE_CHANGED; |
96 | 92 | } |
97 | 93 | if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) { |
94 | ||
98 | 95 | /* |
99 | 96 | * Propagate geometry changes immediately. |
100 | 97 | */ |
118 | 115 | TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState; |
119 | 116 | Tk_MapWindow((Tk_Window) winPtr); |
120 | 117 | if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) { |
118 | ||
121 | 119 | /* |
122 | 120 | * Process all Tk events generated by Tk_MapWindow(). |
123 | 121 | */ |
173 | 171 | return (winPtr ? NO : YES); |
174 | 172 | } |
175 | 173 | |
174 | ||
176 | 175 | #ifdef TK_MAC_DEBUG_NOTIFICATIONS |
177 | 176 | |
178 | 177 | - (void) windowDragStart: (NSNotification *) notification |
212 | 211 | //Tk_UnmapWindow((Tk_Window) winPtr); |
213 | 212 | } |
214 | 213 | } |
214 | ||
215 | ||
215 | 216 | #endif /* TK_MAC_DEBUG_NOTIFICATIONS */ |
216 | 217 | |
217 | 218 | - (void) _setupWindowNotifications |
235 | 236 | observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:); |
236 | 237 | #endif |
237 | 238 | #undef observe |
239 | ||
238 | 240 | } |
239 | 241 | @end |
240 | 242 | |
255 | 257 | #ifdef TK_MAC_DEBUG_NOTIFICATIONS |
256 | 258 | TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); |
257 | 259 | #endif |
258 | TkSuspendClipboard(); | |
259 | 260 | } |
260 | 261 | |
261 | 262 | - (void) applicationShowHide: (NSNotification *) notification |
295 | 296 | /* |
296 | 297 | *---------------------------------------------------------------------- |
297 | 298 | * |
299 | * TkpAppIsDrawing -- | |
300 | * | |
301 | * A widget display procedure can call this to determine whether it | |
302 | * is being run inside of the drawRect method. This is needed for | |
303 | * some tests, especially of the Text widget, which record data in | |
304 | * a global Tcl variable and assume that display procedures will be | |
305 | * run in a predictable sequence as Tcl idle tasks. | |
306 | * | |
307 | * Results: | |
308 | * True only while running the drawRect method of a TKContentView; | |
309 | * | |
310 | * Side effects: | |
311 | * None | |
312 | * | |
313 | *---------------------------------------------------------------------- | |
314 | */ | |
315 | MODULE_SCOPE Bool | |
316 | TkpAppIsDrawing(void) { | |
317 | return [NSApp isDrawing]; | |
318 | } | |
319 | ||
320 | ||
321 | /* | |
322 | *---------------------------------------------------------------------- | |
323 | * | |
298 | 324 | * GenerateUpdates -- |
299 | 325 | * |
300 | 326 | * Given a Macintosh update region and a Tk window this function geneates |
301 | * a X Expose event for the window if it is within the update region. The | |
327 | * an X Expose event for the window if it meets the update region. The | |
302 | 328 | * function will then recursivly have each damaged window generate Expose |
303 | 329 | * events for its child windows. |
304 | 330 | * |
359 | 385 | Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); |
360 | 386 | |
361 | 387 | #ifdef TK_MAC_DEBUG_DRAWING |
362 | NSLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x, | |
388 | TKLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x, | |
363 | 389 | event.xexpose.y, event.xexpose.width, event.xexpose.height); |
364 | 390 | #endif |
365 | 391 | |
578 | 604 | if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) && |
579 | 605 | ((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) { |
580 | 606 | if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) { |
607 | ||
581 | 608 | /* |
582 | 609 | * Don't set external width, since the user didn't change it |
583 | 610 | * from what the widgets asked for. |
584 | 611 | */ |
612 | ||
585 | 613 | } else if (wmPtr->gridWin != NULL) { |
586 | 614 | wmPtr->width = wmPtr->reqGridWidth |
587 | 615 | + (width - winPtr->reqWidth)/wmPtr->widthInc; |
593 | 621 | } |
594 | 622 | |
595 | 623 | if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) { |
624 | ||
596 | 625 | /* |
597 | 626 | * Don't set external height, since the user didn't change it |
598 | 627 | * from what the widgets asked for. |
599 | 628 | */ |
629 | ||
600 | 630 | } else if (wmPtr->gridWin != NULL) { |
601 | 631 | wmPtr->height = wmPtr->reqGridHeight |
602 | 632 | + (height - winPtr->reqHeight)/wmPtr->heightInc; |
795 | 825 | const NSRect *rectsBeingDrawn; |
796 | 826 | NSInteger rectsBeingDrawnCount; |
797 | 827 | |
828 | #ifdef TK_MAC_DEBUG_DRAWING | |
829 | TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); | |
830 | if (winPtr) fprintf(stderr, "drawRect: drawing %s\n", | |
831 | Tk_PathName(winPtr)); | |
832 | #endif | |
833 | ||
834 | if ([NSApp simulateDrawing]) { | |
835 | return; | |
836 | } | |
837 | ||
838 | /* | |
839 | * We do not allow recursive calls to drawRect, but we only log | |
840 | * them on OSX > 10.13, where they should never happen. | |
841 | */ | |
842 | ||
843 | if ([NSApp isDrawing] && [NSApp macMinorVersion] > 13) { | |
844 | TKLog(@"WARNING: a recursive call to drawRect was aborted."); | |
845 | return; | |
846 | } | |
847 | ||
848 | [NSApp setIsDrawing: YES]; | |
849 | ||
798 | 850 | [self getRectsBeingDrawn:&rectsBeingDrawn count:&rectsBeingDrawnCount]; |
799 | ||
800 | #ifdef TK_MAC_DEBUG_DRAWING | |
801 | TKLog(@"-[%@(%p) %s%@]", [self class], self, _cmd, NSStringFromRect(rect)); | |
802 | [[NSColor colorWithDeviceRed:0.0 green:1.0 blue:0.0 alpha:.1] setFill]; | |
803 | NSRectFillListUsingOperation(rectsBeingDrawn, rectsBeingDrawnCount, | |
804 | NSCompositeSourceOver); | |
805 | #endif | |
806 | ||
807 | 851 | CGFloat height = [self bounds].size.height; |
808 | 852 | HIMutableShapeRef drawShape = HIShapeCreateMutable(); |
809 | 853 | |
810 | 854 | while (rectsBeingDrawnCount--) { |
811 | 855 | CGRect r = NSRectToCGRect(*rectsBeingDrawn++); |
856 | ||
857 | #ifdef TK_MAC_DEBUG_DRAWING | |
858 | fprintf(stderr, "drawRect: %dx%d@(%d,%d)\n", (int)r.size.width, | |
859 | (int)r.size.height, (int)r.origin.x, (int)r.origin.y); | |
860 | #endif | |
861 | ||
812 | 862 | r.origin.y = height - (r.origin.y + r.size.height); |
813 | 863 | HIShapeUnionWithRect(drawShape, &r); |
814 | 864 | } |
815 | if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) { | |
816 | [self generateExposeEvents:(HIShapeRef)drawShape]; | |
817 | } else { | |
818 | [self performSelectorOnMainThread:@selector(generateExposeEvents:) | |
819 | withObject:(id)drawShape waitUntilDone:NO | |
820 | modes:[NSArray arrayWithObjects:NSRunLoopCommonModes, | |
821 | ||
822 | NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, | |
823 | nil]]; | |
824 | } | |
825 | ||
865 | [self generateExposeEvents:(HIShapeRef)drawShape]; | |
826 | 866 | CFRelease(drawShape); |
867 | [NSApp setIsDrawing: NO]; | |
868 | ||
869 | #ifdef TK_MAC_DEBUG_DRAWING | |
870 | fprintf(stderr, "drawRect: done.\n"); | |
871 | #endif | |
827 | 872 | } |
828 | 873 | |
829 | 874 | -(void) setFrameSize: (NSSize)newsize |
830 | 875 | { |
831 | 876 | [super setFrameSize: newsize]; |
832 | if ([self inLiveResize]) { | |
833 | NSWindow *w = [self window]; | |
834 | TkWindow *winPtr = TkMacOSXGetTkWindow(w); | |
835 | Tk_Window tkwin = (Tk_Window) winPtr; | |
877 | NSWindow *w = [self window]; | |
878 | TkWindow *winPtr = TkMacOSXGetTkWindow(w); | |
879 | Tk_Window tkwin = (Tk_Window) winPtr; | |
880 | if (winPtr) { | |
881 | /* On OSX versions below 10.14 setFrame calls drawRect. | |
882 | * On 10.14 it does its own drawing. | |
883 | */ | |
884 | if ([NSApp macMinorVersion] > 13) { | |
885 | [NSApp setIsDrawing:YES]; | |
886 | } | |
836 | 887 | unsigned int width = (unsigned int)newsize.width; |
837 | 888 | unsigned int height=(unsigned int)newsize.height; |
838 | 889 | ClientData oldArg; |
839 | 890 | Tk_RestrictProc *oldProc; |
840 | 891 | |
841 | /* This can be called from outside the Tk event loop. | |
892 | /* | |
893 | * This can be called from outside the Tk event loop. | |
842 | 894 | * Since it calls Tcl_DoOneEvent, we need to make sure we |
843 | 895 | * don't clobber the AutoreleasePool set up by the caller. |
844 | 896 | */ |
897 | ||
845 | 898 | [NSApp _lockAutoreleasePool]; |
846 | 899 | |
847 | 900 | /* |
848 | * Try to prevent flickers and flashes. | |
901 | * Disable Tk drawing until the window has been completely configured. | |
849 | 902 | */ |
850 | [w disableFlushWindow]; | |
851 | NSDisableScreenUpdates(); | |
852 | ||
853 | /* Disable Tk drawing until the window has been completely configured.*/ | |
903 | ||
854 | 904 | TkMacOSXSetDrawingEnabled(winPtr, 0); |
855 | 905 | |
856 | /* Generate and handle a ConfigureNotify event for the new size.*/ | |
906 | /* | |
907 | * Generate and handle a ConfigureNotify event for the new size. | |
908 | */ | |
909 | ||
857 | 910 | TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height, |
858 | 911 | TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY); |
859 | 912 | oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg); |
860 | while (Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT)) {} | |
861 | 913 | Tk_RestrictEvents(oldProc, oldArg, &oldArg); |
862 | 914 | |
863 | /* Now that Tk has configured all subwindows we can create the clip regions. */ | |
915 | /* | |
916 | * Now that Tk has configured all subwindows, create the clip regions. | |
917 | */ | |
918 | ||
864 | 919 | TkMacOSXSetDrawingEnabled(winPtr, 1); |
865 | 920 | TkMacOSXInvalClipRgns(tkwin); |
866 | 921 | TkMacOSXUpdateClipRgn(winPtr); |
867 | 922 | |
868 | /* Finally, generate and process expose events to redraw the window. */ | |
923 | /* | |
924 | * Generate and process expose events to redraw the window. | |
925 | */ | |
926 | ||
869 | 927 | HIRect bounds = NSRectToCGRect([self bounds]); |
870 | 928 | HIShapeRef shape = HIShapeCreateWithRect(&bounds); |
871 | 929 | [self generateExposeEvents: shape]; |
872 | while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {} | |
873 | [w enableFlushWindow]; | |
874 | [w flushWindowIfNeeded]; | |
875 | NSEnableScreenUpdates(); | |
930 | [w displayIfNeeded]; | |
931 | ||
932 | /* | |
933 | * Finally, unlock the main autoreleasePool. | |
934 | */ | |
935 | ||
876 | 936 | [NSApp _unlockAutoreleasePool]; |
877 | 937 | } |
878 | 938 | } |
879 | 939 | |
880 | 940 | /* |
881 | * As insurance against bugs that might cause layout glitches during a live | |
882 | * resize, we redraw the window one more time at the end of the resize | |
883 | * operation. | |
884 | */ | |
885 | ||
886 | - (void)viewDidEndLiveResize | |
887 | { | |
888 | HIRect bounds = NSRectToCGRect([self bounds]); | |
889 | HIShapeRef shape = HIShapeCreateWithRect(&bounds); | |
890 | [super viewDidEndLiveResize]; | |
891 | [self generateExposeEvents: shape]; | |
892 | } | |
893 | ||
894 | /* Core method of this class: generates expose events for redrawing. If the | |
895 | * Tcl_ServiceMode is set to TCL_SERVICE_ALL then the expose events will be | |
896 | * immediately removed from the Tcl event loop and processed. Typically, they | |
897 | * should be queued, however. | |
898 | */ | |
941 | * Core method of this class: generates expose events for redrawing. The | |
942 | * expose events are immediately removed from the Tcl event loop and processed. | |
943 | * This causes drawing procedures to be scheduled as idle events. Then all | |
944 | * pending idle events are processed so the drawing will actually take place. | |
945 | */ | |
946 | ||
899 | 947 | - (void) generateExposeEvents: (HIShapeRef) shape |
900 | 948 | { |
901 | 949 | unsigned long serial; |
902 | 950 | CGRect updateBounds; |
903 | 951 | int updatesNeeded; |
904 | 952 | TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); |
905 | ||
953 | ClientData oldArg; | |
954 | Tk_RestrictProc *oldProc; | |
906 | 955 | if (!winPtr) { |
907 | return; | |
908 | } | |
909 | ||
910 | /* Generate Tk Expose events. */ | |
956 | return; | |
957 | } | |
958 | ||
959 | /* | |
960 | * Generate Tk Expose events. | |
961 | */ | |
962 | ||
911 | 963 | HIShapeGetBounds(shape, &updateBounds); |
912 | /* All of these events will share the same serial number. */ | |
964 | ||
965 | /* | |
966 | * All of these events will share the same serial number. | |
967 | */ | |
968 | ||
913 | 969 | serial = LastKnownRequestProcessed(Tk_Display(winPtr)); |
914 | 970 | updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr); |
915 | 971 | |
916 | /* Process the Expose events if the service mode is TCL_SERVICE_ALL */ | |
917 | if (updatesNeeded && Tcl_GetServiceMode() == TCL_SERVICE_ALL) { | |
918 | ClientData oldArg; | |
919 | Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc, | |
920 | UINT2PTR(serial), &oldArg); | |
921 | while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {} | |
972 | if (updatesNeeded) { | |
973 | ||
974 | /* | |
975 | * First process all of the Expose events. | |
976 | */ | |
977 | ||
978 | oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg); | |
979 | while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}; | |
922 | 980 | Tk_RestrictEvents(oldProc, oldArg, &oldArg); |
981 | ||
982 | /* | |
983 | * Starting with OSX 10.14, which uses Core Animation to draw windows, | |
984 | * all drawing must be done within the drawRect method. (The CGContext | |
985 | * which draws to the backing CALayer is created by the NSView before | |
986 | * calling drawRect, and destroyed when drawRect returns. Drawing done | |
987 | * with the current CGContext outside of the drawRect method has no | |
988 | * effect.) | |
989 | * | |
990 | * Fortunately, Tk schedules all drawing to be done while Tcl is idle. | |
991 | * So we can do the drawing by processing all of the idle events that | |
992 | * were created when the expose events were processed. | |
993 | */ | |
994 | while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {} | |
995 | } | |
996 | } | |
997 | ||
998 | /* | |
999 | * This method is called when a user changes between light and dark mode. | |
1000 | * The implementation here generates a Tk virtual event which can be bound | |
1001 | * to a function that redraws the window in an appropriate style. | |
1002 | */ | |
1003 | ||
1004 | - (void) viewDidChangeEffectiveAppearance | |
1005 | { | |
1006 | XVirtualEvent event; | |
1007 | int x, y; | |
1008 | NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; | |
1009 | NSWindow *w = [self window]; | |
1010 | TkWindow *winPtr = TkMacOSXGetTkWindow(w); | |
1011 | Tk_Window tkwin = (Tk_Window) winPtr; | |
1012 | ||
1013 | if (!winPtr) { | |
1014 | return; | |
1015 | } | |
1016 | bzero(&event, sizeof(XVirtualEvent)); | |
1017 | event.type = VirtualEvent; | |
1018 | event.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); | |
1019 | event.send_event = false; | |
1020 | event.display = Tk_Display(tkwin); | |
1021 | event.event = Tk_WindowId(tkwin); | |
1022 | event.root = XRootWindow(Tk_Display(tkwin), 0); | |
1023 | event.subwindow = None; | |
1024 | event.time = TkpGetMS(); | |
1025 | XQueryPointer(NULL, winPtr->window, NULL, NULL, | |
1026 | &event.x_root, &event.y_root, &x, &y, &event.state); | |
1027 | Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y); | |
1028 | event.same_screen = true; | |
1029 | if (osxMode == nil) { | |
1030 | event.name = Tk_GetUid("LightAqua"); | |
1031 | Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); | |
1032 | return; | |
1033 | } | |
1034 | if ([osxMode isEqual:@"Dark"]) { | |
1035 | event.name = Tk_GetUid("DarkAqua"); | |
1036 | Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); | |
1037 | return; | |
923 | 1038 | } |
924 | 1039 | } |
925 | 1040 | |
927 | 1042 | * This is no-op on 10.7 and up because Apple has removed this widget, |
928 | 1043 | * but we are leaving it here for backwards compatibility. |
929 | 1044 | */ |
1045 | ||
930 | 1046 | - (void) tkToolbarButton: (id) sender |
931 | 1047 | { |
932 | 1048 | #ifdef TK_MAC_DEBUG_EVENTS |
936 | 1052 | int x, y; |
937 | 1053 | TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); |
938 | 1054 | Tk_Window tkwin = (Tk_Window) winPtr; |
1055 | if (!winPtr){ | |
1056 | return; | |
1057 | } | |
939 | 1058 | bzero(&event, sizeof(XVirtualEvent)); |
940 | 1059 | event.type = VirtualEvent; |
941 | 1060 | event.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); |
956 | 1075 | - (BOOL) isOpaque |
957 | 1076 | { |
958 | 1077 | NSWindow *w = [self window]; |
959 | ||
960 | 1078 | return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) || |
961 | 1079 | ![w isOpaque]) ? NO : YES); |
962 | 1080 | } |
203 | 203 | |
204 | 204 | @implementation NSWindow(TKWm) |
205 | 205 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1070 |
206 | - (NSPoint) convertPointToScreen: (NSPoint) point | |
206 | - (NSPoint) tkConvertPointToScreen: (NSPoint) point | |
207 | 207 | { |
208 | 208 | return [self convertBaseToScreen:point]; |
209 | 209 | } |
210 | - (NSPoint) convertPointFromScreen: (NSPoint)point | |
210 | - (NSPoint) tkConvertPointFromScreen: (NSPoint)point | |
211 | 211 | { |
212 | 212 | return [self convertScreenToBase:point]; |
213 | 213 | } |
214 | 214 | #else |
215 | - (NSPoint) convertPointToScreen: (NSPoint) point | |
215 | - (NSPoint) tkConvertPointToScreen: (NSPoint) point | |
216 | 216 | { |
217 | 217 | NSRect pointrect; |
218 | 218 | pointrect.origin = point; |
220 | 220 | pointrect.size.height = 0; |
221 | 221 | return [self convertRectToScreen:pointrect].origin; |
222 | 222 | } |
223 | - (NSPoint) convertPointFromScreen: (NSPoint)point | |
223 | - (NSPoint) tkConvertPointFromScreen: (NSPoint)point | |
224 | 224 | { |
225 | 225 | NSRect pointrect; |
226 | 226 | pointrect.origin = point; |
230 | 230 | } |
231 | 231 | #endif |
232 | 232 | |
233 | - (NSSize)windowWillResize:(NSWindow *)sender | |
234 | toSize:(NSSize)frameSize | |
235 | { | |
236 | NSRect currentFrame = [sender frame]; | |
237 | TkWindow *winPtr = TkMacOSXGetTkWindow(sender); | |
238 | if (winPtr) { | |
239 | if (winPtr->wmInfoPtr->flags & WM_WIDTH_NOT_RESIZABLE) { | |
240 | frameSize.width = currentFrame.size.width; | |
241 | } | |
242 | if (winPtr->wmInfoPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { | |
243 | frameSize.height = currentFrame.size.height; | |
244 | } | |
245 | } | |
246 | return frameSize; | |
247 | } | |
233 | 248 | @end |
234 | 249 | |
235 | 250 | #pragma mark - |
371 | 386 | |
372 | 387 | |
373 | 388 | @implementation TKWindow: NSWindow |
374 | #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12 | |
375 | /* | |
376 | * Override automatic fullscreen button on >10.12 because system fullscreen API | |
377 | * confuses Tk window geometry. | |
378 | */ | |
389 | ||
390 | /* Custom fullscreen implementation on 10.13 and above. On older versions of | |
391 | * macOS dating back to 10.7, the NSWindow fullscreen API was opt-in, requiring | |
392 | * explicit calls to toggleFullScreen. On 10.13, the API became implicit, | |
393 | * applying to all NSWindows unless they were marked non-resizable; this caused | |
394 | * issues with Tk, which was not aware of changes in screen geometry. Here we | |
395 | * override the toggleFullScreen call to hook directly into Tk's own fullscreen | |
396 | * API, allowing Tk to function smoothly with the Mac's fullscreen button. | |
397 | */ | |
398 | ||
399 | NSStatusItem *exitFullScreen; | |
400 | ||
401 | ||
379 | 402 | - (void)toggleFullScreen:(id)sender |
380 | 403 | { |
381 | if ([self isZoomed]) { | |
382 | TkMacOSXZoomToplevel(self, inZoomIn); | |
383 | } else { | |
384 | TkMacOSXZoomToplevel(self, inZoomOut); | |
385 | } | |
386 | } | |
387 | #endif | |
404 | TkWindow *winPtr = TkMacOSXGetTkWindow(self); | |
405 | if (!winPtr) { | |
406 | return; | |
407 | } | |
408 | Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr); | |
409 | if ([NSApp macMinorVersion] > 12) { | |
410 | if (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask) { | |
411 | TkMacOSXMakeFullscreen(winPtr, self, 0, interp); | |
412 | } else { | |
413 | TkMacOSXMakeFullscreen(winPtr, self, 1, interp); | |
414 | } | |
415 | } else { | |
416 | TKLog (@"toggleFullScreen is ignored by Tk on OSX versions < 10.13"); | |
417 | } | |
418 | } | |
419 | ||
420 | -(void)restoreOldScreen:(id)sender | |
421 | { | |
422 | TkWindow *winPtr = TkMacOSXGetTkWindow(self); | |
423 | if (!winPtr) { | |
424 | return; | |
425 | } | |
426 | Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr); | |
427 | TkMacOSXMakeFullscreen(winPtr, self, 0, interp); | |
428 | [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen]; | |
429 | } | |
430 | ||
388 | 431 | @end |
389 | 432 | |
390 | 433 | @implementation TKWindow(TKWm) |
392 | 435 | - (BOOL) canBecomeKeyWindow |
393 | 436 | { |
394 | 437 | TkWindow *winPtr = TkMacOSXGetTkWindow(self); |
395 | ||
396 | return (winPtr && winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass == | |
397 | kHelpWindowClass || winPtr->wmInfoPtr->attributes & | |
398 | kWindowNoActivatesAttribute)) ? NO : YES; | |
399 | } | |
400 | ||
401 | ||
438 | if (!winPtr) { | |
439 | return NO; | |
440 | } | |
441 | return (winPtr->wmInfoPtr && | |
442 | (winPtr->wmInfoPtr->macClass == kHelpWindowClass || | |
443 | winPtr->wmInfoPtr->attributes & kWindowNoActivatesAttribute) | |
444 | ) ? NO : YES; | |
445 | } | |
402 | 446 | |
403 | 447 | #if DEBUG_ZOMBIES |
404 | 448 | - (id) retain |
409 | 453 | title = "unnamed window"; |
410 | 454 | } |
411 | 455 | if (DEBUG_ZOMBIES > 1){ |
412 | printf("Retained <%s>. Count is: %lu\n", title, [self retainCount]); | |
456 | fprintf(stderr, "Retained <%s>. Count is: %lu\n", | |
457 | title, [self retainCount]); | |
413 | 458 | } |
414 | 459 | return result; |
415 | 460 | } |
422 | 467 | title = "unnamed window"; |
423 | 468 | } |
424 | 469 | if (DEBUG_ZOMBIES > 1){ |
425 | printf("Autoreleased <%s>. Count is %lu\n", title, [self retainCount]); | |
470 | fprintf(stderr, "Autoreleased <%s>. Count is %lu\n", | |
471 | title, [self retainCount]); | |
426 | 472 | } |
427 | 473 | return result; |
428 | 474 | } |
433 | 479 | title = "unnamed window"; |
434 | 480 | } |
435 | 481 | if (DEBUG_ZOMBIES > 1){ |
436 | printf("Releasing <%s>. Count is %lu\n", title, [self retainCount]); | |
482 | fprintf(stderr, "Releasing <%s>. Count is %lu\n", | |
483 | title, [self retainCount]); | |
437 | 484 | } |
438 | 485 | [super release]; |
439 | 486 | } |
444 | 491 | title = "unnamed window"; |
445 | 492 | } |
446 | 493 | if (DEBUG_ZOMBIES > 0){ |
447 | printf(">>>> Freeing <%s>. Count is %lu\n", title, [self retainCount]); | |
494 | fprintf(stderr, ">>>> Freeing <%s>. Count is %lu\n", | |
495 | title, [self retainCount]); | |
448 | 496 | } |
449 | 497 | [super dealloc]; |
450 | 498 | } |
565 | 613 | { |
566 | 614 | NSPoint p = NSMakePoint(x, tkMacOSXZeroScreenHeight - y); |
567 | 615 | NSArray *windows = [NSApp orderedWindows]; |
568 | TkWindow *front = NULL; | |
616 | TkWindow *winPtr = NULL; | |
569 | 617 | |
570 | 618 | for (NSWindow *w in windows) { |
571 | if (w && NSMouseInRect(p, [w frame], NO)) { | |
572 | front = TkMacOSXGetTkWindow(w); | |
573 | break; | |
574 | } | |
575 | } | |
576 | return front; | |
619 | winPtr = TkMacOSXGetTkWindow(w); | |
620 | if (winPtr && NSMouseInRect(p, [w frame], NO)) { | |
621 | break; | |
622 | } | |
623 | } | |
624 | return winPtr; | |
577 | 625 | } |
578 | 626 | |
579 | 627 | /* |
701 | 749 | * mapped. */ |
702 | 750 | { |
703 | 751 | WmInfo *wmPtr = winPtr->wmInfoPtr; |
704 | ||
705 | 752 | if (wmPtr->flags & WM_NEVER_MAPPED) { |
706 | 753 | /* |
707 | 754 | * Create the underlying Mac window for this Tk window. |
773 | 820 | /*Add window to Window menu.*/ |
774 | 821 | NSWindow *win = TkMacOSXDrawableWindow(winPtr->window); |
775 | 822 | [win setExcludedFromWindowsMenu:NO]; |
776 | ||
777 | 823 | } |
778 | 824 | |
779 | 825 | /* |
3429 | 3475 | if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) { |
3430 | 3476 | return TCL_ERROR; |
3431 | 3477 | } |
3432 | Tk_MakeWindowExist(master); | |
3478 | TkWindow* masterPtr = (TkWindow*) master; | |
3479 | while (!Tk_TopWinHierarchy(masterPtr)) { | |
3480 | /* | |
3481 | * Ensure that the master window is actually a Tk toplevel. | |
3482 | */ | |
3483 | ||
3484 | masterPtr = masterPtr->parentPtr; | |
3485 | } | |
3486 | Tk_MakeWindowExist((Tk_Window)masterPtr); | |
3433 | 3487 | |
3434 | 3488 | if (wmPtr->iconFor != NULL) { |
3435 | 3489 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
3439 | 3493 | return TCL_ERROR; |
3440 | 3494 | } |
3441 | 3495 | |
3442 | wmPtr2 = ((TkWindow *) master)->wmInfoPtr; | |
3443 | ||
3496 | wmPtr2 = masterPtr->wmInfoPtr; | |
3444 | 3497 | /* Under some circumstances, wmPtr2 is NULL here */ |
3445 | 3498 | if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) { |
3446 | 3499 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
3450 | 3503 | return TCL_ERROR; |
3451 | 3504 | } |
3452 | 3505 | |
3453 | if ((TkWindow *) master == winPtr) { | |
3506 | if (masterPtr == winPtr) { | |
3454 | 3507 | Tcl_SetObjResult(interp, Tcl_ObjPrintf( |
3455 | 3508 | "can't make \"%s\" its own master", Tk_PathName(winPtr))); |
3456 | 3509 | Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL); |
3457 | 3510 | return TCL_ERROR; |
3458 | 3511 | } |
3459 | 3512 | |
3460 | wmPtr->master = Tk_WindowId(master); | |
3461 | masterWindowName = Tcl_GetStringFromObj(objv[3], &length); | |
3513 | wmPtr->master = Tk_WindowId(masterPtr); | |
3514 | masterWindowName = masterPtr->pathName; | |
3515 | length = strlen(masterWindowName); | |
3462 | 3516 | if (wmPtr->masterWindowName != NULL) { |
3463 | 3517 | ckfree(wmPtr->masterWindowName); |
3464 | 3518 | } |
4250 | 4304 | */ |
4251 | 4305 | |
4252 | 4306 | winPtr = otherPtr; |
4253 | ||
4254 | /* | |
4255 | * Remember to offset by the container window here, since at the | |
4256 | * end of this if branch, we will pop out to the container's | |
4257 | * parent... | |
4258 | */ | |
4259 | ||
4260 | x += winPtr->changes.x + winPtr->changes.border_width; | |
4261 | y += winPtr->changes.y + winPtr->changes.border_width; | |
4307 | continue; | |
4262 | 4308 | } |
4263 | 4309 | winPtr = winPtr->parentPtr; |
4264 | 4310 | } |
5611 | 5657 | } |
5612 | 5658 | TKContentView *contentView = [[TKContentView alloc] |
5613 | 5659 | initWithFrame:NSZeroRect]; |
5614 | [window setColorSpace:[NSColorSpace deviceRGBColorSpace]]; | |
5615 | 5660 | [window setContentView:contentView]; |
5616 | 5661 | [contentView release]; |
5617 | 5662 | [window setDelegate:NSApp]; |
5618 | 5663 | [window setAcceptsMouseMovedEvents:YES]; |
5619 | 5664 | [window setReleasedWhenClosed:NO]; |
5620 | [window setAutodisplay:NO]; | |
5621 | 5665 | if (styleMask & NSUtilityWindowMask) { |
5622 | 5666 | [(NSPanel*)window setFloatingPanel:YES]; |
5623 | 5667 | } |
5624 | 5668 | if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) && |
5625 | 5669 | !(styleMask & NSDocModalWindowMask)) { |
5626 | 5670 | /* |
5627 | * Workaround for [Bug 2824538]: Texured windows are draggable | |
5671 | * Workaround for [Bug 2824538]: Textured windows are draggable | |
5628 | 5672 | * from opaque content. |
5629 | 5673 | */ |
5630 | 5674 | [window setMovableByWindowBackground:NO]; |
5640 | 5684 | geometry.size.height += structureRect.size.height; |
5641 | 5685 | geometry.origin.y = tkMacOSXZeroScreenHeight - (geometry.origin.y + |
5642 | 5686 | geometry.size.height); |
5643 | [window setFrame:geometry display:NO]; | |
5687 | [window setFrame:geometry display:YES]; | |
5644 | 5688 | TkMacOSXRegisterOffScreenWindow((Window) macWin, window); |
5645 | 5689 | macWin->flags |= TK_HOST_EXISTS; |
5690 | } | |
5691 | ||
5692 | /* | |
5693 | *---------------------------------------------------------------------- | |
5694 | * | |
5695 | * TkpDisplayWindow -- | |
5696 | * | |
5697 | * Mark the contentView of this window as needing display so the | |
5698 | * window will be drawn by the window manager. If this is called | |
5699 | * within the drawRect method, do nothing. | |
5700 | * | |
5701 | * Results: | |
5702 | * None. | |
5703 | * | |
5704 | * Side effects: | |
5705 | * The window's contentView is marked as needing display. | |
5706 | * | |
5707 | *---------------------------------------------------------------------- | |
5708 | */ | |
5709 | ||
5710 | MODULE_SCOPE void | |
5711 | TkpDisplayWindow(Tk_Window tkwin) { | |
5712 | if (![NSApp isDrawing]) { | |
5713 | TkWindow *winPtr = (TkWindow*)tkwin; | |
5714 | NSWindow *w = TkMacOSXDrawableWindow(winPtr->window); | |
5715 | [[w contentView] setNeedsDisplay: YES]; | |
5716 | } | |
5646 | 5717 | } |
5647 | 5718 | |
5648 | 5719 | /* |
6267 | 6338 | [[macWindow standardWindowButton:NSWindowZoomButton] |
6268 | 6339 | setEnabled:(newAttributes & kWindowResizableAttribute) && |
6269 | 6340 | (newAttributes & kWindowFullZoomAttribute)]; |
6270 | if (newAttributes & kWindowResizableAttribute) { | |
6271 | wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE | | |
6272 | WM_HEIGHT_NOT_RESIZABLE); | |
6341 | if (newAttributes & kWindowHorizontalZoomAttribute) { | |
6342 | wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE); | |
6273 | 6343 | } else { |
6274 | wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE | | |
6275 | WM_HEIGHT_NOT_RESIZABLE); | |
6344 | wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE); | |
6345 | } | |
6346 | if (newAttributes & kWindowVerticalZoomAttribute) { | |
6347 | wmPtr->flags &= ~(WM_HEIGHT_NOT_RESIZABLE); | |
6348 | } else { | |
6349 | wmPtr->flags |= (WM_HEIGHT_NOT_RESIZABLE); | |
6276 | 6350 | } |
6277 | 6351 | WmUpdateGeom(wmPtr, winPtr); |
6278 | 6352 | } |
6456 | 6530 | Tcl_Interp *interp) |
6457 | 6531 | { |
6458 | 6532 | WmInfo *wmPtr = winPtr->wmInfoPtr; |
6459 | int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN); | |
6460 | static unsigned long prevMask = 0, prevPres = 0; | |
6533 | int screenWidth = WidthOfScreen(Tk_Screen(winPtr)); | |
6534 | int screenHeight = HeightOfScreen(Tk_Screen(winPtr)); | |
6461 | 6535 | |
6462 | 6536 | if (fullscreen) { |
6463 | int screenWidth = WidthOfScreen(Tk_Screen(winPtr)); | |
6464 | int screenHeight = HeightOfScreen(Tk_Screen(winPtr)); | |
6465 | 6537 | |
6466 | 6538 | /* |
6467 | 6539 | * Check max width and height if set by the user. |
6476 | 6548 | Tcl_SetErrorCode(interp, "TK", "FULLSCREEN", |
6477 | 6549 | "CONSTRAINT_FAILURE", NULL); |
6478 | 6550 | } |
6479 | result = TCL_ERROR; | |
6480 | 6551 | wmPtr->flags &= ~WM_FULLSCREEN; |
6481 | } else { | |
6482 | Tk_UnmapWindow((Tk_Window) winPtr); | |
6483 | NSRect bounds = [window contentRectForFrameRect:[window frame]]; | |
6484 | NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight); | |
6485 | ||
6486 | if (!NSEqualRects(bounds, screenBounds) && !wasFullscreen) { | |
6487 | wmPtr->configX = wmPtr->x; | |
6488 | wmPtr->configY = wmPtr->y; | |
6489 | wmPtr->configAttributes = wmPtr->attributes; | |
6490 | wmPtr->attributes &= ~kWindowResizableAttribute; | |
6491 | ApplyWindowAttributeFlagChanges(winPtr, window, | |
6492 | wmPtr->configAttributes, wmPtr->flags, 1, 0); | |
6493 | wmPtr->flags |= WM_SYNC_PENDING; | |
6494 | [window setFrame:[window frameRectForContentRect: | |
6495 | screenBounds] display:YES]; | |
6496 | wmPtr->flags &= ~WM_SYNC_PENDING; | |
6497 | } | |
6498 | wmPtr->flags |= WM_FULLSCREEN; | |
6499 | } | |
6500 | ||
6501 | prevMask = [window styleMask]; | |
6502 | prevPres = [NSApp presentationOptions]; | |
6503 | [window setStyleMask: NSBorderlessWindowMask]; | |
6504 | [NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock | |
6505 | | NSApplicationPresentationAutoHideMenuBar]; | |
6506 | Tk_MapWindow((Tk_Window) winPtr); | |
6552 | return TCL_ERROR; | |
6553 | } | |
6554 | ||
6555 | /* | |
6556 | * Save the current window state. | |
6557 | */ | |
6558 | ||
6559 | wmPtr->cachedBounds = [window frame]; | |
6560 | wmPtr->cachedStyle = [window styleMask]; | |
6561 | wmPtr->cachedPresentation = [NSApp presentationOptions]; | |
6562 | ||
6563 | /* | |
6564 | * Adjust the window style so it looks like a Fullscreen window. | |
6565 | */ | |
6566 | ||
6567 | [window setStyleMask: NSFullScreenWindowMask]; | |
6568 | [NSApp setPresentationOptions: (NSApplicationPresentationAutoHideDock | | |
6569 | NSApplicationPresentationAutoHideMenuBar)]; | |
6570 | ||
6571 | /*For 10.13 and later add a button for exiting Fullscreen.*/ | |
6572 | if ([NSApp macMinorVersion] > 12) { | |
6573 | #if MAC_OS_X_VERSION_MAX_ALLOWED > 101200 | |
6574 | exitFullScreen = [[[NSStatusBar systemStatusBar] | |
6575 | statusItemWithLength:NSVariableStatusItemLength] retain]; | |
6576 | NSImage *exitIcon = [NSImage imageNamed:@"NSExitFullScreenTemplate"]; | |
6577 | exitFullScreen.button.image = exitIcon; | |
6578 | exitFullScreen.button.cell.highlighted = NO; | |
6579 | exitFullScreen.button.toolTip = @"Exit Full Screen"; | |
6580 | exitFullScreen.button.target = window; | |
6581 | exitFullScreen.button.action = @selector(restoreOldScreen:); | |
6582 | #endif | |
6583 | } | |
6584 | ||
6585 | /* | |
6586 | * Resize the window to fill the screen. (After setting the style!) | |
6587 | */ | |
6588 | ||
6589 | wmPtr->flags |= WM_SYNC_PENDING; | |
6590 | NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight); | |
6591 | [window setFrame:screenBounds display:YES]; | |
6592 | wmPtr->flags &= ~WM_SYNC_PENDING; | |
6593 | wmPtr->flags |= WM_FULLSCREEN; | |
6507 | 6594 | } else { |
6595 | ||
6596 | /* | |
6597 | * Restore the previous styles and attributes. | |
6598 | */ | |
6599 | ||
6600 | [NSApp setPresentationOptions: wmPtr->cachedPresentation]; | |
6601 | [window setStyleMask: wmPtr->cachedStyle]; | |
6602 | UInt64 oldAttributes = wmPtr->attributes; | |
6508 | 6603 | wmPtr->flags &= ~WM_FULLSCREEN; |
6509 | [NSApp setPresentationOptions: prevPres]; | |
6510 | [window setStyleMask: prevMask]; | |
6511 | } | |
6512 | ||
6513 | if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) { | |
6514 | Tk_UnmapWindow((Tk_Window) winPtr); | |
6515 | UInt64 oldAttributes = wmPtr->attributes; | |
6516 | NSRect bounds = NSMakeRect(wmPtr->configX, tkMacOSXZeroScreenHeight - | |
6517 | (wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight), | |
6518 | wmPtr->xInParent + wmPtr->configWidth, | |
6519 | wmPtr->yInParent + wmPtr->configHeight); | |
6520 | ||
6521 | 6604 | wmPtr->attributes |= wmPtr->configAttributes & |
6522 | 6605 | kWindowResizableAttribute; |
6523 | 6606 | ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes, |
6524 | 6607 | wmPtr->flags, 1, 0); |
6608 | ||
6609 | /* | |
6610 | * Resize the window to its previous size. | |
6611 | */ | |
6612 | ||
6525 | 6613 | wmPtr->flags |= WM_SYNC_PENDING; |
6526 | [window setFrame:[window frameRectForContentRect:bounds] display:YES]; | |
6614 | [window setFrame:wmPtr->cachedBounds display:YES]; | |
6527 | 6615 | wmPtr->flags &= ~WM_SYNC_PENDING; |
6528 | Tk_MapWindow((Tk_Window) winPtr); | |
6529 | } | |
6530 | return result; | |
6616 | } | |
6617 | return TCL_OK; | |
6531 | 6618 | } |
6532 | 6619 | |
6533 | 6620 | /* |
184 | 184 | TkWindow *scrollWinPtr; /* Ptr to scrollbar handling grow widget. */ |
185 | 185 | TkMenu *menuPtr; |
186 | 186 | NSWindow *window; |
187 | ||
188 | /* | |
189 | * Space to cache current window state when window becomes Fullscreen. | |
190 | */ | |
191 | ||
192 | unsigned long cachedStyle; | |
193 | unsigned long cachedPresentation; | |
194 | NSRect cachedBounds; | |
195 | ||
187 | 196 | } WmInfo; |
188 | 197 | |
189 | 198 | /* |
2 | 2 | * |
3 | 3 | * This file contains most of the X calls called by Tk. Many of these |
4 | 4 | * calls are just stubs and either don't make sense on the Macintosh or |
5 | * their implamentation just doesn't do anything. Other calls will | |
5 | * their implementation just doesn't do anything. Other calls will | |
6 | 6 | * eventually be moved into other files. |
7 | 7 | * |
8 | 8 | * Copyright (c) 1995-1997 Sun Microsystems, Inc. |
39 | 39 | * Declarations of static variables used in this file. |
40 | 40 | */ |
41 | 41 | |
42 | /* The unique Macintosh display. */ | |
42 | 43 | static TkDisplay *gMacDisplay = NULL; |
43 | /* Macintosh display. */ | |
44 | /* The default name of the Macintosh display. */ | |
44 | 45 | static const char *macScreenName = ":0"; |
45 | /* Default name of macintosh display. */ | |
46 | /* Timestamp showing the last reset of the inactivity timer. */ | |
47 | static Time lastInactivityReset = 0; | |
48 | ||
46 | 49 | |
47 | 50 | /* |
48 | 51 | * Forward declarations of procedures used in this file. |
174 | 177 | { |
175 | 178 | int major, minor, patch; |
176 | 179 | |
177 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 | |
180 | #if MAC_OS_X_VERSION_MIN_REQUIRED < 101000 | |
178 | 181 | Gestalt(gestaltSystemVersionMajor, (SInt32*)&major); |
179 | 182 | Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor); |
180 | 183 | Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch); |
199 | 202 | screen->root_visual = ckalloc(sizeof(Visual)); |
200 | 203 | screen->root_visual->visualid = 0; |
201 | 204 | screen->root_visual->class = TrueColor; |
202 | screen->root_visual->alpha_mask = 0xFF000000; | |
203 | 205 | screen->root_visual->red_mask = 0x00FF0000; |
204 | 206 | screen->root_visual->green_mask = 0x0000FF00; |
205 | 207 | screen->root_visual->blue_mask = 0x000000FF; |
873 | 875 | Tcl_Interp *interp, /* Not used. */ |
874 | 876 | const char *screenName) /* If NULL, use default string. */ |
875 | 877 | { |
876 | #if 0 | |
877 | 878 | if ((screenName == NULL) || (screenName[0] == '\0')) { |
878 | 879 | screenName = macScreenName; |
879 | 880 | } |
880 | 881 | return screenName; |
881 | #endif | |
882 | return macScreenName; | |
883 | 882 | } |
884 | 883 | |
885 | 884 | /* |
927 | 926 | timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime")); |
928 | 927 | |
929 | 928 | if (timeObj) { |
930 | CFTypeID type = CFGetTypeID(timeObj); | |
931 | ||
932 | if (type == CFDataGetTypeID()) { /* Jaguar */ | |
933 | CFDataGetBytes((CFDataRef) timeObj, | |
934 | CFRangeMake(0, sizeof(time)), (UInt8 *) &time); | |
935 | /* Convert nanoseconds to milliseconds. */ | |
936 | /* ret /= kMillisecondScale; */ | |
937 | ret = (long) (time/kMillisecondScale); | |
938 | } else if (type == CFNumberGetTypeID()) { /* Panther+ */ | |
939 | 929 | CFNumberGetValue((CFNumberRef)timeObj, |
940 | 930 | kCFNumberSInt64Type, &time); |
941 | 931 | /* Convert nanoseconds to milliseconds. */ |
942 | /* ret /= kMillisecondScale; */ | |
943 | 932 | ret = (long) (time/kMillisecondScale); |
944 | } else { | |
945 | ret = -1l; | |
946 | } | |
947 | 933 | } |
948 | 934 | /* Cleanup */ |
949 | 935 | CFRelease(props); |
950 | 936 | |
937 | /* | |
938 | * If the idle time reported by the system is larger than the elapsed | |
939 | * time since the last reset, return the elapsed time. | |
940 | */ | |
941 | long elapsed = (long)(TkpGetMS() - lastInactivityReset); | |
942 | if (ret > elapsed) { | |
943 | ret = elapsed; | |
944 | } | |
945 | ||
951 | 946 | return ret; |
952 | 947 | } |
953 | 948 | |
972 | 967 | Tk_ResetUserInactiveTime( |
973 | 968 | Display *dpy) |
974 | 969 | { |
975 | IOGPoint loc = {0, 0}; | |
976 | kern_return_t kr; | |
977 | NXEvent nullEvent = {NX_NULLEVENT, {0, 0}, 0, -1, 0}; | |
978 | enum { kNULLEventPostThrottle = 10 }; | |
979 | static io_connect_t io_connection = MACH_PORT_NULL; | |
980 | ||
981 | if (io_connection == MACH_PORT_NULL) { | |
982 | io_service_t service = IOServiceGetMatchingService( | |
983 | kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass)); | |
984 | ||
985 | if (service == MACH_PORT_NULL) { | |
986 | return; | |
987 | } | |
988 | kr = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, | |
989 | &io_connection); | |
990 | IOObjectRelease(service); | |
991 | if (kr != KERN_SUCCESS) { | |
992 | return; | |
993 | } | |
994 | } | |
995 | kr = IOHIDPostEvent(io_connection, NX_NULLEVENT, loc, &nullEvent.data, | |
996 | FALSE, 0, FALSE); | |
970 | lastInactivityReset = TkpGetMS(); | |
997 | 971 | } |
998 | 972 | |
999 | 973 | /* |
38 | 38 | # events to make sure that there are no stray events in the ring |
39 | 39 | # buffer which might cause the pattern matcher to find unintended |
40 | 40 | # matches. The size of the ring buffer is EVENT_BUFFER_SIZE, which is |
41 | # currently set to 30. If this changes, the code below will need to | |
42 | # change. | |
41 | # currently set to 30 (or 45 on macOS). If this changes, the code | |
42 | # below will need to change. | |
43 | 43 | proc clearRingBuffer {{event}} { |
44 | for {set i 0} {$i < 30} {incr i} { | |
44 | for {set i 0} {$i < 45} {incr i} { | |
45 | 45 | event generate . $event |
46 | 46 | } |
47 | 47 | } |
83 | 83 | |
84 | 84 | test bitmap-4.1 {FreeBitmapObjProc} -constraints { |
85 | 85 | testbitmap |
86 | } -setup { | |
87 | proc copy {s} {return [string index $s 0][string range $s 1 end]} | |
86 | 88 | } -body { |
87 | set x [join questhead] | |
89 | set x [copy questhead] | |
88 | 90 | button .b -bitmap $x |
89 | set y [join questhead] | |
91 | set y [copy questhead] | |
90 | 92 | .b configure -bitmap $y |
91 | set z [join questhead] | |
93 | set z [copy questhead] | |
92 | 94 | .b configure -bitmap $z |
93 | 95 | set result {} |
94 | 96 | lappend result [testbitmap questhead] |
101 | 103 | set y bogus |
102 | 104 | return $result |
103 | 105 | } -cleanup { |
106 | rename copy {} | |
104 | 107 | destroy .b |
105 | 108 | } -result {{{1 3}} {{1 2}} {{1 1}} {}} |
106 | 109 |
130 | 130 | testborder |
131 | 131 | } -setup { |
132 | 132 | set result {} |
133 | } -body { | |
134 | set x [join purple] | |
133 | proc copy {s} {return [string index $s 0][string range $s 1 end]} | |
134 | } -body { | |
135 | set x [copy purple] | |
135 | 136 | button .b -bg $x -text .b1 |
136 | set y [join purple] | |
137 | set y [copy purple] | |
137 | 138 | .b configure -bg $y |
138 | set z [join purple] | |
139 | set z [copy purple] | |
139 | 140 | .b configure -bg $z |
140 | 141 | lappend result [testborder purple] |
141 | 142 | set x red |
147 | 148 | set y bogus |
148 | 149 | return $result |
149 | 150 | } -cleanup { |
151 | rename copy {} | |
150 | 152 | destroy .b |
151 | 153 | } -result {{{1 3}} {{1 2}} {{1 1}} {}} |
152 | 154 |
172 | 172 | .c delete all |
173 | 173 | image delete foo |
174 | 174 | image delete foo2 |
175 | } -result {{{foo free}} {{foo2 get} {foo2 display 0 0 80 60 30 30}} {50 100 130 160}} | |
175 | } -result {{{foo free}} {{foo2 get} {foo2 display 0 0 80 60}} {50 100 130 160}} | |
176 | 176 | test canvImg-4.3 {ConfiugreImage procedure} -constraints testImageType -setup { |
177 | 177 | .c delete all |
178 | 178 | } -body { |
732 | 732 | } -cleanup { |
733 | 733 | .c delete all |
734 | 734 | image delete foo |
735 | } -result {{foo display 2 4 6 8 30 30}} | |
735 | } -result {{foo display 2 4 6 8}} | |
736 | 736 | |
737 | 737 | test canvImg-11.1 {TranslateImage procedure} -constraints testImageType -setup { |
738 | 738 | .c delete all |
747 | 747 | } -cleanup { |
748 | 748 | .c delete all |
749 | 749 | image delete foo |
750 | } -result {{foo display 0 0 40 50 30 30}} | |
750 | } -result {{foo display 0 0 40 50}} | |
751 | 751 | test canvImg-11.2 {ImageChangedProc procedure} -constraints { |
752 | 752 | testImageType |
753 | 753 | } -setup { |
783 | 783 | } -cleanup { |
784 | 784 | .c delete all |
785 | 785 | image delete foo foo2 |
786 | } -result {{foo2 display 0 0 20 40 50 40}} | |
786 | } -result {{foo2 display 0 0 20 40}} | |
787 | 787 | |
788 | 788 | # cleanup |
789 | 789 | imageFinish |
54 | 54 | list [lindex [.c itemconfigure test -stipple] 4] [.c itemcget test -stipple] |
55 | 55 | } -result {gray50 gray50} |
56 | 56 | test canvasText-1.11 {configuration options: bad value for "stipple"} -body { |
57 | .c itemconfigure test -stipple xyz | |
58 | } -returnCodes error -result {bitmap "xyz" not defined} | |
57 | .c itemconfigure test -stipple abcxyz | |
58 | } -returnCodes error -result {bitmap "abcxyz" not defined} | |
59 | 59 | test canvText-1.12 {configuration options: good value for "underline"} -body { |
60 | 60 | .c itemconfigure test -underline 0 |
61 | 61 | list [lindex [.c itemconfigure test -underline] 4] [.c itemcget test -underline] |
84 | 84 | |
85 | 85 | set parent . |
86 | 86 | |
87 | test choosedir-1.1 {tk_chooseDirectory command} -constraints unix -body { | |
87 | test choosedir-1.1 {tk_chooseDirectory command} -body { | |
88 | 88 | tk_chooseDirectory -initialdir |
89 | 89 | } -returnCodes error -result {value for "-initialdir" missing} |
90 | test choosedir-1.2 {tk_chooseDirectory command} -constraints unix -body { | |
90 | test choosedir-1.2 {tk_chooseDirectory command} -body { | |
91 | 91 | tk_chooseDirectory -mustexist |
92 | 92 | } -returnCodes error -result {value for "-mustexist" missing} |
93 | test choosedir-1.3 {tk_chooseDirectory command} -constraints unix -body { | |
93 | test choosedir-1.3 {tk_chooseDirectory command} -body { | |
94 | 94 | tk_chooseDirectory -parent |
95 | 95 | } -returnCodes error -result {value for "-parent" missing} |
96 | test choosedir-1.4 {tk_chooseDirectory command} -constraints unix -body { | |
96 | test choosedir-1.4 {tk_chooseDirectory command} -body { | |
97 | 97 | tk_chooseDirectory -title |
98 | 98 | } -returnCodes error -result {value for "-title" missing} |
99 | ||
100 | test choosedir-1.5 {tk_chooseDirectory command} -constraints unix -body { | |
99 | test choosedir-1.5.1 {tk_chooseDirectory command} -constraints notAqua -body { | |
101 | 100 | tk_chooseDirectory -foo bar |
102 | 101 | } -returnCodes error -result {bad option "-foo": must be -initialdir, -mustexist, -parent, or -title} |
103 | test choosedir-1.6 {tk_chooseDirectory command} -constraints unix -body { | |
102 | test choosedir-1.5.2 {tk_chooseDirectory command} -constraints aqua -body { | |
103 | tk_chooseDirectory -foo bar | |
104 | } -returnCodes error -result {bad option "-foo": must be -initialdir, -message, -mustexist, -parent, -title, or -command} | |
105 | test choosedir-1.6 {tk_chooseDirectory command} -body { | |
104 | 106 | tk_chooseDirectory -parent foo.bar |
105 | 107 | } -returnCodes error -result {bad window path name "foo.bar"} |
106 | 108 |
160 | 160 | clipboard append "Test" |
161 | 161 | clipboard append -t TEST "Test2" |
162 | 162 | selection clear -s CLIPBOARD |
163 | catch {clipboard get} | |
164 | clipboard get -t TEST | |
163 | clipboard get -t TEST | |
165 | 164 | } -cleanup { |
166 | 165 | clipboard clear |
167 | 166 | } -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined} |
183 | 182 | clipboard append -t TEST "Test2" |
184 | 183 | clipboard append "Test3" |
185 | 184 | selection clear -s CLIPBOARD |
186 | catch {clipboard get} | |
187 | clipboard get -t TEST | |
185 | clipboard get -t TEST | |
188 | 186 | } -cleanup { |
189 | 187 | clipboard clear |
190 | 188 | } -returnCodes error -result {CLIPBOARD selection doesn't exist or form "TEST" not defined} |
229 | 227 | } -cleanup { |
230 | 228 | clipboard clear |
231 | 229 | } -returnCodes ok -result {first chunk second chunk} |
232 | test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints unix -setup { | |
230 | test clipboard-6.2 {Tk_ClipboardAppend procedure} -constraints x11 -setup { | |
233 | 231 | clipboard clear |
234 | 232 | } -body { |
235 | 233 | setupbg |
276 | 276 | lappend result [testcolor purple] |
277 | 277 | } {{{4 1} {3 0} {2 0} {1 0}} {{4 1} {2 0} {1 0}} {{4 1} {2 0}} {{2 0}} {}} |
278 | 278 | |
279 | test color-4.1 {FreeColorObjProc} colorsFree { | |
279 | test color-4.1 {FreeColorObjProc} -constraints { | |
280 | colorsFree | |
281 | } -setup { | |
282 | proc copy {s} {return [string index $s 0][string range $s 1 end]} | |
283 | } -body { | |
280 | 284 | destroy .b |
281 | set x [format purple] | |
285 | set x [copy purple] | |
282 | 286 | button .b -foreground $x -text .b1 |
283 | set y [format purple] | |
287 | set y [copy purple] | |
284 | 288 | .b configure -foreground $y |
285 | set z [format purple] | |
289 | set z [copy purple] | |
286 | 290 | .b configure -foreground $z |
287 | 291 | set result {} |
288 | 292 | lappend result [testcolor purple] |
294 | 298 | lappend result [testcolor purple] |
295 | 299 | set y bogus |
296 | 300 | set result |
297 | } {{{1 3}} {{1 2}} {{1 1}} {}} | |
301 | } -cleanup { | |
302 | rename copy {} | |
303 | } -result {{{1 3}} {{1 2}} {{1 1}} {}} | |
298 | 304 | |
299 | 305 | destroy .t |
300 | 306 |
678 | 678 | test config-4.57 {DoObjConfig - invalid bitmap} -constraints { |
679 | 679 | testobjconfig |
680 | 680 | } -body { |
681 | testobjconfig alltypes .foo -bitmap foo | |
682 | } -cleanup { | |
683 | killTables | |
684 | } -returnCodes error -result {bitmap "foo" not defined} | |
681 | testobjconfig alltypes .foo -bitmap foobar | |
682 | } -cleanup { | |
683 | killTables | |
684 | } -returnCodes error -result {bitmap "foobar" not defined} | |
685 | 685 | test config-4.58 {DoObjConfig - null bitmap} -constraints testobjconfig -body { |
686 | 686 | testobjconfig alltypes .foo -bitmap {} |
687 | 687 | } -cleanup { |
143 | 143 | |
144 | 144 | test cursor-4.1 {FreeCursorObjProc} -constraints { |
145 | 145 | testcursor |
146 | } -body { | |
147 | set x [join heart] | |
146 | } -setup { | |
147 | proc copy {s} {return [string index $s 0][string range $s 1 end]} | |
148 | } -body { | |
149 | set x [copy heart] | |
148 | 150 | button .b -cursor $x |
149 | set y [join heart] | |
151 | set y [copy heart] | |
150 | 152 | .b configure -cursor $y |
151 | set z [join heart] | |
153 | set z [copy heart] | |
152 | 154 | .b configure -cursor $z |
153 | 155 | set result {} |
154 | 156 | lappend result [testcursor heart] |
161 | 163 | set y bogus |
162 | 164 | set result |
163 | 165 | } -cleanup { |
166 | rename copy {} | |
164 | 167 | destroy .b |
165 | 168 | } -result {{{1 3}} {{1 2}} {{1 1}} {}} |
166 | 169 |
Binary diff not shown
109 | 109 | set modes 1 |
110 | 110 | } |
111 | 111 | |
112 | set unknownOptionsMsg(tk_getOpenFile) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable} | |
113 | set unknownOptionsMsg(tk_getSaveFile) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable} | |
112 | set unknownOptionsMsg(tk_getOpenFile,notAqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -multiple, -parent, -title, or -typevariable} | |
113 | set unknownOptionsMsg(tk_getOpenFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -multiple, -parent, -title, -typevariable, or -command} | |
114 | set unknownOptionsMsg(tk_getSaveFile,notAqua) {bad option "-foo": must be -confirmoverwrite, -defaultextension, -filetypes, -initialdir, -initialfile, -parent, -title, or -typevariable} | |
115 | set unknownOptionsMsg(tk_getSaveFile,aqua) {bad option "-foo": must be -defaultextension, -filetypes, -initialdir, -initialfile, -message, -parent, -title, -typevariable, -command, or -confirmoverwrite} | |
114 | 116 | |
115 | 117 | set tmpFile "filebox.tmp" |
116 | 118 | makeFile { |
154 | 156 | } |
155 | 157 | } |
156 | 158 | |
157 | test filebox-1.1-$mode "tk_getOpenFile command" -body { | |
159 | test filebox-1.1.1-$mode "tk_getOpenFile command" -constraints notAqua -body { | |
158 | 160 | tk_getOpenFile -foo |
159 | } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile) | |
161 | } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,notAqua) | |
162 | test filebox-1.1.2-$mode "tk_getOpenFile command" -constraints aqua -body { | |
163 | tk_getOpenFile -foo | |
164 | } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,aqua) | |
160 | 165 | |
161 | 166 | catch {tk_getOpenFile -foo 1} msg |
162 | 167 | regsub -all , $msg "" options |
170 | 175 | } |
171 | 176 | } |
172 | 177 | |
173 | test filebox-1.3-$mode "tk_getOpenFile command" -body { | |
178 | test filebox-1.3.1-$mode "tk_getOpenFile command" -constraints notAqua -body { | |
174 | 179 | tk_getOpenFile -foo bar |
175 | } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile) | |
180 | } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,notAqua) | |
181 | test filebox-1.3.2-$mode "tk_getOpenFile command" -constraints aqua -body { | |
182 | tk_getOpenFile -foo bar | |
183 | } -returnCodes error -result $unknownOptionsMsg(tk_getOpenFile,aqua) | |
176 | 184 | test filebox-1.4-$mode "tk_getOpenFile command" -body { |
177 | 185 | tk_getOpenFile -initialdir |
178 | 186 | } -returnCodes error -result {value for "-initialdir" missing} |
288 | 296 | } $res |
289 | 297 | } |
290 | 298 | |
291 | test filebox-4.1-$mode "tk_getSaveFile command" -body { | |
299 | test filebox-4.1.1-$mode "tk_getSaveFile command" -constraints notAqua -body { | |
292 | 300 | tk_getSaveFile -foo |
293 | } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile) | |
301 | } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,notAqua) | |
302 | test filebox-4.1.2-$mode "tk_getSaveFile command" -constraints aqua -body { | |
303 | tk_getSaveFile -foo | |
304 | } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,aqua) | |
294 | 305 | |
295 | 306 | catch {tk_getSaveFile -foo 1} msg |
296 | 307 | regsub -all , $msg "" options |
304 | 315 | } |
305 | 316 | } |
306 | 317 | |
307 | test filebox-4.3-$mode "tk_getSaveFile command" -body { | |
318 | test filebox-4.3.1-$mode "tk_getSaveFile command" -constraints notAqua -body { | |
308 | 319 | tk_getSaveFile -foo bar |
309 | } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile) | |
320 | } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,notAqua) | |
321 | test filebox-4.3.2-$mode "tk_getSaveFile command" -constraints aqua -body { | |
322 | tk_getSaveFile -foo bar | |
323 | } -returnCodes error -result $unknownOptionsMsg(tk_getSaveFile,aqua) | |
310 | 324 | test filebox-4.4-$mode "tk_getSaveFile command" -body { |
311 | 325 | tk_getSaveFile -initialdir |
312 | 326 | } -returnCodes error -result {value for "-initialdir" missing} |
37 | 37 | update idletasks |
38 | 38 | |
39 | 39 | switch [tk windowingsystem] { |
40 | x11 {set fixed "fixed"} | |
40 | x11 {set fixed "TkFixedFont"} | |
41 | 41 | win32 {set fixed "courier 12"} |
42 | 42 | aqua {set fixed "monaco 9"} |
43 | 43 | } |
920 | 920 | } |
921 | 921 | } -result {LucidaBright} |
922 | 922 | test font-21.6 {Tk_PostscriptFontName procedure: spaces} -constraints { |
923 | unix | |
923 | x11 | |
924 | 924 | } -body { |
925 | 925 | psfontname "{new century schoolbook} 10" |
926 | 926 | } -result {NewCenturySchlbk-Roman} |
2355 | 2355 | test font-45.2 {TkFontGetAliasList: match} -constraints win -body { |
2356 | 2356 | font actual {times 10} -family |
2357 | 2357 | } -result {Times New Roman} |
2358 | test font-45.3 {TkFontGetAliasList: match} -constraints {unix noExceed} -body { | |
2359 | # can fail on Unix systems that have a real "times new roman" font | |
2360 | font actual {{times new roman} 10} -family | |
2361 | } -result [font actual {times 10} -family] | |
2358 | test font-45.3 {TkFontGetAliasList: match} -constraints {noExceed} -body { | |
2359 | if {[font actual {{times new roman} 10} -family] eq "Times New Roman"} { | |
2360 | # avoid test failure on systems that have a real "times new roman" font | |
2361 | set res 1 | |
2362 | } else { | |
2363 | set res [expr {[font actual {{times new roman} 10} -family] eq \ | |
2364 | [font actual {times 10} -family]} ] | |
2365 | } | |
2366 | } -result {1} | |
2362 | 2367 | |
2363 | 2368 | |
2364 | 2369 | test font-46.1 {font actual, with character, no option, no --} -body { |
66 | 66 | return $x |
67 | 67 | } -cleanup { |
68 | 68 | imageCleanup |
69 | } -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}} | |
69 | } -result {{myimage free} {myimage free} {myimage delete} {myimage get} {myimage get} {myimage display 0 0 30 15} {myimage display 0 0 30 15}} | |
70 | 70 | test image-1.8 {Tk_ImageCmd procedure, "create" option} -constraints { |
71 | 71 | testImageType |
72 | 72 | } -setup { |
85 | 85 | } -cleanup { |
86 | 86 | .c delete all |
87 | 87 | imageCleanup |
88 | } -result {{myimage get} {myimage get} {myimage display 0 0 30 15 30 30} {myimage display 0 0 30 15 30 130}} | |
88 | } -result {{myimage get} {myimage get} {myimage display 0 0 30 15} {myimage display 0 0 30 15}} | |
89 | 89 | test image-1.9 {Tk_ImageCmd procedure, "create" option} -constraints { |
90 | 90 | testImageType |
91 | 91 | } -body { |
359 | 359 | } -cleanup { |
360 | 360 | .c delete all |
361 | 361 | imageCleanup |
362 | } -result {{foo display 5 6 7 8 30 30}} | |
362 | } -result {{foo display 5 6 7 8}} | |
363 | 363 | test image-9.2 {Tk_ImageChanged procedure} -constraints testImageType -setup { |
364 | 364 | .c delete all |
365 | 365 | imageCleanup |
375 | 375 | } -cleanup { |
376 | 376 | .c delete all |
377 | 377 | imageCleanup |
378 | } -result {{foo display 5 6 25 9 30 30} {foo display 0 0 12 14 65 74}} | |
378 | } -result {{foo display 5 6 25 9} {foo display 0 0 12 14}} | |
379 | 379 | |
380 | 380 | |
381 | 381 | test image-10.1 {Tk_GetImage procedure} -setup { |
416 | 416 | } -cleanup { |
417 | 417 | .c delete all |
418 | 418 | imageCleanup |
419 | } -result {foo {{foo free} {foo display 0 0 30 15 103 121}}} | |
419 | } -result {foo {{foo free} {foo display 0 0 30 15}}} | |
420 | 420 | test image-11.2 {Tk_FreeImage procedure} -constraints testImageType -setup { |
421 | 421 | .c delete all |
422 | 422 | imageCleanup |
1200 | 1200 | } -cleanup { |
1201 | 1201 | image delete $i |
1202 | 1202 | } -returnCodes error -result {malformed image} |
1203 | test imgPhoto-14.5 {Bug [fbaed1f66b] - GIF decoder with deferred clear code} -setup { | |
1204 | set fileName [file join [file dirname [info script]] deferredClearCode.gif] | |
1205 | } -body { | |
1206 | # This erroneously produced "malformed image" error. | |
1207 | # The animated GIF "deferredClearCode.gif" has two frames, and calling for -index 2 | |
1208 | # simply is an easy way to trigger the problem of improper management of a deferred | |
1209 | # clear code. The effect was that the GIF decoder bailed out before the end of the | |
1210 | # image reading, and produced the inappropriate "malformed image error". | |
1211 | image create photo -file $fileName -format "gif -index 2" | |
1212 | } -returnCodes error -result {no image data for this index} | |
1203 | 1213 | |
1204 | 1214 | test imgPhoto-15.1 {photo images can fail to allocate memory gracefully} -constraints { |
1205 | 1215 | nonPortable |
10 | 10 | namespace import -force tcltest::test |
11 | 11 | |
12 | 12 | |
13 | test msgbox-1.1 {tk_messageBox command} -body { | |
13 | test msgbox-1.1.1 {tk_messageBox command} -constraints notAqua -body { | |
14 | 14 | tk_messageBox -foo |
15 | 15 | } -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type} |
16 | test msgbox-1.2 {tk_messageBox command} -body { | |
16 | test msgbox-1.1.2 {tk_messageBox command} -constraints aqua -body { | |
17 | tk_messageBox -foo | |
18 | } -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, -type, or -command} | |
19 | test msgbox-1.2.1 {tk_messageBox command} -constraints notAqua -body { | |
17 | 20 | tk_messageBox -foo bar |
18 | 21 | } -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, or -type} |
22 | test msgbox-1.2.2 {tk_messageBox command} -constraints aqua -body { | |
23 | tk_messageBox -foo bar | |
24 | } -returnCodes error -result {bad option "-foo": must be -default, -detail, -icon, -message, -parent, -title, -type, or -command} | |
19 | 25 | |
20 | 26 | test msgbox-1.3 {tk_messageBox command} -body { |
21 | 27 | tk_messageBox -default |
47 | 53 | tk_messageBox -type foo |
48 | 54 | } -returnCodes error -result {bad -type value "foo": must be abortretryignore, ok, okcancel, retrycancel, yesno, or yesnocancel} |
49 | 55 | |
50 | test msgbox-1.12 {tk_messageBox command} -constraints unix -body { | |
51 | tk_messageBox -default 1.1 | |
52 | } -returnCodes error -result {invalid default button "1.1"} | |
53 | test msgbox-1.13 {tk_messageBox command} -constraints macOrWin -body { | |
56 | test msgbox-1.13 {tk_messageBox command} -body { | |
54 | 57 | tk_messageBox -default 1.1 |
55 | 58 | } -returnCodes error -result {bad -default value "1.1": must be abort, retry, ignore, ok, cancel, no, or yes} |
56 | 59 | |
57 | test msgbox-1.14 {tk_messageBox command} -constraints unix -body { | |
58 | tk_messageBox -default foo | |
59 | } -returnCodes error -result {invalid default button "foo"} | |
60 | test msgbox-1.15 {tk_messageBox command} -constraints macOrWin -body { | |
60 | test msgbox-1.14 {tk_messageBox command} -body { | |
61 | 61 | tk_messageBox -default foo |
62 | 62 | } -returnCodes error -result {bad -default value "foo": must be abort, retry, ignore, ok, cancel, no, or yes} |
63 | 63 | |
64 | test msgbox-1.16 {tk_messageBox command} -constraints unix -body { | |
65 | tk_messageBox -type yesno -default 3 | |
66 | } -returnCodes error -result {invalid default button "3"} | |
67 | test msgbox-1.17 {tk_messageBox command} -constraints macOrWin -body { | |
64 | test msgbox-1.16 {tk_messageBox command} -body { | |
68 | 65 | tk_messageBox -type yesno -default 3 |
69 | 66 | } -returnCodes error -result {bad -default value "3": must be abort, retry, ignore, ok, cancel, no, or yes} |
70 | 67 | |
71 | 68 | test msgbox-1.18 {tk_messageBox command} -body { |
72 | 69 | tk_messageBox -icon foo |
73 | 70 | } -returnCodes error -result {bad -icon value "foo": must be error, info, question, or warning} |
71 | ||
74 | 72 | test msgbox-1.19 {tk_messageBox command} -body { |
75 | 73 | tk_messageBox -parent foo.bar |
76 | 74 | } -returnCodes error -result {bad window path name "foo.bar"} |
385 | 385 | test option-15.7 {database files} -body { |
386 | 386 | option read $option1 |
387 | 387 | option get . x9 color |
388 | } -result " \t\\A\n" | |
388 | } -result " \\\t\\A\n" | |
389 | 389 | test option-15.8 {database files} -body { |
390 | 390 | option read $option1 widget foo |
391 | 391 | } -returnCodes error -result {wrong # args: should be "option readfile fileName ?priority?"} |
414 | 414 | removeFile $option4 |
415 | 415 | } -result {true false} |
416 | 416 | |
417 | set opt162val {label { | |
418 | foo bar | |
419 | } | |
420 | } | |
421 | set opt162list [split $opt162val \n] | |
422 | ||
423 | test option-16.2 {ticket 766ef52f3} { | |
424 | set option5 [makeFile {} option.file4] | |
425 | set file [open $option5 w] | |
426 | fconfigure $file -translation crlf | |
427 | puts $file "*notok: $opt162list" | |
428 | close $file | |
429 | option read $option5 userDefault | |
430 | option get . notok notok | |
431 | } $opt162list | |
432 | ||
417 | 433 | deleteWindows |
418 | 434 | |
419 | 435 | # cleanup |
245 | 245 | destroy .g |
246 | 246 | } -result {cannot use geometry manager grid inside . which already has slaves managed by pack} |
247 | 247 | |
248 | test packgrid-4.1 {slave stolen after master destruction - bug [aa7679685e]} -setup { | |
249 | frame .f | |
250 | button .b -text hello | |
251 | } -body { | |
252 | pack .f | |
253 | grid .b -in .f | |
254 | destroy .f | |
255 | set res [winfo manager .b] | |
256 | # shall not crash | |
257 | pack .b | |
258 | set res | |
259 | } -cleanup { | |
260 | destroy .b | |
261 | } -result {} | |
262 | ||
263 | test packgrid-4.2 {slave stolen after master destruction - bug [aa7679685e]} -setup { | |
264 | frame .f | |
265 | button .b -text hello | |
266 | } -body { | |
267 | pack .f | |
268 | pack .b -in .f | |
269 | destroy .f | |
270 | set res [winfo manager .b] | |
271 | # shall not crash | |
272 | grid .b | |
273 | set res | |
274 | } -cleanup { | |
275 | destroy .b | |
276 | } -result {} | |
277 | ||
248 | 278 | cleanupTests |
249 | 279 | return |
0 | # This file is a Tcl script to test entry widgets in Tk. It is | |
1 | # organized in the standard fashion for Tcl tests. | |
2 | # | |
3 | # Copyright (c) 1994 The Regents of the University of California. | |
4 | # Copyright (c) 1994-1997 Sun Microsystems, Inc. | |
5 | # Copyright (c) 1998-1999 by Scriptics Corporation. | |
6 | # All rights reserved. | |
7 | ||
8 | package require tcltest 2.2 | |
9 | namespace import ::tcltest::* | |
10 | eval tcltest::configure $argv | |
11 | tcltest::loadTestedCommands | |
12 | ||
13 | # ------------------------------------------------------------------------------ | |
14 | # Tests that a Safe Base interpreter cannot write to the PRIMARY selection. | |
15 | # ------------------------------------------------------------------------------ | |
16 | # - Tests 3.*, 6.* test that the fix for ticket de156e9efe implemented in branch | |
17 | # bug-de156e9efe has been applied and still works. They test that a Safe Base | |
18 | # slave interpreter cannot write to the PRIMARY selection. | |
19 | # - The other tests verify that the master interpreter and an unsafe slave CAN | |
20 | # write to the PRIMARY selection, and therefore that the test scripts | |
21 | # themselves are valid. | |
22 | # - A text, entry, ttk::entry, listbox, spinbox or ttk::spinbox widget can have | |
23 | # option -exportselection 1, meaning (in an unsafe interpreter) that a | |
24 | # selection made in one of these widgets is automatically written to the | |
25 | # PRIMARY selection. | |
26 | # - A safe interpreter must not write to the PRIMARY selection. | |
27 | # - The spinbox, ttk::spinbox are variants of entry, ttk::entry respectively. | |
28 | # ------------------------------------------------------------------------------ | |
29 | ||
30 | namespace eval ::_test_tmp {} | |
31 | ||
32 | # ------------------------------------------------------------------------------ | |
33 | # Proc ::_test_tmp::unsafeInterp | |
34 | # ------------------------------------------------------------------------------ | |
35 | # Command that creates an unsafe child interpreter and tries to load Tk. | |
36 | # - This is necessary for loading Tk if the tests are done in the build | |
37 | # directory without installing Tk. In that case the usual auto_path loading | |
38 | # mechanism cannot work because the tk binary is not where pkgIndex.tcl says | |
39 | # it is. | |
40 | # - This command is not needed for Safe Base slaves because safe::loadTk does | |
41 | # something similar and works correctly. | |
42 | # - Based on scripts in winSend.test. | |
43 | # ------------------------------------------------------------------------------ | |
44 | ||
45 | namespace eval ::_test_tmp { | |
46 | variable TkLoadCmd | |
47 | } | |
48 | ||
49 | foreach pkg [info loaded] { | |
50 | if {[lindex $pkg 1] eq "Tk"} { | |
51 | set ::_test_tmp::TkLoadCmd [list load {*}$pkg] | |
52 | break | |
53 | } | |
54 | } | |
55 | ||
56 | proc ::_test_tmp::unsafeInterp {name} { | |
57 | variable TkLoadCmd | |
58 | interp create $name | |
59 | $name eval [list set argv [list -name $name]] | |
60 | catch {{*}$TkLoadCmd $name} | |
61 | } | |
62 | ||
63 | ||
64 | set ::_test_tmp::script { | |
65 | package require Tk | |
66 | namespace eval ::_test_tmp {} | |
67 | ||
68 | proc ::_test_tmp::getPrimarySelection {} { | |
69 | if {[catch {::tk::GetSelection . PRIMARY} sel]} { | |
70 | set sel {} | |
71 | } | |
72 | return $sel | |
73 | } | |
74 | ||
75 | proc ::_test_tmp::setPrimarySelection {} { | |
76 | destroy .preset | |
77 | text .preset -exportselection 1 | |
78 | .preset insert end OLD_VALUE | |
79 | # pack .preset | |
80 | .preset tag add sel 1.0 end-1c | |
81 | update | |
82 | return | |
83 | } | |
84 | ||
85 | # Clearing the PRIMARY selection is troublesome. | |
86 | # The window need not be mapped. | |
87 | # However, the window must continue to exist, or some X11 servers | |
88 | # will set the PRIMARY selection to something else. | |
89 | proc ::_test_tmp::clearPrimarySelection {} { | |
90 | destroy .clear | |
91 | text .clear -exportselection 1 | |
92 | .clear insert end TMP_VALUE | |
93 | # pack .clear | |
94 | .clear tag add sel 1.0 end-1c | |
95 | update | |
96 | .clear tag remove sel 1.0 end-1c | |
97 | update | |
98 | return | |
99 | } | |
100 | ||
101 | # If this interpreter can write to the PRIMARY | |
102 | # selection, the commands below will do so. | |
103 | ||
104 | proc ::_test_tmp::tryText {} { | |
105 | text .t -exportselection 1 | |
106 | .t insert end PAYLOAD | |
107 | pack .t | |
108 | .t tag add sel 1.0 end-1c | |
109 | update | |
110 | return | |
111 | } | |
112 | ||
113 | proc ::_test_tmp::tryEntry {} { | |
114 | entry .t -exportselection 1 | |
115 | .t insert end PAYLOAD | |
116 | pack .t | |
117 | .t selection range 0 end | |
118 | update | |
119 | return | |
120 | } | |
121 | ||
122 | proc ::_test_tmp::tryTtkEntry {} { | |
123 | ::ttk::entry .t -exportselection 1 | |
124 | .t insert end PAYLOAD | |
125 | pack .t | |
126 | .t selection range 0 end | |
127 | update | |
128 | return | |
129 | } | |
130 | ||
131 | proc ::_test_tmp::tryListbox {} { | |
132 | listbox .t -exportselection 1 | |
133 | .t insert end list1 PAYLOAD list3 | |
134 | pack .t | |
135 | .t selection set 1 | |
136 | update | |
137 | return | |
138 | } | |
139 | ||
140 | proc ::_test_tmp::trySpinbox {ver} { | |
141 | if {$ver == 1} { | |
142 | # spinbox as entry | |
143 | spinbox .t -exportselection 1 -values {1 2 3 4 5} | |
144 | .t delete 0 end | |
145 | .t insert end PAYLOAD | |
146 | pack .t | |
147 | .t selection range 0 end | |
148 | update | |
149 | return | |
150 | # selects PAYLOAD | |
151 | } elseif {$ver == 2} { | |
152 | # spinbox spun | |
153 | spinbox .t -exportselection 1 -values {1 2 3 4 5} | |
154 | .t invoke buttonup | |
155 | pack .t | |
156 | .t selection range 0 end | |
157 | update | |
158 | return | |
159 | # selects 2 | |
160 | } else { | |
161 | # spinbox spun/selected/spun | |
162 | spinbox .t -exportselection 1 -values {1 2 3 4 5} | |
163 | .t invoke buttonup | |
164 | pack .t | |
165 | .t selection range 0 end | |
166 | update | |
167 | .t invoke buttonup | |
168 | update | |
169 | return | |
170 | # selects 3 | |
171 | } | |
172 | } | |
173 | ||
174 | proc ::_test_tmp::tryTtkSpinbox {ver} { | |
175 | if {$ver == 1} { | |
176 | # ttk::spinbox as entry | |
177 | ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5} | |
178 | .t delete 0 end | |
179 | .t insert end PAYLOAD | |
180 | pack .t | |
181 | .t selection range 0 end | |
182 | update | |
183 | return | |
184 | } elseif {$ver == 2} { | |
185 | # ttk::spinbox spun | |
186 | ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5} | |
187 | ::ttk::spinbox::Spin .t +1 | |
188 | ::ttk::spinbox::Spin .t +1 | |
189 | pack .t | |
190 | # ttk::spinbox::Spin sets selection | |
191 | update | |
192 | return | |
193 | # selects 2 | |
194 | } else { | |
195 | # ttk::spinbox spun/selected/spun | |
196 | ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5} | |
197 | ::ttk::spinbox::Spin .t +1 | |
198 | ::ttk::spinbox::Spin .t +1 | |
199 | pack .t | |
200 | # ttk::spinbox::Spin sets selection | |
201 | update | |
202 | ::ttk::spinbox::Spin .t +1 | |
203 | update | |
204 | return | |
205 | # selects 3 | |
206 | } | |
207 | } | |
208 | } | |
209 | ||
210 | # Do this once for the master interpreter. | |
211 | eval $::_test_tmp::script | |
212 | ||
213 | test safePrimarySelection-1.1 {master interpreter, text, no existing selection} -setup { | |
214 | catch {interp delete slave2} | |
215 | destroy {*}[winfo children .] | |
216 | ::_test_tmp::clearPrimarySelection | |
217 | } -body { | |
218 | ::_test_tmp::tryText | |
219 | ::_test_tmp::getPrimarySelection | |
220 | } -cleanup { | |
221 | destroy {*}[winfo children .] | |
222 | ::_test_tmp::clearPrimarySelection | |
223 | } -result {PAYLOAD} | |
224 | ||
225 | test safePrimarySelection-1.2 {master interpreter, entry, no existing selection} -setup { | |
226 | catch {interp delete slave2} | |
227 | destroy {*}[winfo children .] | |
228 | ::_test_tmp::clearPrimarySelection | |
229 | } -body { | |
230 | ::_test_tmp::tryEntry | |
231 | ::_test_tmp::getPrimarySelection | |
232 | } -cleanup { | |
233 | destroy {*}[winfo children .] | |
234 | ::_test_tmp::clearPrimarySelection | |
235 | } -result {PAYLOAD} | |
236 | ||
237 | test safePrimarySelection-1.3 {master interpreter, ttk::entry, no existing selection} -setup { | |
238 | catch {interp delete slave2} | |
239 | destroy {*}[winfo children .] | |
240 | ::_test_tmp::clearPrimarySelection | |
241 | } -body { | |
242 | ::_test_tmp::tryTtkEntry | |
243 | ::_test_tmp::getPrimarySelection | |
244 | } -cleanup { | |
245 | destroy {*}[winfo children .] | |
246 | ::_test_tmp::clearPrimarySelection | |
247 | } -result {PAYLOAD} | |
248 | ||
249 | test safePrimarySelection-1.4 {master interpreter, listbox, no existing selection} -setup { | |
250 | catch {interp delete slave2} | |
251 | destroy {*}[winfo children .] | |
252 | ::_test_tmp::clearPrimarySelection | |
253 | } -body { | |
254 | ::_test_tmp::tryListbox | |
255 | ::_test_tmp::getPrimarySelection | |
256 | } -cleanup { | |
257 | destroy {*}[winfo children .] | |
258 | ::_test_tmp::clearPrimarySelection | |
259 | } -result {PAYLOAD} | |
260 | ||
261 | test safePrimarySelection-1.5 {master interpreter, spinbox as entry, no existing selection} -setup { | |
262 | catch {interp delete slave2} | |
263 | destroy {*}[winfo children .] | |
264 | ::_test_tmp::clearPrimarySelection | |
265 | } -body { | |
266 | ::_test_tmp::trySpinbox 1 | |
267 | ::_test_tmp::getPrimarySelection | |
268 | } -cleanup { | |
269 | destroy {*}[winfo children .] | |
270 | ::_test_tmp::clearPrimarySelection | |
271 | } -result {PAYLOAD} | |
272 | ||
273 | test safePrimarySelection-1.6 {master interpreter, spinbox spun, no existing selection} -setup { | |
274 | catch {interp delete slave2} | |
275 | destroy {*}[winfo children .] | |
276 | ::_test_tmp::clearPrimarySelection | |
277 | } -body { | |
278 | ::_test_tmp::trySpinbox 2 | |
279 | ::_test_tmp::getPrimarySelection | |
280 | } -cleanup { | |
281 | destroy {*}[winfo children .] | |
282 | ::_test_tmp::clearPrimarySelection | |
283 | } -result {2} | |
284 | ||
285 | test safePrimarySelection-1.7 {master interpreter, spinbox spun/selected/spun, no existing selection} -setup { | |
286 | catch {interp delete slave2} | |
287 | destroy {*}[winfo children .] | |
288 | ::_test_tmp::clearPrimarySelection | |
289 | } -body { | |
290 | ::_test_tmp::trySpinbox 3 | |
291 | ::_test_tmp::getPrimarySelection | |
292 | } -cleanup { | |
293 | destroy {*}[winfo children .] | |
294 | ::_test_tmp::clearPrimarySelection | |
295 | } -result {3} | |
296 | ||
297 | test safePrimarySelection-1.8 {master interpreter, ttk::spinbox as entry, no existing selection} -setup { | |
298 | catch {interp delete slave2} | |
299 | destroy {*}[winfo children .] | |
300 | ::_test_tmp::clearPrimarySelection | |
301 | } -body { | |
302 | ::_test_tmp::tryTtkSpinbox 1 | |
303 | ::_test_tmp::getPrimarySelection | |
304 | } -cleanup { | |
305 | destroy {*}[winfo children .] | |
306 | ::_test_tmp::clearPrimarySelection | |
307 | } -result {PAYLOAD} | |
308 | ||
309 | test safePrimarySelection-1.9 {master interpreter, ttk::spinbox spun, no existing selection} -setup { | |
310 | catch {interp delete slave2} | |
311 | destroy {*}[winfo children .] | |
312 | ::_test_tmp::clearPrimarySelection | |
313 | } -body { | |
314 | ::_test_tmp::tryTtkSpinbox 2 | |
315 | ::_test_tmp::getPrimarySelection | |
316 | } -cleanup { | |
317 | destroy {*}[winfo children .] | |
318 | ::_test_tmp::clearPrimarySelection | |
319 | } -result {2} | |
320 | ||
321 | test safePrimarySelection-1.10 {master interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup { | |
322 | catch {interp delete slave2} | |
323 | destroy {*}[winfo children .] | |
324 | ::_test_tmp::clearPrimarySelection | |
325 | } -body { | |
326 | ::_test_tmp::tryTtkSpinbox 3 | |
327 | ::_test_tmp::getPrimarySelection | |
328 | } -cleanup { | |
329 | destroy {*}[winfo children .] | |
330 | ::_test_tmp::clearPrimarySelection | |
331 | } -result {3} | |
332 | ||
333 | test safePrimarySelection-2.1 {unsafe slave interpreter, text, no existing selection} -setup { | |
334 | catch {interp delete slave2} | |
335 | destroy {*}[winfo children .] | |
336 | ::_test_tmp::clearPrimarySelection | |
337 | } -body { | |
338 | set int2 slave2 | |
339 | ::_test_tmp::unsafeInterp $int2 | |
340 | $int2 eval $::_test_tmp::script | |
341 | $int2 eval ::_test_tmp::tryText | |
342 | $int2 eval ::_test_tmp::getPrimarySelection | |
343 | } -cleanup { | |
344 | interp delete $int2 | |
345 | destroy {*}[winfo children .] | |
346 | unset int2 | |
347 | ::_test_tmp::clearPrimarySelection | |
348 | } -result {PAYLOAD} | |
349 | ||
350 | test safePrimarySelection-2.2 {unsafe slave interpreter, entry, no existing selection} -setup { | |
351 | catch {interp delete slave2} | |
352 | destroy {*}[winfo children .] | |
353 | ::_test_tmp::clearPrimarySelection | |
354 | } -body { | |
355 | set int2 slave2 | |
356 | ::_test_tmp::unsafeInterp $int2 | |
357 | $int2 eval $::_test_tmp::script | |
358 | $int2 eval ::_test_tmp::tryEntry | |
359 | $int2 eval ::_test_tmp::getPrimarySelection | |
360 | } -cleanup { | |
361 | interp delete $int2 | |
362 | destroy {*}[winfo children .] | |
363 | unset int2 | |
364 | ::_test_tmp::clearPrimarySelection | |
365 | } -result {PAYLOAD} | |
366 | ||
367 | test safePrimarySelection-2.3 {unsafe slave interpreter, ttk::entry, no existing selection} -setup { | |
368 | catch {interp delete slave2} | |
369 | destroy {*}[winfo children .] | |
370 | ::_test_tmp::clearPrimarySelection | |
371 | } -body { | |
372 | set int2 slave2 | |
373 | ::_test_tmp::unsafeInterp $int2 | |
374 | $int2 eval $::_test_tmp::script | |
375 | $int2 eval ::_test_tmp::tryTtkEntry | |
376 | $int2 eval ::_test_tmp::getPrimarySelection | |
377 | } -cleanup { | |
378 | interp delete $int2 | |
379 | destroy {*}[winfo children .] | |
380 | unset int2 | |
381 | ::_test_tmp::clearPrimarySelection | |
382 | } -result {PAYLOAD} | |
383 | ||
384 | test safePrimarySelection-2.4 {unsafe slave interpreter, listbox, no existing selection} -setup { | |
385 | catch {interp delete slave2} | |
386 | destroy {*}[winfo children .] | |
387 | ::_test_tmp::clearPrimarySelection | |
388 | } -body { | |
389 | set int2 slave2 | |
390 | ::_test_tmp::unsafeInterp $int2 | |
391 | $int2 eval $::_test_tmp::script | |
392 | $int2 eval ::_test_tmp::tryListbox | |
393 | $int2 eval ::_test_tmp::getPrimarySelection | |
394 | } -cleanup { | |
395 | interp delete $int2 | |
396 | destroy {*}[winfo children .] | |
397 | unset int2 | |
398 | ::_test_tmp::clearPrimarySelection | |
399 | } -result {PAYLOAD} | |
400 | ||
401 | test safePrimarySelection-2.5 {unsafe slave interpreter, spinbox as entry, no existing selection} -setup { | |
402 | catch {interp delete slave2} | |
403 | destroy {*}[winfo children .] | |
404 | ::_test_tmp::clearPrimarySelection | |
405 | } -body { | |
406 | set int2 slave2 | |
407 | ::_test_tmp::unsafeInterp $int2 | |
408 | $int2 eval $::_test_tmp::script | |
409 | $int2 eval ::_test_tmp::trySpinbox 1 | |
410 | $int2 eval ::_test_tmp::getPrimarySelection | |
411 | } -cleanup { | |
412 | interp delete $int2 | |
413 | destroy {*}[winfo children .] | |
414 | unset int2 | |
415 | ::_test_tmp::clearPrimarySelection | |
416 | } -result {PAYLOAD} | |
417 | ||
418 | test safePrimarySelection-2.6 {unsafe slave interpreter, spinbox spun, no existing selection} -setup { | |
419 | catch {interp delete slave2} | |
420 | destroy {*}[winfo children .] | |
421 | ::_test_tmp::clearPrimarySelection | |
422 | } -body { | |
423 | set int2 slave2 | |
424 | ::_test_tmp::unsafeInterp $int2 | |
425 | $int2 eval $::_test_tmp::script | |
426 | $int2 eval ::_test_tmp::trySpinbox 2 | |
427 | $int2 eval ::_test_tmp::getPrimarySelection | |
428 | } -cleanup { | |
429 | interp delete $int2 | |
430 | destroy {*}[winfo children .] | |
431 | unset int2 | |
432 | ::_test_tmp::clearPrimarySelection | |
433 | } -result {2} | |
434 | ||
435 | test safePrimarySelection-2.7 {unsafe slave interpreter, spinbox spun/selected/spun, no existing selection} -setup { | |
436 | catch {interp delete slave2} | |
437 | destroy {*}[winfo children .] | |
438 | ::_test_tmp::clearPrimarySelection | |
439 | } -body { | |
440 | set int2 slave2 | |
441 | ::_test_tmp::unsafeInterp $int2 | |
442 | $int2 eval $::_test_tmp::script | |
443 | $int2 eval ::_test_tmp::trySpinbox 3 | |
444 | $int2 eval ::_test_tmp::getPrimarySelection | |
445 | } -cleanup { | |
446 | interp delete $int2 | |
447 | destroy {*}[winfo children .] | |
448 | unset int2 | |
449 | ::_test_tmp::clearPrimarySelection | |
450 | } -result {3} | |
451 | ||
452 | test safePrimarySelection-2.8 {unsafe slave interpreter, ttk::spinbox as entry, no existing selection} -setup { | |
453 | catch {interp delete slave2} | |
454 | destroy {*}[winfo children .] | |
455 | ::_test_tmp::clearPrimarySelection | |
456 | } -body { | |
457 | set int2 slave2 | |
458 | ::_test_tmp::unsafeInterp $int2 | |
459 | $int2 eval $::_test_tmp::script | |
460 | $int2 eval ::_test_tmp::tryTtkSpinbox 1 | |
461 | $int2 eval ::_test_tmp::getPrimarySelection | |
462 | } -cleanup { | |
463 | interp delete $int2 | |
464 | destroy {*}[winfo children .] | |
465 | unset int2 | |
466 | ::_test_tmp::clearPrimarySelection | |
467 | } -result {PAYLOAD} | |
468 | ||
469 | test safePrimarySelection-2.9 {unsafe slave interpreter, ttk::spinbox spun, no existing selection} -setup { | |
470 | catch {interp delete slave2} | |
471 | destroy {*}[winfo children .] | |
472 | ::_test_tmp::clearPrimarySelection | |
473 | } -body { | |
474 | set int2 slave2 | |
475 | ::_test_tmp::unsafeInterp $int2 | |
476 | $int2 eval $::_test_tmp::script | |
477 | $int2 eval ::_test_tmp::tryTtkSpinbox 2 | |
478 | $int2 eval ::_test_tmp::getPrimarySelection | |
479 | } -cleanup { | |
480 | interp delete $int2 | |
481 | destroy {*}[winfo children .] | |
482 | unset int2 | |
483 | ::_test_tmp::clearPrimarySelection | |
484 | } -result {2} | |
485 | ||
486 | test safePrimarySelection-2.10 {unsafe slave interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup { | |
487 | catch {interp delete slave2} | |
488 | destroy {*}[winfo children .] | |
489 | ::_test_tmp::clearPrimarySelection | |
490 | } -body { | |
491 | set int2 slave2 | |
492 | ::_test_tmp::unsafeInterp $int2 | |
493 | $int2 eval $::_test_tmp::script | |
494 | $int2 eval ::_test_tmp::tryTtkSpinbox 3 | |
495 | $int2 eval ::_test_tmp::getPrimarySelection | |
496 | } -cleanup { | |
497 | interp delete $int2 | |
498 | destroy {*}[winfo children .] | |
499 | unset int2 | |
500 | ::_test_tmp::clearPrimarySelection | |
501 | } -result {3} | |
502 | ||
503 | test safePrimarySelection-3.1 {IMPORTANT, safe slave interpreter, text, no existing selection} -setup { | |
504 | catch {interp delete slave2} | |
505 | destroy {*}[winfo children .] | |
506 | ::_test_tmp::clearPrimarySelection | |
507 | } -body { | |
508 | set res0 [::_test_tmp::getPrimarySelection] | |
509 | set int2 slave2 | |
510 | ::safe::interpCreate $int2 | |
511 | ::safe::loadTk $int2 | |
512 | $int2 eval $::_test_tmp::script | |
513 | $int2 eval ::_test_tmp::tryText | |
514 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
515 | set res2 [::_test_tmp::getPrimarySelection] | |
516 | set res3 $res0--$res1--$res2 | |
517 | } -cleanup { | |
518 | interp delete $int2 | |
519 | destroy {*}[winfo children .] | |
520 | unset int2 res0 res1 res2 res3 | |
521 | ::_test_tmp::clearPrimarySelection | |
522 | } -result {----} | |
523 | ||
524 | test safePrimarySelection-3.2 {IMPORTANT, safe slave interpreter, entry, no existing selection} -setup { | |
525 | catch {interp delete slave2} | |
526 | destroy {*}[winfo children .] | |
527 | ::_test_tmp::clearPrimarySelection | |
528 | } -body { | |
529 | set res0 [::_test_tmp::getPrimarySelection] | |
530 | set int2 slave2 | |
531 | ::safe::interpCreate $int2 | |
532 | ::safe::loadTk $int2 | |
533 | $int2 eval $::_test_tmp::script | |
534 | $int2 eval ::_test_tmp::tryEntry | |
535 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
536 | set res2 [::_test_tmp::getPrimarySelection] | |
537 | set res3 $res0--$res1--$res2 | |
538 | } -cleanup { | |
539 | interp delete $int2 | |
540 | destroy {*}[winfo children .] | |
541 | unset int2 res0 res1 res2 res3 | |
542 | ::_test_tmp::clearPrimarySelection | |
543 | } -result {----} | |
544 | ||
545 | test safePrimarySelection-3.3 {IMPORTANT, safe slave interpreter, ttk::entry, no existing selection} -setup { | |
546 | catch {interp delete slave2} | |
547 | destroy {*}[winfo children .] | |
548 | ::_test_tmp::clearPrimarySelection | |
549 | } -body { | |
550 | set res0 [::_test_tmp::getPrimarySelection] | |
551 | set int2 slave2 | |
552 | ::safe::interpCreate $int2 | |
553 | ::safe::loadTk $int2 | |
554 | $int2 eval $::_test_tmp::script | |
555 | $int2 eval ::_test_tmp::tryTtkEntry | |
556 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
557 | set res2 [::_test_tmp::getPrimarySelection] | |
558 | set res3 $res0--$res1--$res2 | |
559 | } -cleanup { | |
560 | interp delete $int2 | |
561 | destroy {*}[winfo children .] | |
562 | unset int2 res0 res1 res2 res3 | |
563 | ::_test_tmp::clearPrimarySelection | |
564 | } -result {----} | |
565 | ||
566 | test safePrimarySelection-3.4 {IMPORTANT, safe slave interpreter, listbox, no existing selection} -setup { | |
567 | catch {interp delete slave2} | |
568 | destroy {*}[winfo children .] | |
569 | ::_test_tmp::clearPrimarySelection | |
570 | } -body { | |
571 | set res0 [::_test_tmp::getPrimarySelection] | |
572 | set int2 slave2 | |
573 | ::safe::interpCreate $int2 | |
574 | ::safe::loadTk $int2 | |
575 | $int2 eval $::_test_tmp::script | |
576 | $int2 eval ::_test_tmp::tryListbox | |
577 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
578 | set res2 [::_test_tmp::getPrimarySelection] | |
579 | set res3 $res0--$res1--$res2 | |
580 | } -cleanup { | |
581 | interp delete $int2 | |
582 | destroy {*}[winfo children .] | |
583 | unset int2 res0 res1 res2 res3 | |
584 | ::_test_tmp::clearPrimarySelection | |
585 | } -result {----} | |
586 | ||
587 | test safePrimarySelection-3.5 {IMPORTANT, safe slave interpreter, spinbox as entry, no existing selection} -setup { | |
588 | catch {interp delete slave2} | |
589 | destroy {*}[winfo children .] | |
590 | ::_test_tmp::clearPrimarySelection | |
591 | } -body { | |
592 | set res0 [::_test_tmp::getPrimarySelection] | |
593 | set int2 slave2 | |
594 | ::safe::interpCreate $int2 | |
595 | ::safe::loadTk $int2 | |
596 | $int2 eval $::_test_tmp::script | |
597 | $int2 eval ::_test_tmp::trySpinbox 1 | |
598 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
599 | set res2 [::_test_tmp::getPrimarySelection] | |
600 | set res3 $res0--$res1--$res2 | |
601 | } -cleanup { | |
602 | interp delete $int2 | |
603 | destroy {*}[winfo children .] | |
604 | unset int2 res0 res1 res2 res3 | |
605 | ::_test_tmp::clearPrimarySelection | |
606 | } -result {----} | |
607 | ||
608 | test safePrimarySelection-3.6 {IMPORTANT, safe slave interpreter, spinbox spun, no existing selection} -setup { | |
609 | catch {interp delete slave2} | |
610 | destroy {*}[winfo children .] | |
611 | ::_test_tmp::clearPrimarySelection | |
612 | } -body { | |
613 | set res0 [::_test_tmp::getPrimarySelection] | |
614 | set int2 slave2 | |
615 | ::safe::interpCreate $int2 | |
616 | ::safe::loadTk $int2 | |
617 | $int2 eval $::_test_tmp::script | |
618 | $int2 eval ::_test_tmp::trySpinbox 2 | |
619 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
620 | set res2 [::_test_tmp::getPrimarySelection] | |
621 | set res3 $res0--$res1--$res2 | |
622 | } -cleanup { | |
623 | interp delete $int2 | |
624 | destroy {*}[winfo children .] | |
625 | unset int2 res0 res1 res2 res3 | |
626 | ::_test_tmp::clearPrimarySelection | |
627 | } -result {----} | |
628 | ||
629 | test safePrimarySelection-3.7 {IMPORTANT, safe slave interpreter, spinbox spun/selected/spun, no existing selection} -setup { | |
630 | catch {interp delete slave2} | |
631 | destroy {*}[winfo children .] | |
632 | ::_test_tmp::clearPrimarySelection | |
633 | } -body { | |
634 | set res0 [::_test_tmp::getPrimarySelection] | |
635 | set int2 slave2 | |
636 | ::safe::interpCreate $int2 | |
637 | ::safe::loadTk $int2 | |
638 | $int2 eval $::_test_tmp::script | |
639 | $int2 eval ::_test_tmp::trySpinbox 3 | |
640 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
641 | set res2 [::_test_tmp::getPrimarySelection] | |
642 | set res3 $res0--$res1--$res2 | |
643 | } -cleanup { | |
644 | interp delete $int2 | |
645 | destroy {*}[winfo children .] | |
646 | unset int2 res0 res1 res2 res3 | |
647 | ::_test_tmp::clearPrimarySelection | |
648 | } -result {----} | |
649 | ||
650 | test safePrimarySelection-3.8 {IMPORTANT, safe slave interpreter, ttk::spinbox as entry, no existing selection} -setup { | |
651 | catch {interp delete slave2} | |
652 | destroy {*}[winfo children .] | |
653 | ::_test_tmp::clearPrimarySelection | |
654 | } -body { | |
655 | set res0 [::_test_tmp::getPrimarySelection] | |
656 | set int2 slave2 | |
657 | ::safe::interpCreate $int2 | |
658 | ::safe::loadTk $int2 | |
659 | $int2 eval $::_test_tmp::script | |
660 | $int2 eval ::_test_tmp::tryTtkSpinbox 1 | |
661 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
662 | set res2 [::_test_tmp::getPrimarySelection] | |
663 | set res3 $res0--$res1--$res2 | |
664 | } -cleanup { | |
665 | interp delete $int2 | |
666 | destroy {*}[winfo children .] | |
667 | unset int2 res0 res1 res2 res3 | |
668 | ::_test_tmp::clearPrimarySelection | |
669 | } -result {----} | |
670 | ||
671 | test safePrimarySelection-3.9 {IMPORTANT, safe slave interpreter, ttk::spinbox spun, no existing selection} -setup { | |
672 | catch {interp delete slave2} | |
673 | destroy {*}[winfo children .] | |
674 | ::_test_tmp::clearPrimarySelection | |
675 | } -body { | |
676 | set res0 [::_test_tmp::getPrimarySelection] | |
677 | set int2 slave2 | |
678 | ::safe::interpCreate $int2 | |
679 | ::safe::loadTk $int2 | |
680 | $int2 eval $::_test_tmp::script | |
681 | $int2 eval ::_test_tmp::tryTtkSpinbox 2 | |
682 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
683 | set res2 [::_test_tmp::getPrimarySelection] | |
684 | set res3 $res0--$res1--$res2 | |
685 | } -cleanup { | |
686 | interp delete $int2 | |
687 | destroy {*}[winfo children .] | |
688 | unset int2 res0 res1 res2 res3 | |
689 | ::_test_tmp::clearPrimarySelection | |
690 | } -result {----} | |
691 | ||
692 | test safePrimarySelection-3.10 {IMPORTANT, safe slave interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup { | |
693 | catch {interp delete slave2} | |
694 | destroy {*}[winfo children .] | |
695 | ::_test_tmp::clearPrimarySelection | |
696 | } -body { | |
697 | set res0 [::_test_tmp::getPrimarySelection] | |
698 | set int2 slave2 | |
699 | ::safe::interpCreate $int2 | |
700 | ::safe::loadTk $int2 | |
701 | $int2 eval $::_test_tmp::script | |
702 | $int2 eval ::_test_tmp::tryTtkSpinbox 3 | |
703 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
704 | set res2 [::_test_tmp::getPrimarySelection] | |
705 | set res3 $res0--$res1--$res2 | |
706 | } -cleanup { | |
707 | interp delete $int2 | |
708 | destroy {*}[winfo children .] | |
709 | unset int2 res0 res1 res2 res3 | |
710 | ::_test_tmp::clearPrimarySelection | |
711 | } -result {----} | |
712 | ||
713 | test safePrimarySelection-4.1 {master interpreter, text, existing selection} -setup { | |
714 | catch {interp delete slave2} | |
715 | destroy {*}[winfo children .] | |
716 | ::_test_tmp::setPrimarySelection | |
717 | } -body { | |
718 | ::_test_tmp::tryText | |
719 | ::_test_tmp::getPrimarySelection | |
720 | } -cleanup { | |
721 | destroy {*}[winfo children .] | |
722 | ::_test_tmp::clearPrimarySelection | |
723 | } -result {PAYLOAD} | |
724 | ||
725 | test safePrimarySelection-4.2 {master interpreter, entry, existing selection} -setup { | |
726 | catch {interp delete slave2} | |
727 | destroy {*}[winfo children .] | |
728 | ::_test_tmp::setPrimarySelection | |
729 | } -body { | |
730 | ::_test_tmp::tryEntry | |
731 | ::_test_tmp::getPrimarySelection | |
732 | } -cleanup { | |
733 | destroy {*}[winfo children .] | |
734 | ::_test_tmp::clearPrimarySelection | |
735 | } -result {PAYLOAD} | |
736 | ||
737 | test safePrimarySelection-4.3 {master interpreter, ttk::entry, existing selection} -setup { | |
738 | catch {interp delete slave2} | |
739 | destroy {*}[winfo children .] | |
740 | ::_test_tmp::setPrimarySelection | |
741 | } -body { | |
742 | ::_test_tmp::tryTtkEntry | |
743 | ::_test_tmp::getPrimarySelection | |
744 | } -cleanup { | |
745 | destroy {*}[winfo children .] | |
746 | ::_test_tmp::clearPrimarySelection | |
747 | } -result {PAYLOAD} | |
748 | ||
749 | test safePrimarySelection-4.4 {master interpreter, listbox, existing selection} -setup { | |
750 | catch {interp delete slave2} | |
751 | destroy {*}[winfo children .] | |
752 | ::_test_tmp::setPrimarySelection | |
753 | } -body { | |
754 | ::_test_tmp::tryListbox | |
755 | ::_test_tmp::getPrimarySelection | |
756 | } -cleanup { | |
757 | destroy {*}[winfo children .] | |
758 | ::_test_tmp::clearPrimarySelection | |
759 | } -result {PAYLOAD} | |
760 | ||
761 | test safePrimarySelection-4.5 {master interpreter, spinbox as entry, existing selection} -setup { | |
762 | catch {interp delete slave2} | |
763 | destroy {*}[winfo children .] | |
764 | ::_test_tmp::setPrimarySelection | |
765 | } -body { | |
766 | ::_test_tmp::trySpinbox 1 | |
767 | ::_test_tmp::getPrimarySelection | |
768 | } -cleanup { | |
769 | destroy {*}[winfo children .] | |
770 | ::_test_tmp::clearPrimarySelection | |
771 | } -result {PAYLOAD} | |
772 | ||
773 | test safePrimarySelection-4.6 {master interpreter, spinbox spun, existing selection} -setup { | |
774 | catch {interp delete slave2} | |
775 | destroy {*}[winfo children .] | |
776 | ::_test_tmp::setPrimarySelection | |
777 | } -body { | |
778 | ::_test_tmp::trySpinbox 2 | |
779 | ::_test_tmp::getPrimarySelection | |
780 | } -cleanup { | |
781 | destroy {*}[winfo children .] | |
782 | ::_test_tmp::clearPrimarySelection | |
783 | } -result {2} | |
784 | ||
785 | test safePrimarySelection-4.7 {master interpreter, spinbox spun/selected/spun, existing selection} -setup { | |
786 | catch {interp delete slave2} | |
787 | destroy {*}[winfo children .] | |
788 | ::_test_tmp::setPrimarySelection | |
789 | } -body { | |
790 | ::_test_tmp::trySpinbox 3 | |
791 | ::_test_tmp::getPrimarySelection | |
792 | } -cleanup { | |
793 | destroy {*}[winfo children .] | |
794 | ::_test_tmp::clearPrimarySelection | |
795 | } -result {3} | |
796 | ||
797 | test safePrimarySelection-4.8 {master interpreter, ttk::spinbox as entry, existing selection} -setup { | |
798 | catch {interp delete slave2} | |
799 | destroy {*}[winfo children .] | |
800 | ::_test_tmp::setPrimarySelection | |
801 | } -body { | |
802 | ::_test_tmp::tryTtkSpinbox 1 | |
803 | ::_test_tmp::getPrimarySelection | |
804 | } -cleanup { | |
805 | destroy {*}[winfo children .] | |
806 | ::_test_tmp::clearPrimarySelection | |
807 | } -result {PAYLOAD} | |
808 | ||
809 | test safePrimarySelection-4.9 {master interpreter, ttk::spinbox spun, existing selection} -setup { | |
810 | catch {interp delete slave2} | |
811 | destroy {*}[winfo children .] | |
812 | ::_test_tmp::setPrimarySelection | |
813 | } -body { | |
814 | ::_test_tmp::tryTtkSpinbox 2 | |
815 | ::_test_tmp::getPrimarySelection | |
816 | } -cleanup { | |
817 | destroy {*}[winfo children .] | |
818 | ::_test_tmp::clearPrimarySelection | |
819 | } -result {2} | |
820 | ||
821 | test safePrimarySelection-4.10 {master interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup { | |
822 | catch {interp delete slave2} | |
823 | destroy {*}[winfo children .] | |
824 | ::_test_tmp::setPrimarySelection | |
825 | } -body { | |
826 | ::_test_tmp::tryTtkSpinbox 3 | |
827 | ::_test_tmp::getPrimarySelection | |
828 | } -cleanup { | |
829 | destroy {*}[winfo children .] | |
830 | ::_test_tmp::clearPrimarySelection | |
831 | } -result {3} | |
832 | ||
833 | test safePrimarySelection-5.1 {unsafe slave interpreter, text, existing selection} -setup { | |
834 | catch {interp delete slave2} | |
835 | destroy {*}[winfo children .] | |
836 | ::_test_tmp::setPrimarySelection | |
837 | } -body { | |
838 | set int2 slave2 | |
839 | ::_test_tmp::unsafeInterp $int2 | |
840 | $int2 eval $::_test_tmp::script | |
841 | $int2 eval ::_test_tmp::tryText | |
842 | $int2 eval ::_test_tmp::getPrimarySelection | |
843 | } -cleanup { | |
844 | interp delete $int2 | |
845 | destroy {*}[winfo children .] | |
846 | unset int2 | |
847 | ::_test_tmp::clearPrimarySelection | |
848 | } -result {PAYLOAD} | |
849 | ||
850 | test safePrimarySelection-5.2 {unsafe slave interpreter, entry, existing selection} -setup { | |
851 | catch {interp delete slave2} | |
852 | destroy {*}[winfo children .] | |
853 | ::_test_tmp::setPrimarySelection | |
854 | } -body { | |
855 | set int2 slave2 | |
856 | ::_test_tmp::unsafeInterp $int2 | |
857 | $int2 eval $::_test_tmp::script | |
858 | $int2 eval ::_test_tmp::tryEntry | |
859 | $int2 eval ::_test_tmp::getPrimarySelection | |
860 | } -cleanup { | |
861 | interp delete $int2 | |
862 | destroy {*}[winfo children .] | |
863 | unset int2 | |
864 | ::_test_tmp::clearPrimarySelection | |
865 | } -result {PAYLOAD} | |
866 | ||
867 | test safePrimarySelection-5.3 {unsafe slave interpreter, ttk::entry, existing selection} -setup { | |
868 | catch {interp delete slave2} | |
869 | destroy {*}[winfo children .] | |
870 | ::_test_tmp::setPrimarySelection | |
871 | } -body { | |
872 | set int2 slave2 | |
873 | ::_test_tmp::unsafeInterp $int2 | |
874 | $int2 eval $::_test_tmp::script | |
875 | $int2 eval ::_test_tmp::tryTtkEntry | |
876 | $int2 eval ::_test_tmp::getPrimarySelection | |
877 | } -cleanup { | |
878 | interp delete $int2 | |
879 | destroy {*}[winfo children .] | |
880 | unset int2 | |
881 | ::_test_tmp::clearPrimarySelection | |
882 | } -result {PAYLOAD} | |
883 | ||
884 | test safePrimarySelection-5.4 {unsafe slave interpreter, listbox, existing selection} -setup { | |
885 | catch {interp delete slave2} | |
886 | destroy {*}[winfo children .] | |
887 | ::_test_tmp::setPrimarySelection | |
888 | } -body { | |
889 | set int2 slave2 | |
890 | ::_test_tmp::unsafeInterp $int2 | |
891 | $int2 eval $::_test_tmp::script | |
892 | $int2 eval ::_test_tmp::tryListbox | |
893 | $int2 eval ::_test_tmp::getPrimarySelection | |
894 | } -cleanup { | |
895 | interp delete $int2 | |
896 | destroy {*}[winfo children .] | |
897 | unset int2 | |
898 | ::_test_tmp::clearPrimarySelection | |
899 | } -result {PAYLOAD} | |
900 | ||
901 | test safePrimarySelection-5.5 {unsafe slave interpreter, spinbox as entry, existing selection} -setup { | |
902 | catch {interp delete slave2} | |
903 | destroy {*}[winfo children .] | |
904 | ::_test_tmp::setPrimarySelection | |
905 | } -body { | |
906 | set int2 slave2 | |
907 | ::_test_tmp::unsafeInterp $int2 | |
908 | $int2 eval $::_test_tmp::script | |
909 | $int2 eval ::_test_tmp::trySpinbox 1 | |
910 | $int2 eval ::_test_tmp::getPrimarySelection | |
911 | } -cleanup { | |
912 | interp delete $int2 | |
913 | destroy {*}[winfo children .] | |
914 | unset int2 | |
915 | ::_test_tmp::clearPrimarySelection | |
916 | } -result {PAYLOAD} | |
917 | ||
918 | test safePrimarySelection-5.6 {unsafe slave interpreter, spinbox spun, existing selection} -setup { | |
919 | catch {interp delete slave2} | |
920 | destroy {*}[winfo children .] | |
921 | ::_test_tmp::setPrimarySelection | |
922 | } -body { | |
923 | set int2 slave2 | |
924 | ::_test_tmp::unsafeInterp $int2 | |
925 | $int2 eval $::_test_tmp::script | |
926 | $int2 eval ::_test_tmp::trySpinbox 2 | |
927 | $int2 eval ::_test_tmp::getPrimarySelection | |
928 | } -cleanup { | |
929 | interp delete $int2 | |
930 | destroy {*}[winfo children .] | |
931 | unset int2 | |
932 | ::_test_tmp::clearPrimarySelection | |
933 | } -result {2} | |
934 | ||
935 | test safePrimarySelection-5.7 {unsafe slave interpreter, spinbox spun/selected/spun, existing selection} -setup { | |
936 | catch {interp delete slave2} | |
937 | destroy {*}[winfo children .] | |
938 | ::_test_tmp::setPrimarySelection | |
939 | } -body { | |
940 | set int2 slave2 | |
941 | ::_test_tmp::unsafeInterp $int2 | |
942 | $int2 eval $::_test_tmp::script | |
943 | $int2 eval ::_test_tmp::trySpinbox 3 | |
944 | $int2 eval ::_test_tmp::getPrimarySelection | |
945 | } -cleanup { | |
946 | interp delete $int2 | |
947 | destroy {*}[winfo children .] | |
948 | unset int2 | |
949 | ::_test_tmp::clearPrimarySelection | |
950 | } -result {3} | |
951 | ||
952 | test safePrimarySelection-5.8 {unsafe slave interpreter, ttk::spinbox as entry, existing selection} -setup { | |
953 | catch {interp delete slave2} | |
954 | destroy {*}[winfo children .] | |
955 | ::_test_tmp::setPrimarySelection | |
956 | } -body { | |
957 | set int2 slave2 | |
958 | ::_test_tmp::unsafeInterp $int2 | |
959 | $int2 eval $::_test_tmp::script | |
960 | $int2 eval ::_test_tmp::tryTtkSpinbox 1 | |
961 | $int2 eval ::_test_tmp::getPrimarySelection | |
962 | } -cleanup { | |
963 | interp delete $int2 | |
964 | destroy {*}[winfo children .] | |
965 | unset int2 | |
966 | ::_test_tmp::clearPrimarySelection | |
967 | } -result {PAYLOAD} | |
968 | ||
969 | test safePrimarySelection-5.9 {unsafe slave interpreter, ttk::spinbox spun, existing selection} -setup { | |
970 | catch {interp delete slave2} | |
971 | destroy {*}[winfo children .] | |
972 | ::_test_tmp::setPrimarySelection | |
973 | } -body { | |
974 | set int2 slave2 | |
975 | ::_test_tmp::unsafeInterp $int2 | |
976 | $int2 eval $::_test_tmp::script | |
977 | $int2 eval ::_test_tmp::tryTtkSpinbox 2 | |
978 | $int2 eval ::_test_tmp::getPrimarySelection | |
979 | } -cleanup { | |
980 | interp delete $int2 | |
981 | destroy {*}[winfo children .] | |
982 | unset int2 | |
983 | ::_test_tmp::clearPrimarySelection | |
984 | } -result {2} | |
985 | ||
986 | test safePrimarySelection-5.10 {unsafe slave interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup { | |
987 | catch {interp delete slave2} | |
988 | destroy {*}[winfo children .] | |
989 | ::_test_tmp::setPrimarySelection | |
990 | } -body { | |
991 | set int2 slave2 | |
992 | ::_test_tmp::unsafeInterp $int2 | |
993 | $int2 eval $::_test_tmp::script | |
994 | $int2 eval ::_test_tmp::tryTtkSpinbox 3 | |
995 | $int2 eval ::_test_tmp::getPrimarySelection | |
996 | } -cleanup { | |
997 | interp delete $int2 | |
998 | destroy {*}[winfo children .] | |
999 | unset int2 | |
1000 | ::_test_tmp::clearPrimarySelection | |
1001 | } -result {3} | |
1002 | ||
1003 | test safePrimarySelection-6.1 {IMPORTANT, safe slave interpreter, text, existing selection} -setup { | |
1004 | catch {interp delete slave2} | |
1005 | destroy {*}[winfo children .] | |
1006 | ::_test_tmp::setPrimarySelection | |
1007 | } -body { | |
1008 | set res0 [::_test_tmp::getPrimarySelection] | |
1009 | set int2 slave2 | |
1010 | ::safe::interpCreate $int2 | |
1011 | ::safe::loadTk $int2 | |
1012 | $int2 eval $::_test_tmp::script | |
1013 | $int2 eval ::_test_tmp::tryText | |
1014 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1015 | set res2 [::_test_tmp::getPrimarySelection] | |
1016 | set res3 $res0--$res1--$res2 | |
1017 | } -cleanup { | |
1018 | interp delete $int2 | |
1019 | destroy {*}[winfo children .] | |
1020 | unset int2 res0 res1 res2 res3 | |
1021 | ::_test_tmp::clearPrimarySelection | |
1022 | } -result {OLD_VALUE----OLD_VALUE} | |
1023 | ||
1024 | test safePrimarySelection-6.2 {IMPORTANT, safe slave interpreter, entry, existing selection} -setup { | |
1025 | catch {interp delete slave2} | |
1026 | destroy {*}[winfo children .] | |
1027 | ::_test_tmp::setPrimarySelection | |
1028 | } -body { | |
1029 | set res0 [::_test_tmp::getPrimarySelection] | |
1030 | set int2 slave2 | |
1031 | ::safe::interpCreate $int2 | |
1032 | ::safe::loadTk $int2 | |
1033 | $int2 eval $::_test_tmp::script | |
1034 | $int2 eval ::_test_tmp::tryEntry | |
1035 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1036 | set res2 [::_test_tmp::getPrimarySelection] | |
1037 | set res3 $res0--$res1--$res2 | |
1038 | } -cleanup { | |
1039 | interp delete $int2 | |
1040 | destroy {*}[winfo children .] | |
1041 | unset int2 res0 res1 res2 res3 | |
1042 | ::_test_tmp::clearPrimarySelection | |
1043 | } -result {OLD_VALUE----OLD_VALUE} | |
1044 | ||
1045 | test safePrimarySelection-6.3 {IMPORTANT, safe slave interpreter, ttk::entry, existing selection} -setup { | |
1046 | catch {interp delete slave2} | |
1047 | destroy {*}[winfo children .] | |
1048 | ::_test_tmp::setPrimarySelection | |
1049 | } -body { | |
1050 | set res0 [::_test_tmp::getPrimarySelection] | |
1051 | set int2 slave2 | |
1052 | ::safe::interpCreate $int2 | |
1053 | ::safe::loadTk $int2 | |
1054 | $int2 eval $::_test_tmp::script | |
1055 | $int2 eval ::_test_tmp::tryTtkEntry | |
1056 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1057 | set res2 [::_test_tmp::getPrimarySelection] | |
1058 | set res3 $res0--$res1--$res2 | |
1059 | } -cleanup { | |
1060 | interp delete $int2 | |
1061 | destroy {*}[winfo children .] | |
1062 | unset int2 res0 res1 res2 res3 | |
1063 | ::_test_tmp::clearPrimarySelection | |
1064 | } -result {OLD_VALUE----OLD_VALUE} | |
1065 | ||
1066 | test safePrimarySelection-6.4 {IMPORTANT, safe slave interpreter, listbox, existing selection} -setup { | |
1067 | catch {interp delete slave2} | |
1068 | destroy {*}[winfo children .] | |
1069 | ::_test_tmp::setPrimarySelection | |
1070 | } -body { | |
1071 | set res0 [::_test_tmp::getPrimarySelection] | |
1072 | set int2 slave2 | |
1073 | ::safe::interpCreate $int2 | |
1074 | ::safe::loadTk $int2 | |
1075 | $int2 eval $::_test_tmp::script | |
1076 | $int2 eval ::_test_tmp::tryListbox | |
1077 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1078 | set res2 [::_test_tmp::getPrimarySelection] | |
1079 | set res3 $res0--$res1--$res2 | |
1080 | } -cleanup { | |
1081 | interp delete $int2 | |
1082 | destroy {*}[winfo children .] | |
1083 | unset int2 res0 res1 res2 res3 | |
1084 | ::_test_tmp::clearPrimarySelection | |
1085 | } -result {OLD_VALUE----OLD_VALUE} | |
1086 | ||
1087 | test safePrimarySelection-6.5 {IMPORTANT, safe slave interpreter, spinbox as entry, existing selection} -setup { | |
1088 | catch {interp delete slave2} | |
1089 | destroy {*}[winfo children .] | |
1090 | ::_test_tmp::setPrimarySelection | |
1091 | } -body { | |
1092 | set res0 [::_test_tmp::getPrimarySelection] | |
1093 | set int2 slave2 | |
1094 | ::safe::interpCreate $int2 | |
1095 | ::safe::loadTk $int2 | |
1096 | $int2 eval $::_test_tmp::script | |
1097 | $int2 eval ::_test_tmp::trySpinbox 1 | |
1098 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1099 | set res2 [::_test_tmp::getPrimarySelection] | |
1100 | set res3 $res0--$res1--$res2 | |
1101 | } -cleanup { | |
1102 | interp delete $int2 | |
1103 | destroy {*}[winfo children .] | |
1104 | unset int2 res0 res1 res2 res3 | |
1105 | ::_test_tmp::clearPrimarySelection | |
1106 | } -result {OLD_VALUE----OLD_VALUE} | |
1107 | ||
1108 | test safePrimarySelection-6.6 {IMPORTANT, safe slave interpreter, spinbox spun, existing selection} -setup { | |
1109 | catch {interp delete slave2} | |
1110 | destroy {*}[winfo children .] | |
1111 | ::_test_tmp::setPrimarySelection | |
1112 | } -body { | |
1113 | set res0 [::_test_tmp::getPrimarySelection] | |
1114 | set int2 slave2 | |
1115 | ::safe::interpCreate $int2 | |
1116 | ::safe::loadTk $int2 | |
1117 | $int2 eval $::_test_tmp::script | |
1118 | $int2 eval ::_test_tmp::trySpinbox 2 | |
1119 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1120 | set res2 [::_test_tmp::getPrimarySelection] | |
1121 | set res3 $res0--$res1--$res2 | |
1122 | } -cleanup { | |
1123 | interp delete $int2 | |
1124 | destroy {*}[winfo children .] | |
1125 | unset int2 res0 res1 res2 res3 | |
1126 | ::_test_tmp::clearPrimarySelection | |
1127 | } -result {OLD_VALUE----OLD_VALUE} | |
1128 | ||
1129 | test safePrimarySelection-6.7 {IMPORTANT, safe slave interpreter, spinbox spun/selected/spun, existing selection} -setup { | |
1130 | catch {interp delete slave2} | |
1131 | destroy {*}[winfo children .] | |
1132 | ::_test_tmp::setPrimarySelection | |
1133 | } -body { | |
1134 | set res0 [::_test_tmp::getPrimarySelection] | |
1135 | set int2 slave2 | |
1136 | ::safe::interpCreate $int2 | |
1137 | ::safe::loadTk $int2 | |
1138 | $int2 eval $::_test_tmp::script | |
1139 | $int2 eval ::_test_tmp::trySpinbox 3 | |
1140 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1141 | set res2 [::_test_tmp::getPrimarySelection] | |
1142 | set res3 $res0--$res1--$res2 | |
1143 | } -cleanup { | |
1144 | interp delete $int2 | |
1145 | destroy {*}[winfo children .] | |
1146 | unset int2 res0 res1 res2 res3 | |
1147 | ::_test_tmp::clearPrimarySelection | |
1148 | } -result {OLD_VALUE----OLD_VALUE} | |
1149 | ||
1150 | test safePrimarySelection-6.8 {IMPORTANT, safe slave interpreter, ttk::spinbox as entry, existing selection} -setup { | |
1151 | catch {interp delete slave2} | |
1152 | destroy {*}[winfo children .] | |
1153 | ::_test_tmp::setPrimarySelection | |
1154 | } -body { | |
1155 | set res0 [::_test_tmp::getPrimarySelection] | |
1156 | set int2 slave2 | |
1157 | ::safe::interpCreate $int2 | |
1158 | ::safe::loadTk $int2 | |
1159 | $int2 eval $::_test_tmp::script | |
1160 | $int2 eval ::_test_tmp::tryTtkSpinbox 1 | |
1161 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1162 | set res2 [::_test_tmp::getPrimarySelection] | |
1163 | set res3 $res0--$res1--$res2 | |
1164 | } -cleanup { | |
1165 | interp delete $int2 | |
1166 | destroy {*}[winfo children .] | |
1167 | unset int2 res0 res1 res2 res3 | |
1168 | ::_test_tmp::clearPrimarySelection | |
1169 | } -result {OLD_VALUE----OLD_VALUE} | |
1170 | ||
1171 | test safePrimarySelection-6.9 {IMPORTANT, safe slave interpreter, ttk::spinbox spun, existing selection} -setup { | |
1172 | catch {interp delete slave2} | |
1173 | destroy {*}[winfo children .] | |
1174 | ::_test_tmp::setPrimarySelection | |
1175 | } -body { | |
1176 | set res0 [::_test_tmp::getPrimarySelection] | |
1177 | set int2 slave2 | |
1178 | ::safe::interpCreate $int2 | |
1179 | ::safe::loadTk $int2 | |
1180 | $int2 eval $::_test_tmp::script | |
1181 | $int2 eval ::_test_tmp::tryTtkSpinbox 2 | |
1182 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1183 | set res2 [::_test_tmp::getPrimarySelection] | |
1184 | set res3 $res0--$res1--$res2 | |
1185 | } -cleanup { | |
1186 | interp delete $int2 | |
1187 | destroy {*}[winfo children .] | |
1188 | unset int2 res0 res1 res2 res3 | |
1189 | ::_test_tmp::clearPrimarySelection | |
1190 | } -result {OLD_VALUE----OLD_VALUE} | |
1191 | ||
1192 | test safePrimarySelection-6.10 {IMPORTANT, safe slave interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup { | |
1193 | catch {interp delete slave2} | |
1194 | destroy {*}[winfo children .] | |
1195 | ::_test_tmp::setPrimarySelection | |
1196 | } -body { | |
1197 | set res0 [::_test_tmp::getPrimarySelection] | |
1198 | set int2 slave2 | |
1199 | ::safe::interpCreate $int2 | |
1200 | ::safe::loadTk $int2 | |
1201 | $int2 eval $::_test_tmp::script | |
1202 | $int2 eval ::_test_tmp::tryTtkSpinbox 3 | |
1203 | set res1 [$int2 eval ::_test_tmp::getPrimarySelection] | |
1204 | set res2 [::_test_tmp::getPrimarySelection] | |
1205 | set res3 $res0--$res1--$res2 | |
1206 | } -cleanup { | |
1207 | interp delete $int2 | |
1208 | destroy {*}[winfo children .] | |
1209 | unset int2 res0 res1 res2 res3 | |
1210 | ::_test_tmp::clearPrimarySelection | |
1211 | } -result {OLD_VALUE----OLD_VALUE} | |
1212 | ||
1213 | ||
1214 | namespace delete ::_test_tmp | |
1215 | ||
1216 | # option clear | |
1217 | # cleanup | |
1218 | cleanupTests | |
1219 | return |
17 | 17 | |
18 | 18 | proc getTroughSize {w} { |
19 | 19 | if {[testConstraint testmetrics]} { |
20 | # Only Windows has [testmetrics] | |
20 | 21 | if [string match v* [$w cget -orient]] { |
21 | 22 | return [expr [winfo height $w] - 2*[testmetrics cyvscroll $w]] |
22 | 23 | } else { |
23 | 24 | return [expr [winfo width $w] - 2*[testmetrics cxhscroll $w]] |
24 | 25 | } |
25 | 26 | } else { |
26 | if [string match v* [$w cget -orient]] { | |
27 | return [expr [winfo height $w] \ | |
28 | - ([winfo width $w] \ | |
29 | - [$w cget -highlightthickness] \ | |
30 | - [$w cget -bd] + 1)*2] | |
31 | } else { | |
32 | return [expr [winfo width $w] \ | |
33 | - ([winfo height $w] \ | |
34 | - [$w cget -highlightthickness] \ | |
35 | - [$w cget -bd] + 1)*2] | |
36 | } | |
27 | if {[tk windowingsystem] eq "x11"} { | |
28 | # Calculations here assume that the arrow area is a square. | |
29 | if [string match v* [$w cget -orient]] { | |
30 | return [expr [winfo height $w] \ | |
31 | - ([winfo width $w] \ | |
32 | - [$w cget -highlightthickness] \ | |
33 | - [$w cget -bd] + 1)*2] | |
34 | } else { | |
35 | return [expr [winfo width $w] \ | |
36 | - ([winfo height $w] \ | |
37 | - [$w cget -highlightthickness] \ | |
38 | - [$w cget -bd] + 1)*2] | |
39 | } | |
40 | } else { | |
41 | # macOS aqua | |
42 | if [string match v* [$w cget -orient]] { | |
43 | return [expr [winfo height $w] \ | |
44 | - ([$w cget -highlightthickness] \ | |
45 | +[$w cget -bd])*2] | |
46 | } else { | |
47 | return [expr [winfo width $w] \ | |
48 | - ([$w cget -highlightthickness] \ | |
49 | +[$w cget -bd])*2] | |
50 | } | |
51 | } | |
37 | 52 | } |
38 | 53 | } |
39 | 54 | |
254 | 269 | format {%.6g} [.s fraction 4 21] |
255 | 270 | } [format %.6g [expr (21.0 - ([winfo height .s] - [getTroughSize .s])/2.0) \ |
256 | 271 | /([getTroughSize .s] - 1)]] |
257 | test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} unix { | |
272 | test scrollbar-3.36 {ScrollbarWidgetCmd procedure, "fraction" option} x11 { | |
258 | 273 | format {%.6g} [.s fraction 4 179] |
259 | 274 | } {1} |
260 | 275 | test scrollbar-3.37 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics} { |
261 | 276 | format {%.6g} [.s fraction 4 [expr 200 - [testmetrics cyvscroll .s]]] |
262 | 277 | } {1} |
263 | test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} unix { | |
278 | test scrollbar-3.38 {ScrollbarWidgetCmd procedure, "fraction" option} x11 { | |
264 | 279 | format {%.6g} [.s fraction 4 178] |
265 | 280 | } {0.993711} |
266 | 281 | test scrollbar-3.39 {ScrollbarWidgetCmd procedure, "fraction" option} {testmetrics win} { |
280 | 295 | format {%.6g} [.t.s fraction 100 0] |
281 | 296 | } {0.5} |
282 | 297 | if {[testConstraint testmetrics]} { |
298 | # Only Windows has [testmetrics] | |
283 | 299 | place configure .t.s -width [expr 2*[testmetrics cxhscroll .t.s]+1] |
284 | 300 | } else { |
285 | place configure .t.s -width [expr [winfo reqwidth .t.s] - 4] | |
301 | if {[tk windowingsystem] eq "x11"} { | |
302 | place configure .t.s -width [expr [winfo height .t.s] - 2*([.t.s cget -highlightthickness] + [.t.s cget -bd] + 1)] | |
303 | } else { | |
304 | # macOS aqua | |
305 | place configure .t.s -width [expr 2*([.t.s cget -highlightthickness] + [.t.s cget -bd])] | |
306 | } | |
286 | 307 | } |
287 | 308 | update |
288 | 309 | test scrollbar-3.42 {ScrollbarWidgetCmd procedure, "fraction" option} { |
316 | 337 | test scrollbar-3.49 {ScrollbarWidgetCmd procedure, "identify" option} { |
317 | 338 | list [catch {.s identify -1 bogus} msg] $msg |
318 | 339 | } {1 {expected integer but got "bogus"}} |
319 | test scrollbar-3.50 {ScrollbarWidgetCmd procedure, "identify" option} { | |
340 | test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua { | |
320 | 341 | .s identify 5 5 |
321 | 342 | } {arrow1} |
343 | test scrollbar-3.50.1 {ScrollbarWidgetCmd procedure, "identify" option} aqua { | |
344 | # macOS scrollbars have no arrows nowadays | |
345 | .s identify 5 5 | |
346 | } {trough1} | |
322 | 347 | test scrollbar-3.51 {ScrollbarWidgetCmd procedure, "identify" option} { |
323 | 348 | .s identify 5 35 |
324 | 349 | } {trough1} |
329 | 354 | test scrollbar-3.53 {ScrollbarWidgetCmd procedure, "identify" option} { |
330 | 355 | .s identify 5 145 |
331 | 356 | } {trough2} |
332 | test scrollbar-3.54 {ScrollbarWidgetCmd procedure, "identify" option} {unixOrPc} { | |
357 | test scrollbar-3.54.1 {ScrollbarWidgetCmd procedure, "identify" option} notAqua { | |
333 | 358 | .s identify 5 195 |
334 | 359 | } {arrow2} |
360 | test scrollbar-3.54.2 {ScrollbarWidgetCmd procedure, "identify" option} aqua { | |
361 | # macOS scrollbars have no arrows nowadays | |
362 | .s identify 5 195 | |
363 | } {trough2} | |
335 | 364 | test scrollbar-3.56 {ScrollbarWidgetCmd procedure, "identify" option} unix { |
336 | 365 | .s identify 0 0 |
337 | 366 | } {} |
454 | 483 | test scrollbar-6.10 {ScrollbarPosition procedure} { |
455 | 484 | .s identify [winfo width .s] [expr [winfo height .s] / 2] |
456 | 485 | } {} |
457 | test scrollbar-6.11 {ScrollbarPosition procedure} unix { | |
486 | test scrollbar-6.11.1 {ScrollbarPosition procedure} x11 { | |
458 | 487 | .s identify 8 4 |
459 | 488 | } {arrow1} |
460 | test scrollbar-6.12 {ScrollbarPosition procedure} unix { | |
489 | test scrollbar-6.11.2 {ScrollbarPosition procedure} aqua { | |
490 | # macOS scrollbars have no arrows nowadays | |
491 | .s identify 8 4 | |
492 | } {trough1} | |
493 | test scrollbar-6.12.1 {ScrollbarPosition procedure} x11 { | |
461 | 494 | .s identify 8 19 |
462 | 495 | } {arrow1} |
496 | test scrollbar-6.12.2 {ScrollbarPosition procedure} aqua { | |
497 | # macOS scrollbars have no arrows nowadays | |
498 | .s identify 8 19 | |
499 | } {trough1} | |
463 | 500 | test scrollbar-6.14 {ScrollbarPosition procedure} win { |
464 | 501 | .s identify [expr [winfo width .s] / 2] 0 |
465 | 502 | } {arrow1} |
503 | 540 | test scrollbar-6.25 {ScrollbarPosition procedure} unix { |
504 | 541 | .s identify 8 179 |
505 | 542 | } {trough2} |
506 | test scrollbar-6.27 {ScrollbarPosition procedure} {testmetrics win knownBug} { | |
507 | # This asks for 8,21, which is actually the slider, but there is a | |
508 | # bug in that GetSystemMetrics(SM_CYVTHUMB) actually returns a value | |
509 | # that is larger than the thumb displayed, skewing the ability to | |
510 | # calculate the trough2 area correctly (Win2k). -- hobbs | |
543 | test scrollbar-6.27 {ScrollbarPosition procedure} {testmetrics win} { | |
511 | 544 | .s identify [expr [winfo width .s] / 2] [expr int(.4 / [.s delta 0 1]) \ |
512 | 545 | + [testmetrics cyvscroll .s]] |
513 | 546 | } {trough2} |
515 | 548 | .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] \ |
516 | 549 | - [testmetrics cyvscroll .s] - 1] |
517 | 550 | } {trough2} |
518 | test scrollbar-6.29 {ScrollbarPosition procedure} unix { | |
551 | test scrollbar-6.29.1 {ScrollbarPosition procedure} x11 { | |
519 | 552 | .s identify 8 180 |
520 | 553 | } {arrow2} |
521 | test scrollbar-6.30 {ScrollbarPosition procedure} unix { | |
554 | test scrollbar-6.29.2 {ScrollbarPosition procedure} aqua { | |
555 | # macOS scrollbars have no arrows nowadays | |
556 | .s identify 8 180 | |
557 | } {trough2} | |
558 | test scrollbar-6.30.1 {ScrollbarPosition procedure} x11 { | |
522 | 559 | .s identify 8 195 |
523 | 560 | } {arrow2} |
561 | test scrollbar-6.30.2 {ScrollbarPosition procedure} aqua { | |
562 | # macOS scrollbars have no arrows nowadays | |
563 | .s identify 8 195 | |
564 | } {trough2} | |
524 | 565 | test scrollbar-6.32 {ScrollbarPosition procedure} {testmetrics win} { |
525 | 566 | .s identify [expr [winfo width .s] / 2] [expr [winfo height .s] \ |
526 | 567 | - [testmetrics cyvscroll .s]] |
549 | 590 | .t.s set .2 .4 |
550 | 591 | update |
551 | 592 | |
552 | test scrollbar-6.39 {ScrollbarPosition procedure} unix { | |
593 | test scrollbar-6.39.1 {ScrollbarPosition procedure} x11 { | |
553 | 594 | .t.s identify 4 8 |
554 | 595 | } {arrow1} |
596 | test scrollbar-6.39.2 {ScrollbarPosition procedure} aqua { | |
597 | # macOS scrollbars have no arrows nowadays | |
598 | .t.s identify 4 8 | |
599 | } {trough1} | |
555 | 600 | test scrollbar-6.40 {ScrollbarPosition procedure} win { |
556 | 601 | .t.s identify 0 [expr [winfo height .t.s] / 2] |
557 | 602 | } {arrow1} |
558 | test scrollbar-6.41 {ScrollbarPosition procedure} unix { | |
603 | test scrollbar-6.41.1 {ScrollbarPosition procedure} x11 { | |
559 | 604 | .t.s identify 82 8 |
560 | 605 | } {slider} |
606 | test scrollbar-6.41.2 {ScrollbarPosition procedure} aqua { | |
607 | # macOS scrollbars have no arrows nowadays | |
608 | .t.s identify 82 8 | |
609 | } {trough2} | |
561 | 610 | test scrollbar-6.43 {ScrollbarPosition procedure} {testmetrics win} { |
562 | 611 | .t.s identify [expr int(.4 / [.t.s delta 1 0]) + [testmetrics cxhscroll .t.s] \ |
563 | 612 | - 1] [expr [winfo height .t.s] / 2] |
581 | 630 | catch {destroy .t} |
582 | 631 | toplevel .t |
583 | 632 | wm geometry .t +0+0 |
584 | test scrollbar-8.1 {TkScrollbarEventProc: recursive deletion} { | |
633 | test scrollbar-8.1 {TkScrollbarEventProc: recursive deletion} notAqua { | |
634 | # constrained by notAqua because this test clicks on an arrow of the | |
635 | # scrollbar - but macOS has no such arrows in modern scrollbars | |
585 | 636 | proc doit {args} { destroy .t.f } |
586 | 637 | proc bgerror {args} {} |
587 | 638 | destroy .t.f |
600 | 651 | rename bgerror {} |
601 | 652 | set result |
602 | 653 | } {1 0 0} |
603 | test scrollbar-8.2 {TkScrollbarEventProc: recursive deletion} { | |
654 | test scrollbar-8.2 {TkScrollbarEventProc: recursive deletion} notAqua { | |
655 | # constrained by notAqua because this test clicks on an arrow of the | |
656 | # scrollbar - but macOS has no such arrows in modern scrollbars | |
604 | 657 | proc doit {args} { destroy .t.f.s } |
605 | 658 | proc bgerror {args} {} |
606 | 659 | destroy .t.f |
631 | 684 | list [winfo children .] [interp hidden] |
632 | 685 | } [list {} $l] |
633 | 686 | |
634 | test scrollbar-10.1 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup { | |
687 | test scrollbar-10.1.1 {<MouseWheel> event on scrollbar} -constraints {notAqua} -setup { | |
635 | 688 | destroy .t .s |
636 | 689 | } -body { |
637 | 690 | pack [text .t -yscrollcommand {.s set}] -side left |
645 | 698 | } -cleanup { |
646 | 699 | destroy .t .s |
647 | 700 | } -result {5.0} |
648 | ||
649 | test scrollbar-10.2 {<MouseWheel> event on scrollbar} -constraints {win|unix} -setup { | |
701 | test scrollbar-10.1.2 {<MouseWheel> event on scrollbar} -constraints {aqua} -setup { | |
702 | destroy .t .s | |
703 | } -body { | |
704 | pack [text .t -yscrollcommand {.s set}] -side left | |
705 | for {set i 1} {$i < 100} {incr i} {.t insert end "Line $i\n"} | |
706 | pack [scrollbar .s -command {.t yview}] -fill y -expand 1 -side left | |
707 | update | |
708 | focus -force .s | |
709 | event generate .s <MouseWheel> -delta -4 | |
710 | after 200 {set eventprocessed 1} ; vwait eventprocessed | |
711 | .t index @0,0 | |
712 | } -cleanup { | |
713 | destroy .t .s | |
714 | } -result {5.0} | |
715 | ||
716 | test scrollbar-10.2.1 {<MouseWheel> event on scrollbar} -constraints {notAqua} -setup { | |
650 | 717 | destroy .t .s |
651 | 718 | } -body { |
652 | 719 | pack [text .t -xscrollcommand {.s set} -wrap none] -side top |
655 | 722 | update |
656 | 723 | focus -force .s |
657 | 724 | event generate .s <Shift-MouseWheel> -delta -120 |
725 | after 200 {set eventprocessed 1} ; vwait eventprocessed | |
726 | .t index @0,0 | |
727 | } -cleanup { | |
728 | destroy .t .s | |
729 | } -result {1.4} | |
730 | test scrollbar-10.2.2 {<MouseWheel> event on scrollbar} -constraints {aqua} -setup { | |
731 | destroy .t .s | |
732 | } -body { | |
733 | pack [text .t -xscrollcommand {.s set} -wrap none] -side top | |
734 | for {set i 1} {$i < 100} {incr i} {.t insert end "Char $i "} | |
735 | pack [scrollbar .s -command {.t xview} -orient horizontal] -fill x -expand 1 -side top | |
736 | update | |
737 | focus -force .s | |
738 | event generate .s <Shift-MouseWheel> -delta -4 | |
658 | 739 | after 200 {set eventprocessed 1} ; vwait eventprocessed |
659 | 740 | .t index @0,0 |
660 | 741 | } -cleanup { |
332 | 332 | selection clear .f1 |
333 | 333 | lappend result $lostSel |
334 | 334 | } -result {owned lost2} |
335 | test select-3.7 {Tk_OwnSelection procedure} -constraints unix -setup { | |
335 | test select-3.7 {Tk_OwnSelection procedure} -constraints x11 -setup { | |
336 | 336 | global lostSel |
337 | 337 | setup |
338 | 338 | setupbg |
406 | 406 | } -body { |
407 | 407 | list [selection clear .f1] [selection clear .f1] |
408 | 408 | } -result {{} {}} |
409 | test select-4.4 {Tk_ClearSelection procedure} -constraints unix -setup { | |
409 | test select-4.4 {Tk_ClearSelection procedure} -constraints x11 -setup { | |
410 | 410 | global lostSel |
411 | 411 | setup |
412 | 412 | setupbg |
438 | 438 | list $lostSel $lostSel2 |
439 | 439 | } -result {owned lost2} |
440 | 440 | test select-4.6 {Tk_ClearSelection procedure} -constraints { |
441 | unix altDisplay | |
441 | x11 altDisplay | |
442 | 442 | } -setup { |
443 | 443 | setup .f1 |
444 | 444 | setup .f2 $env(TK_ALT_DISPLAY) |
524 | 524 | }} STRING} |
525 | 525 | list [selection get] $selInfo [catch {selection get} msg] $msg |
526 | 526 | } -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}" |
527 | test select-5.9 {Tk_GetSelection procedure} -constraints unix -setup { | |
527 | test select-5.9 {Tk_GetSelection procedure} -constraints x11 -setup { | |
528 | 528 | setup |
529 | 529 | setupbg |
530 | 530 | } -body { |
537 | 537 | cleanupbg |
538 | 538 | lappend result $selInfo |
539 | 539 | } -result {{Test value} {TEST 0 4000}} |
540 | test select-5.10 {Tk_GetSelection procedure} -constraints unix -setup { | |
540 | test select-5.10 {Tk_GetSelection procedure} -constraints x11 -setup { | |
541 | 541 | setup |
542 | 542 | setupbg |
543 | 543 | } -body { |
585 | 585 | $selInfo |
586 | 586 | } -result {0 {Test value} {TEST 0 4000} 1 {PRIMARY selection doesn't exist or form "TEST" not defined} {}} |
587 | 587 | test select-5.13 {Tk_GetSelection procedure} -constraints { |
588 | unix altDisplay | |
588 | x11 altDisplay | |
589 | 589 | } -setup { |
590 | 590 | setup .f1 |
591 | 591 | setup .f2 $env(TK_ALT_DISPLAY) |
606 | 606 | lappend result $selInfo |
607 | 607 | } -result {{Test value} {Test value2} {TEST2 0 4000 TEST 0 4000}} |
608 | 608 | test select-5.14 {Tk_GetSelection procedure} -constraints { |
609 | unix altDisplay | |
609 | x11 altDisplay | |
610 | 610 | } -setup { |
611 | 611 | setup .f1 |
612 | 612 | setup .f2 $env(TK_ALT_DISPLAY) |
863 | 863 | ############################################################################## |
864 | 864 | |
865 | 865 | # Check reentrancy on losing selection |
866 | test select-8.1 {TkSelEventProc procedure} -constraints unix -setup { | |
866 | test select-8.1 {TkSelEventProc procedure} -constraints x11 -setup { | |
867 | 867 | setup |
868 | 868 | setupbg |
869 | 869 | } -body { |
870 | 870 | selection own -selection CLIPBOARD -command {destroy .f1} .f1 |
871 | 871 | update |
872 | 872 | dobg {selection own -selection CLIPBOARD .} |
873 | winfo children . | |
873 | 874 | } -cleanup { |
874 | 875 | cleanupbg |
875 | 876 | } -result {} |
879 | 880 | test select-9.1 {SelCvtToX and SelCvtFromX procedures} -setup { |
880 | 881 | setup |
881 | 882 | setupbg |
882 | } -constraints unix -body { | |
883 | } -constraints x11 -body { | |
883 | 884 | set selValue "1024" |
884 | 885 | set selInfo "" |
885 | 886 | selection handle -selection PRIMARY -format INTEGER -type TEST \ |
893 | 894 | test select-9.2 {SelCvtToX and SelCvtFromX procedures} -setup { |
894 | 895 | setup |
895 | 896 | setupbg |
896 | } -constraints unix -body { | |
897 | } -constraints x11 -body { | |
897 | 898 | set selValue "1024 0xffff 2048 -2 " |
898 | 899 | set selInfo "" |
899 | 900 | selection handle -selection PRIMARY -format INTEGER -type TEST \ |
906 | 907 | test select-9.3 {SelCvtToX and SelCvtFromX procedures} -setup { |
907 | 908 | setup |
908 | 909 | setupbg |
909 | } -constraints unix -body { | |
910 | } -constraints x11 -body { | |
910 | 911 | set selValue " " |
911 | 912 | set selInfo "" |
912 | 913 | selection handle -selection PRIMARY -format INTEGER -type TEST \ |
919 | 920 | test select-9.4 {SelCvtToX and SelCvtFromX procedures} -setup { |
920 | 921 | setup |
921 | 922 | setupbg |
922 | } -constraints unix -body { | |
923 | } -constraints x11 -body { | |
923 | 924 | set selValue "16 foobar 32" |
924 | 925 | set selInfo "" |
925 | 926 | selection handle -selection PRIMARY -format INTEGER -type TEST \ |
932 | 933 | test select-9.5 {SelCvtToX and SelCvtFromX procedures} -setup { |
933 | 934 | setup |
934 | 935 | setupbg |
935 | } -constraints unix -body { | |
936 | } -constraints x11 -body { | |
936 | 937 | # Ensure that lists of atoms are constructed correctly, even when the |
937 | 938 | # atom names have spaces in. [Bug 1353414] |
938 | 939 | set selValue "foo bar" |
950 | 951 | |
951 | 952 | # most control paths have been exercised above |
952 | 953 | test select-10.1 {ConvertSelection procedure, race with selection clear} -constraints { |
953 | unix | |
954 | x11 | |
954 | 955 | } -setup { |
955 | 956 | setup |
956 | 957 | } -body { |
980 | 981 | catch {close $fd} |
981 | 982 | lappend x $selInfo |
982 | 983 | } -result {{1:PRIMARY selection doesn't exist or form "STRING" not defined} {}} |
983 | test select-10.2 {ConvertSelection procedure} -constraints unix -setup { | |
984 | test select-10.2 {ConvertSelection procedure} -constraints x11 -setup { | |
984 | 985 | setup |
985 | 986 | setupbg |
986 | 987 | } -body { |
992 | 993 | cleanupbg |
993 | 994 | lappend result $selInfo |
994 | 995 | } -result [list [string range $longValue 0 3999] {STRING 0 4000 STRING 4000 4000 STRING 0 4000 STRING 4000 4000}] |
995 | test select-10.3 {ConvertSelection procedure} -constraints unix -setup { | |
996 | test select-10.3 {ConvertSelection procedure} -constraints x11 -setup { | |
996 | 997 | setup |
997 | 998 | setupbg |
998 | 999 | } -body { |
1004 | 1005 | # testing timers |
1005 | 1006 | # This one hangs in Exceed |
1006 | 1007 | test select-10.4 {ConvertSelection procedure} -constraints { |
1007 | unix noExceed | |
1008 | x11 noExceed | |
1008 | 1009 | } -setup { |
1009 | 1010 | setup |
1010 | 1011 | setupbg |
1019 | 1020 | lappend result $selInfo |
1020 | 1021 | } -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}} |
1021 | 1022 | test select-10.5 {ConvertSelection procedure, reentrancy issues} -constraints { |
1022 | unix | |
1023 | x11 | |
1023 | 1024 | } -setup { |
1024 | 1025 | setup |
1025 | 1026 | setupbg |
1034 | 1035 | lappend result $selInfo |
1035 | 1036 | } -result {{PRIMARY selection doesn't exist or form "STRING" not defined} {.f1 STRING 0 4000}} |
1036 | 1037 | test select-10.6 {ConvertSelection procedure, reentrancy issues} -constraints { |
1037 | unix | |
1038 | x11 | |
1038 | 1039 | } -setup { |
1039 | 1040 | setup |
1040 | 1041 | setupbg |
1057 | 1058 | ############################################################################## |
1058 | 1059 | |
1059 | 1060 | # testing reentrancy |
1060 | test select-11.1 {TkSelPropProc procedure} -constraints unix -setup { | |
1061 | test select-11.1 {TkSelPropProc procedure} -constraints x11 -setup { | |
1061 | 1062 | setup |
1062 | 1063 | setupbg |
1063 | 1064 | } -body { |
1075 | 1076 | ############################################################################## |
1076 | 1077 | |
1077 | 1078 | # Note, this assumes we are using CurrentTtime |
1078 | test select-12.1 {DefaultSelection procedure} -constraints unix -body { | |
1079 | test select-12.1 {DefaultSelection procedure} -constraints x11 -body { | |
1079 | 1080 | setup |
1080 | 1081 | set result [selection get -type TIMESTAMP] |
1081 | 1082 | setupbg |
1083 | 1084 | cleanupbg |
1084 | 1085 | set result |
1085 | 1086 | } -result {0x0 {0x0 }} |
1086 | test select-12.2 {DefaultSelection procedure} -constraints unix -body { | |
1087 | test select-12.2 {DefaultSelection procedure} -constraints x11 -body { | |
1087 | 1088 | setup |
1088 | 1089 | set result [lsort [list [selection get -type TARGETS]]] |
1089 | 1090 | setupbg |
1091 | 1092 | cleanupbg |
1092 | 1093 | set result |
1093 | 1094 | } -result {{MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}} |
1094 | test select-12.3 {DefaultSelection procedure} -constraints unix -body { | |
1095 | test select-12.3 {DefaultSelection procedure} -constraints x11 -body { | |
1095 | 1096 | setup |
1096 | 1097 | selection handle .f1 {handler TEST} TEST |
1097 | 1098 | set result [list [lsort [selection get -type TARGETS]]] |
1100 | 1101 | cleanupbg |
1101 | 1102 | set result |
1102 | 1103 | } -result {{MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW} {MULTIPLE TARGETS TEST TIMESTAMP TK_APPLICATION TK_WINDOW}} |
1103 | test select-12.4 {DefaultSelection procedure} -constraints unix -setup { | |
1104 | test select-12.4 {DefaultSelection procedure} -constraints x11 -setup { | |
1104 | 1105 | setup |
1105 | 1106 | set result "" |
1106 | 1107 | } -body { |
1110 | 1111 | cleanupbg |
1111 | 1112 | set result |
1112 | 1113 | } -result [list [winfo name .] [winfo name .]] |
1113 | test select-12.5 {DefaultSelection procedure} -constraints unix -body { | |
1114 | test select-12.5 {DefaultSelection procedure} -constraints x11 -body { | |
1114 | 1115 | setup |
1115 | 1116 | set result [selection get -type TK_WINDOW] |
1116 | 1117 | setupbg |
1129 | 1130 | } -result {{Targets value} {TARGETS.f1 0 4000} {MULTIPLE TARGETS TIMESTAMP TK_APPLICATION TK_WINDOW}} |
1130 | 1131 | |
1131 | 1132 | test select-13.1 {SelectionSize procedure, handler deleted} -constraints { |
1132 | unix | |
1133 | x11 | |
1133 | 1134 | } -setup { |
1134 | 1135 | setup |
1135 | 1136 | setupbg |
1583 | 1583 | for {set i 0} {$i < 2} {incr i} { |
1584 | 1584 | .tt replace 2.0 3.0 b |
1585 | 1585 | } |
1586 | } -cleanup { | |
1587 | destroy .tt | |
1588 | } -result {} | |
1589 | test text-8.28 {TextWidgetCmd procedure, "replace" option crash} -setup { | |
1590 | text .tt | |
1591 | } -body { | |
1592 | .tt insert end "foo\n" | |
1593 | .tt tag add sel 1.0 end | |
1594 | .tt replace sel.first sel.last "bar" | |
1586 | 1595 | } -cleanup { |
1587 | 1596 | destroy .tt |
1588 | 1597 | } -result {} |
5547 | 5556 | } -cleanup { |
5548 | 5557 | destroy .t |
5549 | 5558 | } -result {2.0 19} |
5550 | test text-22.199 {TextSearchCmd, regexp search multi-line} -constraints { | |
5551 | knownBug | |
5552 | } -body { | |
5559 | test text-22.199 {TextSearchCmd, regexp search multi-line} -body { | |
5553 | 5560 | pack [text .t] |
5554 | 5561 | .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n" |
5555 | 5562 | set foo {} |
5558 | 5565 | } -cleanup { |
5559 | 5566 | destroy .t |
5560 | 5567 | } -result {2.0 19} |
5561 | test text-22.200 {TextSearchCmd, regexp search multi-line} -constraints { | |
5562 | knownBug | |
5563 | } -body { | |
5568 | test text-22.200 {TextSearchCmd, regexp search multi-line} -body { | |
5564 | 5569 | pack [text .t] |
5565 | 5570 | .t insert 1.0 "aaaa\nbbbb\ncccc\nbbbb\naaaa\n" |
5566 | 5571 | set foo {} |
5578 | 5583 | } -cleanup { |
5579 | 5584 | destroy .t |
5580 | 5585 | } -result {1.0 24} |
5581 | test text-22.202 {TextSearchCmd, regexp search multi-line} -constraints { | |
5582 | knownBug | |
5583 | } -body { | |
5586 | test text-22.202 {TextSearchCmd, regexp search multi-line} -body { | |
5584 | 5587 | pack [text .t] |
5585 | 5588 | .t insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n" |
5586 | 5589 | list [.t search -regexp -backward -all -count foo \ |
5587 | -- {b+\n|a+\n(b+\n)+} end] $foo | |
5590 | -- {(b+\n|a+\n)(b+\n)+} end] $foo | |
5588 | 5591 | } -cleanup { |
5589 | 5592 | destroy .t |
5590 | 5593 | } -result {1.0 25} |
5591 | test text-22.203 {TextSearchCmd, regexp search multi-line} -constraints { | |
5592 | knownBug | |
5593 | } -body { | |
5594 | test text-22.203 {TextSearchCmd, regexp search multi-line} -body { | |
5594 | 5595 | pack [text .t] |
5595 | 5596 | .t insert 1.0 "aaaa\nbbbb\nbbbb\nbbbb\nbbbb\n" |
5596 | .t search -regexp -backward -- {b+\n|a+\n(b+\n)+} end | |
5597 | # Should match at 1.0 for a true greedy match | |
5597 | .t search -regexp -backward -- {(b+\n|a+\n)(b+\n)+} end | |
5598 | 5598 | } -cleanup { |
5599 | 5599 | destroy .t |
5600 | 5600 | } -result {1.0} |
5863 | 5863 | } -cleanup { |
5864 | 5864 | destroy .t |
5865 | 5865 | } -result {} |
5866 | ||
5866 | test text-22.226 {TextSearchCmd, exact search for the empty string} -body { | |
5867 | text .t | |
5868 | set res [.t search -count C "" 1.0] | |
5869 | lappend res $C | |
5870 | } -cleanup { | |
5871 | destroy .t | |
5872 | unset -nocomplain res C | |
5873 | } -result {1.0 0} | |
5874 | test text-22.227 {TextSearchCmd, exact search for the empty string} -body { | |
5875 | text .t | |
5876 | .t insert end "Searching for the\nempty string!" | |
5877 | set res [.t search -count C "" 2.5] | |
5878 | lappend res $C | |
5879 | } -cleanup { | |
5880 | destroy .t | |
5881 | unset -nocomplain res C | |
5882 | } -result {2.5 0} | |
5883 | test text-22.228 {TextSearchCmd, exact search all empty strings} -body { | |
5884 | text .t | |
5885 | set res [.t search -count C -all "" 1.0] | |
5886 | lappend res $C | |
5887 | } -cleanup { | |
5888 | destroy .t | |
5889 | unset -nocomplain res C | |
5890 | } -result {1.0 0} | |
5891 | test text-22.229 {TextSearchCmd, exact search all empty strings} -body { | |
5892 | text .t | |
5893 | .t insert end "Searching for the\nempty string!" | |
5894 | set res [.t search -count C -all "" 2.5 2.8] | |
5895 | lappend res $C | |
5896 | } -cleanup { | |
5897 | destroy .t | |
5898 | unset -nocomplain res C | |
5899 | } -result {2.5 2.6 2.7 {0 0 0}} | |
5900 | test text-22.230 {TextSearchCmd, exact search all empty strings, with overlap} -body { | |
5901 | text .t | |
5902 | set res [.t search -count C -all -overlap "" 1.0] | |
5903 | lappend res $C | |
5904 | } -cleanup { | |
5905 | destroy .t | |
5906 | unset -nocomplain res C | |
5907 | } -result {1.0 0} | |
5908 | test text-22.231 {TextSearchCmd, exact search all empty strings, with overlap} -body { | |
5909 | text .t | |
5910 | .t insert end "Searching for the\nempty string!" | |
5911 | set res [.t search -count C -all -overlap "" 2.5 2.8] | |
5912 | lappend res $C | |
5913 | } -cleanup { | |
5914 | destroy .t | |
5915 | unset -nocomplain res C | |
5916 | } -result {2.5 2.6 2.7 {0 0 0}} | |
5917 | test text-22.232 {TextSearchCmd, regexp search for the empty string} -body { | |
5918 | text .t | |
5919 | set res [.t search -count C -regexp "" 1.0] | |
5920 | lappend res $C | |
5921 | } -cleanup { | |
5922 | destroy .t | |
5923 | unset -nocomplain res C | |
5924 | } -result {1.0 0} | |
5925 | test text-22.233 {TextSearchCmd, regexp search for the empty string} -body { | |
5926 | text .t | |
5927 | .t insert end "Searching for the\nempty string!" | |
5928 | set res [.t search -count C -regexp "" 2.5] | |
5929 | lappend res $C | |
5930 | } -cleanup { | |
5931 | destroy .t | |
5932 | unset -nocomplain res C | |
5933 | } -result {2.5 0} | |
5934 | test text-22.234 {TextSearchCmd, regexp search all empty strings} -body { | |
5935 | text .t | |
5936 | set res [.t search -count C -all -regexp "" 1.0] | |
5937 | lappend res $C | |
5938 | } -cleanup { | |
5939 | destroy .t | |
5940 | unset -nocomplain res C | |
5941 | } -result {1.0 0} | |
5942 | test text-22.235 {TextSearchCmd, regexp search all empty strings} -body { | |
5943 | text .t | |
5944 | .t insert end "Searching for the\nempty string!" | |
5945 | set res [.t search -count C -all -regexp "" 2.5 2.8] | |
5946 | lappend res $C | |
5947 | } -cleanup { | |
5948 | destroy .t | |
5949 | unset -nocomplain res C | |
5950 | } -result {2.5 2.6 2.7 {0 0 0}} | |
5951 | test text-22.236 {TextSearchCmd, regexp search all empty strings, with overlap} -body { | |
5952 | text .t | |
5953 | set res [.t search -count C -all -regexp -overlap "" 1.0] | |
5954 | lappend res $C | |
5955 | } -cleanup { | |
5956 | destroy .t | |
5957 | unset -nocomplain res C | |
5958 | } -result {1.0 0} | |
5959 | test text-22.237 {TextSearchCmd, regexp search all empty strings, with overlap} -body { | |
5960 | text .t | |
5961 | .t insert end "Searching for the\nempty string!" | |
5962 | set res [.t search -count C -all -regexp -overlap "" 2.5 2.8] | |
5963 | lappend res $C | |
5964 | } -cleanup { | |
5965 | destroy .t | |
5966 | unset -nocomplain res C | |
5967 | } -result {2.5 2.6 2.7 {0 0 0}} | |
5968 | test text-22.238 {TextSearchCmd, exact backwards search for the empty string} -body { | |
5969 | text .t | |
5970 | set res [.t search -count C -backwards "" 1.0] | |
5971 | lappend res $C | |
5972 | } -cleanup { | |
5973 | destroy .t | |
5974 | unset -nocomplain res C | |
5975 | } -result {1.0 0} | |
5976 | test text-22.239 {TextSearchCmd, exact backwards search for the empty string} -body { | |
5977 | text .t | |
5978 | .t insert end "Searching for the\nempty string!" | |
5979 | set res [.t search -count C -backwards "" 2.5] | |
5980 | lappend res $C | |
5981 | } -cleanup { | |
5982 | destroy .t | |
5983 | unset -nocomplain res C | |
5984 | } -result {2.4 0} | |
5985 | test text-22.240 {TextSearchCmd, exact backwards search all empty strings} -body { | |
5986 | text .t | |
5987 | set res [.t search -count C -backwards -all "" 1.0] | |
5988 | lappend res $C | |
5989 | } -cleanup { | |
5990 | destroy .t | |
5991 | unset -nocomplain res C | |
5992 | } -result {1.0 0} | |
5993 | test text-22.241 {TextSearchCmd, exact backwards search all empty strings} -body { | |
5994 | text .t | |
5995 | .t insert end "Searching for the\nempty string!" | |
5996 | set res [.t search -count C -backwards -all "" 2.5 2.0] | |
5997 | lappend res $C | |
5998 | } -cleanup { | |
5999 | destroy .t | |
6000 | unset -nocomplain res C | |
6001 | } -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} | |
6002 | test text-22.242 {TextSearchCmd, exact backwards search all empty strings, with overlap} -body { | |
6003 | text .t | |
6004 | set res [.t search -count C -backwards -all -overlap "" 1.0] | |
6005 | lappend res $C | |
6006 | } -cleanup { | |
6007 | destroy .t | |
6008 | unset -nocomplain res C | |
6009 | } -result {1.0 0} | |
6010 | test text-22.243 {TextSearchCmd, exact backwards search all empty strings, with overlap} -body { | |
6011 | text .t | |
6012 | .t insert end "Searching for the\nempty string!" | |
6013 | set res [.t search -count C -backwards -all -overlap "" 2.5 2.0] | |
6014 | lappend res $C | |
6015 | } -cleanup { | |
6016 | destroy .t | |
6017 | unset -nocomplain res C | |
6018 | } -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} | |
6019 | test text-22.244 {TextSearchCmd, regexp backwards search for the empty string} -body { | |
6020 | text .t | |
6021 | set res [.t search -count C -backwards -regexp "" 1.0] | |
6022 | lappend res $C | |
6023 | } -cleanup { | |
6024 | destroy .t | |
6025 | unset -nocomplain res C | |
6026 | } -result {1.0 0} | |
6027 | test text-22.245 {TextSearchCmd, regexpbackwards search for the empty string} -body { | |
6028 | text .t | |
6029 | .t insert end "Searching for the\nempty string!" | |
6030 | set res [.t search -count C -backwards -regexp "" 2.5] | |
6031 | lappend res $C | |
6032 | } -cleanup { | |
6033 | destroy .t | |
6034 | unset -nocomplain res C | |
6035 | } -result {2.4 0} | |
6036 | test text-22.246 {TextSearchCmd, regexp backwards search all empty strings} -body { | |
6037 | text .t | |
6038 | set res [.t search -count C -backwards -all -regexp "" 1.0] | |
6039 | lappend res $C | |
6040 | } -cleanup { | |
6041 | destroy .t | |
6042 | unset -nocomplain res C | |
6043 | } -result {1.0 0} | |
6044 | test text-22.247 {TextSearchCmd, regexp backwards search all empty strings} -body { | |
6045 | text .t | |
6046 | .t insert end "Searching for the\nempty string!" | |
6047 | set res [.t search -count C -backwards -all -regexp "" 2.5 2.0] | |
6048 | lappend res $C | |
6049 | } -cleanup { | |
6050 | destroy .t | |
6051 | unset -nocomplain res C | |
6052 | } -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} | |
6053 | test text-22.248 {TextSearchCmd, regexp backwards search all empty strings, with overlap} -body { | |
6054 | text .t | |
6055 | set res [.t search -count C -backwards -all -regexp -overlap "" 1.0] | |
6056 | lappend res $C | |
6057 | } -cleanup { | |
6058 | destroy .t | |
6059 | unset -nocomplain res C | |
6060 | } -result {1.0 0} | |
6061 | test text-22.249 {TextSearchCmd, regexp backwards search all empty strings, with overlap} -body { | |
6062 | text .t | |
6063 | .t insert end "Searching for the\nempty string!" | |
6064 | set res [.t search -count C -backwards -all -regexp -overlap "" 2.5 2.0] | |
6065 | lappend res $C | |
6066 | } -cleanup { | |
6067 | destroy .t | |
6068 | unset -nocomplain res C | |
6069 | } -result {2.4 2.3 2.2 2.1 2.0 {0 0 0 0 0}} | |
6070 | test text-22.250 {TextSearchCmd, backwards search all matching at start of line} -body { | |
6071 | text .t | |
6072 | .t insert end "abc" | |
6073 | set res [.t search -backwards -all b end] ; # works | |
6074 | lappend res [.t search -backwards a end] ; # works | |
6075 | lappend res [.t search -backwards -all a end] ; # used to hang | |
6076 | } -cleanup { | |
6077 | destroy .t | |
6078 | } -result {1.1 1.0 1.0} | |
5867 | 6079 | |
5868 | 6080 | test text-23.1 {TkTextGetTabs procedure} -setup { |
5869 | 6081 | text .t -highlightthickness 0 -bd 0 -relief flat -padx 0 -width 100 |
6394 | 6606 | } -cleanup { |
6395 | 6607 | destroy .t .tt |
6396 | 6608 | } -result {4} |
6397 | test text-27.15 {<<Selection>> virtual event} -body { | |
6609 | test text-27.15 {<<Selection>> virtual event on sel tagging} -body { | |
6398 | 6610 | set ::retval no_selection |
6399 | pack [text .t -undo 1] | |
6611 | pack [text .t] | |
6400 | 6612 | bind .t <<Selection>> "set ::retval selection_changed" |
6401 | 6613 | update idletasks |
6402 | 6614 | .t insert end "nothing special\n" |
6406 | 6618 | } -cleanup { |
6407 | 6619 | destroy .t |
6408 | 6620 | } -result {selection_changed} |
6621 | test text-27.15a {<<Selection>> virtual event on sel removal} -body { | |
6622 | set ::retval no_selection | |
6623 | pack [text .t] | |
6624 | .t insert end "nothing special\n" | |
6625 | .t tag add sel 1.0 1.1 | |
6626 | bind .t <<Selection>> "set ::retval selection_changed" | |
6627 | update idletasks | |
6628 | .t tag remove 1.0 end | |
6629 | update | |
6630 | set ::retval | |
6631 | } -cleanup { | |
6632 | destroy .t | |
6633 | } -result {selection_changed} | |
6634 | test text-27.15b {<<Selection>> virtual event on <<PasteSelection>> inside widget selection} -body { | |
6635 | pack [text .t] | |
6636 | .t insert end "There is a selection in this text widget,\n" | |
6637 | .t insert end "and it will be impacted by the <<PasteSelection>> event received.\n" | |
6638 | .t insert end "Therefore a <<Selection>> event must fire back." | |
6639 | .t tag add sel 1.0 1.28 | |
6640 | bind .t <<Selection>> "set ::retval <<Selection>>_fired" | |
6641 | update | |
6642 | set ::retval no_<<Selection>>_event_fired | |
6643 | event generate .t <<PasteSelection>> -x 15 -y 3 | |
6644 | update | |
6645 | set ::retval | |
6646 | } -cleanup { | |
6647 | destroy .t | |
6648 | } -result {<<Selection>>_fired} | |
6649 | test text-27.15c {No <<Selection>> virtual event on <<PasteSelection>> outside widget selection} -body { | |
6650 | pack [text .t] | |
6651 | .t insert end "There is a selection in this text widget,\n" | |
6652 | .t insert end "but it will not be impacted by the <<PasteSelection>> event received." | |
6653 | .t tag add sel 1.0 1.28 | |
6654 | bind .t <<Selection>> "set ::retval <<Selection>>_fired" | |
6655 | update | |
6656 | set ::retval no_<<Selection>>_event_fired | |
6657 | event generate .t <<PasteSelection>> -x 15 -y 80 | |
6658 | update | |
6659 | set ::retval | |
6660 | } -cleanup { | |
6661 | destroy .t | |
6662 | } -result {no_<<Selection>>_event_fired} | |
6663 | test text-27.15d {<<Selection>> virtual event on <Delete> with cursor inside selection} -body { | |
6664 | pack [text .t] | |
6665 | .t insert end "There is a selection in this text widget,\n" | |
6666 | .t insert end "and it will be impacted by the <Delete> event received.\n" | |
6667 | .t insert end "Therefore a <<Selection>> event must fire back." | |
6668 | .t tag add sel 1.0 1.28 | |
6669 | bind .t <<Selection>> "set ::retval <<Selection>>_fired" | |
6670 | update | |
6671 | set ::retval no_<<Selection>>_event_fired | |
6672 | .t mark set insert 1.15 | |
6673 | focus .t | |
6674 | event generate .t <Delete> | |
6675 | update | |
6676 | set ::retval | |
6677 | } -cleanup { | |
6678 | destroy .t | |
6679 | } -result {<<Selection>>_fired} | |
6680 | test text-27.15e {No <<Selection>> virtual event on <Delete> with cursor outside selection} -body { | |
6681 | pack [text .t] | |
6682 | .t insert end "There is a selection in this text widget,\n" | |
6683 | .t insert end "but it will not be impacted by the <Delete> event received." | |
6684 | .t tag add sel 1.0 1.28 | |
6685 | bind .t <<Selection>> "set ::retval <<Selection>>_fired" | |
6686 | update | |
6687 | set ::retval no_<<Selection>>_event_fired | |
6688 | .t mark set insert 2.15 | |
6689 | focus .t | |
6690 | event generate .t <Delete> | |
6691 | update | |
6692 | set ::retval | |
6693 | } -cleanup { | |
6694 | destroy .t | |
6695 | } -result {no_<<Selection>>_event_fired} | |
6696 | test text-27.15f {<<Selection>> virtual event on <<Cut>> with a widget selection} -body { | |
6697 | pack [text .t] | |
6698 | .t insert end "There is a selection in this text widget,\n" | |
6699 | .t insert end "and it will be impacted by the <<Cut>> event received.\n" | |
6700 | .t insert end "Therefore a <<Selection>> event must fire back." | |
6701 | .t tag add sel 1.0 1.28 | |
6702 | bind .t <<Selection>> "set ::retval <<Selection>>_fired" | |
6703 | update | |
6704 | set ::retval no_<<Selection>>_event_fired | |
6705 | event generate .t <<Cut>> | |
6706 | update | |
6707 | set ::retval | |
6708 | } -cleanup { | |
6709 | destroy .t | |
6710 | } -result {<<Selection>>_fired} | |
6711 | test text-27.15g {No <<Selection>> virtual event on <<Cut>> without widget selection} -body { | |
6712 | pack [text .t] | |
6713 | .t insert end "There is a selection in this text widget,\n" | |
6714 | .t insert end "and it will be impacted by the <<Cut>> event received.\n" | |
6715 | .t insert end "Therefore a <<Selection>> event must fire back." | |
6716 | bind .t <<Selection>> "set ::retval <<Selection>>_fired" | |
6717 | update | |
6718 | set ::retval no_<<Selection>>_event_fired | |
6719 | event generate .t <<Cut>> | |
6720 | update | |
6721 | set ::retval | |
6722 | } -cleanup { | |
6723 | destroy .t | |
6724 | } -result {no_<<Selection>>_event_fired} | |
6409 | 6725 | test text-27.16 {-maxundo configuration option} -body { |
6410 | 6726 | text .t -undo 1 -autoseparators 1 -maxundo 2 |
6411 | 6727 | pack .t |
3373 | 3373 | .t tag add x 1.0 end |
3374 | 3374 | list [.t bbox 1.0] [.t bbox 1.10] |
3375 | 3375 | } [list [list 45 3 7 $fixedHeight] [list 94 3 7 $fixedHeight]] |
3376 | test textDisp-24.25 {TkTextCharLayoutProc, justification and tabs} -constraints {textfonts} -setup { | |
3377 | text .tt -tabs {40 right} -wrap none -font $fixedFont | |
3378 | pack .tt | |
3379 | } -body { | |
3380 | .tt insert end \t9\n\t99\n\t999 | |
3381 | update | |
3382 | list [.tt bbox 1.1] [.tt bbox 2.2] [.tt bbox 3.3] | |
3383 | } -cleanup { | |
3384 | destroy .tt | |
3385 | } -result [list [list 38 5 7 $fixedHeight] [list 38 20 7 $fixedHeight] [list 38 35 7 $fixedHeight]] | |
3376 | 3386 | |
3377 | 3387 | .t configure -width 40 -bd 0 -relief flat -highlightthickness 0 -padx 0 \ |
3378 | 3388 | -tabs 100 |
1745 | 1745 | text .t -width 30 -height 4 -relief sunken -borderwidth 10 \ |
1746 | 1746 | -highlightthickness 10 -pady 2 |
1747 | 1747 | pack .t |
1748 | update ; # map the window, otherwise -warp can't be done | |
1748 | 1749 | |
1749 | 1750 | .t insert end " Tag here " TAG " no tag here" |
1750 | 1751 | .t tag configure TAG -borderwidth 4 -relief raised |
10 | 10 | tcltest::configure {*}$argv |
11 | 11 | tcltest::loadTestedCommands |
12 | 12 | |
13 | # Create entries in the option database to be sure that geometry options | |
14 | # like border width have predictable values. | |
15 | ||
16 | option add *Text.borderWidth 2 | |
17 | option add *Text.highlightThickness 2 | |
18 | option add *Text.font {Courier -12} | |
19 | ||
20 | ||
21 | 13 | deleteWindows |
22 | # Widget used in tests 1.* - 16.* | |
23 | text .t -width 30 -height 6 -bd 2 -highlightthickness 2 | |
14 | ||
15 | set fixedFont {"Courier New" -12} | |
16 | set fixedHeight [font metrics $fixedFont -linespace] | |
17 | set fixedWidth [font measure $fixedFont m] | |
18 | set fixedAscent [font metrics $fixedFont -ascent] | |
19 | ||
20 | # Widget used in almost all tests | |
21 | set tWidth 30 | |
22 | set tHeight 6 | |
23 | text .t -width $tWidth -height $tHeight -bd 2 -highlightthickness 2 \ | |
24 | -font $fixedFont | |
24 | 25 | pack .t -expand 1 -fill both |
25 | 26 | update |
26 | 27 | .t debug on |
27 | 28 | |
28 | # 15 on XP, 13 on Solaris 8 | |
29 | set fixedHeight [font metrics {Courier -12} -linespace] | |
30 | set fixedDiff [expr {$fixedHeight - 13}] ;# 2 on XP | |
31 | 29 | set color [expr {[winfo depth .t] > 1 ? "green" : "black"}] |
32 | 30 | |
33 | 31 | wm geometry . {} |
34 | ||
32 | ||
35 | 33 | # The statements below reset the main window; it's needed if the window |
36 | 34 | # manager is mwm to make mwm forget about a previous minimum size setting. |
37 | 35 | |
40 | 38 | wm positionfrom . user |
41 | 39 | wm deiconify . |
42 | 40 | |
41 | set bw [.t cget -borderwidth] | |
42 | set px [.t cget -padx] | |
43 | set py [.t cget -pady] | |
44 | set hlth [.t cget -highlightthickness] | |
45 | set padx [expr {$bw+$px+$hlth}] | |
46 | set pady [expr {$bw+$py+$hlth}] | |
47 | ||
43 | 48 | # ---------------------------------------------------------------------- |
44 | 49 | |
45 | test textWind-1.1 {basic tests of options} -constraints fonts -setup { | |
50 | test textWind-1.1 {basic tests of options} -setup { | |
46 | 51 | .t delete 1.0 end |
47 | 52 | } -body { |
48 | 53 | .t insert end "This is the first line" |
52 | 57 | update |
53 | 58 | list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \ |
54 | 59 | [.t window configure .f -window] |
55 | } -result {1 3x3+19+23 {19 23 3 3} {-window {} {} {} .f}} | |
56 | test textWind-1.2 {basic tests of options} -constraints fonts -setup { | |
60 | } -result [list \ | |
61 | 1 \ | |
62 | 3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] \ | |
63 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+(($fixedHeight-3)/2)}] 3 3] \ | |
64 | {-window {} {} {} .f}] | |
65 | ||
66 | test textWind-1.2 {basic tests of options} -setup { | |
57 | 67 | .t delete 1.0 end |
58 | 68 | } -body { |
59 | 69 | .t insert end "This is the first line" |
63 | 73 | update |
64 | 74 | list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] \ |
65 | 75 | [.t window configure .f -align] |
66 | } -result {1 3x3+19+18 {19 18 3 3} {-align {} {} center top}} | |
76 | } -result [list \ | |
77 | 1 \ | |
78 | 3x3+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \ | |
79 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 3 3] \ | |
80 | {-align {} {} center top}] | |
81 | ||
67 | 82 | test textWind-1.3 {basic tests of options} -setup { |
68 | 83 | .t delete 1.0 end |
69 | 84 | } -body { |
72 | 87 | .t window create 2.2 -create "Test script" |
73 | 88 | .t window configure 2.2 -create |
74 | 89 | } -result {-create {} {} {} {Test script}} |
75 | test textWind-1.4 {basic tests of options} -constraints fonts -setup { | |
90 | ||
91 | test textWind-1.4 {basic tests of options} -setup { | |
76 | 92 | .t delete 1.0 end |
77 | 93 | } -body { |
78 | 94 | .t insert end "This is the first line" |
79 | 95 | .t insert end "\nAnd this is a second line, which wraps around" |
96 | # the window .f should be wider than the fixed width | |
80 | 97 | frame .f -width 10 -height 20 -bg $color |
81 | 98 | .t window create 2.2 -window .f -padx 5 |
82 | 99 | update |
83 | 100 | list [winfo geom .f] [.t window configure .f -padx] [.t bbox 2.3] |
84 | } -result {10x20+24+18 {-padx {} {} 0 5} {39 21 7 13}} | |
85 | test textWind-1.5 {basic tests of options} -constraints fonts -setup { | |
101 | } -result [list \ | |
102 | 10x20+[expr {$padx+2*$fixedWidth+5}]+[expr {$pady+$fixedHeight}] \ | |
103 | {-padx {} {} 0 5} \ | |
104 | [list [expr {$padx+2*$fixedWidth+10+2*5}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]] | |
105 | ||
106 | test textWind-1.5 {basic tests of options} -setup { | |
86 | 107 | .t delete 1.0 end |
87 | 108 | } -body { |
88 | 109 | .t insert end "This is the first line" |
91 | 112 | .t window create 2.2 -window .f -pady 4 |
92 | 113 | update |
93 | 114 | list [winfo geom .f] [.t window configure .f -pady] [.t bbox 2.31] |
94 | } -result {10x20+19+22 {-pady {} {} 0 4} {19 46 7 13}} | |
95 | test textWind-1.6 {basic tests of options} -constraints fonts -setup { | |
115 | } -result [list \ | |
116 | 10x20+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight+4}] \ | |
117 | {-pady {} {} 0 4} \ | |
118 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight+20+2*4}] $fixedWidth $fixedHeight]] | |
119 | ||
120 | test textWind-1.6 {basic tests of options} -setup { | |
96 | 121 | .t delete 1.0 end |
97 | 122 | } -body { |
98 | 123 | .t insert end "This is the first line" |
101 | 126 | .t window create 2.2 -window .f -stretch 1 |
102 | 127 | update |
103 | 128 | list [winfo geom .f] [.t window configure .f -stretch] |
104 | } -result {5x13+19+18 {-stretch {} {} 0 1}} | |
129 | } -result [list \ | |
130 | 5x$fixedHeight+[expr {$padx+2*$fixedWidth}]+[expr {$pady+$fixedHeight}] \ | |
131 | {-stretch {} {} 0 1}] | |
105 | 132 | |
106 | 133 | |
107 | 134 | .t delete 1.0 end |
300 | 327 | } -cleanup { |
301 | 328 | destroy .f |
302 | 329 | } -returnCodes error -result {unknown option "-foo"} |
303 | test textWind-3.2 {EmbWinConfigure procedure} -constraints fonts -setup { | |
330 | ||
331 | test textWind-3.2 {EmbWinConfigure procedure} -setup { | |
304 | 332 | destroy .f |
305 | 333 | } -body { |
306 | 334 | .t insert 1.0 "Some sample text" |
313 | 341 | } -cleanup { |
314 | 342 | destroy .f |
315 | 343 | } -returnCodes error -result {bad text index ".f"} |
316 | test textWind-3.3 {EmbWinConfigure procedure} -constraints fonts -setup { | |
344 | ||
345 | test textWind-3.3 {EmbWinConfigure procedure} -setup { | |
317 | 346 | destroy .f |
318 | 347 | } -body { |
319 | 348 | .t insert 1.0 "Some sample text" |
326 | 355 | list [winfo ismapped .f] [.t bbox 1.4] |
327 | 356 | } -cleanup { |
328 | 357 | destroy .f |
329 | } -result {0 {26 5 7 13}} | |
330 | test textWind-3.4 {EmbWinConfigure procedure} -constraints fonts -setup { | |
358 | } -result [list 0 \ | |
359 | [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]] | |
360 | ||
361 | test textWind-3.4 {EmbWinConfigure procedure} -setup { | |
331 | 362 | destroy .t.f |
332 | 363 | } -body { |
333 | 364 | .t insert 1.0 "Some sample text" |
340 | 371 | } -cleanup { |
341 | 372 | destroy .t.f |
342 | 373 | } -returnCodes error -result {bad text index ".t.f"} |
343 | test textWind-3.5 {EmbWinConfigure procedure} -constraints fonts -setup { | |
374 | ||
375 | test textWind-3.5 {EmbWinConfigure procedure} -setup { | |
344 | 376 | destroy .t.f |
345 | 377 | } -body { |
346 | 378 | .t insert 1.0 "Some sample text" |
353 | 385 | list [winfo ismapped .t.f] [.t bbox 1.4] |
354 | 386 | } -cleanup { |
355 | 387 | destroy .t.f |
356 | } -result {0 {26 5 7 13}} | |
357 | test textWind-3.6 {EmbWinConfigure procedure} -constraints fonts -setup { | |
388 | } -result [list 0 \ | |
389 | [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight]] | |
390 | ||
391 | test textWind-3.6 {EmbWinConfigure procedure} -setup { | |
358 | 392 | destroy .f |
359 | 393 | } -body { |
360 | 394 | .t insert 1.0 "Some sample text" |
366 | 400 | list [catch {.t index .f} msg] $msg [winfo ismapped .f] [.t bbox 1.4] |
367 | 401 | } -cleanup { |
368 | 402 | destroy .f |
369 | } -result {0 1.3 1 {36 8 7 13}} | |
403 | } -result [list 0 1.3 1 \ | |
404 | [list [expr {$padx+3*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]] | |
405 | ||
370 | 406 | test textWind-3.7 {EmbWinConfigure procedure} -setup { |
371 | 407 | destroy .f |
372 | 408 | } -body { |
449 | 485 | .t window configure 1.0 -align |
450 | 486 | } -result {-align {} {} center top} |
451 | 487 | |
452 | ||
453 | test textWind-5.1 {EmbWinStructureProc procedure} -constraints fonts -setup { | |
488 | test textWind-5.1 {EmbWinStructureProc procedure} -setup { | |
454 | 489 | .t delete 1.0 end |
455 | 490 | destroy .f |
456 | 491 | } -body { |
461 | 496 | destroy .f |
462 | 497 | .t index .f |
463 | 498 | } -returnCodes error -result {bad text index ".f"} |
464 | test textWind-5.2 {EmbWinStructureProc procedure} -constraints fonts -setup { | |
499 | ||
500 | test textWind-5.2 {EmbWinStructureProc procedure} -setup { | |
465 | 501 | .t delete 1.0 end |
466 | 502 | destroy .f |
467 | 503 | } -body { |
472 | 508 | destroy .f |
473 | 509 | catch {.t index .f} |
474 | 510 | list [.t bbox 1.2] [.t bbox 1.3] |
475 | } -result {{19 11 0 0} {19 5 7 13}} | |
476 | test textWind-5.3 {EmbWinStructureProc procedure} -constraints fonts -setup { | |
511 | } -result [list \ | |
512 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \ | |
513 | [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]] | |
514 | ||
515 | test textWind-5.3 {EmbWinStructureProc procedure} -setup { | |
477 | 516 | .t delete 1.0 end |
478 | 517 | destroy .f |
479 | 518 | } -body { |
485 | 524 | destroy .f |
486 | 525 | .t index .f |
487 | 526 | } -returnCodes error -result {bad text index ".f"} |
488 | test textWind-5.4 {EmbWinStructureProc procedure} -constraints fonts -setup { | |
527 | ||
528 | test textWind-5.4 {EmbWinStructureProc procedure} -setup { | |
489 | 529 | .t delete 1.0 end |
490 | 530 | } -body { |
491 | 531 | .t insert 1.0 "Some sample text" |
496 | 536 | destroy .f |
497 | 537 | catch {.t index .f} |
498 | 538 | list [.t bbox 1.2] [.t bbox 1.3] |
499 | } -result {{19 18 0 0} {19 5 7 13}} | |
500 | test textWind-5.5 {EmbWinStructureProc procedure} -constraints fonts -setup { | |
539 | } -result [list \ | |
540 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+$fixedHeight}] 0 0] \ | |
541 | [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight]] | |
542 | ||
543 | test textWind-5.5 {EmbWinStructureProc procedure} -setup { | |
501 | 544 | .t delete 1.0 end |
502 | 545 | destroy .f |
503 | 546 | } -body { |
508 | 551 | destroy .f |
509 | 552 | update |
510 | 553 | list [catch {.t index .f} msg] $msg [.t bbox 1.2] [.t bbox 1.3] |
511 | } -result {0 1.2 {19 6 20 10} {39 5 7 13}} | |
512 | ||
513 | ||
514 | test textWind-6.1 {EmbWinRequestProc procedure} -constraints fonts -setup { | |
554 | } -result [list 0 1.2 \ | |
555 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+(($fixedHeight-10)/2)}] 20 10] \ | |
556 | [list [expr {$padx+2*$fixedWidth+20}] $pady $fixedWidth $fixedHeight]] | |
557 | ||
558 | ||
559 | test textWind-6.1 {EmbWinRequestProc procedure} -setup { | |
515 | 560 | .t delete 1.0 end |
516 | 561 | destroy .f |
517 | 562 | set result {} |
524 | 569 | lappend result [.t bbox 1.2] [.t bbox 1.3] |
525 | 570 | } -cleanup { |
526 | 571 | destroy .f |
527 | } -result {{19 5 10 20} {29 8 7 13} {19 5 25 30} {44 13 7 13}} | |
528 | ||
529 | ||
530 | test textWind-7.1 {EmbWinLostSlaveProc procedure} -constraints { | |
531 | textfonts | |
532 | } -setup { | |
572 | } -result [list \ | |
573 | [list [expr {$padx+2*$fixedWidth}] $pady 10 20] \ | |
574 | [list [expr {$padx+2*$fixedWidth+10}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight] \ | |
575 | [list [expr {$padx+2*$fixedWidth}] $pady 25 30] \ | |
576 | [list [expr {$padx+2*$fixedWidth+25}] [expr {$pady+((30-$fixedHeight)/2)}] $fixedWidth $fixedHeight]] | |
577 | ||
578 | ||
579 | test textWind-7.1 {EmbWinLostSlaveProc procedure} -setup { | |
533 | 580 | .t delete 1.0 end |
534 | 581 | destroy .f |
535 | 582 | } -body { |
542 | 589 | list [winfo geom .f] [.t bbox 1.2] |
543 | 590 | } -cleanup { |
544 | 591 | destroy .f |
545 | } -result [list 10x20+105+55 [list 19 [expr {11+$fixedDiff/2}] 0 0]] | |
546 | test textWind-7.2 {EmbWinLostSlaveProc procedure} -constraints { | |
547 | textfonts | |
548 | } -setup { | |
592 | } -result [list \ | |
593 | 10x20+[expr {$padx+100}]+[expr {$pady+50}] \ | |
594 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]] | |
595 | ||
596 | test textWind-7.2 {EmbWinLostSlaveProc procedure} -setup { | |
549 | 597 | .t delete 1.0 end |
550 | 598 | destroy .t.f |
551 | 599 | } -body { |
558 | 606 | list [winfo geom .t.f] [.t bbox 1.2] |
559 | 607 | } -cleanup { |
560 | 608 | destroy .t.f |
561 | } -result [list 10x20+105+55 [list 19 [expr {11+$fixedDiff/2}] 0 0]] | |
562 | ||
563 | ||
564 | test textWind-8.1 {EmbWinDeleteProc procedure} -constraints fonts -setup { | |
609 | } -result [list \ | |
610 | 10x20+[expr {$padx+100}]+[expr {$pady+50}] \ | |
611 | [list [expr {$padx+2*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]] | |
612 | ||
613 | test textWind-8.1 {EmbWinDeleteProc procedure} -setup { | |
565 | 614 | .t delete 1.0 end |
566 | 615 | destroy .f |
567 | 616 | } -body { |
572 | 621 | set x XXX |
573 | 622 | .t delete 1.2 |
574 | 623 | list $x [.t bbox 1.2] [.t bbox 1.3] [winfo exists .f] |
575 | } -result {destroyed {19 5 7 13} {26 5 7 13} 0} | |
576 | test textWind-8.2 {EmbWinDeleteProc procedure} -constraints fonts -setup { | |
624 | } -result [list destroyed \ | |
625 | [list [expr {$padx+2*$fixedWidth}] $pady $fixedWidth $fixedHeight] \ | |
626 | [list [expr {$padx+3*$fixedWidth}] $pady $fixedWidth $fixedHeight] \ | |
627 | 0] | |
628 | ||
629 | test textWind-8.2 {EmbWinDeleteProc procedure} -setup { | |
577 | 630 | .t delete 1.0 end |
578 | 631 | destroy .f |
579 | 632 | } -body { |
614 | 667 | } -cleanup { |
615 | 668 | destroy .f |
616 | 669 | } -result {1 10 20 1.5} |
617 | test textWind-10.2 {EmbWinLayoutProc procedure, error in creating window} -constraints { | |
618 | fonts | |
619 | } -setup { | |
670 | ||
671 | test textWind-10.2 {EmbWinLayoutProc procedure, error in creating window} -setup { | |
620 | 672 | .t delete 1.0 end |
621 | 673 | proc bgerror args { |
622 | 674 | global msg |
624 | 676 | } |
625 | 677 | } -body { |
626 | 678 | .t insert 1.0 "Some sample text" |
627 | .t window create 1.5 -create { | |
679 | .t window create 1.5 -create { | |
628 | 680 | error "couldn't create window" |
629 | 681 | } |
630 | 682 | set msg xyzzy |
632 | 684 | list $msg [.t bbox 1.5] |
633 | 685 | } -cleanup { |
634 | 686 | rename bgerror {} |
635 | } -result {{{couldn't create window}} {40 11 0 0}} | |
636 | test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} -constraints { | |
637 | fonts | |
638 | } -setup { | |
687 | } -result [list \ | |
688 | {{couldn't create window}} \ | |
689 | [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]] | |
690 | ||
691 | test textWind-10.3 {EmbWinLayoutProc procedure, error in creating window} -setup { | |
639 | 692 | .t delete 1.0 end |
640 | 693 | proc bgerror args { |
641 | 694 | global msg |
651 | 704 | list $msg [.t bbox 1.5] |
652 | 705 | } -cleanup { |
653 | 706 | rename bgerror {} |
654 | } -result {{{bad window path name "gorp"}} {40 11 0 0}} | |
707 | } -result [list \ | |
708 | {{bad window path name "gorp"}} \ | |
709 | [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]] | |
710 | ||
711 | test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} -setup { | |
655 | 712 | .t delete 1.0 end |
656 | 713 | destroy .t.f |
657 | 714 | proc bgerror args { |
658 | 715 | global msg |
659 | if {[lsearch -exact $msg $args] == -1} { | |
660 | lappend msg $args | |
661 | } | |
662 | } | |
663 | ||
664 | test textWind-10.4 {EmbWinLayoutProc procedure, error in creating window} -constraints { | |
665 | textfonts | |
666 | } -setup { | |
667 | .t delete 1.0 end | |
668 | destroy .t.f | |
669 | proc bgerror args { | |
670 | global msg | |
671 | if {[lsearch -exact $msg $args] == -1} { | |
672 | lappend msg $args | |
673 | } | |
716 | lappend msg $args | |
674 | 717 | } |
675 | 718 | } -body { |
676 | 719 | .t insert 1.0 "Some sample text" |
692 | 735 | } -cleanup { |
693 | 736 | destroy .t.f |
694 | 737 | rename bgerror {} |
695 | } -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] | |
696 | test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} -constraints { | |
697 | textfonts | |
698 | } -setup { | |
738 | } -result [list \ | |
739 | {{can't embed .t.f.f relative to .t}} {{window name "f" already exists in parent}} \ | |
740 | [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0] \ | |
741 | 1] | |
742 | ||
743 | test textWind-10.5 {EmbWinLayoutProc procedure, error in creating window} -setup { | |
699 | 744 | .t delete 1.0 end |
700 | 745 | destroy .t.f |
746 | proc bgerror args { | |
747 | global msg | |
748 | lappend msg $args | |
749 | } | |
750 | } -body { | |
751 | .t insert 1.0 "Some sample text" | |
752 | .t window create 1.5 -create { | |
753 | frame .t.f | |
754 | frame .t.f.f -width 10 -height 20 -bg $color | |
755 | } | |
756 | set msg {} | |
757 | update idletasks | |
758 | lappend msg [winfo exists .t.f.f] | |
759 | } -cleanup { | |
760 | destroy .t.f | |
761 | rename bgerror {} | |
762 | } -result {{{can't embed .t.f.f relative to .t}} 1} | |
763 | ||
764 | test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} -setup { | |
765 | .t delete 1.0 end | |
701 | 766 | proc bgerror args { |
702 | 767 | global msg |
703 | 768 | if {[lsearch -exact $msg $args] == -1} { |
706 | 771 | } |
707 | 772 | } -body { |
708 | 773 | .t insert 1.0 "Some sample text" |
709 | .t window create 1.5 -create { | |
710 | frame .t.f | |
711 | frame .t.f.f -width 10 -height 20 -bg $color | |
712 | } | |
713 | set msg {} | |
714 | update idletasks | |
715 | lappend msg [winfo exists .t.f.f] | |
716 | } -cleanup { | |
717 | destroy .t.f | |
718 | rename bgerror {} | |
719 | } -result {{{can't embed .t.f.f relative to .t}} 1} | |
720 | catch {destroy .t.f} | |
721 | test textWind-10.6 {EmbWinLayoutProc procedure, error in creating window} -constraints { | |
722 | textfonts | |
723 | } -setup { | |
724 | .t delete 1.0 end | |
725 | proc bgerror args { | |
726 | global msg | |
727 | if {[lsearch -exact $msg $args] == -1} { | |
728 | lappend msg $args | |
729 | } | |
730 | } | |
731 | } -body { | |
732 | .t insert 1.0 "Some sample text" | |
774 | update | |
733 | 775 | .t window create 1.5 -create { |
734 | 776 | concat .t |
735 | 777 | } |
738 | 780 | lappend msg [.t bbox 1.5] |
739 | 781 | } -cleanup { |
740 | 782 | rename bgerror {} |
741 | } -result [list {{can't embed .t relative to .t}} [list 40 [expr {11+$fixedDiff/2}] 0 0]] | |
742 | test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -constraints { | |
743 | textfonts | |
744 | } -setup { | |
783 | } -result [list \ | |
784 | {{can't embed .t relative to .t}} \ | |
785 | [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]] | |
786 | ||
787 | test textWind-10.7 {EmbWinLayoutProc procedure, error in creating window} -setup { | |
745 | 788 | .t delete 1.0 end |
746 | 789 | destroy .t2 |
747 | 790 | proc bgerror args { |
748 | 791 | global msg |
749 | if {[lsearch -exact $msg $args] == -1} { | |
750 | lappend msg $args | |
751 | } | |
792 | lappend msg $args | |
752 | 793 | } |
753 | 794 | } -body { |
754 | 795 | .t insert 1.0 "Some sample text" |
762 | 803 | lappend msg [.t bbox 1.5] |
763 | 804 | } -cleanup { |
764 | 805 | rename bgerror {} |
765 | } -result [list {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} [list 40 [expr {11+$fixedDiff/2}] 0 0]] | |
806 | } -result [list \ | |
807 | {{can't embed .t2 relative to .t}} {{window name "t2" already exists in parent}} \ | |
808 | [list [expr {$padx+5*$fixedWidth}] [expr {$pady+($fixedHeight/2)}] 0 0]] | |
809 | ||
766 | 810 | test textWind-10.8 {EmbWinLayoutProc procedure, error in creating window} -setup { |
767 | 811 | .t delete 1.0 end |
768 | 812 | destroy .t2 |
769 | 813 | proc bgerror args { |
770 | 814 | global msg |
771 | if {[lsearch -exact $msg $args] == -1} { | |
772 | lappend msg $args | |
773 | } | |
815 | lappend msg $args | |
774 | 816 | } |
775 | 817 | } -body { |
776 | 818 | .t insert 1.0 "Some sample text" |
803 | 845 | } -cleanup { |
804 | 846 | destroy .t.b |
805 | 847 | } -result {1.3} |
806 | test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints { | |
807 | fonts | |
808 | } -setup { | |
848 | ||
849 | test textWind-10.10 {EmbWinLayoutProc procedure, doesn't fit on line} -setup { | |
809 | 850 | .t delete 1.0 end |
810 | 851 | destroy .f |
811 | 852 | } -body { |
816 | 857 | list [.t bbox .f] [.t bbox 1.13] |
817 | 858 | } -cleanup { |
818 | 859 | destroy .f |
819 | } -result {{89 5 126 20} {5 25 7 13}} | |
820 | test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints { | |
821 | fonts | |
822 | } -setup { | |
860 | } -result [list \ | |
861 | [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \ | |
862 | [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]] | |
863 | ||
864 | test textWind-10.11 {EmbWinLayoutProc procedure, doesn't fit on line} -setup { | |
823 | 865 | .t delete 1.0 end |
824 | 866 | destroy .f |
825 | 867 | } -body { |
831 | 873 | list [.t bbox .f] [.t bbox 1.13] |
832 | 874 | } -cleanup { |
833 | 875 | destroy .f |
834 | } -result {{89 5 126 20} {5 25 7 13}} | |
835 | test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints { | |
836 | fonts | |
837 | } -setup { | |
876 | } -result [list \ | |
877 | [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \ | |
878 | [list $padx [expr {$pady+20}] $fixedWidth $fixedHeight]] | |
879 | ||
880 | test textWind-10.12 {EmbWinLayoutProc procedure, doesn't fit on line} -setup { | |
838 | 881 | .t delete 1.0 end |
839 | 882 | destroy .f |
840 | 883 | } -body { |
846 | 889 | list [.t bbox .f] [.t bbox 1.13] |
847 | 890 | } -cleanup { |
848 | 891 | destroy .f |
849 | } -result {{5 18 127 20} {132 21 7 13}} | |
892 | } -result [list \ | |
893 | [list $padx [expr {$pady+$fixedHeight}] 127 20] \ | |
894 | [list [expr {$padx+127}] [expr {$pady+$fixedHeight+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]] | |
895 | ||
850 | 896 | test textWind-10.13 {EmbWinLayoutProc procedure, doesn't fit on line} -setup { |
851 | 897 | .t delete 1.0 end |
852 | 898 | destroy .f |
859 | 905 | list [.t bbox .f] [.t bbox 1.13] |
860 | 906 | } -cleanup { |
861 | 907 | destroy .f |
862 | } -result {{89 5 126 20} {}} | |
863 | test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints { | |
864 | fonts | |
865 | } -setup { | |
908 | } -result [list \ | |
909 | [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] 20] \ | |
910 | {}] | |
911 | ||
912 | test textWind-10.14 {EmbWinLayoutProc procedure, doesn't fit on line} -setup { | |
866 | 913 | .t delete 1.0 end |
867 | 914 | destroy .f |
868 | 915 | } -body { |
874 | 921 | list [.t bbox .f] [.t bbox 1.13] |
875 | 922 | } -cleanup { |
876 | 923 | destroy .f |
877 | } -result {{89 5 126 78} {}} | |
878 | test textWind-10.15 {EmbWinLayoutProc procedure, doesn't fit on line} -constraints { | |
879 | fonts | |
880 | } -setup { | |
924 | } -result [list \ | |
925 | [list [expr {$padx+12*$fixedWidth}] $pady [expr {$tWidth*$fixedWidth-12*$fixedWidth}] [expr {$tHeight*$fixedHeight}]] \ | |
926 | {}] | |
927 | ||
928 | test textWind-10.15 {EmbWinLayoutProc procedure, doesn't fit on line} -setup { | |
881 | 929 | .t delete 1.0 end |
882 | 930 | destroy .f |
883 | 931 | } -body { |
889 | 937 | list [.t bbox .f] [.t bbox 1.13] |
890 | 938 | } -cleanup { |
891 | 939 | destroy .f |
892 | } -result {{5 18 210 65} {}} | |
893 | ||
940 | } -result [list \ | |
941 | [list $padx [expr {$pady+$fixedHeight}] [expr {$tWidth*$fixedWidth}] [expr {($tHeight-1)*$fixedHeight}]] \ | |
942 | {}] | |
894 | 943 | |
895 | 944 | test textWind-11.1 {EmbWinDisplayProc procedure, geometry transforms} -setup { |
896 | 945 | .t delete 1.0 end |
908 | 957 | } -cleanup { |
909 | 958 | destroy .f |
910 | 959 | place forget .t |
911 | } -result {30x20+119+55} | |
960 | } -result [list 30x20+[expr {$padx+30+12*$fixedWidth}]+[expr {$pady+50}]] | |
961 | ||
912 | 962 | test textWind-11.2 {EmbWinDisplayProc procedure, geometry transforms} -setup { |
913 | 963 | .t delete 1.0 end |
914 | 964 | destroy .t.f |
926 | 976 | destroy .t.f |
927 | 977 | place forget .t |
928 | 978 | pack .t |
929 | } -result {30x20+89+5} | |
979 | } -result [list 30x20+[expr {$padx+12*$fixedWidth}]+$pady] | |
980 | ||
930 | 981 | test textWind-11.3 {EmbWinDisplayProc procedure, configuration optimization} -setup { |
931 | 982 | .t delete 1.0 end |
932 | 983 | destroy .f |
948 | 999 | place forget .t |
949 | 1000 | pack .t |
950 | 1001 | } -result {no configures} |
951 | test textWind-11.4 {EmbWinDisplayProc procedure, horizontal scrolling} -constraints { | |
952 | fonts | |
953 | } -setup { | |
1002 | ||
1003 | test textWind-11.4 {EmbWinDisplayProc procedure, horizontal scrolling} -setup { | |
954 | 1004 | .t delete 1.0 end |
955 | 1005 | destroy .f .f2 |
956 | 1006 | } -body { |
968 | 1018 | list [winfo ismapped .f] [winfo geom .f] [.t bbox .f] [winfo ismapped .f2] |
969 | 1019 | } -cleanup { |
970 | 1020 | destroy .f .f2 |
971 | } -result {1 30x20+103+18 {103 18 30 20} 0} | |
972 | test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} -constraints { | |
973 | fonts | |
974 | } -setup { | |
1021 | } -result [list 1 \ | |
1022 | 30x20+[expr {$padx+14*$fixedWidth}]+[expr {$pady+$fixedHeight}] \ | |
1023 | [list [expr {$padx+14*$fixedWidth}] [expr {$pady+$fixedHeight}] 30 20] \ | |
1024 | 0] | |
1025 | ||
1026 | test textWind-11.5 {EmbWinDisplayProc procedure, horizontal scrolling} -setup { | |
975 | 1027 | .t delete 1.0 end |
976 | 1028 | destroy .f .f2 |
977 | 1029 | } -body { |
989 | 1041 | update |
990 | 1042 | list [winfo ismapped .f] [winfo ismapped .f2] [winfo geom .f2] [.t bbox .f2] |
991 | 1043 | } -cleanup { |
992 | destroy .f .f2 | |
993 | } -result {0 1 40x10+119+23 {119 23 40 10}} | |
994 | .t configure -wrap char | |
995 | ||
1044 | destroy .f .f2 | |
1045 | .t configure -wrap char | |
1046 | } -result [list 0 1 \ | |
1047 | 40x10+[expr {$padx+37*$fixedWidth+30-25*$fixedWidth}]+[expr {$pady+$fixedHeight+((20-10)/2)}] \ | |
1048 | [list [expr {$padx+37*$fixedWidth+30-25*$fixedWidth}] [expr {$pady+$fixedHeight+((20-10)/2)}] 40 10]] | |
996 | 1049 | |
997 | 1050 | test textWind-12.1 {EmbWinUndisplayProc procedure, mapping/unmapping} -setup { |
998 | 1051 | .t delete 1.0 end |
1034 | 1087 | list [winfo geom .f] [.t bbox .f] |
1035 | 1088 | } -cleanup { |
1036 | 1089 | destroy .f |
1037 | } -result {5x5+21+6 {21 6 5 5}} | |
1038 | test textWind-13.2 {EmbWinBboxProc procedure} -constraints fonts -setup { | |
1090 | } -result [list \ | |
1091 | 5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \ | |
1092 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 5]] | |
1093 | ||
1094 | test textWind-13.2 {EmbWinBboxProc procedure} -setup { | |
1039 | 1095 | .t delete 1.0 end |
1040 | 1096 | destroy .f |
1041 | 1097 | } -body { |
1046 | 1102 | list [winfo geom .f] [.t bbox .f] |
1047 | 1103 | } -cleanup { |
1048 | 1104 | destroy .f |
1049 | } -result {5x5+21+9 {21 9 5 5}} | |
1050 | test textWind-13.3 {EmbWinBboxProc procedure} -constraints fonts -setup { | |
1105 | } -result [list \ | |
1106 | 5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+(($fixedHeight-7)/2)}] \ | |
1107 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+(($fixedHeight-7)/2)}] 5 5]] | |
1108 | ||
1109 | test textWind-13.3 {EmbWinBboxProc procedure} -setup { | |
1051 | 1110 | .t delete 1.0 end |
1052 | 1111 | destroy .f |
1053 | 1112 | } -body { |
1058 | 1117 | list [winfo geom .f] [.t bbox .f] |
1059 | 1118 | } -cleanup { |
1060 | 1119 | destroy .f |
1061 | } -result {5x5+21+10 {21 10 5 5}} | |
1062 | test textWind-13.4 {EmbWinBboxProc procedure} -constraints fonts -setup { | |
1120 | } -result [list \ | |
1121 | 5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedAscent-6)}] \ | |
1122 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedAscent-6)}] 5 5]] | |
1123 | ||
1124 | test textWind-13.4 {EmbWinBboxProc procedure} -setup { | |
1063 | 1125 | .t delete 1.0 end |
1064 | 1126 | destroy .f |
1065 | 1127 | } -body { |
1070 | 1132 | list [winfo geom .f] [.t bbox .f] |
1071 | 1133 | } -cleanup { |
1072 | 1134 | destroy .f |
1073 | } -result {5x5+21+12 {21 12 5 5}} | |
1074 | test textWind-13.5 {EmbWinBboxProc procedure} -constraints fonts -setup { | |
1135 | } -result [list \ | |
1136 | 5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1+($fixedHeight-7)}] \ | |
1137 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1+($fixedHeight-7)}] 5 5]] | |
1138 | ||
1139 | test textWind-13.5 {EmbWinBboxProc procedure} -setup { | |
1075 | 1140 | .t delete 1.0 end |
1076 | 1141 | destroy .f |
1077 | 1142 | } -body { |
1082 | 1147 | list [winfo geom .f] [.t bbox .f] |
1083 | 1148 | } -cleanup { |
1084 | 1149 | destroy .f |
1085 | } -result {5x11+21+6 {21 6 5 11}} | |
1086 | test textWind-13.6 {EmbWinBboxProc procedure} -constraints fonts -setup { | |
1150 | } -result [list \ | |
1151 | 5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \ | |
1152 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]] | |
1153 | ||
1154 | test textWind-13.6 {EmbWinBboxProc procedure} -setup { | |
1087 | 1155 | .t delete 1.0 end |
1088 | 1156 | destroy .f |
1089 | 1157 | } -body { |
1094 | 1162 | list [winfo geom .f] [.t bbox .f] |
1095 | 1163 | } -cleanup { |
1096 | 1164 | destroy .f |
1097 | } -result {5x11+21+6 {21 6 5 11}} | |
1098 | test textWind-13.7 {EmbWinBboxProc procedure} -constraints fonts -setup { | |
1165 | } -result [list \ | |
1166 | 5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \ | |
1167 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]] | |
1168 | ||
1169 | test textWind-13.7 {EmbWinBboxProc procedure} -setup { | |
1099 | 1170 | .t delete 1.0 end |
1100 | 1171 | destroy .f |
1101 | 1172 | } -body { |
1106 | 1177 | list [winfo geom .f] [.t bbox .f] |
1107 | 1178 | } -cleanup { |
1108 | 1179 | destroy .f |
1109 | } -result {5x9+21+6 {21 6 5 9}} | |
1110 | test textWind-13.8 {EmbWinBboxProc procedure} -constraints fonts -setup { | |
1180 | } -result [list \ | |
1181 | 5x[expr {$fixedAscent-1}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \ | |
1182 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedAscent-1}]]] | |
1183 | ||
1184 | test textWind-13.8 {EmbWinBboxProc procedure} -setup { | |
1111 | 1185 | .t delete 1.0 end |
1112 | 1186 | destroy .f |
1113 | 1187 | } -body { |
1118 | 1192 | list [winfo geom .f] [.t bbox .f] |
1119 | 1193 | } -cleanup { |
1120 | 1194 | destroy .f |
1121 | } -result {5x11+21+6 {21 6 5 11}} | |
1122 | test textWind-13.9 {EmbWinBboxProc procedure, spacing options} -constraints { | |
1123 | fonts | |
1124 | } -setup { | |
1195 | } -result [list \ | |
1196 | 5x[expr {$fixedHeight-2}]+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+1}] \ | |
1197 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+1}] 5 [expr {$fixedHeight-2}]]] | |
1198 | ||
1199 | test textWind-13.9 {EmbWinBboxProc procedure, spacing options} -setup { | |
1125 | 1200 | .t delete 1.0 end |
1126 | 1201 | destroy .f |
1127 | 1202 | } -body { |
1133 | 1208 | update |
1134 | 1209 | list [winfo geom .f] [.t bbox .f] |
1135 | 1210 | } -cleanup { |
1136 | destroy .f | |
1137 | } -result {5x5+21+14 {21 14 5 5}} | |
1211 | .t configure -spacing1 0 -spacing3 0 | |
1212 | destroy .f | |
1213 | } -result [list \ | |
1214 | 5x5+[expr {$padx+2*$fixedWidth+2}]+[expr {$pady+5+(($fixedHeight-5)/2)}] \ | |
1215 | [list [expr {$padx+2*$fixedWidth+2}] [expr {$pady+5+(($fixedHeight-5)/2)}] 5 5]] | |
1138 | 1216 | |
1139 | 1217 | |
1140 | 1218 | test textWind-14.1 {EmbWinDelayedUnmap procedure} -setup { |
1156 | 1234 | } -cleanup { |
1157 | 1235 | destroy .f |
1158 | 1236 | } -result {modified removed unmapped updated} |
1237 | ||
1159 | 1238 | test textWind-14.2 {EmbWinDelayedUnmap procedure} -setup { |
1160 | 1239 | .t delete 1.0 end |
1161 | 1240 | destroy .f |
1175 | 1254 | } -cleanup { |
1176 | 1255 | destroy .f |
1177 | 1256 | } -result {modified deleted updated} |
1257 | ||
1178 | 1258 | test textWind-14.3 {EmbWinDelayedUnmap procedure} -setup { |
1179 | 1259 | .t delete 1.0 end |
1180 | 1260 | destroy .f |
1190 | 1270 | } -cleanup { |
1191 | 1271 | destroy .f |
1192 | 1272 | } -result {1 0} |
1273 | ||
1193 | 1274 | test textWind-14.4 {EmbWinDelayedUnmap procedure} -setup { |
1194 | 1275 | .t delete 1.0 end |
1195 | 1276 | destroy .t.f |
1206 | 1287 | destroy .t.f |
1207 | 1288 | } -result {1 0} |
1208 | 1289 | |
1209 | ||
1210 | 1290 | test textWind-15.1 {TkTextWindowIndex procedure} -setup { |
1211 | 1291 | .t delete 1.0 end |
1212 | 1292 | } -body { |
1213 | 1293 | .t index .foo |
1214 | 1294 | } -returnCodes error -result {bad text index ".foo"} |
1215 | test textWind-15.2 {TkTextWindowIndex procedure} -constraints fonts -setup { | |
1295 | ||
1296 | test textWind-15.2 {TkTextWindowIndex procedure} -setup { | |
1216 | 1297 | .t delete 1.0 end |
1217 | 1298 | destroy .f |
1218 | 1299 | } -body { |
1226 | 1307 | list [.t index .f] [.t bbox 1.7] |
1227 | 1308 | } -cleanup { |
1228 | 1309 | destroy .f |
1229 | } -result {1.6 {77 8 7 13}} | |
1310 | } -result [list 1.6 \ | |
1311 | [list [expr {$padx+6*$fixedWidth+30}] [expr {$pady+((20-$fixedHeight)/2)}] $fixedWidth $fixedHeight]] | |
1230 | 1312 | |
1231 | 1313 | |
1232 | 1314 | test textWind-16.1 {EmbWinTextStructureProc procedure} -setup { |
1244 | 1326 | } -cleanup { |
1245 | 1327 | pack .t |
1246 | 1328 | } -result 0 |
1329 | ||
1247 | 1330 | test textWind-16.2 {EmbWinTextStructureProc procedure} -setup { |
1248 | 1331 | .t delete 1.0 end |
1249 | 1332 | destroy .f .f2 |
1262 | 1345 | lappend result [winfo geom .f] [.t bbox .f] |
1263 | 1346 | } -cleanup { |
1264 | 1347 | destroy .f .f2 |
1265 | } -result {30x20+47+5 {47 5 30 20} 30x20+47+35 {47 5 30 20}} | |
1348 | } -result [list \ | |
1349 | 30x20+[expr {$padx+6*$fixedWidth}]+$pady \ | |
1350 | [list [expr {$padx+6*$fixedWidth}] $pady 30 20] \ | |
1351 | 30x20+[expr {$padx+6*$fixedWidth}]+[expr {$pady+30}] \ | |
1352 | [list [expr {$padx+6*$fixedWidth}] $pady 30 20]] | |
1353 | ||
1266 | 1354 | test textWind-16.3 {EmbWinTextStructureProc procedure} -setup { |
1267 | 1355 | .t delete 1.0 end |
1268 | 1356 | } -body { |
1275 | 1363 | } -cleanup { |
1276 | 1364 | pack .t |
1277 | 1365 | } -result {} |
1366 | ||
1278 | 1367 | test textWind-16.4 {EmbWinTextStructureProc procedure} -setup { |
1279 | 1368 | .t delete 1.0 end |
1280 | 1369 | } -body { |
1289 | 1378 | list [winfo ismapped .t.f] [.t bbox .t.f] |
1290 | 1379 | } -cleanup { |
1291 | 1380 | pack .t |
1292 | } -result {1 {47 5 30 20}} | |
1381 | } -result [list 1 [list [expr {$padx+6*$fixedWidth}] $pady 30 20]] | |
1293 | 1382 | |
1294 | 1383 | |
1295 | 1384 | test textWind-17.1 {peer widgets and embedded windows} -setup { |
60 | 60 | update ; # shall not trigger error invalid command name ".top.b" |
61 | 61 | } -result {} |
62 | 62 | |
63 | # Bug [fa8de77936] | |
64 | test checkbutton-1.8 "Empty -variable" -body { | |
65 | # shall simply not crash | |
66 | ttk::checkbutton .cbev -variable {} | |
67 | .cbev invoke | |
68 | } -cleanup { | |
69 | destroy .cbev | |
70 | } -result {} | |
71 | ||
63 | 72 | tcltest::cleanupTests |
20 | 20 | |
21 | 21 | } -cleanup { destroy .b } -result [list 24 24] |
22 | 22 | |
23 | test layout-2 "Empty -children not allowed" -body { | |
24 | ttk::style layout Test.Tentry {Entry.field -children {}} | |
25 | } -returnCodes error -result {Invalid -children value} | |
23 | 26 | |
24 | 27 | tcltest::cleanupTests |
64 | 64 | .s set 1 ; update |
65 | 65 | } -returnCodes 1 -match glob -result "*" |
66 | 66 | |
67 | test scale-2.1 "-state option" -setup { | |
68 | ttk::scale .s | |
69 | set res "" | |
70 | } -body { | |
71 | # defaults | |
72 | lappend res [.s instate disabled] [.s cget -state] | |
73 | # set -state: instate returns accordingly | |
74 | .s configure -state disabled | |
75 | lappend res [.s instate disabled] [.s cget -state] | |
76 | # back to normal | |
77 | .s configure -state normal | |
78 | lappend res [.s instate disabled] [.s cget -state] | |
79 | # use state command: -state does NOT reflect it | |
80 | .s state disabled | |
81 | lappend res [.s instate disabled] [.s cget -state] | |
82 | # further use state command | |
83 | .s state readonly | |
84 | lappend res [.s state] [.s cget -state] | |
85 | } -cleanup { | |
86 | destroy .s | |
87 | unset -nocomplain res | |
88 | } -result {0 normal 1 disabled 0 normal 1 normal {disabled readonly} normal} | |
89 | ||
67 | 90 | tcltest::cleanupTests |
68 | 91 |
107 | 107 | # ---------------------------------------------------------------------- |
108 | 108 | |
109 | 109 | test unixSelect-1.1 {TkSelGetSelection procedure: simple i18n text} -constraints { |
110 | unix | |
110 | x11 | |
111 | 111 | } -setup { |
112 | 112 | destroy .e |
113 | 113 | setupbg |
123 | 123 | } -result {4} |
124 | 124 | |
125 | 125 | test unixSelect-1.2 {TkSelGetSelection procedure: simple i18n text, iso8859-1} -constraints { |
126 | unix | |
126 | x11 | |
127 | 127 | } -setup { |
128 | 128 | setupbg |
129 | 129 | } -body { |
139 | 139 | } -result \u00fc? |
140 | 140 | |
141 | 141 | test unixSelect-1.3 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints { |
142 | unix | |
142 | x11 | |
143 | 143 | } -setup { |
144 | 144 | setupbg |
145 | 145 | setup |
159 | 159 | } -result {1 2 {COMPOUND_TEXT 0 4000}} |
160 | 160 | |
161 | 161 | test unixSelect-1.4 {TkSelGetSelection procedure: INCR i18n text, iso2022} -constraints { |
162 | unix | |
162 | x11 | |
163 | 163 | } -setup { |
164 | 164 | setupbg |
165 | 165 | setup |
185 | 185 | } -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}} |
186 | 186 | |
187 | 187 | test unixSelect-1.5 {TkSelGetSelection procedure: simple i18n text, iso2022} -constraints { |
188 | unix | |
188 | x11 | |
189 | 189 | } -setup { |
190 | 190 | setupbg |
191 | 191 | setup |
205 | 205 | } -result {1 2 {COMPOUND_TEXT 0 4000}} |
206 | 206 | |
207 | 207 | test unixSelect-1.6 {TkSelGetSelection procedure: INCR i18n text} -constraints { |
208 | unix | |
208 | x11 | |
209 | 209 | } -setup { |
210 | 210 | setupbg |
211 | 211 | } -body { |
218 | 218 | } -result [expr {4 + [string length $longValue]}] |
219 | 219 | |
220 | 220 | test unixSelect-1.7 {TkSelGetSelection procedure: INCR i18n text} -constraints { |
221 | unix | |
221 | x11 | |
222 | 222 | } -setup { |
223 | 223 | setupbg |
224 | 224 | } -body { |
234 | 234 | } -result [string repeat x 3999]\u00fc |
235 | 235 | |
236 | 236 | test unixSelect-1.8 {TkSelGetSelection procedure: INCR i18n text} -constraints { |
237 | unix | |
237 | x11 | |
238 | 238 | } -setup { |
239 | 239 | setupbg |
240 | 240 | } -body { |
250 | 250 | } -result \u00fc[string repeat x 3999] |
251 | 251 | |
252 | 252 | test unixSelect-1.9 {TkSelGetSelection procedure: INCR i18n text} -constraints { |
253 | unix | |
253 | x11 | |
254 | 254 | } -setup { |
255 | 255 | setupbg |
256 | 256 | } -body { |
269 | 269 | # from rearing its ugly head again. |
270 | 270 | |
271 | 271 | test unixSelect-1.10 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints { |
272 | unix | |
272 | x11 | |
273 | 273 | } -setup { |
274 | 274 | setupbg |
275 | 275 | } -body { |
285 | 285 | } -result [string repeat x 3999]\u00fc |
286 | 286 | |
287 | 287 | test unixSelect-1.11 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints { |
288 | unix | |
288 | x11 | |
289 | 289 | } -setup { |
290 | 290 | setupbg |
291 | 291 | } -body { |
301 | 301 | } -result \u00fc[string repeat x 3999] |
302 | 302 | |
303 | 303 | test unixSelect-1.12 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints { |
304 | unix | |
304 | x11 | |
305 | 305 | } -setup { |
306 | 306 | setupbg |
307 | 307 | } -body { |
317 | 317 | } -result [string repeat x 3999]\u00fc[string repeat x 4000] |
318 | 318 | |
319 | 319 | test unixSelect-1.13 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints { |
320 | unix | |
320 | x11 | |
321 | 321 | } -setup { |
322 | 322 | destroy .e |
323 | 323 | setupbg |
333 | 333 | } -result {5} |
334 | 334 | |
335 | 335 | test unixSelect-1.14 {TkSelGetSelection procedure: simple i18n text, utf-8} -constraints { |
336 | unix | |
336 | x11 | |
337 | 337 | } -setup { |
338 | 338 | setupbg |
339 | 339 | } -body { |
349 | 349 | } -result \u00fc\u0444 |
350 | 350 | |
351 | 351 | test unixSelect-1.15 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints { |
352 | unix | |
352 | x11 | |
353 | 353 | } -setup { |
354 | 354 | setupbg |
355 | 355 | } -body { |
365 | 365 | } -result [string repeat [string repeat \u00c4\u00e4 50]\n 21] |
366 | 366 | |
367 | 367 | test unixSelect-1.16 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints { |
368 | unix | |
368 | x11 | |
369 | 369 | } -setup { |
370 | 370 | setupbg |
371 | 371 | } -body { |
381 | 381 | } -result i[string repeat [string repeat \u00c4\u00e4 50]\n 21] |
382 | 382 | |
383 | 383 | test unixSelect-1.17 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints { |
384 | unix | |
384 | x11 | |
385 | 385 | } -setup { |
386 | 386 | setupbg |
387 | 387 | } -body { |
399 | 399 | } -result [string repeat [string repeat \u00c4\u00e4 50]\n 21] |
400 | 400 | |
401 | 401 | test unixSelect-1.18 {TkSelGetSelection procedure: INCR i18n text, utf-8} -constraints { |
402 | unix | |
402 | x11 | |
403 | 403 | } -setup { |
404 | 404 | setupbg |
405 | 405 | } -body { |
139 | 139 | } -result {bad attribute "_": must be -alpha, -topmost, -zoomed, -fullscreen, or -type} |
140 | 140 | test wm-attributes-1.2.5 {usage} -constraints aqua -returnCodes error -body { |
141 | 141 | wm attributes . _ |
142 | } -result {bad attribute "_": must be -alpha, -modified, -notify, or -titlepath} | |
142 | } -result {bad attribute "_": must be -alpha, -fullscreen, -modified, -notify, -titlepath, -topmost, or -transparent} | |
143 | 143 | |
144 | 144 | |
145 | 145 | ### wm client ### |
736 | 736 | test wm-iconbitmap-1.3 {usage} -constraints win -returnCodes error -body { |
737 | 737 | wm iconbitmap .t 12 13 |
738 | 738 | } -result {illegal option "12" must be "-default"} |
739 | test wm-iconbitmap-1.4 {usage} -returnCodes error -body { | |
739 | test wm-iconbitmap-1.4 {usage} -constraints notAqua -returnCodes error -body { | |
740 | 740 | wm iconbitmap .t bad-bitmap |
741 | 741 | } -result {bitmap "bad-bitmap" not defined} |
742 | 742 | |
743 | test wm-iconbitmap-2.1 {setting and reading values} -setup { | |
743 | test wm-iconbitmap-2.1 {setting and reading values} -constraints notAqua -setup { | |
744 | 744 | set result {} |
745 | 745 | } -body { |
746 | 746 | lappend result [wm iconbitmap .t] |
1241 | 1241 | } -result {expected boolean value but got "bad"} |
1242 | 1242 | |
1243 | 1243 | test wm-resizable-2.1 {setting and reading values} { |
1244 | wm resizable .t 0 0 | |
1245 | set result [wm resizable .t] | |
1244 | 1246 | wm resizable .t 0 1 |
1245 | set result [wm resizable .t] | |
1247 | lappend result [wm resizable .t] | |
1246 | 1248 | wm resizable .t 1 0 |
1247 | 1249 | lappend result [wm resizable .t] |
1248 | 1250 | wm resizable .t 1 1 |
1249 | 1251 | lappend result [wm resizable .t] |
1250 | } {0 1 {1 0} {1 1}} | |
1252 | } {0 0 {0 1} {1 0} {1 1}} | |
1251 | 1253 | |
1252 | 1254 | |
1253 | 1255 | ### wm sizefrom ### |
186 | 186 | # Tk does not used deprecated Tcl constructs so it should |
187 | 187 | # compile fine with -DTCL_NO_DEPRECATED. To remove its own |
188 | 188 | # set of deprecated code uncomment the second line. |
189 | NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED | |
190 | #NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED | |
189 | NO_DEPRECATED_FLAGS = | |
190 | #NO_DEPRECATED_FLAGS = -DTK_NO_DEPRECATED | |
191 | 191 | |
192 | 192 | # Some versions of make, like SGI's, use the following variable to |
193 | 193 | # determine which shell to use for executing commands: |
1337 | 1337 | TK_VERSION=8.6 |
1338 | 1338 | TK_MAJOR_VERSION=8 |
1339 | 1339 | TK_MINOR_VERSION=6 |
1340 | TK_PATCH_LEVEL=".8" | |
1340 | TK_PATCH_LEVEL=".9" | |
1341 | 1341 | VERSION=${TK_VERSION} |
1342 | 1342 | LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv" |
1343 | 1343 | |
1428 | 1428 | for i in `ls -d ${libdir} 2>/dev/null` \ |
1429 | 1429 | `ls -d ${exec_prefix}/lib 2>/dev/null` \ |
1430 | 1430 | `ls -d ${prefix}/lib 2>/dev/null` \ |
1431 | `ls -d /usr/local/lib 2>/dev/null` \ | |
1431 | 1432 | `ls -d /usr/contrib/lib 2>/dev/null` \ |
1432 | `ls -d /usr/local/lib 2>/dev/null` \ | |
1433 | 1433 | `ls -d /usr/pkg/lib 2>/dev/null` \ |
1434 | 1434 | `ls -d /usr/lib 2>/dev/null` \ |
1435 | 1435 | `ls -d /usr/lib64 2>/dev/null` \ |
1436 | `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \ | |
1437 | `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \ | |
1436 | 1438 | ; do |
1437 | 1439 | if test -f "$i/tclConfig.sh" ; then |
1438 | 1440 | ac_cv_c_tclconfig="`(cd $i; pwd)`" |
4793 | 4795 | LDFLAGS="$LDFLAGS -Wl,--export-dynamic" |
4794 | 4796 | SHLIB_CFLAGS="-fPIC" |
4795 | 4797 | SHLIB_SUFFIX=".so" |
4796 | SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' | |
4798 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' | |
4797 | 4799 | DL_OBJS="tclLoadDl.o" |
4798 | 4800 | DL_LIBS="-lroot" |
4799 | 4801 | echo "$as_me:$LINENO: checking for inet_ntoa in -lnetwork" >&5 |
5222 | 5224 | # get rid of the warnings. |
5223 | 5225 | #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" |
5224 | 5226 | |
5225 | SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' | |
5227 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' | |
5226 | 5228 | DL_OBJS="tclLoadDl.o" |
5227 | 5229 | DL_LIBS="-ldl" |
5228 | 5230 | LDFLAGS="$LDFLAGS -Wl,--export-dynamic" |
5364 | 5366 | SHLIB_CFLAGS="-fpic" |
5365 | 5367 | ;; |
5366 | 5368 | esac |
5367 | SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' | |
5369 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' | |
5368 | 5370 | SHLIB_SUFFIX=".so" |
5369 | 5371 | DL_OBJS="tclLoadDl.o" |
5370 | 5372 | DL_LIBS="" |
5393 | 5395 | NetBSD-*) |
5394 | 5396 | # NetBSD has ELF and can use 'cc -shared' to build shared libs |
5395 | 5397 | SHLIB_CFLAGS="-fPIC" |
5396 | SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' | |
5398 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' | |
5397 | 5399 | SHLIB_SUFFIX=".so" |
5398 | 5400 | DL_OBJS="tclLoadDl.o" |
5399 | 5401 | DL_LIBS="" |
5414 | 5416 | fi |
5415 | 5417 | |
5416 | 5418 | ;; |
5417 | FreeBSD-*) | |
5419 | DragonFly-*|FreeBSD-*) | |
5418 | 5420 | # This configuration from FreeBSD Ports. |
5419 | 5421 | SHLIB_CFLAGS="-fPIC" |
5420 | 5422 | SHLIB_LD="${CC} -shared" |
6622 | 6624 | BSD/OS*) ;; |
6623 | 6625 | CYGWIN_*|MINGW32_*) ;; |
6624 | 6626 | IRIX*) ;; |
6625 | NetBSD-*|FreeBSD-*|OpenBSD-*) ;; | |
6627 | NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;; | |
6626 | 6628 | Darwin-*) ;; |
6627 | 6629 | SCO_SV-3.2*) ;; |
6628 | 6630 | *) SHLIB_CFLAGS="-fPIC" ;; |
7394 | 7396 | |
7395 | 7397 | cat >>confdefs.h <<\_ACEOF |
7396 | 7398 | #define HAVE_STRUCT_DIRENT64 1 |
7399 | _ACEOF | |
7400 | ||
7401 | fi | |
7402 | ||
7403 | echo "$as_me:$LINENO: checking for DIR64" >&5 | |
7404 | echo $ECHO_N "checking for DIR64... $ECHO_C" >&6 | |
7405 | if test "${tcl_cv_DIR64+set}" = set; then | |
7406 | echo $ECHO_N "(cached) $ECHO_C" >&6 | |
7407 | else | |
7408 | ||
7409 | cat >conftest.$ac_ext <<_ACEOF | |
7410 | /* confdefs.h. */ | |
7411 | _ACEOF | |
7412 | cat confdefs.h >>conftest.$ac_ext | |
7413 | cat >>conftest.$ac_ext <<_ACEOF | |
7414 | /* end confdefs.h. */ | |
7415 | #include <sys/types.h> | |
7416 | #include <dirent.h> | |
7417 | int | |
7418 | main () | |
7419 | { | |
7420 | struct dirent64 *p; DIR64 d = opendir64("."); | |
7421 | p = readdir64(d); rewinddir64(d); closedir64(d); | |
7422 | ; | |
7423 | return 0; | |
7424 | } | |
7425 | _ACEOF | |
7426 | rm -f conftest.$ac_objext | |
7427 | if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 | |
7428 | (eval $ac_compile) 2>conftest.er1 | |
7429 | ac_status=$? | |
7430 | grep -v '^ *+' conftest.er1 >conftest.err | |
7431 | rm -f conftest.er1 | |
7432 | cat conftest.err >&5 | |
7433 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7434 | (exit $ac_status); } && | |
7435 | { ac_try='test -z "$ac_c_werror_flag" | |
7436 | || test ! -s conftest.err' | |
7437 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7438 | (eval $ac_try) 2>&5 | |
7439 | ac_status=$? | |
7440 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7441 | (exit $ac_status); }; } && | |
7442 | { ac_try='test -s conftest.$ac_objext' | |
7443 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
7444 | (eval $ac_try) 2>&5 | |
7445 | ac_status=$? | |
7446 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
7447 | (exit $ac_status); }; }; then | |
7448 | tcl_cv_DIR64=yes | |
7449 | else | |
7450 | echo "$as_me: failed program was:" >&5 | |
7451 | sed 's/^/| /' conftest.$ac_ext >&5 | |
7452 | ||
7453 | tcl_cv_DIR64=no | |
7454 | fi | |
7455 | rm -f conftest.err conftest.$ac_objext conftest.$ac_ext | |
7456 | fi | |
7457 | echo "$as_me:$LINENO: result: $tcl_cv_DIR64" >&5 | |
7458 | echo "${ECHO_T}$tcl_cv_DIR64" >&6 | |
7459 | if test "x${tcl_cv_DIR64}" = "xyes" ; then | |
7460 | ||
7461 | cat >>confdefs.h <<\_ACEOF | |
7462 | #define HAVE_DIR64 1 | |
7397 | 7463 | _ACEOF |
7398 | 7464 | |
7399 | 7465 | fi |
8220 | 8286 | |
8221 | 8287 | |
8222 | 8288 | #-------------------------------------------------------------------- |
8223 | # Under Solaris 2.4, strtod returns the wrong value for the | |
8224 | # terminating character under some conditions. Check for this | |
8225 | # and if the problem exists use a substitute procedure | |
8226 | # "fixstrtod" (provided by Tcl) that corrects the error. | |
8227 | #-------------------------------------------------------------------- | |
8228 | ||
8229 | ||
8230 | echo "$as_me:$LINENO: checking for strtod" >&5 | |
8231 | echo $ECHO_N "checking for strtod... $ECHO_C" >&6 | |
8232 | if test "${ac_cv_func_strtod+set}" = set; then | |
8233 | echo $ECHO_N "(cached) $ECHO_C" >&6 | |
8234 | else | |
8235 | cat >conftest.$ac_ext <<_ACEOF | |
8236 | /* confdefs.h. */ | |
8237 | _ACEOF | |
8238 | cat confdefs.h >>conftest.$ac_ext | |
8239 | cat >>conftest.$ac_ext <<_ACEOF | |
8240 | /* end confdefs.h. */ | |
8241 | /* Define strtod to an innocuous variant, in case <limits.h> declares strtod. | |
8242 | For example, HP-UX 11i <limits.h> declares gettimeofday. */ | |
8243 | #define strtod innocuous_strtod | |
8244 | ||
8245 | /* System header to define __stub macros and hopefully few prototypes, | |
8246 | which can conflict with char strtod (); below. | |
8247 | Prefer <limits.h> to <assert.h> if __STDC__ is defined, since | |
8248 | <limits.h> exists even on freestanding compilers. */ | |
8249 | ||
8250 | #ifdef __STDC__ | |
8251 | # include <limits.h> | |
8252 | #else | |
8253 | # include <assert.h> | |
8254 | #endif | |
8255 | ||
8256 | #undef strtod | |
8257 | ||
8258 | /* Override any gcc2 internal prototype to avoid an error. */ | |
8259 | #ifdef __cplusplus | |
8260 | extern "C" | |
8261 | { | |
8262 | #endif | |
8263 | /* We use char because int might match the return type of a gcc2 | |
8264 | builtin and then its argument prototype would still apply. */ | |
8265 | char strtod (); | |
8266 | /* The GNU C library defines this for functions which it implements | |
8267 | to always fail with ENOSYS. Some functions are actually named | |
8268 | something starting with __ and the normal name is an alias. */ | |
8269 | #if defined (__stub_strtod) || defined (__stub___strtod) | |
8270 | choke me | |
8271 | #else | |
8272 | char (*f) () = strtod; | |
8273 | #endif | |
8274 | #ifdef __cplusplus | |
8275 | } | |
8276 | #endif | |
8277 | ||
8278 | int | |
8279 | main () | |
8280 | { | |
8281 | return f != strtod; | |
8282 | ; | |
8283 | return 0; | |
8284 | } | |
8285 | _ACEOF | |
8286 | rm -f conftest.$ac_objext conftest$ac_exeext | |
8287 | if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
8288 | (eval $ac_link) 2>conftest.er1 | |
8289 | ac_status=$? | |
8290 | grep -v '^ *+' conftest.er1 >conftest.err | |
8291 | rm -f conftest.er1 | |
8292 | cat conftest.err >&5 | |
8293 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
8294 | (exit $ac_status); } && | |
8295 | { ac_try='test -z "$ac_c_werror_flag" | |
8296 | || test ! -s conftest.err' | |
8297 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
8298 | (eval $ac_try) 2>&5 | |
8299 | ac_status=$? | |
8300 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
8301 | (exit $ac_status); }; } && | |
8302 | { ac_try='test -s conftest$ac_exeext' | |
8303 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
8304 | (eval $ac_try) 2>&5 | |
8305 | ac_status=$? | |
8306 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
8307 | (exit $ac_status); }; }; then | |
8308 | ac_cv_func_strtod=yes | |
8309 | else | |
8310 | echo "$as_me: failed program was:" >&5 | |
8311 | sed 's/^/| /' conftest.$ac_ext >&5 | |
8312 | ||
8313 | ac_cv_func_strtod=no | |
8314 | fi | |
8315 | rm -f conftest.err conftest.$ac_objext \ | |
8316 | conftest$ac_exeext conftest.$ac_ext | |
8317 | fi | |
8318 | echo "$as_me:$LINENO: result: $ac_cv_func_strtod" >&5 | |
8319 | echo "${ECHO_T}$ac_cv_func_strtod" >&6 | |
8320 | if test $ac_cv_func_strtod = yes; then | |
8321 | tcl_strtod=1 | |
8322 | else | |
8323 | tcl_strtod=0 | |
8324 | fi | |
8325 | ||
8326 | if test "$tcl_strtod" = 1; then | |
8327 | echo "$as_me:$LINENO: checking for Solaris2.4/Tru64 strtod bugs" >&5 | |
8328 | echo $ECHO_N "checking for Solaris2.4/Tru64 strtod bugs... $ECHO_C" >&6 | |
8329 | if test "${tcl_cv_strtod_buggy+set}" = set; then | |
8330 | echo $ECHO_N "(cached) $ECHO_C" >&6 | |
8331 | else | |
8332 | ||
8333 | if test "$cross_compiling" = yes; then | |
8334 | tcl_cv_strtod_buggy=buggy | |
8335 | else | |
8336 | cat >conftest.$ac_ext <<_ACEOF | |
8337 | /* confdefs.h. */ | |
8338 | _ACEOF | |
8339 | cat confdefs.h >>conftest.$ac_ext | |
8340 | cat >>conftest.$ac_ext <<_ACEOF | |
8341 | /* end confdefs.h. */ | |
8342 | ||
8343 | extern double strtod(); | |
8344 | int main() { | |
8345 | char *infString="Inf", *nanString="NaN", *spaceString=" "; | |
8346 | char *term; | |
8347 | double value; | |
8348 | value = strtod(infString, &term); | |
8349 | if ((term != infString) && (term[-1] == 0)) { | |
8350 | exit(1); | |
8351 | } | |
8352 | value = strtod(nanString, &term); | |
8353 | if ((term != nanString) && (term[-1] == 0)) { | |
8354 | exit(1); | |
8355 | } | |
8356 | value = strtod(spaceString, &term); | |
8357 | if (term == (spaceString+1)) { | |
8358 | exit(1); | |
8359 | } | |
8360 | exit(0); | |
8361 | } | |
8362 | _ACEOF | |
8363 | rm -f conftest$ac_exeext | |
8364 | if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5 | |
8365 | (eval $ac_link) 2>&5 | |
8366 | ac_status=$? | |
8367 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
8368 | (exit $ac_status); } && { ac_try='./conftest$ac_exeext' | |
8369 | { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 | |
8370 | (eval $ac_try) 2>&5 | |
8371 | ac_status=$? | |
8372 | echo "$as_me:$LINENO: \$? = $ac_status" >&5 | |
8373 | (exit $ac_status); }; }; then | |
8374 | tcl_cv_strtod_buggy=ok | |
8375 | else | |
8376 | echo "$as_me: program exited with status $ac_status" >&5 | |
8377 | echo "$as_me: failed program was:" >&5 | |
8378 | sed 's/^/| /' conftest.$ac_ext >&5 | |
8379 | ||
8380 | ( exit $ac_status ) | |
8381 | tcl_cv_strtod_buggy=buggy | |
8382 | fi | |
8383 | rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext | |
8384 | fi | |
8385 | fi | |
8386 | echo "$as_me:$LINENO: result: $tcl_cv_strtod_buggy" >&5 | |
8387 | echo "${ECHO_T}$tcl_cv_strtod_buggy" >&6 | |
8388 | if test "$tcl_cv_strtod_buggy" = buggy; then | |
8389 | case $LIBOBJS in | |
8390 | "fixstrtod.$ac_objext" | \ | |
8391 | *" fixstrtod.$ac_objext" | \ | |
8392 | "fixstrtod.$ac_objext "* | \ | |
8393 | *" fixstrtod.$ac_objext "* ) ;; | |
8394 | *) LIBOBJS="$LIBOBJS fixstrtod.$ac_objext" ;; | |
8395 | esac | |
8396 | ||
8397 | USE_COMPAT=1 | |
8398 | ||
8399 | cat >>confdefs.h <<\_ACEOF | |
8400 | #define strtod fixstrtod | |
8401 | _ACEOF | |
8402 | ||
8403 | fi | |
8404 | fi | |
8405 | ||
8406 | ||
8407 | #-------------------------------------------------------------------- | |
8408 | 8289 | # Check for various typedefs and provide substitutes if |
8409 | 8290 | # they don't exist. |
8410 | 8291 | #-------------------------------------------------------------------- |
9579 | 9460 | /usr/openwin/share/include' |
9580 | 9461 | |
9581 | 9462 | if test "$ac_x_includes" = no; then |
9582 | # Guess where to find include files, by looking for Xlib.h. | |
9463 | # Guess where to find include files, by looking for Intrinsic.h. | |
9583 | 9464 | # First, try using that file with no special directory specified. |
9584 | 9465 | cat >conftest.$ac_ext <<_ACEOF |
9585 | 9466 | /* confdefs.h. */ |
9587 | 9468 | cat confdefs.h >>conftest.$ac_ext |
9588 | 9469 | cat >>conftest.$ac_ext <<_ACEOF |
9589 | 9470 | /* end confdefs.h. */ |
9590 | #include <X11/Xlib.h> | |
9471 | #include <X11/Intrinsic.h> | |
9591 | 9472 | _ACEOF |
9592 | 9473 | if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 |
9593 | 9474 | (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 |
9614 | 9495 | sed 's/^/| /' conftest.$ac_ext >&5 |
9615 | 9496 | |
9616 | 9497 | for ac_dir in $ac_x_header_dirs; do |
9617 | if test -r "$ac_dir/X11/Xlib.h"; then | |
9498 | if test -r "$ac_dir/X11/Intrinsic.h"; then | |
9618 | 9499 | ac_x_includes=$ac_dir |
9619 | 9500 | break |
9620 | 9501 | fi |
9628 | 9509 | # See if we find them without any special options. |
9629 | 9510 | # Don't add to $LIBS permanently. |
9630 | 9511 | ac_save_LIBS=$LIBS |
9631 | LIBS="-lX11 $LIBS" | |
9512 | LIBS="-lXt $LIBS" | |
9632 | 9513 | cat >conftest.$ac_ext <<_ACEOF |
9633 | 9514 | /* confdefs.h. */ |
9634 | 9515 | _ACEOF |
9635 | 9516 | cat confdefs.h >>conftest.$ac_ext |
9636 | 9517 | cat >>conftest.$ac_ext <<_ACEOF |
9637 | 9518 | /* end confdefs.h. */ |
9638 | #include <X11/Xlib.h> | |
9519 | #include <X11/Intrinsic.h> | |
9639 | 9520 | int |
9640 | 9521 | main () |
9641 | 9522 | { |
9642 | XrmInitialize () | |
9523 | XtMalloc (0) | |
9643 | 9524 | ; |
9644 | 9525 | return 0; |
9645 | 9526 | } |
24 | 24 | TK_VERSION=8.6 |
25 | 25 | TK_MAJOR_VERSION=8 |
26 | 26 | TK_MINOR_VERSION=6 |
27 | TK_PATCH_LEVEL=".8" | |
27 | TK_PATCH_LEVEL=".9" | |
28 | 28 | VERSION=${TK_VERSION} |
29 | 29 | LOCALES="cs da de el en en_gb eo es fr hu it nl pl pt ru sv" |
30 | 30 | |
194 | 194 | |
195 | 195 | AC_CHECK_HEADERS(sys/time.h) |
196 | 196 | AC_HEADER_TIME |
197 | ||
198 | #-------------------------------------------------------------------- | |
199 | # Under Solaris 2.4, strtod returns the wrong value for the | |
200 | # terminating character under some conditions. Check for this | |
201 | # and if the problem exists use a substitute procedure | |
202 | # "fixstrtod" (provided by Tcl) that corrects the error. | |
203 | #-------------------------------------------------------------------- | |
204 | ||
205 | SC_BUGGY_STRTOD | |
206 | 197 | |
207 | 198 | #-------------------------------------------------------------------- |
208 | 199 | # Check for various typedefs and provide substitutes if |
90 | 90 | for i in `ls -d ${libdir} 2>/dev/null` \ |
91 | 91 | `ls -d ${exec_prefix}/lib 2>/dev/null` \ |
92 | 92 | `ls -d ${prefix}/lib 2>/dev/null` \ |
93 | `ls -d /usr/local/lib 2>/dev/null` \ | |
93 | 94 | `ls -d /usr/contrib/lib 2>/dev/null` \ |
94 | `ls -d /usr/local/lib 2>/dev/null` \ | |
95 | 95 | `ls -d /usr/pkg/lib 2>/dev/null` \ |
96 | 96 | `ls -d /usr/lib 2>/dev/null` \ |
97 | 97 | `ls -d /usr/lib64 2>/dev/null` \ |
98 | `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \ | |
99 | `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \ | |
98 | 100 | ; do |
99 | 101 | if test -f "$i/tclConfig.sh" ; then |
100 | 102 | ac_cv_c_tclconfig="`(cd $i; pwd)`" |
223 | 225 | `ls -d ${prefix}/lib 2>/dev/null` \ |
224 | 226 | `ls -d /usr/local/lib 2>/dev/null` \ |
225 | 227 | `ls -d /usr/contrib/lib 2>/dev/null` \ |
228 | `ls -d /usr/pkg/lib 2>/dev/null` \ | |
226 | 229 | `ls -d /usr/lib 2>/dev/null` \ |
227 | 230 | `ls -d /usr/lib64 2>/dev/null` \ |
231 | `ls -d /usr/local/lib/tk8.6 2>/dev/null` \ | |
232 | `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \ | |
228 | 233 | ; do |
229 | 234 | if test -f "$i/tkConfig.sh" ; then |
230 | 235 | ac_cv_c_tkconfig="`(cd $i; pwd)`" |
1257 | 1262 | LDFLAGS="$LDFLAGS -Wl,--export-dynamic" |
1258 | 1263 | SHLIB_CFLAGS="-fPIC" |
1259 | 1264 | SHLIB_SUFFIX=".so" |
1260 | SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' | |
1265 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' | |
1261 | 1266 | DL_OBJS="tclLoadDl.o" |
1262 | 1267 | DL_LIBS="-lroot" |
1263 | 1268 | AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"]) |
1401 | 1406 | # get rid of the warnings. |
1402 | 1407 | #CFLAGS_OPTIMIZE="${CFLAGS_OPTIMIZE} -D__NO_STRING_INLINES -D__NO_MATH_INLINES" |
1403 | 1408 | |
1404 | SHLIB_LD='${CC} -shared ${CFLAGS} ${LDFLAGS}' | |
1409 | SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' | |
1405 | 1410 | DL_OBJS="tclLoadDl.o" |
1406 | 1411 | DL_LIBS="-ldl" |
1407 | 1412 | LDFLAGS="$LDFLAGS -Wl,--export-dynamic" |
1472 | 1477 | SHLIB_CFLAGS="-fpic" |
1473 | 1478 | ;; |
1474 | 1479 | esac |
1475 | SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' | |
1480 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' | |
1476 | 1481 | SHLIB_SUFFIX=".so" |
1477 | 1482 | DL_OBJS="tclLoadDl.o" |
1478 | 1483 | DL_LIBS="" |
1495 | 1500 | NetBSD-*) |
1496 | 1501 | # NetBSD has ELF and can use 'cc -shared' to build shared libs |
1497 | 1502 | SHLIB_CFLAGS="-fPIC" |
1498 | SHLIB_LD='${CC} -shared ${SHLIB_CFLAGS}' | |
1503 | SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' | |
1499 | 1504 | SHLIB_SUFFIX=".so" |
1500 | 1505 | DL_OBJS="tclLoadDl.o" |
1501 | 1506 | DL_LIBS="" |
1510 | 1515 | LDFLAGS="$LDFLAGS -pthread" |
1511 | 1516 | ]) |
1512 | 1517 | ;; |
1513 | FreeBSD-*) | |
1518 | DragonFly-*|FreeBSD-*) | |
1514 | 1519 | # This configuration from FreeBSD Ports. |
1515 | 1520 | SHLIB_CFLAGS="-fPIC" |
1516 | 1521 | SHLIB_LD="${CC} -shared" |
2006 | 2011 | BSD/OS*) ;; |
2007 | 2012 | CYGWIN_*|MINGW32_*) ;; |
2008 | 2013 | IRIX*) ;; |
2009 | NetBSD-*|FreeBSD-*|OpenBSD-*) ;; | |
2014 | NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;; | |
2010 | 2015 | Darwin-*) ;; |
2011 | 2016 | SCO_SV-3.2*) ;; |
2012 | 2017 | *) SHLIB_CFLAGS="-fPIC" ;; |
2392 | 2397 | ]) |
2393 | 2398 | |
2394 | 2399 | #-------------------------------------------------------------------- |
2395 | # SC_BUGGY_STRTOD | |
2396 | # | |
2397 | # Under Solaris 2.4, strtod returns the wrong value for the | |
2398 | # terminating character under some conditions. Check for this | |
2399 | # and if the problem exists use a substitute procedure | |
2400 | # "fixstrtod" (provided by Tcl) that corrects the error. | |
2401 | # Also, on Compaq's Tru64 Unix 5.0, | |
2402 | # strtod(" ") returns 0.0 instead of a failure to convert. | |
2403 | # | |
2404 | # Arguments: | |
2405 | # none | |
2406 | # | |
2407 | # Results: | |
2408 | # | |
2409 | # Might defines some of the following vars: | |
2410 | # strtod (=fixstrtod) | |
2411 | # | |
2412 | #-------------------------------------------------------------------- | |
2413 | ||
2414 | AC_DEFUN([SC_BUGGY_STRTOD], [ | |
2415 | AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0) | |
2416 | if test "$tcl_strtod" = 1; then | |
2417 | AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[ | |
2418 | AC_TRY_RUN([ | |
2419 | extern double strtod(); | |
2420 | int main() { | |
2421 | char *infString="Inf", *nanString="NaN", *spaceString=" "; | |
2422 | char *term; | |
2423 | double value; | |
2424 | value = strtod(infString, &term); | |
2425 | if ((term != infString) && (term[-1] == 0)) { | |
2426 | exit(1); | |
2427 | } | |
2428 | value = strtod(nanString, &term); | |
2429 | if ((term != nanString) && (term[-1] == 0)) { | |
2430 | exit(1); | |
2431 | } | |
2432 | value = strtod(spaceString, &term); | |
2433 | if (term == (spaceString+1)) { | |
2434 | exit(1); | |
2435 | } | |
2436 | exit(0); | |
2437 | }], tcl_cv_strtod_buggy=ok, tcl_cv_strtod_buggy=buggy, | |
2438 | tcl_cv_strtod_buggy=buggy)]) | |
2439 | if test "$tcl_cv_strtod_buggy" = buggy; then | |
2440 | AC_LIBOBJ([fixstrtod]) | |
2441 | USE_COMPAT=1 | |
2442 | AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?]) | |
2443 | fi | |
2444 | fi | |
2445 | ]) | |
2446 | ||
2447 | #-------------------------------------------------------------------- | |
2448 | 2400 | # SC_TCL_LINK_LIBS |
2449 | 2401 | # |
2450 | 2402 | # Search for the libraries needed to link the Tcl shell. |
2469 | 2421 | #-------------------------------------------------------------------- |
2470 | 2422 | # On a few very rare systems, all of the libm.a stuff is |
2471 | 2423 | # already in libc.a. Set compiler flags accordingly. |
2472 | # Also, Linux requires the "ieee" library for math to work | |
2473 | # right (and it must appear before "-lm"). | |
2474 | 2424 | #-------------------------------------------------------------------- |
2475 | 2425 | |
2476 | 2426 | AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") |
2477 | AC_CHECK_LIB(ieee, main, [MATH_LIBS="-lieee $MATH_LIBS"]) | |
2478 | 2427 | |
2479 | 2428 | #-------------------------------------------------------------------- |
2480 | 2429 | # Interactive UNIX requires -linet instead of -lsocket, plus it |
2578 | 2527 | # Might define the following vars: |
2579 | 2528 | # TCL_WIDE_INT_IS_LONG |
2580 | 2529 | # TCL_WIDE_INT_TYPE |
2581 | # HAVE_STRUCT_DIRENT64 | |
2530 | # HAVE_STRUCT_DIRENT64, HAVE_DIR64 | |
2582 | 2531 | # HAVE_STRUCT_STAT64 |
2583 | 2532 | # HAVE_TYPE_OFF64_T |
2584 | 2533 | # |
2612 | 2561 | tcl_cv_struct_dirent64=yes,tcl_cv_struct_dirent64=no)]) |
2613 | 2562 | if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then |
2614 | 2563 | AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in <sys/types.h>?]) |
2564 | fi | |
2565 | ||
2566 | AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[ | |
2567 | AC_TRY_COMPILE([#include <sys/types.h> | |
2568 | #include <dirent.h>],[struct dirent64 *p; DIR64 d = opendir64("."); | |
2569 | p = readdir64(d); rewinddir64(d); closedir64(d);], | |
2570 | tcl_cv_DIR64=yes,tcl_cv_DIR64=no)]) | |
2571 | if test "x${tcl_cv_DIR64}" = "xyes" ; then | |
2572 | AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in <sys/types.h>?]) | |
2615 | 2573 | fi |
2616 | 2574 | |
2617 | 2575 | AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ |
3 | 3 | |
4 | 4 | Name: tk |
5 | 5 | Summary: Tk graphical toolkit for the Tcl scripting language. |
6 | Version: 8.6.8 | |
6 | Version: 8.6.9 | |
7 | 7 | Release: 2 |
8 | 8 | License: BSD |
9 | 9 | Group: Development/Languages |
11 | 11 | |
12 | 12 | /* Do we have access to Darwin CoreFoundation.framework? */ |
13 | 13 | #undef HAVE_COREFOUNDATION |
14 | ||
15 | /* Is 'DIR64' in <sys/types.h>? */ | |
16 | #undef HAVE_DIR64 | |
14 | 17 | |
15 | 18 | /* Compiler support for module scope symbols */ |
16 | 19 | #undef HAVE_HIDDEN |
236 | 239 | |
237 | 240 | /* Define to `unsigned' if <sys/types.h> does not define. */ |
238 | 241 | #undef size_t |
239 | ||
240 | /* Do we want to use the strtod() in compat? */ | |
241 | #undef strtod | |
242 | 242 | |
243 | 243 | /* Define to `int' if <sys/types.h> doesn't define. */ |
244 | 244 | #undef uid_t |
405 | 405 | { |
406 | 406 | const char *srcStart, *srcEnd; |
407 | 407 | char *dstStart, *dstEnd; |
408 | int ch; | |
409 | int result; | |
408 | int ch, result; | |
410 | 409 | static char hexChars[] = "0123456789abcdef"; |
411 | 410 | static char mapChars[] = { |
412 | 411 | 0, 0, 0, 0, 0, 0, 0, |
953 | 952 | TkpGetFontAttrsForChar( |
954 | 953 | Tk_Window tkwin, /* Window on the font's display */ |
955 | 954 | Tk_Font tkfont, /* Font to query */ |
956 | int c, /* Character of interest */ | |
955 | int c, /* Character of interest */ | |
957 | 956 | TkFontAttributes *faPtr) /* Output: Font attributes */ |
958 | 957 | { |
959 | 958 | FontAttributes atts; |
1017 | 1016 | { |
1018 | 1017 | UnixFont *fontPtr; |
1019 | 1018 | SubFont *lastSubFontPtr; |
1020 | int curX, curByte; | |
1019 | int curX, curByte, ch; | |
1021 | 1020 | |
1022 | 1021 | /* |
1023 | 1022 | * Unix does not use kerning or fractional character widths when |
1035 | 1034 | curByte = 0; |
1036 | 1035 | } else if (maxLength < 0) { |
1037 | 1036 | const char *p, *end, *next; |
1038 | int ch; | |
1039 | 1037 | SubFont *thisSubFontPtr; |
1040 | 1038 | FontFamily *familyPtr; |
1041 | 1039 | Tcl_DString runString; |
1089 | 1087 | } else { |
1090 | 1088 | const char *p, *end, *next, *term; |
1091 | 1089 | int newX, termX, sawNonSpace, dstWrote; |
1092 | Tcl_UniChar ch; | |
1093 | 1090 | FontFamily *familyPtr; |
1094 | 1091 | XChar2b buf[8]; |
1095 | 1092 | |
1099 | 1096 | * individually. |
1100 | 1097 | */ |
1101 | 1098 | |
1102 | next = source + Tcl_UtfToUniChar(source, &ch); | |
1099 | next = source + TkUtfToUniChar(source, &ch); | |
1103 | 1100 | newX = curX = termX = 0; |
1104 | 1101 | |
1105 | 1102 | term = source; |
1134 | 1131 | break; |
1135 | 1132 | } |
1136 | 1133 | |
1137 | next += Tcl_UtfToUniChar(next, &ch); | |
1134 | next += TkUtfToUniChar(next, &ch); | |
1138 | 1135 | if ((ch < 256) && isspace(ch)) { |
1139 | 1136 | if (sawNonSpace) { |
1140 | 1137 | term = p; |
1159 | 1156 | */ |
1160 | 1157 | |
1161 | 1158 | curX = newX; |
1162 | p += Tcl_UtfToUniChar(p, &ch); | |
1159 | p += TkUtfToUniChar(p, &ch); | |
1163 | 1160 | } |
1164 | 1161 | if ((flags & TK_AT_LEAST_ONE) && (term == source) && (p < end)) { |
1165 | 1162 | term = p; |
1166 | 1163 | termX = curX; |
1167 | 1164 | if (term == source) { |
1168 | term += Tcl_UtfToUniChar(term, &ch); | |
1165 | term += TkUtfToUniChar(term, &ch); | |
1169 | 1166 | termX = newX; |
1170 | 1167 | } |
1171 | 1168 | } else if ((p >= end) || !(flags & TK_WHOLE_WORDS)) { |
1277 | 1274 | SubFont *thisSubFontPtr, *lastSubFontPtr; |
1278 | 1275 | Tcl_DString runString; |
1279 | 1276 | const char *p, *end, *next; |
1280 | int xStart, needWidth, window_width, do_width; | |
1281 | Tcl_UniChar ch; | |
1277 | int xStart, needWidth, window_width, do_width, ch; | |
1282 | 1278 | FontFamily *familyPtr; |
1283 | 1279 | #ifdef TK_DRAW_CHAR_XWINDOW_CHECK |
1284 | 1280 | int rx, ry; |
1313 | 1309 | needWidth = fontPtr->font.fa.underline + fontPtr->font.fa.overstrike; |
1314 | 1310 | for (p = source; p <= end; ) { |
1315 | 1311 | if (p < end) { |
1316 | next = p + Tcl_UtfToUniChar(p, &ch); | |
1312 | next = p + TkUtfToUniChar(p, &ch); | |
1317 | 1313 | thisSubFontPtr = FindSubFontForChar(fontPtr, ch, &lastSubFontPtr); |
1318 | 1314 | } else { |
1319 | 1315 | next = p + 1; |
1848 | 1844 | if ((familyPtr->faceName == fa.fa.family) |
1849 | 1845 | && (familyPtr->foundry == fa.xa.foundry) |
1850 | 1846 | && (familyPtr->encoding == encoding)) { |
1851 | Tcl_FreeEncoding(encoding); | |
1847 | if (encoding) { | |
1848 | Tcl_FreeEncoding(encoding); | |
1849 | } | |
1852 | 1850 | familyPtr->refCount++; |
1853 | 1851 | return familyPtr; |
1854 | 1852 | } |
1922 | 1920 | if (familyPtr->refCount > 0) { |
1923 | 1921 | return; |
1924 | 1922 | } |
1925 | Tcl_FreeEncoding(familyPtr->encoding); | |
1923 | if (familyPtr->encoding) { | |
1924 | Tcl_FreeEncoding(familyPtr->encoding); | |
1925 | } | |
1926 | 1926 | for (i = 0; i < FONTMAP_PAGES; i++) { |
1927 | 1927 | if (familyPtr->fontMap[i] != NULL) { |
1928 | 1928 | ckfree(familyPtr->fontMap[i]); |
2212 | 2212 | int row) /* Index of the page to be loaded into the |
2213 | 2213 | * cache. */ |
2214 | 2214 | { |
2215 | char buf[16], src[TCL_UTF_MAX]; | |
2215 | char buf[16], src[6]; | |
2216 | 2216 | int minHi, maxHi, minLo, maxLo, scale, checkLo; |
2217 | 2217 | int i, end, bitOffset, isTwoByteFont, n; |
2218 | 2218 | Tcl_Encoding encoding; |
2250 | 2250 | for (i = row << FONTMAP_SHIFT; i < end; i++) { |
2251 | 2251 | int hi, lo; |
2252 | 2252 | |
2253 | if (Tcl_UtfToExternal(NULL, encoding, src, Tcl_UniCharToUtf(i, src), | |
2253 | if (Tcl_UtfToExternal(NULL, encoding, src, TkUniCharToUtf(i, src), | |
2254 | 2254 | TCL_ENCODING_STOPONERROR, NULL, buf, sizeof(buf), NULL, |
2255 | 2255 | NULL, NULL) != TCL_OK) { |
2256 | 2256 | continue; |
2416 | 2416 | unsigned bestScore[2]; |
2417 | 2417 | char **nameList; |
2418 | 2418 | char **nameListOrig; |
2419 | char src[TCL_UTF_MAX]; | |
2419 | char src[6]; | |
2420 | 2420 | FontAttributes want, got; |
2421 | 2421 | Display *display; |
2422 | 2422 | SubFont subFont; |
2446 | 2446 | } |
2447 | 2447 | nameListOrig = nameList; |
2448 | 2448 | |
2449 | srcLen = Tcl_UniCharToUtf(ch, src); | |
2449 | srcLen = TkUniCharToUtf(ch, src); | |
2450 | 2450 | |
2451 | 2451 | want.fa = fontPtr->font.fa; |
2452 | 2452 | want.xa = fontPtr->xa; |
122 | 122 | memcpy(Tcl_DStringValue(dsPtr), kePtr->charValuePtr, |
123 | 123 | (unsigned) kePtr->charValueLen+1); |
124 | 124 | return Tcl_DStringValue(dsPtr); |
125 | } | |
126 | ||
127 | /* | |
128 | * Only do this for KeyPress events, otherwise | |
129 | * further Xlib function behavior might be undefined. | |
130 | */ | |
131 | ||
132 | if (eventPtr->type != KeyPress) { | |
133 | len = 0; | |
134 | Tcl_DStringSetLength(dsPtr, len); | |
135 | goto done; | |
125 | 136 | } |
126 | 137 | |
127 | 138 | #ifdef TK_USE_INPUT_METHODS |
216 | 227 | * from having to reenter the XIM engine. [Bug 1373712] |
217 | 228 | */ |
218 | 229 | |
230 | done: | |
219 | 231 | kePtr->charValuePtr = ckalloc(len + 1); |
220 | 232 | kePtr->charValueLen = len; |
221 | 233 | memcpy(kePtr->charValuePtr, Tcl_DStringValue(dsPtr), (unsigned) len + 1); |
235 | 247 | XEvent *eventPtr) |
236 | 248 | { |
237 | 249 | TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; |
238 | int state; | |
250 | int state, mincode, maxcode; | |
239 | 251 | KeyCode keycode; |
240 | 252 | |
241 | 253 | if (keySym == NoSymbol) { |
257 | 269 | } |
258 | 270 | } |
259 | 271 | } |
272 | ||
273 | /* | |
274 | * Filter keycodes out of range, otherwise further Xlib function | |
275 | * behavior might be undefined, in particular XIM could cause crashes. | |
276 | */ | |
277 | ||
278 | mincode = 0; | |
279 | maxcode = -1; | |
280 | XDisplayKeycodes(dispPtr->display, &mincode, &maxcode); | |
281 | if (keycode < mincode) { | |
282 | keycode = mincode; | |
283 | } else if (keycode > maxcode) { | |
284 | keycode = maxcode; | |
285 | } | |
286 | ||
260 | 287 | eventPtr->xkey.keycode = keycode; |
261 | 288 | } |
262 | 289 |
51 | 51 | static void DrawMenuEntryAccelerator(TkMenu *menuPtr, |
52 | 52 | TkMenuEntry *mePtr, Drawable d, GC gc, |
53 | 53 | Tk_Font tkfont, const Tk_FontMetrics *fmPtr, |
54 | Tk_3DBorder activeBorder, int x, int y, | |
55 | int width, int height, int drawArrow); | |
54 | Tk_3DBorder activeBorder, Tk_3DBorder bgBorder, | |
55 | int x, int y, int width, int height, int drawArrow); | |
56 | 56 | static void DrawMenuEntryBackground(TkMenu *menuPtr, |
57 | 57 | TkMenuEntry *mePtr, Drawable d, |
58 | 58 | Tk_3DBorder activeBorder, Tk_3DBorder bgBorder, |
480 | 480 | Tk_Font tkfont, /* The precalculated font */ |
481 | 481 | const Tk_FontMetrics *fmPtr,/* The precalculated metrics */ |
482 | 482 | Tk_3DBorder activeBorder, /* The border for an active item */ |
483 | Tk_3DBorder bgBorder, /* The background border */ | |
483 | 484 | int x, /* Left coordinate of entry rect */ |
484 | 485 | int y, /* Top coordinate of entry rect */ |
485 | 486 | int width, /* Width of entry */ |
509 | 510 | points[1].y = points[0].y + CASCADE_ARROW_HEIGHT; |
510 | 511 | points[2].x = points[0].x + CASCADE_ARROW_WIDTH; |
511 | 512 | points[2].y = points[0].y + CASCADE_ARROW_HEIGHT/2; |
512 | Tk_Fill3DPolygon(menuPtr->tkwin, d, activeBorder, points, 3, | |
513 | DECORATION_BORDER_WIDTH, | |
513 | Tk_Fill3DPolygon(menuPtr->tkwin, d, | |
514 | (mePtr->state == ENTRY_ACTIVE) ? activeBorder : bgBorder, | |
515 | points, 3, DECORATION_BORDER_WIDTH, | |
514 | 516 | (menuPtr->postedCascade == mePtr) |
515 | 517 | ? TK_RELIEF_SUNKEN : TK_RELIEF_RAISED); |
516 | 518 | } else if (mePtr->accelPtr != NULL) { |
637 | 639 | |
638 | 640 | points[0].x = x; |
639 | 641 | points[0].y = y + height/2; |
640 | points[1].x = width - 1; | |
642 | points[1].x = x + width - 1; | |
641 | 643 | points[1].y = points[0].y; |
642 | 644 | border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); |
643 | 645 | Tk_Draw3DPolygon(menuPtr->tkwin, d, border, points, 2, 1, |
1192 | 1194 | points[0].y = y + height/2; |
1193 | 1195 | points[1].y = points[0].y; |
1194 | 1196 | segmentWidth = 6; |
1195 | maxX = width - 1; | |
1197 | maxX = x + width - 1; | |
1196 | 1198 | border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); |
1197 | 1199 | |
1198 | 1200 | while (points[0].x < maxX) { |
1325 | 1327 | int height, /* Height of the current rectangle */ |
1326 | 1328 | int strictMotif, /* Boolean flag */ |
1327 | 1329 | int drawArrow) /* Whether or not to draw the cascade arrow |
1328 | * for cascade items. Only applies to | |
1329 | * Windows. */ | |
1330 | * for cascade items. */ | |
1330 | 1331 | { |
1331 | 1332 | GC gc, indicatorGC; |
1332 | 1333 | XColor *indicatorColor, *disableColor = NULL; |
1434 | 1435 | DrawMenuEntryLabel(menuPtr, mePtr, d, gc, tkfont, fmPtr, x, adjustedY, |
1435 | 1436 | width, adjustedHeight); |
1436 | 1437 | DrawMenuEntryAccelerator(menuPtr, mePtr, d, gc, tkfont, fmPtr, |
1437 | activeBorder, x, adjustedY, width, adjustedHeight, drawArrow); | |
1438 | activeBorder, bgBorder, x, adjustedY, width, adjustedHeight, | |
1439 | drawArrow); | |
1438 | 1440 | if (!mePtr->hideMargin) { |
1439 | 1441 | if (mePtr->state == ENTRY_ACTIVE) { |
1440 | 1442 | bgBorder = activeBorder; |
1717 | 1719 | menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN; |
1718 | 1720 | } |
1719 | 1721 | windowWidth = x + indicatorSpace + labelWidth + accelWidth |
1720 | + 2 * activeBorderWidth + 2 * borderWidth; | |
1722 | + 2 * activeBorderWidth + borderWidth; | |
1721 | 1723 | |
1722 | 1724 | windowHeight += borderWidth; |
1723 | 1725 |
710 | 710 | (flags & TK_AT_LEAST_ONE && curByte == 0)) { |
711 | 711 | curX = newX; |
712 | 712 | curByte = newByte; |
713 | } else if (flags & TK_WHOLE_WORDS && termX != 0) { | |
714 | curX = termX; | |
715 | curByte = termByte; | |
713 | } else if (flags & TK_WHOLE_WORDS) { | |
714 | if ((flags & TK_AT_LEAST_ONE) && (termX == 0)) { | |
715 | /* | |
716 | * No space was seen before reaching the right | |
717 | * of the allotted maxLength space, i.e. no word | |
718 | * boundary. Return the string that fills the | |
719 | * allotted space, without overfill. | |
720 | * curX and curByte are already the right ones: | |
721 | */ | |
722 | } else { | |
723 | curX = termX; | |
724 | curByte = termByte; | |
725 | } | |
716 | 726 | } |
717 | 727 | break; |
718 | 728 | } |
849 | 859 | * string when drawing. */ |
850 | 860 | { |
851 | 861 | const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */ |
862 | const int minCoord = -maxCoord-1; | |
852 | 863 | UnixFtFont *fontPtr = (UnixFtFont *) tkfont; |
853 | 864 | XGCValues values; |
854 | 865 | XftColor *xftcolor; |
857 | 868 | XGlyphInfo metrics; |
858 | 869 | ThreadSpecificData *tsdPtr = (ThreadSpecificData *) |
859 | 870 | Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); |
860 | ||
861 | if (maxCoord <= y) { | |
862 | return; /* nothing to draw */ | |
863 | } | |
864 | 871 | |
865 | 872 | if (fontPtr->ftDraw == 0) { |
866 | 873 | #if DEBUG_FONTSEL |
899 | 906 | |
900 | 907 | ftFont = GetFont(fontPtr, c, 0.0); |
901 | 908 | if (ftFont) { |
902 | int cx = x; | |
903 | int cy = y; | |
904 | ||
905 | 909 | specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c); |
906 | 910 | XftGlyphExtents(fontPtr->display, ftFont, &specs[nspec].glyph, 1, |
907 | 911 | &metrics); |
908 | if ((x += metrics.xOff) >= maxCoord | |
909 | || (y += metrics.yOff) >= maxCoord) { | |
910 | break; | |
911 | } | |
912 | if (metrics.xOff > 0 && cx >= 0 && cy >= 0) { | |
913 | specs[nspec].font = ftFont; | |
914 | specs[nspec].x = cx; | |
915 | specs[nspec].y = cy; | |
916 | if (++nspec == NUM_SPEC) { | |
917 | XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, | |
918 | specs, nspec); | |
919 | nspec = 0; | |
920 | } | |
912 | ||
913 | /* | |
914 | * Draw glyph only when it fits entirely into 16 bit coords. | |
915 | */ | |
916 | ||
917 | if (x >= minCoord && y >= minCoord && | |
918 | x <= maxCoord - metrics.width && | |
919 | y <= maxCoord - metrics.height) { | |
920 | specs[nspec].font = ftFont; | |
921 | specs[nspec].x = x; | |
922 | specs[nspec].y = y; | |
923 | if (++nspec == NUM_SPEC) { | |
924 | XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, | |
925 | specs, nspec); | |
926 | nspec = 0; | |
927 | } | |
921 | 928 | } |
929 | x += metrics.xOff; | |
930 | y += metrics.yOff; | |
922 | 931 | } |
923 | 932 | } |
924 | 933 | if (nspec) { |
981 | 990 | double angle) /* What angle to put text at, in degrees. */ |
982 | 991 | { |
983 | 992 | const int maxCoord = 0x7FFF;/* Xft coordinates are 16 bit values */ |
984 | const int minCoord = -1000; /* Should be good enough... */ | |
993 | const int minCoord = -maxCoord-1; | |
985 | 994 | UnixFtFont *fontPtr = (UnixFtFont *) tkfont; |
986 | 995 | XGCValues values; |
987 | 996 | XftColor *xftcolor; |
1020 | 1029 | currentFtFont = NULL; |
1021 | 1030 | originX = originY = 0; /* lint */ |
1022 | 1031 | |
1023 | while (numBytes > 0 && x >= minCoord && y >= minCoord) { | |
1032 | while (numBytes > 0) { | |
1024 | 1033 | XftFont *ftFont; |
1025 | 1034 | FcChar32 c; |
1026 | 1035 | |
1049 | 1058 | * this information... but we'll be ready when it does! |
1050 | 1059 | */ |
1051 | 1060 | |
1052 | XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont, | |
1053 | originX, originY, glyphs, nglyph); | |
1061 | XftGlyphExtents(fontPtr->display, currentFtFont, glyphs, | |
1062 | nglyph, &metrics); | |
1063 | /* | |
1064 | * Draw glyph only when it fits entirely into 16 bit coords. | |
1065 | */ | |
1066 | ||
1067 | if (x >= minCoord && y >= minCoord && | |
1068 | x <= maxCoord - metrics.width && | |
1069 | y <= maxCoord - metrics.height) { | |
1070 | ||
1071 | /* | |
1072 | * NOTE: | |
1073 | * The whole algorithm has a design problem, the choice of | |
1074 | * NUM_SPEC is arbitrary, and so the inter-glyph spacing could | |
1075 | * look arbitrary. This algorithm has to draw the whole string | |
1076 | * at once (or whole blocks with same font), this requires a | |
1077 | * dynamic 'glyphs' array. In case of overflow the array has to | |
1078 | * be divided until the maximal string will fit. (GC) | |
1079 | * Given the resolution of current displays though, this should | |
1080 | * not be a huge issue since NUM_SPEC is 1024 and thus able to | |
1081 | * cover about 6000 pixels for a 6 pixel wide font (which is | |
1082 | * a very small barely readable font) | |
1083 | */ | |
1084 | ||
1085 | XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont, | |
1086 | originX, originY, glyphs, nglyph); | |
1087 | } | |
1054 | 1088 | } |
1055 | 1089 | originX = ROUND16(x); |
1056 | 1090 | originY = ROUND16(y); |
1057 | if (nglyph) { | |
1058 | XftGlyphExtents(fontPtr->display, currentFtFont, glyphs, | |
1059 | nglyph, &metrics); | |
1060 | nglyph = 0; | |
1061 | /* | |
1062 | * Breaking at this place is sub-optimal, but the whole algorithm | |
1063 | * has a design problem, the choice of NUM_SPEC is arbitrary, and so | |
1064 | * the inter-glyph spacing will look arbitrary. This algorithm | |
1065 | * has to draw the whole string at once (or whole blocks with same | |
1066 | * font), this requires a dynamic 'glyphs' array. In case of overflow | |
1067 | * the array has to be divided until the maximal string will fit. (GC) | |
1068 | */ | |
1069 | if ((x += metrics.xOff) >= maxCoord || (y += metrics.yOff) >= maxCoord) { | |
1070 | break; | |
1071 | } | |
1072 | } | |
1073 | 1091 | currentFtFont = ftFont; |
1074 | 1092 | } |
1075 | 1093 | glyphs[nglyph++] = XftCharIndex(fontPtr->display, ftFont, c); |
1076 | 1094 | } |
1077 | 1095 | if (nglyph) { |
1078 | XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont, | |
1079 | originX, originY, glyphs, nglyph); | |
1096 | XftGlyphExtents(fontPtr->display, currentFtFont, glyphs, | |
1097 | nglyph, &metrics); | |
1098 | ||
1099 | /* | |
1100 | * Draw glyph only when it fits entirely into 16 bit coords. | |
1101 | */ | |
1102 | ||
1103 | if (x >= minCoord && y >= minCoord && | |
1104 | x <= maxCoord - metrics.width && | |
1105 | y <= maxCoord - metrics.height) { | |
1106 | XftDrawGlyphs(fontPtr->ftDraw, xftcolor, currentFtFont, | |
1107 | originX, originY, glyphs, nglyph); | |
1108 | } | |
1080 | 1109 | } |
1081 | 1110 | #else /* !XFT_HAS_FIXED_ROTATED_PLACEMENT */ |
1082 | 1111 | int clen, nspec; |
1104 | 1133 | XftDrawSetClip(fontPtr->ftDraw, tsdPtr->clipRegion); |
1105 | 1134 | } |
1106 | 1135 | nspec = 0; |
1107 | while (numBytes > 0 && x >= minCoord && y >= minCoord) { | |
1136 | while (numBytes > 0) { | |
1108 | 1137 | XftFont *ftFont, *ft0Font; |
1109 | 1138 | FcChar32 c; |
1110 | 1139 | |
1122 | 1151 | ftFont = GetFont(fontPtr, c, angle); |
1123 | 1152 | ft0Font = GetFont(fontPtr, c, 0.0); |
1124 | 1153 | if (ftFont && ft0Font) { |
1125 | specs[nspec].font = ftFont; | |
1126 | 1154 | specs[nspec].glyph = XftCharIndex(fontPtr->display, ftFont, c); |
1127 | specs[nspec].x = ROUND16(x); | |
1128 | specs[nspec].y = ROUND16(y); | |
1129 | 1155 | XftGlyphExtents(fontPtr->display, ft0Font, &specs[nspec].glyph, 1, |
1130 | 1156 | &metrics); |
1131 | if ((x += metrics.xOff*cosA + metrics.yOff*sinA) > maxCoord | |
1132 | || (y += metrics.yOff*cosA - metrics.xOff*sinA) > maxCoord) { | |
1133 | break; | |
1134 | } | |
1135 | if (++nspec == NUM_SPEC) { | |
1136 | XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, | |
1137 | specs, nspec); | |
1138 | nspec = 0; | |
1157 | ||
1158 | /* | |
1159 | * Draw glyph only when it fits entirely into 16 bit coords. | |
1160 | */ | |
1161 | ||
1162 | if (x >= minCoord && y >= minCoord && | |
1163 | x <= maxCoord - metrics.width && | |
1164 | y <= maxCoord - metrics.height) { | |
1165 | specs[nspec].font = ftFont; | |
1166 | specs[nspec].x = ROUND16(x); | |
1167 | specs[nspec].y = ROUND16(y); | |
1168 | if (++nspec == NUM_SPEC) { | |
1169 | XftDrawGlyphFontSpec(fontPtr->ftDraw, xftcolor, | |
1170 | specs, nspec); | |
1171 | nspec = 0; | |
1172 | } | |
1139 | 1173 | } |
1174 | x += metrics.xOff*cosA + metrics.yOff*sinA; | |
1175 | y += metrics.yOff*cosA - metrics.xOff*sinA; | |
1140 | 1176 | } |
1141 | 1177 | } |
1142 | 1178 | if (nspec) { |
288 | 288 | scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth; |
289 | 289 | width = (scrollPtr->vertical) ? Tk_Width(scrollPtr->tkwin) |
290 | 290 | : Tk_Height(scrollPtr->tkwin); |
291 | ||
292 | /* | |
293 | * Next line assumes that the arrow area is a square. | |
294 | */ | |
295 | ||
291 | 296 | scrollPtr->arrowLength = width - 2*scrollPtr->inset + 1; |
292 | 297 | fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin) |
293 | 298 | : Tk_Width(scrollPtr->tkwin)) |
260 | 260 | unsigned long bytesAfter; |
261 | 261 | Atom actualType; |
262 | 262 | char **propertyPtr; |
263 | Tk_ErrorHandler handler; | |
263 | 264 | |
264 | 265 | if (dispPtr->commTkwin == NULL) { |
265 | 266 | SendInit(interp, dispPtr); |
266 | 267 | } |
268 | ||
269 | handler = Tk_CreateErrorHandler(dispPtr->display, -1, -1, -1, NULL, NULL); | |
267 | 270 | |
268 | 271 | regPtr = ckalloc(sizeof(NameRegistry)); |
269 | 272 | regPtr->dispPtr = dispPtr; |
305 | 308 | XDeleteProperty(dispPtr->display, |
306 | 309 | RootWindow(dispPtr->display, 0), |
307 | 310 | dispPtr->registryProperty); |
308 | } | |
311 | XSync(dispPtr->display, False); | |
312 | } | |
313 | ||
314 | Tk_DeleteErrorHandler(handler); | |
309 | 315 | |
310 | 316 | /* |
311 | 317 | * Xlib placed an extra null byte after the end of the property, just to |
513 | 519 | NameRegistry *regPtr) /* Pointer to a registry opened with a |
514 | 520 | * previous call to RegOpen. */ |
515 | 521 | { |
522 | Tk_ErrorHandler handler; | |
523 | ||
524 | handler = Tk_CreateErrorHandler(regPtr->dispPtr->display, -1, -1, -1, | |
525 | NULL, NULL); | |
526 | ||
516 | 527 | if (regPtr->modified) { |
517 | 528 | if (!regPtr->locked && !localData.sendDebug) { |
518 | 529 | Tcl_Panic("The name registry was modified without being locked!"); |
538 | 549 | */ |
539 | 550 | |
540 | 551 | XFlush(regPtr->dispPtr->display); |
552 | ||
553 | Tk_DeleteErrorHandler(handler); | |
541 | 554 | |
542 | 555 | if (regPtr->property != NULL) { |
543 | 556 | if (regPtr->allocedByX) { |
1094 | 1107 | Tcl_DStringAppend(&request, " ", 1); |
1095 | 1108 | Tcl_DStringAppend(&request, Tcl_GetString(objv[i]), -1); |
1096 | 1109 | } |
1110 | ||
1111 | if (!async) { | |
1112 | /* | |
1113 | * Register the fact that we're waiting for a command to complete | |
1114 | * (this is needed by SendEventProc and by AppendErrorProc to pass | |
1115 | * back the command's results). Set up a timeout handler so that | |
1116 | * we can check during long sends to make sure that the destination | |
1117 | * application is still alive. | |
1118 | * | |
1119 | * We prepare the pending struct here in order to catch potential | |
1120 | * early X errors from AppendPropCarefully() due to XSync(). | |
1121 | */ | |
1122 | ||
1123 | pending.serial = localData.sendSerial; | |
1124 | pending.dispPtr = dispPtr; | |
1125 | pending.target = destName; | |
1126 | pending.commWindow = commWindow; | |
1127 | pending.interp = interp; | |
1128 | pending.result = NULL; | |
1129 | pending.errorInfo = NULL; | |
1130 | pending.errorCode = NULL; | |
1131 | pending.gotResponse = 0; | |
1132 | pending.nextPtr = tsdPtr->pendingCommands; | |
1133 | tsdPtr->pendingCommands = &pending; | |
1134 | } | |
1097 | 1135 | (void) AppendPropCarefully(dispPtr->display, commWindow, |
1098 | 1136 | dispPtr->commProperty, Tcl_DStringValue(&request), |
1099 | 1137 | Tcl_DStringLength(&request) + 1, (async ? NULL : &pending)); |
1106 | 1144 | |
1107 | 1145 | return TCL_OK; |
1108 | 1146 | } |
1109 | ||
1110 | /* | |
1111 | * Register the fact that we're waiting for a command to complete (this is | |
1112 | * needed by SendEventProc and by AppendErrorProc to pass back the | |
1113 | * command's results). Set up a timeout handler so that we can check | |
1114 | * during long sends to make sure that the destination application is | |
1115 | * still alive. | |
1116 | */ | |
1117 | ||
1118 | pending.serial = localData.sendSerial; | |
1119 | pending.dispPtr = dispPtr; | |
1120 | pending.target = destName; | |
1121 | pending.commWindow = commWindow; | |
1122 | pending.interp = interp; | |
1123 | pending.result = NULL; | |
1124 | pending.errorInfo = NULL; | |
1125 | pending.errorCode = NULL; | |
1126 | pending.gotResponse = 0; | |
1127 | pending.nextPtr = tsdPtr->pendingCommands; | |
1128 | tsdPtr->pendingCommands = &pending; | |
1129 | 1147 | |
1130 | 1148 | /* |
1131 | 1149 | * Enter a loop processing X events until the result comes in or the |
1950 | 1968 | "bogus", "prop", "serial", NULL |
1951 | 1969 | }; |
1952 | 1970 | TkWindow *winPtr = clientData; |
1971 | Tk_ErrorHandler handler; | |
1953 | 1972 | int index; |
1954 | 1973 | |
1955 | 1974 | if (objc < 2) { |
1958 | 1977 | return TCL_ERROR; |
1959 | 1978 | } |
1960 | 1979 | |
1961 | if (Tcl_GetIndexFromObjStruct(interp, objv[1], testsendOptions, | |
1980 | if (Tcl_GetIndexFromObjStruct(interp, objv[1], testsendOptions, | |
1962 | 1981 | sizeof(char *), "option", 0, &index) != TCL_OK) { |
1963 | return TCL_ERROR; | |
1964 | } | |
1965 | if (index == TESTSEND_BOGUS) { | |
1982 | return TCL_ERROR; | |
1983 | } | |
1984 | if (index == TESTSEND_BOGUS) { | |
1985 | handler = Tk_CreateErrorHandler(winPtr->dispPtr->display, -1, -1, -1, | |
1986 | NULL, NULL); | |
1966 | 1987 | XChangeProperty(winPtr->dispPtr->display, |
1967 | 1988 | RootWindow(winPtr->dispPtr->display, 0), |
1968 | 1989 | winPtr->dispPtr->registryProperty, XA_INTEGER, 32, |
1969 | 1990 | PropModeReplace, |
1970 | 1991 | (unsigned char *) "This is bogus information", 6); |
1992 | Tk_DeleteErrorHandler(handler); | |
1971 | 1993 | } else if (index == TESTSEND_PROP) { |
1972 | 1994 | int result, actualFormat; |
1973 | 1995 | unsigned long length, bytesAfter; |
2006 | 2028 | XFree(property); |
2007 | 2029 | } |
2008 | 2030 | } else if (Tcl_GetString(objv[4])[0] == 0) { |
2031 | handler = Tk_CreateErrorHandler(winPtr->dispPtr->display, | |
2032 | -1, -1, -1, NULL, NULL); | |
2009 | 2033 | XDeleteProperty(winPtr->dispPtr->display, w, propName); |
2034 | Tk_DeleteErrorHandler(handler); | |
2010 | 2035 | } else { |
2011 | 2036 | Tcl_DString tmp; |
2012 | 2037 | |
2017 | 2042 | *p = 0; |
2018 | 2043 | } |
2019 | 2044 | } |
2020 | ||
2045 | handler = Tk_CreateErrorHandler(winPtr->dispPtr->display, | |
2046 | -1, -1, -1, NULL, NULL); | |
2021 | 2047 | XChangeProperty(winPtr->dispPtr->display, w, propName, XA_STRING, |
2022 | 2048 | 8, PropModeReplace, (unsigned char*)Tcl_DStringValue(&tmp), |
2023 | 2049 | p-Tcl_DStringValue(&tmp)); |
2050 | Tk_DeleteErrorHandler(handler); | |
2024 | 2051 | Tcl_DStringFree(&tmp); |
2025 | 2052 | } |
2026 | 2053 | } else if (index == TESTSEND_SERIAL) { |
206 | 206 | # Tk does not used deprecated Tcl constructs so it should |
207 | 207 | # compile fine with -DTCL_NO_DEPRECATED. To remove its own |
208 | 208 | # set of deprecated code uncomment the second line. |
209 | NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED | |
210 | #NO_DEPRECATED_FLAGS = -DTCL_NO_DEPRECATED -DTK_NO_DEPRECATED | |
209 | NO_DEPRECATED_FLAGS = | |
210 | #NO_DEPRECATED_FLAGS = -DTK_NO_DEPRECATED | |
211 | 211 | |
212 | 212 | # TCL_EXE is the name of a tclsh executable that is available *BEFORE* |
213 | 213 | # running make for the first time. Certain build targets (make genstubs) |
1311 | 1311 | TK_VERSION=8.6 |
1312 | 1312 | TK_MAJOR_VERSION=8 |
1313 | 1313 | TK_MINOR_VERSION=6 |
1314 | TK_PATCH_LEVEL=".8" | |
1314 | TK_PATCH_LEVEL=".9" | |
1315 | 1315 | VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION |
1316 | 1316 | |
1317 | 1317 | #------------------------------------------------------------------------ |
13 | 13 | TK_VERSION=8.6 |
14 | 14 | TK_MAJOR_VERSION=8 |
15 | 15 | TK_MINOR_VERSION=6 |
16 | TK_PATCH_LEVEL=".8" | |
16 | TK_PATCH_LEVEL=".9" | |
17 | 17 | VER=$TK_MAJOR_VERSION$TK_MINOR_VERSION |
18 | 18 | |
19 | 19 | #------------------------------------------------------------------------ |
89 | 89 | |
90 | 90 | # TCLINSTALL is set to 1 by rules.vc to indicate we are building against |
91 | 91 | # an installed Tcl and 0 if building against Tcl source. Tk needs the latter. |
92 | !message TCLINSTALL=$(TCLINSTALL) | |
93 | 92 | !if $(TCLINSTALL) |
94 | 93 | !message *** Warning: Tk requires the source distribution of Tcl to build from, |
95 | 94 | !message *** at this time, sorry. Please set the TCLDIR macro to point to the |
738 | 738 | #if 0 /* This function is not available in Visual C++ 6 */ |
739 | 739 | /* |
740 | 740 | * Use numerics 0 -> FindExInfoStandard, |
741 | * 1 -> FindExSearchLimitToDirectories, | |
741 | * 1 -> FindExSearchLimitToDirectories, | |
742 | 742 | * as these are not defined in Visual C++ 6 |
743 | 743 | */ |
744 | 744 | hSearch = FindFirstFileEx(path, 0, &finfo, 1, NULL, 0); |
753 | 753 | do { |
754 | 754 | int sublen; |
755 | 755 | /* |
756 | * We need to check it is a directory despite the | |
756 | * We need to check it is a directory despite the | |
757 | 757 | * FindExSearchLimitToDirectories in the above call. See SDK docs |
758 | 758 | */ |
759 | 759 | if ((finfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) |
784 | 784 | * that is used to confirm it is the correct directory. |
785 | 785 | * The search path for the package directory is currently only |
786 | 786 | * the parent and grandparent of the current working directory. |
787 | * If found, the command prints | |
787 | * If found, the command prints | |
788 | 788 | * name_DIRPATH=<full path of located directory> |
789 | 789 | * and returns 0. If not found, does not print anything and returns 1. |
790 | 790 | */ |
792 | 792 | { |
793 | 793 | int i, ret; |
794 | 794 | static char *paths[] = {"..", "..\\..", "..\\..\\.."}; |
795 | ||
795 | ||
796 | 796 | for (i = 0; i < (sizeof(paths)/sizeof(paths[0])); ++i) { |
797 | 797 | ret = LocateDependencyHelper(paths[i], keypath); |
798 | 798 | if (ret == 0) |
0 | # This file should only be included in makefiles for Tcl extensions, | |
1 | # NOT in the makefile for Tcl itself. | |
2 | ||
3 | !ifndef _RULES_EXT_VC | |
4 | ||
5 | # We need to run from the directory the parent makefile is located in. | |
6 | # nmake does not tell us what makefile was used to invoke it so parent | |
7 | # makefile has to set the MAKEFILEVC macro or we just make a guess and | |
8 | # warn if we think that is not the case. | |
9 | !if "$(MAKEFILEVC)" == "" | |
10 | ||
11 | !if exist("$(PROJECT).vc") | |
12 | MAKEFILEVC = $(PROJECT).vc | |
13 | !elseif exist("makefile.vc") | |
14 | MAKEFILEVC = makefile.vc | |
15 | !endif | |
16 | !endif # "$(MAKEFILEVC)" == "" | |
17 | ||
18 | !if !exist("$(MAKEFILEVC)") | |
19 | MSG = ^ | |
20 | You must run nmake from the directory containing the project makefile.^ | |
21 | If you are doing that and getting this message, set the MAKEFILEVC^ | |
22 | macro to the name of the project makefile. | |
23 | !message WARNING: $(MSG) | |
24 | !endif | |
25 | ||
26 | !if "$(PROJECT)" == "tcl" | |
27 | !error The rules-ext.vc file is not intended for Tcl itself. | |
28 | !endif | |
29 | ||
30 | # We extract version numbers using the nmakehlp program. For now use | |
31 | # the local copy of nmakehlp. Once we locate Tcl, we will use that | |
32 | # one if it is newer. | |
33 | !if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul] | |
34 | !endif | |
35 | ||
36 | # First locate the Tcl directory that we are working with. | |
37 | !ifdef TCLDIR | |
38 | ||
39 | _RULESDIR = $(TCLDIR:/=\) | |
40 | ||
41 | !else | |
42 | ||
43 | # If an installation path is specified, that is also the Tcl directory. | |
44 | # Also Tk never builds against an installed Tcl, it needs Tcl sources | |
45 | !if defined(INSTALLDIR) && "$(PROJECT)" != "tk" | |
46 | _RULESDIR=$(INSTALLDIR:/=\) | |
47 | !else | |
48 | # Locate Tcl sources | |
49 | !if [echo _RULESDIR = \> nmakehlp.out] \ | |
50 | || [nmakehlp -L generic\tcl.h >> nmakehlp.out] | |
51 | _RULESDIR = ..\..\tcl | |
52 | !else | |
53 | !include nmakehlp.out | |
54 | !endif | |
55 | ||
56 | !endif # defined(INSTALLDIR).... | |
57 | ||
58 | !endif # ifndef TCLDIR | |
59 | ||
60 | # Now look for the targets.vc file under the Tcl root. Note we check this | |
61 | # file and not rules.vc because the latter also exists on older systems. | |
62 | !if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl | |
63 | _RULESDIR = $(_RULESDIR)\lib\nmake | |
64 | !elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources | |
65 | _RULESDIR = $(_RULESDIR)\win | |
66 | !else | |
67 | # If we have not located Tcl's targets file, most likely we are compiling | |
68 | # against an older version of Tcl and so must use our own support files. | |
69 | _RULESDIR = . | |
70 | !endif | |
71 | ||
72 | !if "$(_RULESDIR)" != "." | |
73 | # Potentially using Tcl's support files. If this extension has its own | |
74 | # nmake support files, need to compare the versions and pick newer. | |
75 | ||
76 | !if exist("rules.vc") # The extension has its own copy | |
77 | ||
78 | !if [echo TCL_RULES_MAJOR = \> versions.vc] \ | |
79 | && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc] | |
80 | !endif | |
81 | !if [echo TCL_RULES_MINOR = \>> versions.vc] \ | |
82 | && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc] | |
83 | !endif | |
84 | ||
85 | !if [echo OUR_RULES_MAJOR = \>> versions.vc] \ | |
86 | && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc] | |
87 | !endif | |
88 | !if [echo OUR_RULES_MINOR = \>> versions.vc] \ | |
89 | && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc] | |
90 | !endif | |
91 | !include versions.vc | |
92 | # We have a newer version of the support files, use them | |
93 | !if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR)) | |
94 | _RULESDIR = . | |
95 | !endif | |
96 | ||
97 | !endif # if exist("rules.vc") | |
98 | ||
99 | !endif # if $(_RULESDIR) != "." | |
100 | ||
101 | # Let rules.vc know what copy of nmakehlp.c to use. | |
102 | NMAKEHLPC = $(_RULESDIR)\nmakehlp.c | |
103 | ||
104 | # Get rid of our internal defines before calling rules.vc | |
105 | !undef TCL_RULES_MAJOR | |
106 | !undef TCL_RULES_MINOR | |
107 | !undef OUR_RULES_MAJOR | |
108 | !undef OUR_RULES_MINOR | |
109 | ||
110 | !if exist("$(_RULESDIR)\rules.vc") | |
111 | !message *** Using $(_RULESDIR)\rules.vc | |
112 | !include "$(_RULESDIR)\rules.vc" | |
113 | !else | |
114 | !error *** Could not locate rules.vc in $(_RULESDIR) | |
115 | !endif | |
116 | ||
0 | # This file should only be included in makefiles for Tcl extensions, | |
1 | # NOT in the makefile for Tcl itself. | |
2 | ||
3 | !ifndef _RULES_EXT_VC | |
4 | ||
5 | # We need to run from the directory the parent makefile is located in. | |
6 | # nmake does not tell us what makefile was used to invoke it so parent | |
7 | # makefile has to set the MAKEFILEVC macro or we just make a guess and | |
8 | # warn if we think that is not the case. | |
9 | !if "$(MAKEFILEVC)" == "" | |
10 | ||
11 | !if exist("$(PROJECT).vc") | |
12 | MAKEFILEVC = $(PROJECT).vc | |
13 | !elseif exist("makefile.vc") | |
14 | MAKEFILEVC = makefile.vc | |
15 | !endif | |
16 | !endif # "$(MAKEFILEVC)" == "" | |
17 | ||
18 | !if !exist("$(MAKEFILEVC)") | |
19 | MSG = ^ | |
20 | You must run nmake from the directory containing the project makefile.^ | |
21 | If you are doing that and getting this message, set the MAKEFILEVC^ | |
22 | macro to the name of the project makefile. | |
23 | !message WARNING: $(MSG) | |
24 | !endif | |
25 | ||
26 | !if "$(PROJECT)" == "tcl" | |
27 | !error The rules-ext.vc file is not intended for Tcl itself. | |
28 | !endif | |
29 | ||
30 | # We extract version numbers using the nmakehlp program. For now use | |
31 | # the local copy of nmakehlp. Once we locate Tcl, we will use that | |
32 | # one if it is newer. | |
33 | !if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul] | |
34 | !endif | |
35 | ||
36 | # First locate the Tcl directory that we are working with. | |
37 | !ifdef TCLDIR | |
38 | ||
39 | _RULESDIR = $(TCLDIR:/=\) | |
40 | ||
41 | !else | |
42 | ||
43 | # If an installation path is specified, that is also the Tcl directory. | |
44 | # Also Tk never builds against an installed Tcl, it needs Tcl sources | |
45 | !if defined(INSTALLDIR) && "$(PROJECT)" != "tk" | |
46 | _RULESDIR=$(INSTALLDIR:/=\) | |
47 | !else | |
48 | # Locate Tcl sources | |
49 | !if [echo _RULESDIR = \> nmakehlp.out] \ | |
50 | || [nmakehlp -L generic\tcl.h >> nmakehlp.out] | |
51 | _RULESDIR = ..\..\tcl | |
52 | !else | |
53 | !include nmakehlp.out | |
54 | !endif | |
55 | ||
56 | !endif # defined(INSTALLDIR).... | |
57 | ||
58 | !endif # ifndef TCLDIR | |
59 | ||
60 | # Now look for the targets.vc file under the Tcl root. Note we check this | |
61 | # file and not rules.vc because the latter also exists on older systems. | |
62 | !if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl | |
63 | _RULESDIR = $(_RULESDIR)\lib\nmake | |
64 | !elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources | |
65 | _RULESDIR = $(_RULESDIR)\win | |
66 | !else | |
67 | # If we have not located Tcl's targets file, most likely we are compiling | |
68 | # against an older version of Tcl and so must use our own support files. | |
69 | _RULESDIR = . | |
70 | !endif | |
71 | ||
72 | !if "$(_RULESDIR)" != "." | |
73 | # Potentially using Tcl's support files. If this extension has its own | |
74 | # nmake support files, need to compare the versions and pick newer. | |
75 | ||
76 | !if exist("rules.vc") # The extension has its own copy | |
77 | ||
78 | !if [echo TCL_RULES_MAJOR = \> versions.vc] \ | |
79 | && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc] | |
80 | !endif | |
81 | !if [echo TCL_RULES_MINOR = \>> versions.vc] \ | |
82 | && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc] | |
83 | !endif | |
84 | ||
85 | !if [echo OUR_RULES_MAJOR = \>> versions.vc] \ | |
86 | && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc] | |
87 | !endif | |
88 | !if [echo OUR_RULES_MINOR = \>> versions.vc] \ | |
89 | && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc] | |
90 | !endif | |
91 | !include versions.vc | |
92 | # We have a newer version of the support files, use them | |
93 | !if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR)) | |
94 | _RULESDIR = . | |
95 | !endif | |
96 | ||
97 | !endif # if exist("rules.vc") | |
98 | ||
99 | !endif # if $(_RULESDIR) != "." | |
100 | ||
101 | # Let rules.vc know what copy of nmakehlp.c to use. | |
102 | NMAKEHLPC = $(_RULESDIR)\nmakehlp.c | |
103 | ||
104 | # Get rid of our internal defines before calling rules.vc | |
105 | !undef TCL_RULES_MAJOR | |
106 | !undef TCL_RULES_MINOR | |
107 | !undef OUR_RULES_MAJOR | |
108 | !undef OUR_RULES_MINOR | |
109 | ||
110 | !if exist("$(_RULESDIR)\rules.vc") | |
111 | !message *** Using $(_RULESDIR)\rules.vc | |
112 | !include "$(_RULESDIR)\rules.vc" | |
113 | !else | |
114 | !error *** Could not locate rules.vc in $(_RULESDIR) | |
115 | !endif | |
116 | ||
117 | 117 | !endif # _RULES_EXT_VC⏎ |
23 | 23 | # For modifications that are not backward-compatible, you *must* change |
24 | 24 | # the major version. |
25 | 25 | RULES_VERSION_MAJOR = 1 |
26 | RULES_VERSION_MINOR = 0 | |
26 | RULES_VERSION_MINOR = 1 | |
27 | 27 | |
28 | 28 | # The PROJECT macro must be defined by parent makefile. |
29 | 29 | !if "$(PROJECT)" == "" |
534 | 534 | |
535 | 535 | # We always build nmakehlp even if it exists since we do not know |
536 | 536 | # what source it was built from. |
537 | !message *** Using $(NMAKEHLPC) | |
538 | 537 | !if [$(cc32) -nologo "$(NMAKEHLPC)" -link -subsystem:console > nul] |
539 | 538 | !endif |
540 | 539 | |
589 | 588 | OPTIMIZATIONS = $(FPOPTS) |
590 | 589 | |
591 | 590 | !if [nmakehlp -c -O2] |
592 | !message *** Compiler has 'Optimizations' | |
593 | 591 | OPTIMIZING = 1 |
594 | 592 | OPTIMIZATIONS = $(OPTIMIZATIONS) -O2 |
595 | 593 | !else |
1076 | 1074 | |
1077 | 1075 | !if $(TCLINSTALL) # Building against an installed Tcl |
1078 | 1076 | |
1077 | # When building extensions, we need to locate tclsh. Depending on version | |
1078 | # of Tcl we are building against, this may or may not have a "t" suffix. | |
1079 | # Try various possibilities in turn. | |
1079 | 1080 | TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX).exe |
1080 | 1081 | !if !exist("$(TCLSH)") && $(TCL_THREADS) |
1081 | 1082 | TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)t$(SUFX).exe |
1082 | 1083 | !endif |
1084 | !if !exist("$(TCLSH)") | |
1085 | TCLSH = $(_TCLDIR)\bin\tclsh$(TCL_VERSION)$(SUFX:t=).exe | |
1086 | !endif | |
1087 | ||
1083 | 1088 | TCLSTUBLIB = $(_TCLDIR)\lib\tclstub$(TCL_VERSION).lib |
1084 | 1089 | TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX).lib |
1090 | # When building extensions, may be linking against Tcl that does not add | |
1091 | # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. | |
1092 | !if !exist("$(TCLIMPLIB)") | |
1093 | TCLIMPLIB = $(_TCLDIR)\lib\tcl$(TCL_VERSION)$(SUFX:t=).lib | |
1094 | !endif | |
1085 | 1095 | TCL_LIBRARY = $(_TCLDIR)\lib |
1086 | 1096 | TCLREGLIB = $(_TCLDIR)\lib\tclreg13$(SUFX:t=).lib |
1087 | 1097 | TCLDDELIB = $(_TCLDIR)\lib\tcldde14$(SUFX:t=).lib |
1094 | 1104 | !if !exist($(TCLSH)) && $(TCL_THREADS) |
1095 | 1105 | TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)t$(SUFX).exe |
1096 | 1106 | !endif |
1107 | !if !exist($(TCLSH)) | |
1108 | TCLSH = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclsh$(TCL_VERSION)$(SUFX:t=).exe | |
1109 | !endif | |
1097 | 1110 | TCLSTUBLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclstub$(TCL_VERSION).lib |
1098 | 1111 | TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX).lib |
1112 | # When building extensions, may be linking against Tcl that does not add | |
1113 | # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. | |
1114 | !if !exist("$(TCLIMPLIB)") | |
1115 | TCLIMPLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcl$(TCL_VERSION)$(SUFX:t=).lib | |
1116 | !endif | |
1099 | 1117 | TCL_LIBRARY = $(_TCLDIR)\library |
1100 | 1118 | TCLREGLIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tclreg13$(SUFX:t=).lib |
1101 | 1119 | TCLDDELIB = $(_TCLDIR)\win\$(BUILDDIRTOP)\tcldde14$(SUFX:t=).lib |
1139 | 1157 | WISH = $(_TKDIR)\bin\$(WISHNAME) |
1140 | 1158 | TKSTUBLIB = $(_TKDIR)\lib\$(TKSTUBLIBNAME) |
1141 | 1159 | TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME) |
1160 | # When building extensions, may be linking against Tk that does not add | |
1161 | # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. | |
1162 | !if !exist("$(TKIMPLIB)") | |
1163 | TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib | |
1164 | TKIMPLIB = $(_TKDIR)\lib\$(TKIMPLIBNAME) | |
1165 | !endif | |
1142 | 1166 | TK_INCLUDES = -I"$(_TKDIR)\include" |
1143 | 1167 | !else # Building against Tk sources |
1144 | 1168 | WISH = $(_TKDIR)\win\$(BUILDDIRTOP)\$(WISHNAME) |
1145 | 1169 | TKSTUBLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKSTUBLIBNAME) |
1146 | 1170 | TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME) |
1171 | # When building extensions, may be linking against Tk that does not add | |
1172 | # "t" suffix (e.g. 8.5 or 8.7). If lib not found check for that possibility. | |
1173 | !if !exist("$(TKIMPLIB)") | |
1174 | TKIMPLIBNAME = tk$(TK_VERSION)$(SUFX:t=).lib | |
1175 | TKIMPLIB = $(_TKDIR)\win\$(BUILDDIRTOP)\$(TKIMPLIBNAME) | |
1176 | !endif | |
1147 | 1177 | TK_INCLUDES = -I"$(_TKDIR)\generic" -I"$(_TKDIR)\win" -I"$(_TKDIR)\xlib" |
1148 | 1178 | !endif # TKINSTALL |
1149 | 1179 | tklibs = "$(TKSTUBLIB)" "$(TKIMPLIB)" |
1716 | 1746 | !message *** Output directory will be '$(OUT_DIR)' |
1717 | 1747 | !message *** Installation, if selected, will be in '$(_INSTALLDIR)' |
1718 | 1748 | !message *** Suffix for binaries will be '$(SUFX)' |
1719 | !message *** Compiler version $(VCVER). Target machine is $(MACHINE) | |
1720 | !message *** Host architecture is $(NATIVE_ARCH) | |
1749 | !message *** Compiler version $(VCVER). Target $(MACHINE), host $(NATIVE_ARCH). | |
1721 | 1750 | |
1722 | 1751 | !endif # ifdef _RULES_VC |
0 | #------------------------------------------------------------- -*- makefile -*- | |
1 | # targets.vc -- | |
2 | # | |
3 | # Part of the nmake based build system for Tcl and its extensions. | |
4 | # This file defines some standard targets for the convenience of extensions | |
5 | # and can be optionally included by the extension makefile. | |
6 | # See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs. | |
7 | ||
8 | $(PROJECT): setup pkgindex $(PRJLIB) | |
9 | ||
10 | !ifdef PRJ_STUBOBJS | |
11 | $(PROJECT): $(PRJSTUBLIB) | |
12 | $(PRJSTUBLIB): $(PRJ_STUBOBJS) | |
13 | $(LIBCMD) $** | |
14 | ||
15 | $(PRJ_STUBOBJS): | |
16 | $(CCSTUBSCMD) %s | |
17 | !endif # PRJ_STUBOBJS | |
18 | ||
19 | !ifdef PRJ_MANIFEST | |
20 | $(PROJECT): $(PRJLIB).manifest | |
21 | $(PRJLIB).manifest: $(PRJ_MANIFEST) | |
22 | @nmakehlp -s << $** >$@ | |
23 | @MACHINE@ $(MACHINE:IX86=X86) | |
24 | << | |
25 | !endif | |
26 | ||
27 | !if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk" | |
28 | $(PRJLIB): $(PRJ_OBJS) $(RESFILE) | |
29 | !if $(STATIC_BUILD) | |
30 | $(LIBCMD) $** | |
31 | !else | |
32 | $(DLLCMD) $** | |
33 | $(_VC_MANIFEST_EMBED_DLL) | |
34 | !endif | |
35 | -@del $*.exp | |
36 | !endif | |
37 | ||
38 | !if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != "" | |
39 | $(PRJ_OBJS): $(PRJ_HEADERS) | |
40 | !endif | |
41 | ||
42 | # If parent makefile has defined stub objects, add their installation | |
43 | # to the default install | |
44 | !if "$(PRJ_STUBOBJS)" != "" | |
45 | default-install: default-install-stubs | |
46 | !endif | |
47 | ||
48 | # Unlike the other default targets, these cannot be in rules.vc because | |
49 | # the executed command depends on existence of macro PRJ_HEADERS_PUBLIC | |
50 | # that the parent makefile will not define until after including rules-ext.vc | |
51 | !if "$(PRJ_HEADERS_PUBLIC)" != "" | |
52 | default-install: default-install-headers | |
53 | default-install-headers: | |
54 | @echo Installing headers to '$(INCLUDE_INSTALL_DIR)' | |
55 | @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)" | |
56 | !endif | |
57 | ||
58 | !if "$(DISABLE_STANDARD_TARGETS)" == "" | |
59 | DISABLE_STANDARD_TARGETS = 0 | |
60 | !endif | |
61 | ||
62 | !if "$(DISABLE_TARGET_setup)" == "" | |
63 | DISABLE_TARGET_setup = 0 | |
64 | !endif | |
65 | !if "$(DISABLE_TARGET_install)" == "" | |
66 | DISABLE_TARGET_install = 0 | |
67 | !endif | |
68 | !if "$(DISABLE_TARGET_clean)" == "" | |
69 | DISABLE_TARGET_clean = 0 | |
70 | !endif | |
71 | !if "$(DISABLE_TARGET_test)" == "" | |
72 | DISABLE_TARGET_test = 0 | |
73 | !endif | |
74 | !if "$(DISABLE_TARGET_shell)" == "" | |
75 | DISABLE_TARGET_shell = 0 | |
76 | !endif | |
77 | ||
78 | !if !$(DISABLE_STANDARD_TARGETS) | |
79 | !if !$(DISABLE_TARGET_setup) | |
80 | setup: default-setup | |
81 | !endif | |
82 | !if !$(DISABLE_TARGET_install) | |
83 | install: default-install | |
84 | !endif | |
85 | !if !$(DISABLE_TARGET_clean) | |
86 | clean: default-clean | |
87 | realclean: hose | |
88 | hose: default-hose | |
89 | distclean: realclean default-distclean | |
90 | !endif | |
91 | !if !$(DISABLE_TARGET_test) | |
92 | test: default-test | |
93 | !endif | |
94 | !if !$(DISABLE_TARGET_shell) | |
95 | shell: default-shell | |
96 | !endif | |
97 | !endif # DISABLE_STANDARD_TARGETS | |
0 | #------------------------------------------------------------- -*- makefile -*- | |
1 | # targets.vc -- | |
2 | # | |
3 | # Part of the nmake based build system for Tcl and its extensions. | |
4 | # This file defines some standard targets for the convenience of extensions | |
5 | # and can be optionally included by the extension makefile. | |
6 | # See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for docs. | |
7 | ||
8 | $(PROJECT): setup pkgindex $(PRJLIB) | |
9 | ||
10 | !ifdef PRJ_STUBOBJS | |
11 | $(PROJECT): $(PRJSTUBLIB) | |
12 | $(PRJSTUBLIB): $(PRJ_STUBOBJS) | |
13 | $(LIBCMD) $** | |
14 | ||
15 | $(PRJ_STUBOBJS): | |
16 | $(CCSTUBSCMD) %s | |
17 | !endif # PRJ_STUBOBJS | |
18 | ||
19 | !ifdef PRJ_MANIFEST | |
20 | $(PROJECT): $(PRJLIB).manifest | |
21 | $(PRJLIB).manifest: $(PRJ_MANIFEST) | |
22 | @nmakehlp -s << $** >$@ | |
23 | @MACHINE@ $(MACHINE:IX86=X86) | |
24 | << | |
25 | !endif | |
26 | ||
27 | !if "$(PROJECT)" != "tcl" && "$(PROJECT)" != "tk" | |
28 | $(PRJLIB): $(PRJ_OBJS) $(RESFILE) | |
29 | !if $(STATIC_BUILD) | |
30 | $(LIBCMD) $** | |
31 | !else | |
32 | $(DLLCMD) $** | |
33 | $(_VC_MANIFEST_EMBED_DLL) | |
34 | !endif | |
35 | -@del $*.exp | |
36 | !endif | |
37 | ||
38 | !if "$(PRJ_HEADERS)" != "" && "$(PRJ_OBJS)" != "" | |
39 | $(PRJ_OBJS): $(PRJ_HEADERS) | |
40 | !endif | |
41 | ||
42 | # If parent makefile has defined stub objects, add their installation | |
43 | # to the default install | |
44 | !if "$(PRJ_STUBOBJS)" != "" | |
45 | default-install: default-install-stubs | |
46 | !endif | |
47 | ||
48 | # Unlike the other default targets, these cannot be in rules.vc because | |
49 | # the executed command depends on existence of macro PRJ_HEADERS_PUBLIC | |
50 | # that the parent makefile will not define until after including rules-ext.vc | |
51 | !if "$(PRJ_HEADERS_PUBLIC)" != "" | |
52 | default-install: default-install-headers | |
53 | default-install-headers: | |
54 | @echo Installing headers to '$(INCLUDE_INSTALL_DIR)' | |
55 | @for %f in ($(PRJ_HEADERS_PUBLIC)) do @$(COPY) %f "$(INCLUDE_INSTALL_DIR)" | |
56 | !endif | |
57 | ||
58 | !if "$(DISABLE_STANDARD_TARGETS)" == "" | |
59 | DISABLE_STANDARD_TARGETS = 0 | |
60 | !endif | |
61 | ||
62 | !if "$(DISABLE_TARGET_setup)" == "" | |
63 | DISABLE_TARGET_setup = 0 | |
64 | !endif | |
65 | !if "$(DISABLE_TARGET_install)" == "" | |
66 | DISABLE_TARGET_install = 0 | |
67 | !endif | |
68 | !if "$(DISABLE_TARGET_clean)" == "" | |
69 | DISABLE_TARGET_clean = 0 | |
70 | !endif | |
71 | !if "$(DISABLE_TARGET_test)" == "" | |
72 | DISABLE_TARGET_test = 0 | |
73 | !endif | |
74 | !if "$(DISABLE_TARGET_shell)" == "" | |
75 | DISABLE_TARGET_shell = 0 | |
76 | !endif | |
77 | ||
78 | !if !$(DISABLE_STANDARD_TARGETS) | |
79 | !if !$(DISABLE_TARGET_setup) | |
80 | setup: default-setup | |
81 | !endif | |
82 | !if !$(DISABLE_TARGET_install) | |
83 | install: default-install | |
84 | !endif | |
85 | !if !$(DISABLE_TARGET_clean) | |
86 | clean: default-clean | |
87 | realclean: hose | |
88 | hose: default-hose | |
89 | distclean: realclean default-distclean | |
90 | !endif | |
91 | !if !$(DISABLE_TARGET_test) | |
92 | test: default-test | |
93 | !endif | |
94 | !if !$(DISABLE_TARGET_shell) | |
95 | shell: default-shell | |
96 | !endif | |
97 | !endif # DISABLE_STANDARD_TARGETS |
3377 | 3377 | if (hdPtr->fontObj) { |
3378 | 3378 | Tcl_DecrRefCount(hdPtr->fontObj); |
3379 | 3379 | } |
3380 | (void)Tcl_GetString(objv[i+1]); | |
3380 | Tcl_GetString(objv[i+1]); | |
3381 | 3381 | if (objv[i+1]->length) { |
3382 | 3382 | hdPtr->fontObj = objv[i+1]; |
3383 | 3383 | if (Tcl_IsShared(hdPtr->fontObj)) { |
3392 | 3392 | if (hdPtr->cmdObj) { |
3393 | 3393 | Tcl_DecrRefCount(hdPtr->cmdObj); |
3394 | 3394 | } |
3395 | (void)Tcl_GetString(objv[i+1]); | |
3395 | Tcl_GetString(objv[i+1]); | |
3396 | 3396 | if (objv[i+1]->length) { |
3397 | 3397 | hdPtr->cmdObj = objv[i+1]; |
3398 | 3398 | if (Tcl_IsShared(hdPtr->cmdObj)) { |
199 | 199 | * The TK_INFO messages are required in order to verify if the window to |
200 | 200 | * use is a valid container. Without an id verification, an invalid |
201 | 201 | * window attachment may cause unexpected crashes/panics (bug 1096074). |
202 | * Additional sub messages may be definded/used in future for other | |
202 | * Additional sub messages may be defined/used in future for other | |
203 | 203 | * needs. |
204 | 204 | * |
205 | 205 | * We do not enforce the above protocol for the reason of backward |
302 | 302 | * order to avoid bug 1096074 in future. |
303 | 303 | */ |
304 | 304 | |
305 | char msg[256]; | |
306 | ||
307 | 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); | |
308 | if (IDCANCEL == MessageBoxA(hwnd, msg, "Tk Warning", | |
305 | TCHAR msg[256]; | |
306 | ||
307 | 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); | |
308 | if (IDCANCEL == MessageBox(hwnd, msg, TEXT("Tk Warning"), | |
309 | 309 | MB_OKCANCEL | MB_ICONWARNING)) { |
310 | 310 | Tcl_SetObjResult(interp, Tcl_NewStringObj( |
311 | 311 | "Operation has been canceled", -1)); |
1481 | 1481 | Tk_GetPixelsFromObj(menuPtr->interp, menuPtr->tkwin, |
1482 | 1482 | menuPtr->borderWidthPtr, &borderWidth); |
1483 | 1483 | *widthPtr = indicatorDimensions[1] - borderWidth; |
1484 | ||
1485 | /* | |
1486 | * Quite dubious about the above (why would borderWidth play a role?) | |
1487 | * and about how indicatorDimensions[1] is obtained in SetDefaults(). | |
1488 | * At least don't let the result be negative! | |
1489 | */ | |
1490 | if (*widthPtr < 0) { | |
1491 | *widthPtr = 0; | |
1492 | } | |
1484 | 1493 | } |
1485 | 1494 | } |
1486 | 1495 | |
1839 | 1848 | int width, /* Width of menu entry */ |
1840 | 1849 | int height, /* Height of menu entry */ |
1841 | 1850 | int drawArrow) /* For cascade menus, whether of not to draw |
1842 | * the arraw. I cannot figure out Windows' | |
1851 | * the arrow. I cannot figure out Windows' | |
1843 | 1852 | * algorithm for where to draw this. */ |
1844 | 1853 | { |
1845 | 1854 | COLORREF oldFgColor; |
2427 | 2436 | points[0].y = y + height/2; |
2428 | 2437 | points[1].y = points[0].y; |
2429 | 2438 | segmentWidth = 6; |
2430 | maxX = width - 1; | |
2439 | maxX = x + width - 1; | |
2431 | 2440 | border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); |
2432 | 2441 | |
2433 | 2442 | while (points[0].x < maxX) { |
2499 | 2508 | int strictMotif, /* Boolean flag */ |
2500 | 2509 | int drawingParameters) /* Whether or not to draw the cascade arrow |
2501 | 2510 | * for cascade items and accelerator |
2502 | * cues. Only applies to Windows. */ | |
2511 | * cues. */ | |
2503 | 2512 | { |
2504 | 2513 | GC gc, indicatorGC; |
2505 | 2514 | TkMenu *menuPtr = mePtr->menuPtr; |
2873 | 2882 | menuPtr->entries[j]->entryFlags &= ~ENTRY_LAST_COLUMN; |
2874 | 2883 | } |
2875 | 2884 | x += indicatorSpace + labelWidth + accelWidth |
2876 | + 2 * borderWidth; | |
2885 | + 2 * activeBorderWidth; | |
2877 | 2886 | indicatorSpace = labelWidth = accelWidth = 0; |
2878 | 2887 | lastColumnBreak = i; |
2879 | 2888 | y = borderWidth; |
2943 | 2952 | menuPtr->entries[j]->x = x; |
2944 | 2953 | menuPtr->entries[j]->entryFlags |= ENTRY_LAST_COLUMN; |
2945 | 2954 | } |
2946 | windowWidth = x + indicatorSpace + labelWidth + accelWidth + accelSpace | |
2947 | + 2 * activeBorderWidth + 2 * borderWidth; | |
2955 | windowWidth = x + indicatorSpace + labelWidth + accelWidth | |
2956 | + 2 * activeBorderWidth + borderWidth; | |
2948 | 2957 | |
2949 | 2958 | |
2950 | 2959 | windowHeight += borderWidth; |
3280 | 3289 | * |
3281 | 3290 | * The code below was given to me by Microsoft over the phone. It is the |
3282 | 3291 | * only way to ensure menu items line up, and is not documented. |
3292 | * How strange the calculation of indicatorDimensions[1] is...! | |
3283 | 3293 | */ |
3284 | 3294 | |
3285 | 3295 | indicatorDimensions[0] = GetSystemMetrics(SM_CYMENUCHECK); |
99 | 99 | LPVOID lpMsgBuf; |
100 | 100 | |
101 | 101 | repeatError = 1; |
102 | if (FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
102 | if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | | |
103 | 103 | FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS, |
104 | 104 | NULL, GetLastError(), |
105 | 105 | MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), |
106 | (LPSTR) &lpMsgBuf, 0, NULL)) { | |
107 | MessageBoxA(NULL, (LPCSTR) lpMsgBuf, | |
108 | "Tk_GetPixmap: Error from CreateDIBSection", | |
106 | (LPTSTR)&lpMsgBuf, 0, NULL)) { | |
107 | MessageBox(NULL, (LPTSTR) lpMsgBuf, | |
108 | TEXT("Tk_GetPixmap: Error from CreateDIBSection"), | |
109 | 109 | MB_OK | MB_ICONINFORMATION); |
110 | 110 | LocalFree(lpMsgBuf); |
111 | 111 | } |
81 | 81 | * screen. */ |
82 | 82 | int updatingClipboard; /* If 1, we are updating the clipboard. */ |
83 | 83 | int surrogateBuffer; /* Buffer for first of surrogate pair. */ |
84 | DWORD wheelTickPrev; /* For high resolution wheels. */ | |
85 | short wheelAcc; /* For high resolution wheels. */ | |
84 | 86 | } ThreadSpecificData; |
85 | 87 | static Tcl_ThreadDataKey dataKey; |
86 | 88 | |
607 | 609 | ZeroMemory(tsdPtr->winDisplay, sizeof(TkDisplay)); |
608 | 610 | tsdPtr->winDisplay->display = display; |
609 | 611 | tsdPtr->updatingClipboard = FALSE; |
612 | tsdPtr->wheelTickPrev = GetTickCount(); | |
613 | tsdPtr->wheelAcc = 0; | |
610 | 614 | |
611 | 615 | return tsdPtr->winDisplay; |
612 | 616 | } |
1130 | 1134 | */ |
1131 | 1135 | |
1132 | 1136 | switch (message) { |
1133 | case WM_MOUSEWHEEL: | |
1137 | case WM_MOUSEWHEEL: { | |
1138 | /* | |
1139 | * Support for high resolution wheels. | |
1140 | */ | |
1141 | ||
1142 | DWORD wheelTick = GetTickCount(); | |
1143 | ||
1144 | if (wheelTick - tsdPtr->wheelTickPrev < 1500) { | |
1145 | tsdPtr->wheelAcc += (short) HIWORD(wParam); | |
1146 | } else { | |
1147 | tsdPtr->wheelAcc = (short) HIWORD(wParam); | |
1148 | } | |
1149 | tsdPtr->wheelTickPrev = wheelTick; | |
1150 | if (abs(tsdPtr->wheelAcc) < WHEEL_DELTA) { | |
1151 | return; | |
1152 | } | |
1153 | ||
1134 | 1154 | /* |
1135 | 1155 | * We have invented a new X event type to handle this event. It |
1136 | 1156 | * still uses the KeyPress struct. However, the keycode field has |
1142 | 1162 | event.type = MouseWheelEvent; |
1143 | 1163 | event.xany.send_event = -1; |
1144 | 1164 | event.xkey.nbytes = 0; |
1145 | event.xkey.keycode = (short) HIWORD(wParam); | |
1165 | event.xkey.keycode = tsdPtr->wheelAcc / WHEEL_DELTA * WHEEL_DELTA; | |
1166 | tsdPtr->wheelAcc = tsdPtr->wheelAcc % WHEEL_DELTA; | |
1146 | 1167 | break; |
1168 | } | |
1147 | 1169 | case WM_SYSKEYDOWN: |
1148 | 1170 | case WM_KEYDOWN: |
1149 | 1171 | /* |
202 | 202 | int class; /* class of screen (monochrome, etc.) */ |
203 | 203 | #endif |
204 | 204 | unsigned long red_mask, green_mask, blue_mask; /* mask values */ |
205 | #if defined(MAC_OSX_TK) | |
206 | unsigned long alpha_mask; | |
207 | #endif | |
208 | 205 | int bits_per_rgb; /* log base 2 of distinct color values */ |
209 | 206 | int map_entries; /* color map entries */ |
210 | 207 | } Visual; |
334 | 331 | XPointer obdata; /* hook for the object routines to hang on */ |
335 | 332 | #if defined(MAC_OSX_TK) |
336 | 333 | int pixelpower; /* n such that pixels are 2^n x 2^n blocks*/ |
337 | unsigned long alpha_mask; | |
338 | 334 | #endif |
339 | 335 | struct funcs { /* image manipulation routines */ |
340 | 336 | struct _XImage *(*create_image)(); |