Tk Source Code

Changes On Branch canvas_image
Login
Bounty program for improvements to Tcl and certain Tcl packages.

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

Changes In Branch canvas_image Excluding Merge-Ins

This is equivalent to a diff from 9d1db47d to 39bf9540

2018-03-04
21:45
Merge branch tip-489 following acceptation of this TIP through TCT vote. check-in: afa7b579 user: fvogel tags: trunk
2018-02-21
20:58
Fix error in testing argument numbers in 'canvas image' command. Thanks to RenĂ© Zaumseil. Closed-Leaf check-in: 39bf9540 user: fvogel tags: canvas_image, tip-489
2018-02-10
15:36
Fix formatting in man canvas for the image command check-in: 1633e545 user: fvogel tags: canvas_image, tip-489
2017-11-19
20:50
Fix [73ba07efcd]: Use correct property type when handling MULTIPLE conversion requests. Patch from 'dpb' check-in: 23591c7d user: fvogel tags: core-8-6-branch
2017-11-14
07:05
Don't include the NULL from SAVE_TARGETS request in the expected result. The ICCCM specification doesn't tell what value the clipboard manager should return. Closed-Leaf check-in: 9d1db47d user: fvogel tags: bug-73ba07efcd
2017-11-13
20:39
Use -cleanup with test select-10.6 check-in: a087ba73 user: fvogel tags: bug-73ba07efcd

Changes to .fossil-settings/crlf-glob.

     1         -win/buildall.vc.bat
     2         -win/makefile.vc
     3         -win/mkd.bat
     4         -win/rmd.bat
     5         -win/rules.vc
            1  +win/*.bat
            2  +win/*.vc

Changes to .fossil-settings/crnl-glob.

     1         -win/buildall.vc.bat
     2         -win/makefile.vc
     3         -win/mkd.bat
     4         -win/rmd.bat
     5         -win/rules.vc
            1  +win/*.bat
            2  +win/*.vc

Changes to .fossil-settings/ignore-glob.

    15     15   */config.log
    16     16   */config.status
    17     17   */tkConfig.sh
    18     18   */wish*
    19     19   */tktest*
    20     20   */versions.vc
    21     21   doc/man.macros
    22         -win/Debug_VC*
    23         -win/Release_VC*
           22  +win/Debug*
           23  +win/Release*
           24  +win/nmhlp-out.txt
           25  +win/nmakehlp.out
    24     26   unix/tk.pc
           27  +html/*

Changes to README.

     1      1   README:  Tk
     2         -    This is the Tk 8.6.7 source distribution.
            2  +    This is the Tk 8.6.8 source distribution.
     3      3   	http://sourceforge.net/projects/tcl/files/Tcl/
     4      4       You can get any source release of Tk from the URL above.
     5      5   
     6      6   1. Introduction
     7      7   ---------------
     8      8   
     9      9   This directory contains the sources and documentation for Tk, an X11

Changes to changes.

  1311   1311   canvases) so that it correctly prints all of the characters in the
  1312   1312   ISO Latin-1 character set.
  1313   1313   
  1314   1314   2/19/94 (bug fix) Modified tkBind.c to save and restore the interpreter's
  1315   1315   result across the execution of binding scripts.  Otherwise if an event
  1316   1316   triggers in the middle of some other script (e.g. a destroy event during
  1317   1317   window creation, because there was an error in the creation command),
  1318         -the intepreter's result gets lost.
         1318  +the interpreter's result gets lost.
  1319   1319   
  1320   1320   2/19/94 (bug fix) Fixed bug in dealing with results of sent command
  1321   1321   that could cause them to get lost in some situations.
  1322   1322   
  1323   1323   2/21/94 (bug fix) Don't let user close a dialog window created by
  1324   1324   tk_dialog, since this would cause tk_dialog to hang:  force the user
  1325   1325   to select one of the dialog's buttons.
................................................................................
  7366   7366   
  7367   7367   2017-02-22 (bug)[c492c9] disabled combobox arrow appearance (danckaert)
  7368   7368   
  7369   7369   2017-03-06 (bug)[6b3644] Fix -alpha for 16-bit color PNG (LemonMan)
  7370   7370   
  7371   7371   2017-03-11 (bug)[775273] artifacts on Ubuntu 16.10+ (nemethi)
  7372   7372   
  7373         -2n017-03-26 (TIP 464) Win multimedia keys support (fassel,vogel)
         7373  +2017-03-26 (TIP 464) Win multimedia keys support (fassel,vogel)
  7374   7374   
  7375   7375   2017-03-29 (bug)[28a3c3] test BTree memleaks plugged (anonymous)
  7376   7376   
  7377   7377   2017-04-06 (bug)[db8c54] Stop freed mem access in warp pointer callback (porter)
  7378   7378   
  7379   7379   2017-04-07 (bugs) Fix calculation of ttk::notebook tab widths (vogel)
  7380   7380   
................................................................................
  7411   7411   2017-08-03 (bug)[9eab54] Fix -initialdir for OSX file dialogs (gollwitzer)
  7412   7412   
  7413   7413   2017-08-08 (bug)[28d0b8] Follow ICCCM advice on X selection protocol (donchenko)
  7414   7414   
  7415   7415   2017-08-08 (bug)[4966ca] Scidb race in notebook tab selection (cramer)
  7416   7416   
  7417   7417   --- Released 8.6.7, August 9, 2017 --- http://core.tcl.tk/tk/ for details
         7418  +
         7419  +2017-08-24 (bug)[f1a3ca] Memory leak in [text] B-tree (edhume3)
         7420  +
         7421  +2017-08-24 (bug)[ee40fd] Report [console] init errors (the)
         7422  +
         7423  +2017-08-24 (bug)[3295446] Improve history visibility in [console] (goth)
         7424  +
         7425  +2017-08-24 (bug) canvas closed polylines fully honor -joinstyle (vogel)
         7426  +
         7427  +2017-08-24 (bug)[cc42cc] out of mem crash in tests imgPhoto-18.* (vogel)
         7428  +
         7429  +2017-09-16 (bug)[3406785] fix coords rounding when drawing canvas items (vogel)
         7430  +
         7431  +2017-09-24 (bug)[8277e1] linux fontchooser sync with available fonts (vogel)
         7432  +
         7433  +2017-09-24 (bug)[5239fd] Segfault copying a photo image to itself (bachmann)
         7434  +
         7435  +2017-09-24 (bug)[514ff6] canvas rotated text overlap detection (vogel)
         7436  +
         7437  +2017-09-24 (bug)[1e0db2] canvas rchars artifacts (bruchie,vogel)
         7438  +
         7439  +2017-10-07 (bug)[d9fdfa] display of Long non-wrapped lines in text (cramer)
         7440  +
         7441  +2017-10-07 (bug)[dd9667] text anchor not set (vogel)
         7442  +
         7443  +2017-10-11 (bugs) memleaks and other changes for macOS 10.13 support (culler)
         7444  +
         7445  +2017-10-11 (bug)[111de2] macOS colorspace improvement (walzer,culler)
         7446  +
         7447  +2017-10-13 (bug) macOS scrolling issues (culler)
         7448  +
         7449  +2017-10-15 (bug) clipping regions in scrolling and drawing on macOS (culler)
         7450  +
         7451  +2017-10-15 (bug) macOS redraw artifacts (culler)
         7452  +
         7453  +2017-10-22 (bug)[bb6b40] ::tk::AmpMenuArgs and 'entryconf' (vogel)
         7454  +
         7455  +2017-10-22 (bug)[55b95f] Crash [scale] with a bignum value (vogel)
         7456  +
         7457  +2017-10-28 (bug)[ce62c8] text-37.1 fails (vogel)
         7458  +
         7459  +2017-11-03 (bug)[0ef1c5] OS X - tests menu-22.[345] hang (vogel)
         7460  +
         7461  +2017-11-04 (bug)[c8c52b] repair OBOE in menu.test on macOS (vogel)
         7462  +
         7463  +2017-11-11 (feature) Implement [wm_iconphoto] on macOS (walzer)
         7464  +
         7465  +2017-11-11 (bug) display of embedded toplevels (culler)
         7466  +
         7467  +2017-11-19 (bug)[73ba07] Correct property type for MULTIPLE conversion (dpb)
         7468  +
         7469  +2017-11-20 (bug) Memory leak in tkImgPhoto.c. (werner)
         7470  +
         7471  +2017-11-21 (bug) Defeat zombie toplevels (culler)
         7472  +
         7473  +2017-11-25 (bug) macOS resposive menu bar for command line apps (culler)
         7474  +
         7475  +2017-11-25 (bug)[1c659e] support png from mac screenshots (vogel)
         7476  +
         7477  +2017-11-25 (bug)[de4af1] macOS file selector "all types" setting (culler)
         7478  +
         7479  +2017-11-26 (bug) [wm withdraw] on Window and Dock menus (walzer)
         7480  +
         7481  +2017-11-27 (feature) Drop support for macOS 10.5 (culler)
         7482  +
         7483  +2017-11-30 (bug)[164c1b] Fixes [raise] on macOS (culler)
         7484  +
         7485  +2017-11-30 (bug)[13d63d] macOS support of menu -postcommand (culler)
         7486  +
         7487  +2017-12-05 (bug) enable custom icon display on macOS (walzer)
         7488  +
         7489  +2017-12-05 (bug)[1088805,0feb63] macOS bind failures (culler)
         7490  +
         7491  +2017-12-05 (bug)[3382424] Suppress noisy messages on macOS (culler)
         7492  +
         7493  +2017-12-08 (new)[TIP 477] nmake build system reform (nadkarni)
         7494  +
         7495  +2017-12-18 (bug)[b77626] Make [tk busy -cursor] silent no-op on macOS (vogel)
         7496  +
         7497  +--- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tk/ for details

Changes to doc/bind.n.

    15     15   .SH SYNOPSIS
    16     16   \fBbind\fI tag\fR ?\fIsequence\fR? ?\fB+\fR??\fIscript\fR?
    17     17   .BE
    18     18   .SH "INTRODUCTION"
    19     19   .PP
    20     20   The \fBbind\fR command associates Tcl scripts with X events.
    21     21   If all three arguments are specified, \fBbind\fR will
    22         -arrange for \fIscript\fR (a Tcl script) to be evaluated whenever
    23         -the event(s) given by \fIsequence\fR occur in the window(s)
    24         -identified by \fItag\fR.
           22  +arrange for \fIscript\fR (a Tcl script called the
           23  +.QW "binding script")
           24  +to be evaluated whenever the event(s) given by \fIsequence\fR
           25  +occur in the window(s) identified by \fItag\fR.
    25     26   If \fIscript\fR is prefixed with a
    26     27   .QW + ,
    27     28   then it is appended to
    28     29   any existing binding for \fIsequence\fR;  otherwise \fIscript\fR replaces
    29     30   any existing binding.
    30     31   If \fIscript\fR is an empty string then the current binding for
    31     32   \fIsequence\fR is destroyed, leaving \fIsequence\fR unbound.
................................................................................
   383    384   to print out the keysym name for a particular key.
   384    385   If a keysym \fIdetail\fR is given, then the
   385    386   \fItype\fR field may be omitted;  it will default to \fBKeyPress\fR.
   386    387   For example, \fB<Control\-comma>\fR is equivalent to
   387    388   \fB<Control\-KeyPress\-comma>\fR.
   388    389   .SH "BINDING SCRIPTS AND SUBSTITUTIONS"
   389    390   .PP
   390         -The \fIscript\fR argument to \fBbind\fR is a Tcl script,
          391  +The \fIscript\fR argument to \fBbind\fR is a Tcl script, called the
          392  +.QW "binding script",
   391    393   which will be executed whenever the given event sequence occurs.
   392    394   \fICommand\fR will be executed in the same interpreter that the
   393    395   \fBbind\fR command was executed in, and it will run at global
   394    396   level (only global variables will be accessible).
   395    397   If \fIscript\fR contains
   396    398   any \fB%\fR characters, then the script will not be
   397    399   executed directly.  Instead, a new script will be
................................................................................
   602    604   an \fBall\fR binding.
   603    605   The \fBbindtags\fR command may be used to change this order for
   604    606   a particular window or to associate additional binding tags with
   605    607   the window.
   606    608   .PP
   607    609   The \fBcontinue\fR and \fBbreak\fR commands may be used inside a
   608    610   binding script to control the processing of matching scripts.
   609         -If \fBcontinue\fR is invoked, then the current binding script
   610         -is terminated but Tk will continue processing binding scripts
   611         -associated with other \fItag\fR's.
          611  +If \fBcontinue\fR is invoked within a binding script, then this
          612  +binding script, including all other
          613  +.QW +
          614  +appended scripts, is terminated but Tk will continue processing
          615  +binding scripts associated with other \fItag\fR's.
   612    616   If the \fBbreak\fR command is invoked within a binding script,
   613    617   then that script terminates and no other scripts will be invoked
   614    618   for the event.
          619  +.PP
          620  +Within a script called from the binding script, \fBreturn\fR
          621  +\fB-code ok\fR may be used to continue processing (including
          622  +.QW +
          623  +appended scripts), or \fBreturn\fR \fB-code break\fR may be used to
          624  +stop processing all other binding scripts.
   615    625   .PP
   616    626   If more than one binding matches a particular event and they
   617    627   have the same \fItag\fR, then the most specific binding
   618    628   is chosen and its script is evaluated.
   619    629   The following tests are applied, in order, to determine which of
   620    630   several matching sequences is more specific:
   621    631   .RS

Changes to doc/busy.n.

    24     24   '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    25     25   '\"
    26     26   .TH busy n "" Tk "Tk Built-In Commands"
    27     27   .so man.macros
    28     28   .BS
    29     29   '\" Note:  do not modify the .SH NAME line immediately below!
    30     30   .SH NAME
    31         -busy \- confine pointer and keyboard events to a window sub-tree
           31  +busy \- confine pointer events to a window sub-tree
    32     32   .SH SYNOPSIS
    33     33   \fBtk busy\fR \fIwindow \fR?\fIoptions\fR?
    34     34   .sp
    35     35   \fBtk busy hold\fR \fIwindow \fR?\fIoptions\fR?
    36     36   .sp
    37     37   \fBtk busy configure \fIwindow\fR ?\fIoption value\fR?...
    38     38   .sp
................................................................................
    40     40   .sp
    41     41   \fBtk busy current\fR ?\fIpattern\fR?
    42     42   .sp
    43     43   \fBtk busy status \fIwindow\fR
    44     44   .BE
    45     45   .SH DESCRIPTION
    46     46   .PP
    47         -The \fBtk busy\fR command provides a simple means to block keyboard, button,
    48         -and pointer events from Tk widgets, while overriding the widget's cursor with
    49         -a configurable busy cursor.
           47  +The \fBtk busy\fR command provides a simple means to block pointer events from
           48  +Tk widgets, while overriding the widget's cursor with a configurable busy
           49  +cursor. Note this command does not prevent keyboard events from being sent to
           50  +the widgets made busy.
    50     51   .SH INTRODUCTION
    51     52   .PP
    52     53   There are many times in applications where you want to temporarily restrict
    53     54   what actions the user can take. For example, an application could have a
    54     55   .QW Run
    55     56   button that when pressed causes some processing to occur. However, while the
    56     57   application is busy processing, you probably don't want the user to be
................................................................................
    64     65   The \fBtk busy\fR command lets you make Tk widgets busy. This means that user
    65     66   interactions such as button clicks, moving the mouse, typing at the keyboard,
    66     67   etc.\0are ignored by the widget. You can set a special cursor (like a watch)
    67     68   that overrides the widget's normal cursor, providing feedback that the
    68     69   application (widget) is temporarily busy.
    69     70   .PP
    70     71   When a widget is made busy, the widget and all of its descendants will ignore
    71         -events. It's easy to make an entire panel of widgets busy. You can simply make
    72         -the toplevel widget (such as
           72  +pointer events. It's easy to make an entire panel of widgets busy. You can
           73  +simply make the toplevel widget (such as
    73     74   .QW . )
    74     75   busy. This is easier and far much more efficient than recursively traversing
    75     76   the widget hierarchy, disabling each widget and re-configuring its cursor.
    76     77   .PP
    77     78   Often, the \fBtk busy\fR command can be used instead of Tk's \fBgrab\fR
    78     79   command. Unlike \fBgrab\fR which restricts all user interactions to one
    79     80   widget, with the \fBtk busy\fR command you can have more than one widget
................................................................................
   236    237   .PP
   237    238   Mapping and unmapping busy windows generates Enter/Leave events for all
   238    239   widgets they cover. Please note this if you are tracking Enter/Leave events in
   239    240   widgets.
   240    241   .SS "KEYBOARD EVENTS"
   241    242   .PP
   242    243   When a widget is made busy, the widget is prevented from gaining the keyboard
   243         -focus by the busy window. But if the widget already had focus, it still may
   244         -received keyboard events. To prevent this, you must move focus to another
   245         -window.
          244  +focus by a user clicking on it by the busy window. But if the widget already had
          245  +focus, it still may receive keyboard events. The widget can also still receive
          246  +focus through keyboard traversal. To prevent this, you must move
          247  +focus to another window and make sure the focus can not go back to the widgets
          248  +made busy (e.g. but restricting focus to a cancel button).
   246    249   .PP
   247    250   .CS
          251  +pack [frame .frame]
          252  +pack [text .frame.text]
   248    253   \fBtk busy\fR hold .frame
   249         -label .dummy
   250         -focus .dummy
          254  +pack [button .cancel -text "Cancel" -command exit]
          255  +focus .cancel
          256  +bind .cancel <Tab> {break}
          257  +bind .cancel <Shift-Tab> {break}
   251    258   update
   252    259   .CE
   253    260   .PP
   254    261   The above example moves the focus from .frame immediately after invoking the
   255    262   \fBhold\fR so that no keyboard events will be sent to \fB.frame\fR or any of
   256         -its descendants.
          263  +its descendants. It also makes sure it's not possible to leave button
          264  +\fB.cancel\fR using the keyboard.
   257    265   .SH PORTABILITY
   258    266   .PP
   259    267   Note that the \fBtk busy\fR command does not currently have any effect on OSX
   260    268   when Tk is built using Aqua support.
   261    269   .SH "SEE ALSO"
   262    270   grab(n)
   263    271   .SH KEYWORDS
   264    272   busy, keyboard events, pointer events, window
   265    273   '\" Local Variables:
   266    274   '\" mode: nroff
   267    275   '\" End:

Changes to doc/canvas.n.

   653    653   See \fBINDICES\fR above for a description of the
   654    654   legal forms for \fIindex\fR.
   655    655   Note: the insertion cursor is only displayed in an item if
   656    656   that item currently has the keyboard focus (see the \fBfocus\fR widget
   657    657   command, above), but the cursor position may
   658    658   be set even when the item does not have the focus.
   659    659   This command returns an empty string.
          660  +.TP
          661  +\fIpathName \fBimage \fIimagename\fR ?\fIsubsample\fR? ?\fIzoom\fR?
          662  +.
          663  +Draw the canvas into the Tk photo image named \fIimagename\fR. If a \fB-scrollregion\fR
          664  +has been defined then this will be the boundaries of the canvas region drawn and the
          665  +final size of the photo image. Otherwise the widget width and height with an origin
          666  +of 0,0 will be the size of the canvas region drawn and the final size of the photo
          667  +image. Optionally an integer \fIsubsample\fR factor may be given and the photo image
          668  +will be reduced in size. In addition to the \fIsubsample\fR an integer \fIzoom\fR
          669  +factor can also be given and the photo image will be enlarged. The image background
          670  +will be filled with the canvas background colour. The canvas widget does not need to
          671  +be mapped for this widget command to work, but at least one of it's ancestors must be
          672  +mapped.
          673  +This command returns an empty string.
   660    674   .TP
   661    675   \fIpathName \fBimove \fItagOrId index x y\fR
   662    676   .VS 8.6
   663    677   This command causes the \fIindex\fR'th coordinate of each of the items
   664    678   indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR).
   665    679   Each item interprets \fIindex\fR independently according to the rules
   666    680   described in \fBINDICES\fR above. Out of the standard set of items, only line

Changes to doc/grid.n.

   156    156   This space is added outside the slave(s) border.
   157    157   .TP
   158    158   \fB\-row \fIn\fR
   159    159   .
   160    160   Insert the slave so that it occupies the \fIn\fRth row in the grid.
   161    161   Row numbers start with 0.  If this option is not supplied, then the
   162    162   slave is arranged on the same row as the previous slave specified on this
   163         -call to \fBgrid\fR, or the first unoccupied row if this is the first slave.
          163  +call to \fBgrid\fR, or the next row after the highest occupied row
          164  +if this is the first slave.
   164    165   .TP
   165    166   \fB\-rowspan \fIn\fR
   166    167   .
   167    168   Insert the slave so that it occupies \fIn\fR rows in the grid.
   168    169   The default is one row.  If the next \fBgrid\fR command contains
   169    170   \fB^\fR characters instead of \fIslaves\fR that line up with the columns
   170    171   of this \fIslave\fR, then the \fBrowspan\fR of this \fIslave\fR is

Changes to doc/radiobutton.n.

    37     37   If this option is not specified, the button's desired height is computed
    38     38   from the size of the image or bitmap or text being displayed in it.
    39     39   .OP \-indicatoron indicatorOn IndicatorOn
    40     40   Specifies whether or not the indicator should be drawn.  Must be a
    41     41   proper boolean value.  If false, the \fB\-relief\fR option is
    42     42   ignored and the widget's relief is always sunken if the widget is
    43     43   selected and raised otherwise.
    44         -.OP \-selectcolor selectColor Background
    45         -Specifies a background color to use when the button is selected.
    46         -If \fB\-indicatoron\fR is true then the color applies to the indicator.
    47         -Under Windows, this color is used as the background for the indicator
    48         -regardless of the select state.
    49         -If \fB\-indicatoron\fR is false, this color is used as the background
    50         -for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR,
    51         -whenever the widget is selected.
    52         -If specified as an empty string then no special color is used for
    53         -displaying when the widget is selected.
    54     44   .OP \-offrelief offRelief OffRelief
    55     45   Specifies the relief for the checkbutton when the indicator is not drawn and
    56     46   the checkbutton is off.  The default value is
    57     47   .QW raised .
    58     48   By setting this option to
    59     49   .QW flat
    60     50   and setting \fB\-indicatoron\fR to false and \fB\-overrelief\fR to
................................................................................
    67     57   .OP \-overrelief overRelief OverRelief
    68     58   Specifies an alternative relief for the radiobutton, to be used when the
    69     59   mouse cursor is over the widget.  This option can be used to make
    70     60   toolbar buttons, by configuring \fB\-relief flat \-overrelief
    71     61   raised\fR.  If the value of this option is the empty string, then no
    72     62   alternative relief is used when the mouse cursor is over the radiobutton.
    73     63   The empty string is the default value.
           64  +.OP \-selectcolor selectColor Background
           65  +Specifies a background color to use when the button is selected.
           66  +If \fB\-indicatoron\fR is true then the color applies to the indicator.
           67  +Under Windows, this color is used as the background for the indicator
           68  +regardless of the select state.
           69  +If \fB\-indicatoron\fR is false, this color is used as the background
           70  +for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR,
           71  +whenever the widget is selected.
           72  +If specified as an empty string then no special color is used for
           73  +displaying when the widget is selected.
    74     74   .OP \-selectimage selectImage SelectImage
    75     75   Specifies an image to display (in place of the \fB\-image\fR option)
    76     76   when the radiobutton is selected.
    77     77   This option is ignored unless the \fB\-image\fR option has been
    78     78   specified.
    79     79   .OP \-state state State
    80     80   Specifies one of three states for the radiobutton:  \fBnormal\fR, \fBactive\fR,

Changes to doc/raise.n.

    27     27   \fIwindow\fR into the stacking order just above \fIaboveThis\fR
    28     28   (or the ancestor of \fIaboveThis\fR that is a sibling of \fIwindow\fR);
    29     29   this could end up either raising or lowering \fIwindow\fR.
    30     30   .PP
    31     31   All \fBtoplevel\fR windows may be restacked with respect to each
    32     32   other, whatever their relative path names, but the window manager is
    33     33   not obligated to strictly honor requests to restack.
           34  +.PP
           35  +On macOS raising an iconified \fBtoplevel\fR window causes it to be
           36  +deiconified.
    34     37   .SH EXAMPLE
    35     38   .PP
    36     39   Make a button appear to be in a sibling frame that was created after
    37     40   it. This is is often necessary when building GUIs in the style where
    38     41   you create your activity widgets first before laying them out on the
    39     42   display:
    40     43   .CS

Changes to doc/scale.n.

    87     87   .OP \-variable variable Variable
    88     88   Specifies the name of a global variable to link to the scale.  Whenever the
    89     89   value of the variable changes, the scale will update to reflect this
    90     90   value.
    91     91   Whenever the scale is manipulated interactively, the variable
    92     92   will be modified to reflect the scale's new value.
    93     93   .OP \-width width Width
    94         -Specifies the desired narrow dimension of the trough in screen units
           94  +Specifies the desired narrow dimension of the scale in screen units
    95     95   (i.e. any of the forms acceptable to \fBTk_GetPixels\fR).
    96         -For vertical scales this is the trough's width;  for horizontal scales
    97         -this is the trough's height.
           96  +For vertical scales this is the scale's width;  for horizontal scales
           97  +this is the scale's height.
    98     98   .BE
    99     99   .SH DESCRIPTION
   100    100   .PP
   101    101   The \fBscale\fR command creates a new window (given by the
   102    102   \fIpathName\fR argument) and makes it into a scale widget.
   103    103   Additional
   104    104   options, described above, may be specified on the command line

Changes to doc/selection.n.

   136    136   the new owner of \fIselection\fR on \fIwindow\fR's display, returning
   137    137   an empty string as result. The existing owner, if any, is notified
   138    138   that it has lost the selection.
   139    139   If \fIcommand\fR is specified, it is a Tcl script to execute when
   140    140   some other window claims ownership of the selection away from
   141    141   \fIwindow\fR.  \fISelection\fR defaults to PRIMARY.
   142    142   .RE
          143  +.SH WIDGET FACILITIES
          144  +.PP
          145  +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.
          146  +.PP
          147  +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.
          148  +.PP
          149  +.SH PORTABILITY ISSUES
          150  +.PP
          151  +On X11, the \fBPRIMARY\fR selection is a system-wide feature of the X server, allowing communication between different processes that are X11 clients.
          152  +.PP
          153  +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.
          154  +.PP
          155  +.SH SECURITY
          156  +.PP
          157  +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.
          158  +.PP
          159  +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.
          160  +.PP
          161  +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.
          162  +.PP
   143    163   .SH EXAMPLES
   144    164   .PP
   145    165   On X11 platforms, one of the standard selections available is the
   146    166   \fBSECONDARY\fR selection. Hardly anything uses it, but here is how to read
   147    167   it using Tk:
   148    168   .PP
   149    169   .CS

Changes to doc/text.n.

   533    533   option is only used when wrapping is enabled. If a text line wraps, the right
   534    534   margin for each line on the display is determined by the first non-elided
   535    535   character of that display line.
   536    536   .TP
   537    537   \fB\-rmargincolor \fIcolor\fR
   538    538   .
   539    539   \fIColor\fR specifies the background color to use in regions that do not
   540         -contain characters because they are indented by \fB\-rmargin1\fR. It may
          540  +contain characters because they are indented by \fB\-rmargin\fR. It may
   541    541   have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not
   542    542   been specified, or if it is specified as an empty string, then the color
   543    543   used is specified by the \fB-background\fR tag option (or, if this is also
   544    544   unspecified, by the \fB-background\fR widget option).
   545    545   .TP
   546    546   \fB\-selectbackground \fIcolor\fR
   547    547   \fIColor\fR specifies the background color to use when displaying selected

Changes to doc/ttk_button.n.

    35     35   \fBdisabled\fR means that it is not defaultable.
    36     36   The default is \fBnormal\fR.
    37     37   .RS
    38     38   .PP
    39     39   Depending on the theme, the default button may be displayed
    40     40   with an extra highlight ring, or with a different border color.
    41     41   .RE
    42         -.OP \-width width Width
    43         -If greater than zero, specifies how much space, in character widths,
    44         -to allocate for the text label.
    45         -If less than zero, specifies a minimum width.
    46         -If zero or unspecified, the natural width of the text label is used.
    47         -Note that some themes may specify a non-zero \fB\-width\fR
    48         -in the style.
    49     42   .\" Not documented -- may go away
    50     43   .\" .OP \-padding padding Padding
    51     44   .\" .OP \-foreground foreground Foreground
    52     45   .\" .OP \-font font Font
    53     46   .\" .OP \-anchor anchor Anchor
    54     47   .\" .OP \-relief relief Relief
    55     48   .SH "WIDGET COMMAND"
................................................................................
    60     53   .TP
    61     54   \fIpathName \fBinvoke\fR
    62     55   Invokes the command associated with the button.
    63     56   .SH "STANDARD STYLES"
    64     57   .PP
    65     58   \fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard
    66     59   themes, which is useful for creating widgets for toolbars.
    67         -.SH "COMPATIBILITY OPTIONS"
    68         -.OP \-state state State
    69         -May be set to \fBnormal\fR or \fBdisabled\fR to control the
    70         -\fBdisabled\fR state bit. This is a
    71         -.QW write-only
    72         -option: setting it changes the widget state, but the \fBstate\fR
    73         -widget command does not affect the state option.
    74     60   .SH "SEE ALSO"
    75     61   ttk::widget(n), button(n)
    76     62   .SH "KEYWORDS"
    77     63   widget, button, default, command
    78     64   '\" Local Variables:
    79     65   '\" mode: nroff
    80     66   '\" End:

Changes to doc/ttk_label.n.

    15     15   .SH DESCRIPTION
    16     16   .PP
    17     17   A \fBttk::label\fR widget displays a textual label and/or image.
    18     18   The label may be linked to a Tcl variable
    19     19   to automatically change the displayed text.
    20     20   .SO ttk_widget
    21     21   \-class	\-compound	\-cursor
    22         -\-image	\-padding	\-style	\-takefocus
           22  +\-image	\-padding	\-state	\-style	\-takefocus
    23     23   \-text	\-textvariable	\-underline
    24     24   \-width
    25     25   .SE
    26     26   .SH "WIDGET-SPECIFIC OPTIONS"
    27     27   .OP \-anchor anchor Anchor
    28     28   Specifies how the information in the widget is positioned
    29     29   relative to the inner margins.  Legal values are

Changes to doc/ttk_panedwindow.n.

   102    102   Sash positions are further constrained to be between 0
   103    103   and the total size of the widget.
   104    104   .\" Full story: "total size" is either the -height (resp -width),
   105    105   .\" or the actual window height (resp actual window width),
   106    106   .\" depending on which changed most recently.
   107    107   Returns the new position of sash number \fIindex\fR.
   108    108   .\" Full story: new position may be different than the requested position.
          109  +.PP
          110  +The panedwindow widget also supports the following generic \fBttk::widget\fR
          111  +widget subcommands (see \fIttk::widget(n)\fR for details):
          112  +.DS
          113  +.ta 5.5c 11c
          114  +\fBcget\fR	\fBconfigure\fR
          115  +\fBinstate\fR	\fBstate\fR
          116  +.DE
   109    117   .SH "VIRTUAL EVENTS"
   110    118   .PP
   111    119   The panedwindow widget generates an \fB<<EnteredChild>>\fR virtual event on
   112    120   LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts
   113    121   for <Leave> events when the pointer crosses from a parent to a child. The
   114    122   panedwindow widget needs to know when that happens.
   115    123   .SH "SEE ALSO"
   116    124   ttk::widget(n), ttk::notebook(n), panedwindow(n)
   117    125   '\" Local Variables:
   118    126   '\" mode: nroff
   119    127   '\" End:

Changes to doc/ttk_progressbar.n.

    20     20   \fIindeterminate\fR mode provides an animated display to let the user know
    21     21   that something is happening.
    22     22   .SO ttk_widget
    23     23   \-class	\-cursor	\-takefocus
    24     24   \-style
    25     25   .SE
    26     26   .SH "WIDGET-SPECIFIC OPTIONS"
    27         -.OP \-orient orient Orient
    28         -One of \fBhorizontal\fR or \fBvertical\fR.
    29         -Specifies the orientation of the progress bar.
    30     27   .OP \-length length Length
    31     28   Specifies the length of the long axis of the progress bar
    32     29   (width if horizontal, height if vertical).
    33         -.OP \-mode mode Mode
    34         -One of \fBdeterminate\fR or \fBindeterminate\fR.
    35     30   .OP \-maximum maximum Maximum
    36     31   A floating point number specifying the maximum \fB\-value\fR.
    37     32   Defaults to 100.
           33  +.OP \-mode mode Mode
           34  +One of \fBdeterminate\fR or \fBindeterminate\fR.
           35  +.OP \-orient orient Orient
           36  +One of \fBhorizontal\fR or \fBvertical\fR.
           37  +Specifies the orientation of the progress bar.
           38  +.OP \-phase phase Phase
           39  +Read-only option.
           40  +The widget periodically increments the value of this option
           41  +whenever the \fB\-value\fR is greater than 0 and,
           42  +in \fIdeterminate\fR mode, less than \fB\-maximum\fR.
           43  +This option may be used by the current theme
           44  +to provide additional animation effects.
    38     45   .OP \-value value Value
    39     46   The current value of the progress bar.
    40     47   In \fIdeterminate\fR mode, this represents the amount of work completed.
    41     48   In \fIindeterminate\fR mode, it is interpreted modulo \fB\-maximum\fR;
    42     49   that is, the progress bar completes one
    43     50   .QW cycle
    44     51   when the \fB\-value\fR increases by \fB\-maximum\fR.
    45     52   .OP \-variable variable Variable
    46     53   The name of a global Tcl variable which is linked to the \fB\-value\fR.
    47     54   If specified, the \fB\-value\fR of the progress bar is
    48     55   automatically set to the value of the variable whenever
    49     56   the latter is modified.
    50         -.OP \-phase phase Phase
    51         -Read-only option.
    52         -The widget periodically increments the value of this option
    53         -whenever the \fB\-value\fR is greater than 0 and,
    54         -in \fIdeterminate\fR mode, less than \fB\-maximum\fR.
    55         -This option may be used by the current theme
    56         -to provide additional animation effects.
    57     57   .SH "WIDGET COMMAND"
    58     58   .PP
    59     59   .TP
    60     60   \fIpathName \fBcget \fIoption\fR
    61     61   Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR.
    62     62   .TP
    63     63   \fIpathName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR?

Changes to doc/ttk_separator.n.

    13     13   \fBttk::separator\fR \fIpathName \fR?\fIoptions\fR?
    14     14   .BE
    15     15   .SH DESCRIPTION
    16     16   .PP
    17     17   A \fBttk::separator\fR widget displays a horizontal or vertical separator
    18     18   bar.
    19     19   .SO ttk_widget
    20         -\-class	\-cursor	\-state
           20  +\-class	\-cursor
    21     21   \-style	\-takefocus
    22     22   .SE
    23     23   .SH "WIDGET-SPECIFIC OPTIONS"
    24     24   .OP \-orient orient Orient
    25     25   One of \fBhorizontal\fR or \fBvertical\fR.
    26     26   Specifies the orientation of the separator.
    27     27   .SH "WIDGET COMMAND"
    28     28   .PP
    29     29   Separator widgets support the standard
    30     30   \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
    31     31   methods.  No other widget methods are used.
           32  +.PP
    32     33   .SH "SEE ALSO"
    33     34   ttk::widget(n)
    34     35   .SH "KEYWORDS"
    35     36   widget, separator
    36     37   '\" Local Variables:
    37     38   '\" mode: nroff
    38     39   '\" End:

Changes to doc/ttk_sizegrip.n.

    14     14   .BE
    15     15   .SH DESCRIPTION
    16     16   .PP
    17     17   A \fBttk::sizegrip\fR widget (also known as a \fIgrow box\fR)
    18     18   allows the user to resize the containing toplevel window
    19     19   by pressing and dragging the grip.
    20     20   .SO ttk_widget
    21         -\-class	\-cursor	\-state
           21  +\-class	\-cursor
    22     22   \-style	\-takefocus
    23     23   .SE
    24     24   .SH "WIDGET COMMAND"
    25     25   .PP
    26     26   Sizegrip widgets support the standard
    27     27   \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR
    28     28   methods.  No other widget methods are used.

Changes to doc/ttk_spinbox.n.

    17     17   A \fBttk::spinbox\fR widget is a \fBttk::entry\fR widget with built-in
    18     18   up and down buttons that are used to either modify a numeric value or
    19     19   to select among a set of values. The widget implements all the features
    20     20   of the \fBttk::entry\fR widget including support of the
    21     21   \fB\-textvariable\fR option to link the value displayed by the widget
    22     22   to a Tcl variable.
    23     23   .SO ttk_widget
    24         -\-class	\-cursor	\-style
           24  +\-class	\-cursor	\-state	\-style
    25     25   \-takefocus	\-xscrollcommand
    26     26   .SE
    27     27   .SO ttk_entry
    28     28   \-validate	\-validatecommand
    29     29   .SE
    30     30   .SH "WIDGET-SPECIFIC OPTIONS"
           31  +.OP \-command command Command
           32  +Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
           33  +.OP \-format format Format
           34  +Specifies an alternate format to use when setting the string value
           35  +when using the \fB\-from\fR and \fB\-to\fR range.
           36  +This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
           37  +as it will format a floating-point number.
    31     38   .OP \-from from From
    32     39   A floating\-point value specifying the lowest value for the spinbox. This is
    33     40   used in conjunction with \fB\-to\fR and \fB\-increment\fR to set a numerical
    34     41   range.
    35         -.OP \-to to To
    36         -A floating\-point value specifying the highest permissible value for the
    37         -widget. See also \fB\-from\fR and \fB\-increment\fR.
    38         -range.
    39     42   .OP \-increment increment Increment
    40     43   A floating\-point value specifying the change in value to be applied each
    41     44   time one of the widget spin buttons is pressed. The up button applies a
    42     45   positive increment, the down button applies a negative increment.
           46  +.OP \-to to To
           47  +A floating\-point value specifying the highest permissible value for the
           48  +widget. See also \fB\-from\fR and \fB\-increment\fR.
           49  +range.
    43     50   .OP \-values values Values
    44     51   This must be a Tcl list of values. If this option is set then this will
    45     52   override any range set using the \fB\-from\fR, \fB\-to\fR and
    46     53   \fB\-increment\fR options. The widget will instead use the values
    47     54   specified beginning with the first value.
    48     55   .OP \-wrap wrap Wrap
    49     56   Must be a proper boolean value.  If on, the spinbox will wrap around the
    50     57   values of data in the widget.
    51         -.OP \-format format Format
    52         -Specifies an alternate format to use when setting the string value
    53         -when using the \fB\-from\fR and \fB\-to\fR range.
    54         -This must be a format specifier of the form \fB%<pad>.<pad>f\fR,
    55         -as it will format a floating-point number.
    56         -.OP \-command command Command
    57         -Specifies a Tcl command to be invoked whenever a spinbutton is invoked.
    58     58   .SH "INDICES"
    59     59   .PP
    60     60   See the \fBttk::entry\fR manual for information about indexing characters.
    61     61   .SH "VALIDATION"
    62     62   .PP
    63     63   See the \fBttk::entry\fR manual for information about using the
    64     64   \fB\-validate\fR and \fB\-validatecommand\fR options.
    65     65   .SH "WIDGET COMMAND"
    66     66   .PP
    67     67   The following subcommands are possible for spinbox widgets in addition to
    68     68   the commands described for the \fBttk::entry\fR widget:
    69     69   .TP
    70         -\fIpathName \fBcurrent \fIindex\fR
    71         -.TP
    72     70   \fIpathName \fBget\fR
    73     71   Returns the spinbox's current value.
    74     72   .TP
    75     73   \fIpathName \fBset \fIvalue\fR
    76     74   Set the spinbox string to \fIvalue\fR. If a \fB\-format\fR option has
    77     75   been configured then this format will be applied. If formatting fails
    78     76   or is not set or the \fB\-values\fR option has been used then the value

Changes to doc/ttk_widget.n.

   121    121   The underlined character is used for mnemonic activation.
   122    122   .OP \-width width Width
   123    123   If greater than zero, specifies how much space, in character widths,
   124    124   to allocate for the text label.
   125    125   If less than zero, specifies a minimum width.
   126    126   If zero or unspecified, the natural width of the text label is used.
   127    127   .SH "COMPATIBILITY OPTIONS"
          128  +This option is only available for themed widgets that have
          129  +.QW corresponding
          130  +traditional Tk widgets.
   128    131   .OP \-state state State
   129    132   May be set to \fBnormal\fR or \fBdisabled\fR
   130    133   to control the \fBdisabled\fR state bit.
   131    134   This is a write-only option:
   132    135   setting it changes the widget state,
   133    136   but the \fBstate\fR widget command
   134    137   does not affect the \fB\-state\fR option.

Changes to doc/wm.n.

   484    484   vice versa.
   485    485   .PP
   486    486   On X, the images are arranged into the _NET_WM_ICON X property, which
   487    487   most modern window managers support.  A \fBwm iconbitmap\fR may exist
   488    488   simultaneously.  It is recommended to use not more than 2 icons, placing
   489    489   the larger icon first.
   490    490   .PP
   491         -On Macintosh, this currently does nothing.
          491  +On Macintosh, the first image called is loaded into an OSX-native icon
          492  +format, and becomes the application icon in dialogs, the Dock, and
          493  +other contexts. At the
          494  +script level the command will accept only the first image passed in the
          495  +parameters as support for multiple sizes/resolutions on macOS is outside Tk's
          496  +scope. Developers should use the largest icon they can support
          497  +(preferably 512 pixels) to ensure smooth rendering on the Mac. 
   492    498   .RE
   493    499   .TP
   494    500   \fBwm iconposition \fIwindow\fR ?\fIx y\fR?
   495    501   .
   496    502   If \fIx\fR and \fIy\fR are specified, they are passed to the window
   497    503   manager as a hint about where to position the icon for \fIwindow\fR.
   498    504   In this case an empty string is returned.  If \fIx\fR and \fIy\fR are

Changes to generic/tk.h.

    71     71    * You may also need to update some of these files when the numbers change for
    72     72    * the version of Tcl that this release of Tk is compiled against.
    73     73    */
    74     74   
    75     75   #define TK_MAJOR_VERSION	8
    76     76   #define TK_MINOR_VERSION	6
    77     77   #define TK_RELEASE_LEVEL	TCL_FINAL_RELEASE
    78         -#define TK_RELEASE_SERIAL	7
           78  +#define TK_RELEASE_SERIAL	8
    79     79   
    80     80   #define TK_VERSION		"8.6"
    81         -#define TK_PATCH_LEVEL		"8.6.7"
           81  +#define TK_PATCH_LEVEL		"8.6.8"
    82     82   
    83     83   /*
    84     84    * A special definition used to allow this header file to be included from
    85     85    * windows or mac resource files so that they can obtain version information.
    86     86    * RC_INVOKED is defined by default by the windows RC tool and manually set
    87     87    * for macintosh.
    88     88    *

Changes to generic/tkBind.c.

  1734   1734   
  1735   1735   		if ((state & modMask) != modMask) {
  1736   1736   		    goto nextSequence;
  1737   1737   		}
  1738   1738   	    }
  1739   1739   	    if (psPtr->flags & PAT_NEARBY) {
  1740   1740   		XEvent *firstPtr = &bindPtr->eventRing[bindPtr->curEvent];
  1741         -		int timeDiff;
         1741  +		long timeDiff;
  1742   1742   
  1743         -		timeDiff = (Time) firstPtr->xkey.time - eventPtr->xkey.time;
         1743  +		timeDiff = ((long)firstPtr->xkey.time -
         1744  +			    (long)eventPtr->xkey.time);
  1744   1745   		if ((firstPtr->xkey.x_root
  1745   1746   			    < (eventPtr->xkey.x_root - NEARBY_PIXELS))
  1746   1747   			|| (firstPtr->xkey.x_root
  1747   1748   			    > (eventPtr->xkey.x_root + NEARBY_PIXELS))
  1748   1749   			|| (firstPtr->xkey.y_root
  1749   1750   			    < (eventPtr->xkey.y_root - NEARBY_PIXELS))
  1750   1751   			|| (firstPtr->xkey.y_root
................................................................................
  3329   3330   	    }
  3330   3331   	    break;
  3331   3332   	case EVENT_TIME:
  3332   3333   	    if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) {
  3333   3334   		return TCL_ERROR;
  3334   3335   	    }
  3335   3336   	    if (flags & KEY_BUTTON_MOTION_CROSSING) {
  3336         -		event.general.xkey.time = (Time) number;
         3337  +		event.general.xkey.time = number;
  3337   3338   	    } else if (flags & PROP) {
  3338         -		event.general.xproperty.time = (Time) number;
         3339  +		event.general.xproperty.time = number;
  3339   3340   	    } else {
  3340   3341   		goto badopt;
  3341   3342   	    }
  3342   3343   	    break;
  3343   3344   	case EVENT_WIDTH:
  3344   3345   	    if (Tk_GetPixelsFromObj(interp,tkwin,valuePtr,&number) != TCL_OK) {
  3345   3346   		return TCL_ERROR;
................................................................................
  3462   3463       /*
  3463   3464        * We only allow warping if the window is mapped.
  3464   3465        */
  3465   3466   
  3466   3467       if ((warp != 0) && Tk_IsMapped(tkwin)) {
  3467   3468   	TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display);
  3468   3469   
  3469         -Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display,
         3470  +	Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display,
  3470   3471   		event.general.xmotion.window);
  3471   3472   
  3472   3473   	if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) {
  3473   3474   	    Tcl_DoWhenIdle(DoWarp, dispPtr);
  3474   3475   	    dispPtr->flags |= TK_DISPLAY_IN_WARP;
  3475   3476   	}
  3476   3477   

Changes to generic/tkBusy.c.

    13     13    */
    14     14   
    15     15   #include "tkInt.h"
    16     16   #include "tkBusy.h"
    17     17   #include "default.h"
    18     18   
    19     19   /*
    20         - * Things about the busy system that may be configured. Note that currently on
    21         - * OSX/Aqua, that's nothing at all.
           20  + * Things about the busy system that may be configured. Note that on some
           21  + * platforms this may or may not have an effect.
    22     22    */
    23     23   
    24     24   static const Tk_OptionSpec busyOptionSpecs[] = {
    25         -#ifndef MAC_OSX_TK
    26     25       {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor",
    27     26   	DEF_BUSY_CURSOR, -1, Tk_Offset(Busy, cursor),
    28     27   	TK_OPTION_NULL_OK, 0, 0},
    29         -#endif
    30     28       {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0}
    31     29   };
    32     30   
    33     31   /*
    34     32    * Forward declarations of functions defined in this file.
    35     33    */
    36     34   

Changes to generic/tkButton.c.

  1605   1605       const char *name1,		/* Name of variable. */
  1606   1606       const char *name2,		/* Second part of variable name. */
  1607   1607       int flags)			/* Information about what happened. */
  1608   1608   {
  1609   1609       register TkButton *butPtr = clientData;
  1610   1610       const char *value;
  1611   1611       Tcl_Obj *valuePtr;
         1612  +
         1613  +    /*
         1614  +     * See ticket [5d991b82].
         1615  +     */
         1616  +
         1617  +    if (butPtr->selVarNamePtr == NULL) {
         1618  +	if (!(flags & TCL_INTERP_DESTROYED)) {
         1619  +	    Tcl_UntraceVar2(interp, name1, name2,
         1620  +		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
         1621  +		    ButtonVarProc, clientData);
         1622  +	}
         1623  +	return NULL;
         1624  +    }
  1612   1625   
  1613   1626       /*
  1614   1627        * If the variable is being unset, then just re-establish the trace unless
  1615   1628        * the whole interpreter is going away.
  1616   1629        */
  1617   1630   
  1618   1631       if (flags & TCL_TRACE_UNSETS) {
................................................................................
  1688   1701    */
  1689   1702   
  1690   1703   	/* ARGSUSED */
  1691   1704   static char *
  1692   1705   ButtonTextVarProc(
  1693   1706       ClientData clientData,	/* Information about button. */
  1694   1707       Tcl_Interp *interp,		/* Interpreter containing variable. */
  1695         -    const char *name1,		/* Not used. */
  1696         -    const char *name2,		/* Not used. */
         1708  +    const char *name1,		/* Name of variable. */
         1709  +    const char *name2,		/* Second part of variable name. */
  1697   1710       int flags)			/* Information about what happened. */
  1698   1711   {
  1699   1712       TkButton *butPtr = clientData;
  1700   1713       Tcl_Obj *valuePtr;
  1701   1714   
  1702   1715       if (butPtr->flags & BUTTON_DELETED) {
  1703   1716   	return NULL;
  1704   1717       }
  1705   1718   
         1719  +    /*
         1720  +     * See ticket [5d991b82].
         1721  +     */
         1722  +
         1723  +    if (butPtr->textVarNamePtr == NULL) {
         1724  +	if (!(flags & TCL_INTERP_DESTROYED)) {
         1725  +	    Tcl_UntraceVar2(interp, name1, name2,
         1726  +		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
         1727  +		    ButtonTextVarProc, clientData);
         1728  +	}
         1729  + 	return NULL;
         1730  +     }
         1731  + 
  1706   1732       /*
  1707   1733        * If the variable is unset, then immediately recreate it unless the whole
  1708   1734        * interpreter is going away.
  1709   1735        */
  1710   1736   
  1711   1737       if (flags & TCL_TRACE_UNSETS) {
  1712   1738   	if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {

Changes to generic/tkCanvas.c.

   264    264   			    Tcl_Interp *interp, int argc,
   265    265   			    Tcl_Obj *const *argv);
   266    266   static void		CanvasWorldChanged(ClientData instanceData);
   267    267   static int		ConfigureCanvas(Tcl_Interp *interp,
   268    268   			    TkCanvas *canvasPtr, int argc,
   269    269   			    Tcl_Obj *const *argv, int flags);
   270    270   static void		DestroyCanvas(char *memPtr);
          271  +static int              DrawCanvas(Tcl_Interp *interp, ClientData clientData, Tk_PhotoHandle photohandle, int subsample, int zoom);
   271    272   static void		DisplayCanvas(ClientData clientData);
   272    273   static void		DoItem(Tcl_Obj *accumObj,
   273    274   			    Tk_Item *itemPtr, Tk_Uid tag);
   274    275   static void		EventuallyRedrawItem(TkCanvas *canvasPtr,
   275    276   			    Tk_Item *itemPtr);
   276    277   #ifdef USE_OLD_TAG_SEARCH
   277    278   static int		FindItems(Tcl_Interp *interp, TkCanvas *canvasPtr,
................................................................................
   801    802   
   802    803       int index;
   803    804       static const char *const optionStrings[] = {
   804    805   	"addtag",	"bbox",		"bind",		"canvasx",
   805    806   	"canvasy",	"cget",		"configure",	"coords",
   806    807   	"create",	"dchars",	"delete",	"dtag",
   807    808   	"find",		"focus",	"gettags",	"icursor",
          809  +        "image",
   808    810   	"imove",	"index",	"insert",	"itemcget",
   809    811   	"itemconfigure",
   810    812   	"lower",	"move",		"moveto",	"postscript",
   811    813   	"raise",	"rchars",	"scale",	"scan",
   812    814   	"select",	"type",		"xview",	"yview",
   813    815   	NULL
   814    816       };
   815    817       enum options {
   816    818   	CANV_ADDTAG,	CANV_BBOX,	CANV_BIND,	CANV_CANVASX,
   817    819   	CANV_CANVASY,	CANV_CGET,	CANV_CONFIGURE,	CANV_COORDS,
   818    820   	CANV_CREATE,	CANV_DCHARS,	CANV_DELETE,	CANV_DTAG,
   819    821   	CANV_FIND,	CANV_FOCUS,	CANV_GETTAGS,	CANV_ICURSOR,
          822  +        CANV_IMAGE,
   820    823   	CANV_IMOVE,	CANV_INDEX,	CANV_INSERT,	CANV_ITEMCGET,
   821    824   	CANV_ITEMCONFIGURE,
   822    825   	CANV_LOWER,	CANV_MOVE,	CANV_MOVETO,	CANV_POSTSCRIPT,
   823    826   	CANV_RAISE,	CANV_RCHARS,	CANV_SCALE,	CANV_SCAN,
   824    827   	CANV_SELECT,	CANV_TYPE,	CANV_XVIEW,	CANV_YVIEW
   825    828       };
   826    829   
................................................................................
  1182   1185   	 * modifications in the loop.
  1183   1186   	 */
  1184   1187   
  1185   1188   	tmpObj = Tcl_NewListObj(2, objv+4);
  1186   1189   
  1187   1190   	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) {
  1188   1191   	    int index;
  1189         -	    int x1,x2,y1,y2;
  1190         -	    int dontRedraw1,dontRedraw2;
         1192  +	    int x1, x2, y1, y2;
         1193  +	    int dontRedraw1, dontRedraw2;
  1191   1194   
  1192   1195   	    /*
  1193   1196   	     * The TK_MOVABLE_POINTS flag should only be set for types that
  1194   1197   	     * support the same semantics of index, dChars and insert methods
  1195   1198   	     * as lines and canvases.
  1196   1199   	     */
  1197   1200   
................................................................................
  1213   1216   	     */
  1214   1217   
  1215   1218   	    x1 = itemPtr->x1; y1 = itemPtr->y1;
  1216   1219   	    x2 = itemPtr->x2; y2 = itemPtr->y2;
  1217   1220   
  1218   1221   	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
  1219   1222   	    ItemDelChars(canvasPtr, itemPtr, index, index);
  1220         -	    dontRedraw1=itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
         1223  +	    dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
  1221   1224   
  1222   1225   	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
  1223   1226   	    ItemInsert(canvasPtr, itemPtr, index, tmpObj);
  1224         -	    dontRedraw2=itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
         1227  +	    dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
  1225   1228   
  1226   1229   	    if (!(dontRedraw1 && dontRedraw2)) {
  1227   1230   		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
  1228   1231   			x1, y1, x2, y2);
  1229   1232   		EventuallyRedrawItem(canvasPtr, itemPtr);
  1230   1233   	    }
  1231   1234   	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
................................................................................
  1330   1333   	EventuallyRedrawItem(canvasPtr, itemPtr);
  1331   1334   	canvasPtr->flags |= REPICK_NEEDED;
  1332   1335   	Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id));
  1333   1336   	break;
  1334   1337       }
  1335   1338       case CANV_DCHARS: {
  1336   1339   	int first, last;
  1337         -	int x1,x2,y1,y2;
         1340  +	int x1, x2, y1, y2;
  1338   1341   
  1339   1342   	if ((objc != 4) && (objc != 5)) {
  1340   1343   	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?");
  1341   1344   	    result = TCL_ERROR;
  1342   1345   	    goto done;
  1343   1346   	}
  1344   1347   	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
................................................................................
  1358   1361   	    } else {
  1359   1362   		last = first;
  1360   1363   	    }
  1361   1364   
  1362   1365   	    /*
  1363   1366   	     * Redraw both item's old and new areas: it's possible that a
  1364   1367   	     * delete could result in a new area larger than the old area.
  1365         -	     * Except if the insertProc sets the TK_ITEM_DONT_REDRAW flag,
         1368  +	     * Except if the dCharsProc sets the TK_ITEM_DONT_REDRAW flag,
  1366   1369   	     * nothing more needs to be done.
  1367   1370   	     */
  1368   1371   
  1369   1372   	    x1 = itemPtr->x1; y1 = itemPtr->y1;
  1370   1373   	    x2 = itemPtr->x2; y2 = itemPtr->y2;
  1371   1374   	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
  1372   1375   	    ItemDelChars(canvasPtr, itemPtr, first, last);
................................................................................
  1568   1571   	    goto done;
  1569   1572   	}
  1570   1573   	Tcl_SetObjResult(interp, Tcl_NewIntObj(index));
  1571   1574   	break;
  1572   1575       }
  1573   1576       case CANV_INSERT: {
  1574   1577   	int beforeThis;
  1575         -	int x1,x2,y1,y2;
         1578  +	int x1, x2, y1, y2;
  1576   1579   
  1577   1580   	if (objc != 5) {
  1578   1581   	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string");
  1579   1582   	    result = TCL_ERROR;
  1580   1583   	    goto done;
  1581   1584   	}
  1582   1585   	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
................................................................................
  1796   1799   	    }
  1797   1800   	}
  1798   1801   	RELINK_ITEMS(objv[2], prevPtr);
  1799   1802   	break;
  1800   1803       }
  1801   1804       case CANV_RCHARS: {
  1802   1805   	int first, last;
  1803         -	int x1,x2,y1,y2;
         1806  +	int x1, x2, y1, y2;
         1807  +	int dontRedraw1, dontRedraw2;
  1804   1808   
  1805   1809   	if (objc != 6) {
  1806   1810   	    Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string");
  1807   1811   	    result = TCL_ERROR;
  1808   1812   	    goto done;
  1809   1813   	}
  1810   1814   	FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto done) {
................................................................................
  1827   1831   	     * replace could result in a new area larger than the old area.
  1828   1832   	     * Except if the dCharsProc or insertProc sets the
  1829   1833   	     * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done.
  1830   1834   	     */
  1831   1835   
  1832   1836   	    x1 = itemPtr->x1; y1 = itemPtr->y1;
  1833   1837   	    x2 = itemPtr->x2; y2 = itemPtr->y2;
  1834         -	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
  1835   1838   
         1839  +            itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
  1836   1840   	    ItemDelChars(canvasPtr, itemPtr, first, last);
         1841  +	    dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
         1842  +
         1843  +            itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
  1837   1844   	    ItemInsert(canvasPtr, itemPtr, first, objv[5]);
         1845  +	    dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW;
  1838   1846   
  1839         -	    if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) {
         1847  +            if (!(dontRedraw1 && dontRedraw2)) {
  1840   1848   		Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
  1841   1849   			x1, y1, x2, y2);
  1842   1850   		EventuallyRedrawItem(canvasPtr, itemPtr);
  1843   1851   	    }
  1844   1852   	    itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW;
  1845   1853   	}
  1846   1854   	break;
................................................................................
  2122   2130   			* (Tk_Height(canvasPtr->tkwin) - 2*canvasPtr->inset));
  2123   2131   	    }
  2124   2132   	    break;
  2125   2133   	}
  2126   2134   	CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY);
  2127   2135   	break;
  2128   2136       }
         2137  +    case CANV_IMAGE: {
         2138  +        Tk_PhotoHandle photohandle;
         2139  +        int subsample = 1, zoom = 1;
         2140  +
         2141  +        if (objc < 3 || objc > 5) {
         2142  +            Tcl_WrongNumArgs(interp, 2, objv, "imagename ?subsample? ?zoom?");
         2143  +            result = TCL_ERROR;
         2144  +            goto done;
         2145  +        }
         2146  +
         2147  +        if ((photohandle = Tk_FindPhoto(interp, Tcl_GetString(objv[2]) )) == 0) {
         2148  +            result = TCL_ERROR;
         2149  +            goto done;
         2150  +        }
         2151  +
         2152  +        /*
         2153  +         * If we are given a subsample or a zoom then grab them.
         2154  +         */
         2155  +
         2156  +        if (objc >= 4 && Tcl_GetIntFromObj(interp, objv[3], &subsample) != TCL_OK) {
         2157  +            result = TCL_ERROR;
         2158  +            goto done;
         2159  +        }
         2160  +        if (objc >= 5 && Tcl_GetIntFromObj(interp, objv[4], &zoom) != TCL_OK) {
         2161  +            result = TCL_ERROR;
         2162  +            goto done;
         2163  +        }
         2164  +
         2165  +        /*
         2166  +         * Set the image size to zero, which allows the DrawCanvas() function
         2167  +         * to expand the image automatically when it copies the pixmap into it.
         2168  +         */
         2169  +
         2170  +        if (Tk_PhotoSetSize(interp, photohandle, 0, 0) != TCL_OK) {
         2171  +            result = TCL_ERROR;
         2172  +            goto done;
         2173  +        }
         2174  +
         2175  +        result = DrawCanvas(interp, clientData, photohandle, subsample, zoom);
         2176  +    }
  2129   2177       }
  2130   2178   
  2131   2179     done:
  2132   2180   #ifndef USE_OLD_TAG_SEARCH
  2133   2181       TagSearchDestroy(searchPtr);
  2134   2182   #endif /* not USE_OLD_TAG_SEARCH */
  2135   2183       Tcl_Release(canvasPtr);
................................................................................
  2407   2455       canvasPtr->flags |= REPICK_NEEDED;
  2408   2456       Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr,
  2409   2457   	    canvasPtr->xOrigin, canvasPtr->yOrigin,
  2410   2458   	    canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin),
  2411   2459   	    canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin));
  2412   2460   }
  2413   2461   
         2462  +/*
         2463  + *----------------------------------------------------------------------
         2464  + *
         2465  + * DecomposeMaskToShiftAndBits --
         2466  + *
         2467  + *      Given a 32 bit pixel mask, we find the position of the lowest bit and the
         2468  + *      width of the mask bits.
         2469  + *
         2470  + * Results:
         2471  + *	None.
         2472  + *
         2473  + * Side effects:
         2474  +*       None.
         2475  + *
         2476  + *----------------------------------------------------------------------
         2477  + */
         2478  +static void
         2479  +DecomposeMaskToShiftAndBits(
         2480  +    unsigned long mask,     /* The pixel mask to examine */
         2481  +    int *shift,             /* Where to put the shift count (position of lowest bit) */
         2482  +    int *bits)              /* Where to put the bit count (width of the pixel mask) */
         2483  +{
         2484  +    int i;
         2485  +    
         2486  +    *shift = 0;
         2487  +    *bits = 0;
         2488  +    
         2489  +    /*
         2490  +     * Find the lowest '1' bit in the mask.
         2491  +     */
         2492  +
         2493  +    for (i = 0; i < 32; ++i) {
         2494  +        if (mask & 1 << i)
         2495  +            break;
         2496  +    }
         2497  +    if (i < 32) {
         2498  +        *shift = i;
         2499  +        
         2500  +        /*
         2501  +        * Now find the next '0' bit and the width of the mask.
         2502  +        */
         2503  + 
         2504  +        for ( ; i < 32; ++i) {
         2505  +            if ((mask & 1 << i) == 0)
         2506  +                break;
         2507  +            else
         2508  +                ++*bits;
         2509  +        }
         2510  +        
         2511  +        /*
         2512  +        * Limit to the top 8 bits if the mask was wider than 8.
         2513  +        */
         2514  +
         2515  +        if (*bits > 8) {
         2516  +            *shift += *bits - 8;
         2517  +            *bits = 8;
         2518  +        }
         2519  +    }
         2520  +}
         2521  +
         2522  +/*
         2523  + *----------------------------------------------------------------------
         2524  + *
         2525  + * DrawCanvas --
         2526  + *
         2527  + *      This function draws the contents of a canvas into the given Photo image.
         2528  + *      This function is called from the widget "image" subcommand.
         2529  + *      The canvas does not need to be mapped (one of it's ancestors must be)
         2530  + *      in order for this function to work. 
         2531  + *
         2532  + * Results:
         2533  + *	None.
         2534  + *
         2535  + * Side effects:
         2536  + *      Canvas contents from within the -scrollregion or widget size are rendered
         2537  + *      into the Photo. Any errors are left in the result.
         2538  + *
         2539  + *----------------------------------------------------------------------
         2540  + */
         2541  +
         2542  +#define OVERDRAW_PIXELS 32        /* How much larger we make the pixmap
         2543  +                                   * that the canvas objects are drawn into */
         2544  +
         2545  +/* From stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine */
         2546  +#define IS_BIG_ENDIAN (*(unsigned short *)"\0\xff" < 0x100)
         2547  +
         2548  +#define BYTE_SWAP16(n) ((((unsigned short)n)>>8) | (((unsigned short)n)<<8))
         2549  +#define BYTE_SWAP32(n) (((n>>24)&0x000000FF) | ((n<<8)&0x00FF0000) | ((n>>8)&0x0000FF00) | ((n<<24)&0xFF000000))
         2550  +
         2551  +static int
         2552  +DrawCanvas(
         2553  +    Tcl_Interp *interp,           /* As passed to the widget command, and we will leave errors here */
         2554  +    ClientData clientData,
         2555  +    Tk_PhotoHandle photohandle,   /* The photo we are rendering into */
         2556  +    int subsample,                /* If either subsample or zoom are not 1 then we call Tk_PhotoPutZoomedBlock() */
         2557  +    int zoom)
         2558  +{
         2559  +    TkCanvas * canvasPtr = clientData;
         2560  +    Tk_Window tkwin;
         2561  +    Display *displayPtr;
         2562  +    Tk_PhotoImageBlock blockPtr = {0};
         2563  +    Window wid;
         2564  +    Tk_Item * itemPtr;
         2565  +    Pixmap pixmap = 0;
         2566  +    XImage *ximagePtr = NULL;
         2567  +    Visual *visualPtr;
         2568  +    GC xgc = 0;
         2569  +    XGCValues xgcValues;
         2570  +    int canvasX1, canvasY1, canvasX2, canvasY2, cWidth, cHeight,
         2571  +        pixmapX1, pixmapY1, pixmapX2, pixmapY2, pmWidth, pmHeight,
         2572  +        bitsPerPixel, bytesPerPixel, x, y, result = TCL_OK,
         2573  +        rshift, gshift, bshift, rbits, gbits, bbits;
         2574  +
         2575  +#ifdef DEBUG_DRAWCANVAS
         2576  +    char buffer[128];
         2577  +#endif
         2578  +
         2579  +    if ((tkwin = canvasPtr->tkwin) == NULL) {
         2580  +        Tcl_AppendResult(interp, "canvas tkwin is NULL!", NULL);
         2581  +        result = TCL_ERROR;
         2582  +        goto done;
         2583  +    }
         2584  +
         2585  +    /*
         2586  +     * If this canvas is unmapped, then we won't have a window id, so we will
         2587  +     * try the ancestors of the canvas until we find a window that has a
         2588  +     * valid window id. The Tk_GetPixmap() call requires a valid window id.
         2589  +     */
         2590  +
         2591  +    do {
         2592  +
         2593  +        if ((displayPtr = Tk_Display(tkwin)) == NULL) {
         2594  +            Tcl_AppendResult(interp, "canvas (or parent) display is NULL!", NULL);
         2595  +            result = TCL_ERROR;
         2596  +            goto done;
         2597  +        }
         2598  +
         2599  +        if ((wid = Tk_WindowId(tkwin)) != 0) {
         2600  +            continue;
         2601  +        }
         2602  +
         2603  +        if ((tkwin = Tk_Parent(tkwin)) == NULL) {
         2604  +            Tcl_AppendResult(interp, "canvas has no parent with a valid window id! Is the toplevel window mapped?", NULL);
         2605  +            result = TCL_ERROR;
         2606  +            goto done;
         2607  +        }
         2608  +
         2609  +    } while (wid == 0);
         2610  +
         2611  +    bitsPerPixel = Tk_Depth(tkwin);
         2612  +    visualPtr = Tk_Visual(tkwin);
         2613  +
         2614  +    if (subsample == 0) {
         2615  +        Tcl_AppendResult(interp, "subsample cannot be zero", NULL);
         2616  +        result = TCL_ERROR;
         2617  +        goto done;
         2618  +    }
         2619  +
         2620  +    /*
         2621  +    * Scan through the item list, registering the bounding box for all items
         2622  +    * that didn't do that for the final coordinates yet. This can be
         2623  +    * determined by the FORCE_REDRAW flag.
         2624  +    */
         2625  +
         2626  +    for (itemPtr = canvasPtr -> firstItemPtr; itemPtr != NULL; 
         2627  +            itemPtr = itemPtr -> nextPtr) {
         2628  +        if (itemPtr -> redraw_flags & FORCE_REDRAW) {
         2629  +            itemPtr -> redraw_flags &= ~FORCE_REDRAW;
         2630  +            EventuallyRedrawItem(canvasPtr, itemPtr);
         2631  +            itemPtr -> redraw_flags &= ~FORCE_REDRAW;
         2632  +        }
         2633  +    }
         2634  +
         2635  +    /*
         2636  +     * The DisplayCanvas() function works out the region that needs redrawing,
         2637  +     * but we don't do this. We grab the whole scrollregion or canvas window
         2638  +     * area. If we have a defined -scrollregion we use that as the drawing
         2639  +     * region, otherwise use the canvas window height and width with an origin
         2640  +     * of 0,0.
         2641  +     */
         2642  +    if (canvasPtr->scrollX1 != 0 || canvasPtr->scrollY1 != 0 ||
         2643  +            canvasPtr->scrollX2 != 0 || canvasPtr->scrollY2 != 0) {
         2644  +
         2645  +        canvasX1 = canvasPtr->scrollX1;
         2646  +        canvasY1 = canvasPtr->scrollY1;
         2647  +        canvasX2 = canvasPtr->scrollX2;
         2648  +        canvasY2 = canvasPtr->scrollY2;
         2649  +        cWidth = canvasX2 - canvasX1 + 1;
         2650  +        cHeight = canvasY2 - canvasY1 + 1;
         2651  +
         2652  +    } else {
         2653  +
         2654  +        cWidth = Tk_Width(tkwin);
         2655  +        cHeight = Tk_Height(tkwin);
         2656  +        canvasX1 = 0;
         2657  +        canvasY1 = 0;
         2658  +        canvasX2 = canvasX1 + cWidth - 1;
         2659  +        canvasY2 = canvasY1 + cHeight - 1;
         2660  +    }
         2661  +    
         2662  +    /*
         2663  +     * Allocate a pixmap to draw into. We add OVERDRAW_PIXELS in the same way
         2664  +     * that DisplayCanvas() does to avoid problems on some systems when objects
         2665  +     * are being drawn too close to the edge.
         2666  +     */
         2667  +
         2668  +    pixmapX1 = canvasX1 - OVERDRAW_PIXELS;
         2669  +    pixmapY1 = canvasY1 - OVERDRAW_PIXELS;
         2670  +    pixmapX2 = canvasX2 + OVERDRAW_PIXELS;
         2671  +    pixmapY2 = canvasY2 + OVERDRAW_PIXELS;
         2672  +    pmWidth = pixmapX2 - pixmapX1 + 1;
         2673  +    pmHeight = pixmapY2 - pixmapY1 + 1;
         2674  +    if ((pixmap = Tk_GetPixmap(displayPtr, Tk_WindowId(tkwin), pmWidth, pmHeight,
         2675  +            bitsPerPixel)) == 0) {
         2676  +        Tcl_AppendResult(interp, "failed to create drawing Pixmap", NULL);
         2677  +        result = TCL_ERROR;
         2678  +        goto done;
         2679  +    }
         2680  +
         2681  +    /*
         2682  +     * Before we can draw the canvas objects into the pixmap it's background
         2683  +     * should be filled with canvas background colour.
         2684  +     */
         2685  +
         2686  +    xgcValues.function = GXcopy;
         2687  +    xgcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel;
         2688  +    xgc = XCreateGC(displayPtr, pixmap, GCFunction|GCForeground, &xgcValues);
         2689  +    XFillRectangle(displayPtr,pixmap,xgc,0,0,pmWidth,pmHeight);
         2690  +
         2691  +    /*
         2692  +     * Draw all the cavas items into the pixmap
         2693  +     */
         2694  +
         2695  +    canvasPtr->drawableXOrigin = pixmapX1;
         2696  +    canvasPtr->drawableYOrigin = pixmapY1;
         2697  +    for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL;
         2698  +            itemPtr = itemPtr->nextPtr) {
         2699  +        if ((itemPtr->x1 >= pixmapX2) || (itemPtr->y1 >= pixmapY2) ||
         2700  +                (itemPtr->x2 < pixmapX1) || (itemPtr->y2 < pixmapY1)) {
         2701  +            if (!AlwaysRedraw(itemPtr)) {
         2702  +                continue;
         2703  +            }
         2704  +        }
         2705  +        if (itemPtr->state == TK_STATE_HIDDEN || 
         2706  +                (itemPtr->state == TK_STATE_NULL && canvasPtr->canvas_state
         2707  +                == TK_STATE_HIDDEN)) {
         2708  +            continue;
         2709  +        }
         2710  +        ItemDisplay(canvasPtr, itemPtr, pixmap, pixmapX1, pixmapY1, pmWidth,
         2711  +                pmHeight);
         2712  +    }
         2713  +    
         2714  +    /*
         2715  +     * Copy the Pixmap into an ZPixmap format XImage so we can copy it across
         2716  +     * to the photo image. This seems to be the only way to get Pixmap image
         2717  +     * data out of an image. Note we have to account for the OVERDRAW_PIXELS
         2718  +     * border width.
         2719  +     */
         2720  +
         2721  +    if ((ximagePtr = XGetImage(displayPtr, pixmap, -pixmapX1, -pixmapY1, cWidth,
         2722  +            cHeight, AllPlanes, ZPixmap)) == NULL) {
         2723  +        Tcl_AppendResult(interp, "failed to copy Pixmap to XImage", NULL);
         2724  +        result = TCL_ERROR;
         2725  +        goto done;
         2726  +    }
         2727  +    
         2728  +#ifdef DEBUG_DRAWCANVAS
         2729  +    Tcl_AppendResult(interp, "ximagePtr {", NULL);
         2730  +    sprintf(buffer,"%d",ximagePtr->width);   Tcl_AppendResult(interp, " width ", buffer, NULL);
         2731  +    sprintf(buffer,"%d",ximagePtr->height);  Tcl_AppendResult(interp, " height ", buffer, NULL);
         2732  +    sprintf(buffer,"%d",ximagePtr->xoffset); Tcl_AppendResult(interp, " xoffset ", buffer, NULL);
         2733  +    sprintf(buffer,"%d",ximagePtr->format);  Tcl_AppendResult(interp, " format ", buffer, NULL);
         2734  +                                             Tcl_AppendResult(interp, " ximagePtr->data", NULL);
         2735  +    if (ximagePtr->data != NULL) {
         2736  +	int ix, iy;
         2737  +
         2738  +        Tcl_AppendResult(interp, " {", NULL);
         2739  +	for (iy = 0; iy < ximagePtr->height; ++ iy) {
         2740  +	    Tcl_AppendResult(interp, " {", NULL);
         2741  +	    for (ix = 0; ix < ximagePtr->bytes_per_line; ++ ix) {
         2742  +	        if (ix > 0) {
         2743  +                    if (ix % 4 == 0)
         2744  +                        Tcl_AppendResult(interp, "-", NULL);
         2745  +                    else
         2746  +                        Tcl_AppendResult(interp, " ", NULL);
         2747  +                }
         2748  +	        sprintf(buffer,"%2.2x",ximagePtr->data[ximagePtr->bytes_per_line * iy + ix]&0xFF);
         2749  +	        Tcl_AppendResult(interp, buffer, NULL);
         2750  +	    }
         2751  +	    Tcl_AppendResult(interp, " }", NULL);
         2752  +	}
         2753  +	Tcl_AppendResult(interp, " }", NULL);
         2754  +    } else
         2755  +	sprintf(buffer," NULL");
         2756  +    sprintf(buffer,"%d",ximagePtr->byte_order);       Tcl_AppendResult(interp, " byte_order ", buffer, NULL);
         2757  +    sprintf(buffer,"%d",ximagePtr->bitmap_unit);      Tcl_AppendResult(interp, " bitmap_unit ", buffer, NULL);
         2758  +    sprintf(buffer,"%d",ximagePtr->bitmap_bit_order); Tcl_AppendResult(interp, " bitmap_bit_order ", buffer, NULL);
         2759  +    sprintf(buffer,"%d",ximagePtr->bitmap_pad);       Tcl_AppendResult(interp, " bitmap_pad ", buffer, NULL);
         2760  +    sprintf(buffer,"%d",ximagePtr->depth);            Tcl_AppendResult(interp, " depth ", buffer, NULL);
         2761  +    sprintf(buffer,"%d",ximagePtr->bytes_per_line);   Tcl_AppendResult(interp, " bytes_per_line ", buffer, NULL);
         2762  +    sprintf(buffer,"%d",ximagePtr->bits_per_pixel);   Tcl_AppendResult(interp, " bits_per_pixel ", buffer, NULL);
         2763  +    sprintf(buffer,"0x%8.8lx",ximagePtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
         2764  +    sprintf(buffer,"0x%8.8lx",ximagePtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
         2765  +    sprintf(buffer,"0x%8.8lx",ximagePtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
         2766  +    Tcl_AppendResult(interp, " }", NULL);
         2767  +    
         2768  +    Tcl_AppendResult(interp, "\nvisualPtr {", NULL);
         2769  +    sprintf(buffer,"0x%8.8lx",visualPtr->red_mask);   Tcl_AppendResult(interp, " red_mask ", buffer, NULL);
         2770  +    sprintf(buffer,"0x%8.8lx",visualPtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL);
         2771  +    sprintf(buffer,"0x%8.8lx",visualPtr->blue_mask);  Tcl_AppendResult(interp, " blue_mask ", buffer, NULL);
         2772  +    Tcl_AppendResult(interp, " }", NULL);
         2773  +    
         2774  +#endif
         2775  +
         2776  +    /*
         2777  +     * Fill in the PhotoImageBlock structure abd allocate a block of memory
         2778  +     * for the converted image data. Note we allocate an alpha channel even
         2779  +     * though we don't use one, because this layout helps Tk_PhotoPutBlock()
         2780  +     * use memcpy() instead of the slow pixel or line copy.
         2781  +     */
         2782  +
         2783  +    blockPtr.width = cWidth;
         2784  +    blockPtr.height = cHeight;
         2785  +    blockPtr.pixelSize = 4;
         2786  +    blockPtr.pitch = blockPtr.pixelSize * blockPtr.width;
         2787  +    blockPtr.offset[0] = 0;
         2788  +    blockPtr.offset[1] = 1;
         2789  +    blockPtr.offset[2] = 2;
         2790  +    blockPtr.offset[3] = 3;
         2791  +    blockPtr.pixelPtr = ckalloc(blockPtr.pixelSize * blockPtr.height * blockPtr.width);
         2792  +
         2793  +    /*
         2794  +     * Now convert the image data pixel by pixel from XImage to 32bit RGBA
         2795  +     * format suitable for Tk_PhotoPutBlock().
         2796  +     */
         2797  +
         2798  +    DecomposeMaskToShiftAndBits(visualPtr->red_mask,&rshift,&rbits);
         2799  +    DecomposeMaskToShiftAndBits(visualPtr->green_mask,&gshift,&gbits);
         2800  +    DecomposeMaskToShiftAndBits(visualPtr->blue_mask,&bshift,&bbits);
         2801  +
         2802  +#ifdef DEBUG_DRAWCANVAS
         2803  +    sprintf(buffer,"%d",rshift); Tcl_AppendResult(interp, "\nbits { rshift ", buffer, NULL);
         2804  +    sprintf(buffer,"%d",gshift); Tcl_AppendResult(interp, " gshift ", buffer, NULL);
         2805  +    sprintf(buffer,"%d",bshift); Tcl_AppendResult(interp, " bshift ", buffer, NULL);
         2806  +    sprintf(buffer,"%d",rbits);  Tcl_AppendResult(interp, " rbits ", buffer, NULL);
         2807  +    sprintf(buffer,"%d",gbits);  Tcl_AppendResult(interp, " gbits ", buffer, NULL);
         2808  +    sprintf(buffer,"%d",bbits);  Tcl_AppendResult(interp, " bbits ", buffer, " }", NULL);
         2809  +    Tcl_AppendResult(interp, "\nConverted_image {", NULL);
         2810  +#endif
         2811  +
         2812  +    /* Ok, had to use ximagePtr->bits_per_pixel here and in the switch (...)
         2813  +     * below to get this to work on Windows. X11 correctly sets the bitmap
         2814  +     *_pad and bitmap_unit fields to 32, but on Windows they are 0 and 8
         2815  +     * respectively!
         2816  +     */
         2817  +
         2818  +    bytesPerPixel = ximagePtr->bits_per_pixel/8;
         2819  +    for (y = 0; y < blockPtr.height; ++y) {
         2820  +
         2821  +#ifdef DEBUG_DRAWCANVAS
         2822  +        Tcl_AppendResult(interp, " {", NULL);
         2823  +#endif
         2824  +
         2825  +        for(x = 0; x < blockPtr.width; ++x) {
         2826  +            unsigned long pixel;
         2827  +
         2828  +            switch (ximagePtr->bits_per_pixel) {
         2829  +
         2830  +                /*
         2831  +                 * Get an 8 bit pixel from the XImage.
         2832  +                 */
         2833  +
         2834  +                case 8 :
         2835  +                    pixel = *((unsigned char *)(ximagePtr->data + bytesPerPixel * x
         2836  +                            + ximagePtr->bytes_per_line * y));
         2837  +                    break;
         2838  +
         2839  +                /*
         2840  +                 * Get a 16 bit pixel from the XImage, and correct the
         2841  +                 * byte order as necessary.
         2842  +                 */
         2843  +
         2844  +                case 16 :
         2845  +                    pixel = *((unsigned short *)(ximagePtr->data + bytesPerPixel * x
         2846  +                            + ximagePtr->bytes_per_line * y));
         2847  +                    if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
         2848  +                            || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
         2849  +                        pixel = BYTE_SWAP16(pixel);
         2850  +                    break;
         2851  +
         2852  +                /*
         2853  +                 * Grab a 32 bit pixel from the XImage, and correct the
         2854  +                 * byte order as necessary.
         2855  +                 */
         2856  +
         2857  +                case 32 :
         2858  +                    pixel = *((unsigned long *)(ximagePtr->data + bytesPerPixel * x
         2859  +                            + ximagePtr->bytes_per_line * y));
         2860  +                    if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst)
         2861  +                            || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst))
         2862  +                        pixel = BYTE_SWAP32(pixel);
         2863  +                    break;
         2864  +            }
         2865  +
         2866  +            /*
         2867  +             * We have a pixel with the correct byte order, so pull out the
         2868  +             * colours and place them in the photo block. Perhaps we could
         2869  +             * just not bother with the alpha byte because we are using
         2870  +             * TK_PHOTO_COMPOSITE_SET later?
         2871  +             * ***Windows: We have to swap the red and blue values. The
         2872  +             * XImage storage is B - G - R - A which becomes a 32bit ARGB
         2873  +             * quad. However the visual mask is a 32bit ABGR quad. And
         2874  +             * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad.
         2875  +             * If the visual mask was correct there would be no need to
         2876  +             * swap anything here.
         2877  +             */
         2878  +
         2879  +#ifdef _WIN32
         2880  +#define   R_OFFSET 2
         2881  +#define   B_OFFSET 0
         2882  +#else
         2883  +#define   R_OFFSET 0
         2884  +#define   B_OFFSET 2
         2885  +#endif
         2886  +            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + R_OFFSET] =
         2887  +                    (unsigned char)((pixel & visualPtr->red_mask) >> rshift);
         2888  +            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +1] =
         2889  +                    (unsigned char)((pixel & visualPtr->green_mask) >> gshift);
         2890  +            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + B_OFFSET] =
         2891  +                    (unsigned char)((pixel & visualPtr->blue_mask) >> bshift);
         2892  +            blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +3] = 0xFF;
         2893  +
         2894  +#ifdef DEBUG_DRAWCANVAS
         2895  +            {
         2896  +		int ix;
         2897  +                if (x > 0)
         2898  +                    Tcl_AppendResult(interp, "-", NULL);
         2899  +	        for (ix = 0; ix < 4; ++ix) {
         2900  +                    if (ix > 0)
         2901  +                        Tcl_AppendResult(interp, " ", NULL);
         2902  +		    sprintf(buffer,"%2.2x",blockPtr.pixelPtr[blockPtr.pitch * y
         2903  +                            + blockPtr.pixelSize * x + ix]&0xFF);
         2904  +                    Tcl_AppendResult(interp, buffer, NULL);
         2905  +                }
         2906  +            }
         2907  +#endif
         2908  +
         2909  +        }
         2910  +
         2911  +#ifdef DEBUG_DRAWCANVAS
         2912  +        Tcl_AppendResult(interp, " }", NULL);
         2913  +#endif
         2914  +
         2915  +    }
         2916  +
         2917  +#ifdef DEBUG_DRAWCANVAS
         2918  +    Tcl_AppendResult(interp, " }", NULL);
         2919  +#endif
         2920  +
         2921  +    /*
         2922  +     * Now put the copied pixmap into the photo.
         2923  +     * If either zoom or subsample are not 1, we use the zoom function.
         2924  +     */
         2925  +
         2926  +    if (subsample != 1 || zoom != 1) {
         2927  +        if ((result = Tk_PhotoPutZoomedBlock(interp, photohandle, &blockPtr,
         2928  +                0, 0, cWidth * zoom / subsample, cHeight * zoom / subsample,
         2929  +                zoom, zoom, subsample, subsample, TK_PHOTO_COMPOSITE_SET))
         2930  +                != TCL_OK) {
         2931  +            goto done;
         2932  +        }
         2933  +    } else {
         2934  +        if ((result = Tk_PhotoPutBlock(interp, photohandle, &blockPtr, 0, 0,
         2935  +            cWidth, cHeight, TK_PHOTO_COMPOSITE_SET)) != TCL_OK) {
         2936  +            goto done;
         2937  +        }
         2938  +    }
         2939  +
         2940  +    /*
         2941  +     * Clean up anything we have allocated and exit.
         2942  +     */
         2943  +
         2944  +done:
         2945  +    if (blockPtr.pixelPtr)
         2946  +        ckfree(blockPtr.pixelPtr);
         2947  +    if (pixmap)
         2948  +        Tk_FreePixmap(Tk_Display(tkwin), pixmap);
         2949  +    if (ximagePtr)
         2950  +        XDestroyImage(ximagePtr);
         2951  +    if (xgc)
         2952  +        XFreeGC(displayPtr,xgc);
         2953  +    return result;
         2954  +}
         2955  +
  2414   2956   /*
  2415   2957    *----------------------------------------------------------------------
  2416   2958    *
  2417   2959    * DisplayCanvas --
  2418   2960    *
  2419   2961    *	This function redraws the contents of a canvas window. It is invoked
  2420   2962    *	as a do-when-idle handler, so it only runs when there's nothing else

Changes to generic/tkEntry.c.

   883    883   		entryPtr->selectFirst = -1;
   884    884   		entryPtr->selectLast = -1;
   885    885   	    } else {
   886    886   		entryPtr->selectFirst = index;
   887    887   		entryPtr->selectLast = index2;
   888    888   	    }
   889    889   	    if (!(entryPtr->flags & GOT_SELECTION)
   890         -		    && (entryPtr->exportSelection)) {
          890  +		    && (entryPtr->exportSelection)
          891  +		    && (!Tcl_IsSafe(entryPtr->interp))) {
   891    892   		Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
   892    893   			EntryLostSelection, entryPtr);
   893    894   		entryPtr->flags |= GOT_SELECTION;
   894    895   	    }
   895    896   	    EventuallyRedraw(entryPtr);
   896    897   	    break;
   897    898   
................................................................................
  1118   1119       }
  1119   1120   
  1120   1121       /*
  1121   1122        * Store old values that we need to effect certain behavior if they change
  1122   1123        * value.
  1123   1124        */
  1124   1125   
  1125         -    oldExport = entryPtr->exportSelection;
         1126  +    oldExport = (entryPtr->exportSelection) && (!Tcl_IsSafe(entryPtr->interp));
  1126   1127       if (entryPtr->type == TK_SPINBOX) {
  1127   1128   	oldValues = sbPtr->valueStr;
  1128   1129   	oldFormat = sbPtr->reqFormat;
  1129   1130   	oldFrom = sbPtr->fromValue;
  1130   1131   	oldTo = sbPtr->toValue;
  1131   1132       }
  1132   1133   
................................................................................
  1272   1273   	}
  1273   1274   
  1274   1275   	/*
  1275   1276   	 * Claim the selection if we've suddenly started exporting it.
  1276   1277   	 */
  1277   1278   
  1278   1279   	if (entryPtr->exportSelection && (!oldExport)
         1280  +		&& (!Tcl_IsSafe(entryPtr->interp))
  1279   1281   		&& (entryPtr->selectFirst != -1)
  1280   1282   		&& !(entryPtr->flags & GOT_SELECTION)) {
  1281   1283   	    Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
  1282   1284   		    entryPtr);
  1283   1285   	    entryPtr->flags |= GOT_SELECTION;
  1284   1286   	}
  1285   1287   
................................................................................
  2741   2743   {
  2742   2744       int newFirst, newLast;
  2743   2745   
  2744   2746       /*
  2745   2747        * Grab the selection if we don't own it already.
  2746   2748        */
  2747   2749   
  2748         -    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)) {
         2750  +    if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)
         2751  +	    && (!Tcl_IsSafe(entryPtr->interp))) {
  2749   2752   	Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection,
  2750   2753   		entryPtr);
  2751   2754   	entryPtr->flags |= GOT_SELECTION;
  2752   2755       }
  2753   2756   
  2754   2757       /*
  2755   2758        * Pick new starting and ending points for the selection.
................................................................................
  2808   2811   				 * not including terminating NUL character. */
  2809   2812   {
  2810   2813       Entry *entryPtr = clientData;
  2811   2814       int byteCount;
  2812   2815       const char *string;
  2813   2816       const char *selStart, *selEnd;
  2814   2817   
  2815         -    if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) {
         2818  +    if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection)
         2819  +	    || Tcl_IsSafe(entryPtr->interp)) {
  2816   2820   	return -1;
  2817   2821       }
  2818   2822       string = entryPtr->displayString;
  2819   2823       selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst);
  2820   2824       selEnd = Tcl_UtfAtIndex(selStart,
  2821   2825   	    entryPtr->selectLast - entryPtr->selectFirst);
  2822   2826       byteCount = selEnd - selStart - offset;
................................................................................
  2861   2865        * On Windows and Mac systems, we want to remember the selection for the
  2862   2866        * next time the focus enters the window. On Unix, we need to clear the
  2863   2867        * selection since it is always visible.
  2864   2868        * This is controlled by ::tk::AlwaysShowSelection.
  2865   2869        */
  2866   2870   
  2867   2871       if (TkpAlwaysShowSelection(entryPtr->tkwin)
  2868         -	    && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection) {
         2872  +	    && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection
         2873  +	    && (!Tcl_IsSafe(entryPtr->interp))) {
  2869   2874   	entryPtr->selectFirst = -1;
  2870   2875   	entryPtr->selectLast = -1;
  2871   2876   	EventuallyRedraw(entryPtr);
  2872   2877       }
  2873   2878   }
  2874   2879   
  2875   2880   /*
................................................................................
  3126   3131    */
  3127   3132   
  3128   3133   	/* ARGSUSED */
  3129   3134   static char *
  3130   3135   EntryTextVarProc(
  3131   3136       ClientData clientData,	/* Information about button. */
  3132   3137       Tcl_Interp *interp,		/* Interpreter containing variable. */
  3133         -    const char *name1,		/* Not used. */
  3134         -    const char *name2,		/* Not used. */
         3138  +    const char *name1,		/* Name of variable. */
         3139  +    const char *name2,		/* Second part of variable name. */
  3135   3140       int flags)			/* Information about what happened. */
  3136   3141   {
  3137   3142       Entry *entryPtr = clientData;
  3138   3143       const char *value;
  3139   3144   
  3140   3145       if (entryPtr->flags & ENTRY_DELETED) {
  3141   3146   	/*
  3142   3147   	 * Just abort early if we entered here while being deleted.
  3143   3148   	 */
  3144   3149   	return NULL;
  3145   3150       }
         3151  +
         3152  +    /*
         3153  +     * See ticket [5d991b82].
         3154  +     */
         3155  +
         3156  +    if (entryPtr->textVarName == NULL) {
         3157  +	if (!(flags & TCL_INTERP_DESTROYED)) {
         3158  +	    Tcl_UntraceVar2(interp, name1, name2,
         3159  +		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
         3160  +		    EntryTextVarProc, clientData);
         3161  +	}
         3162  + 	return NULL;
         3163  +     }
  3146   3164   
  3147   3165       /*
  3148   3166        * If the variable is unset, then immediately recreate it unless the whole
  3149   3167        * interpreter is going away.
  3150   3168        */
  3151   3169   
  3152   3170       if (flags & TCL_TRACE_UNSETS) {
................................................................................
  4030   4048   		entryPtr->selectFirst = -1;
  4031   4049   		entryPtr->selectLast = -1;
  4032   4050   	    } else {
  4033   4051   		entryPtr->selectFirst = index;
  4034   4052   		entryPtr->selectLast = index2;
  4035   4053   	    }
  4036   4054   	    if (!(entryPtr->flags & GOT_SELECTION)
  4037         -		    && entryPtr->exportSelection) {
         4055  +		    && entryPtr->exportSelection
         4056  +		    && (!Tcl_IsSafe(entryPtr->interp))) {
  4038   4057   		Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY,
  4039   4058   			EntryLostSelection, entryPtr);
  4040   4059   		entryPtr->flags |= GOT_SELECTION;
  4041   4060   	    }
  4042   4061   	    EventuallyRedraw(entryPtr);
  4043   4062   	    break;
  4044   4063   

Changes to generic/tkFont.c.

  3147   3147   	    continue;
  3148   3148   	}
  3149   3149   
  3150   3150   	cx[0] = cx[3] = chunkPtr->x;
  3151   3151   	cy[0] = cy[1] = chunkPtr->y - fontPtr->fm.ascent;
  3152   3152   	cx[1] = cx[2] = chunkPtr->x + chunkPtr->displayWidth;
  3153   3153   	cy[2] = cy[3] = chunkPtr->y + fontPtr->fm.descent;
  3154         -	if (	!PointInQuadrilateral(cx, cy, rx[0], ry[0]) ||
  3155         -		!PointInQuadrilateral(cx, cy, rx[1], ry[1]) ||
  3156         -		!PointInQuadrilateral(cx, cy, rx[2], ry[2]) ||
  3157         -		!PointInQuadrilateral(cx, cy, rx[3], ry[3])) {
  3158         -	    goto notReverseInside;
  3159         -	}
         3154  +	if (	PointInQuadrilateral(cx, cy, rx[0], ry[0]) &&
         3155  +		PointInQuadrilateral(cx, cy, rx[1], ry[1]) &&
         3156  +		PointInQuadrilateral(cx, cy, rx[2], ry[2]) &&
         3157  +		PointInQuadrilateral(cx, cy, rx[3], ry[3])) {
         3158  +            return 0;
         3159  +        }
  3160   3160       }
  3161         -    return 0;
  3162   3161   
  3163   3162       /*
  3164   3163        * If we're overlapping now, we must be partially in and out of at least
  3165   3164        * one chunk. If that is the case, there must be one line segment of the
  3166   3165        * rectangle that is touching or crossing a line segment of a chunk.
  3167   3166        */
  3168   3167   
  3169         -  notReverseInside:
  3170   3168       chunkPtr = layoutPtr->chunks;
  3171   3169   
  3172   3170       for (i=0 ; i<layoutPtr->numChunks ; i++,chunkPtr++) {
  3173   3171   	int j;
  3174   3172   
  3175   3173   	if (chunkPtr->start[0] == '\n') {
  3176   3174   	    /*

Changes to generic/tkGrid.c.

  2864   2864   	    if (!(gridPtr->masterPtr->flags & REQUESTED_RELAYOUT)) {
  2865   2865   		gridPtr->doubleBw = 2*Tk_Changes(gridPtr->tkwin)->border_width;
  2866   2866   		gridPtr->masterPtr->flags |= REQUESTED_RELAYOUT;
  2867   2867   		Tcl_DoWhenIdle(ArrangeGrid, gridPtr->masterPtr);
  2868   2868   	    }
  2869   2869   	}
  2870   2870       } else if (eventPtr->type == DestroyNotify) {
  2871         -	register Gridder *gridPtr2, *nextPtr;
         2871  +	register Gridder *slavePtr, *nextPtr;
  2872   2872   
  2873   2873   	if (gridPtr->masterPtr != NULL) {
  2874   2874   	    Unlink(gridPtr);
  2875   2875   	}
  2876         -	for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
  2877         -		gridPtr2 = nextPtr) {
  2878         -	    Tk_UnmapWindow(gridPtr2->tkwin);
  2879         -	    gridPtr2->masterPtr = NULL;
  2880         -	    nextPtr = gridPtr2->nextPtr;
  2881         -	    gridPtr2->nextPtr = NULL;
         2876  +	for (slavePtr = gridPtr->slavePtr; slavePtr != NULL;
         2877  +		slavePtr = nextPtr) {
         2878  +	    Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL);
         2879  +	    Tk_UnmapWindow(slavePtr->tkwin);
         2880  +	    slavePtr->masterPtr = NULL;
         2881  +	    nextPtr = slavePtr->nextPtr;
         2882  +	    slavePtr->nextPtr = NULL;
  2882   2883   	}
  2883   2884   	Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable,
  2884   2885   		(char *) gridPtr->tkwin));
  2885   2886   	if (gridPtr->flags & REQUESTED_RELAYOUT) {
  2886   2887   	    Tcl_CancelIdleCall(ArrangeGrid, gridPtr);
  2887   2888   	}
  2888   2889   	gridPtr->tkwin = NULL;
................................................................................
  2890   2891       } else if (eventPtr->type == MapNotify) {
  2891   2892   	if ((gridPtr->slavePtr != NULL)
  2892   2893   		&& !(gridPtr->flags & REQUESTED_RELAYOUT)) {
  2893   2894   	    gridPtr->flags |= REQUESTED_RELAYOUT;
  2894   2895   	    Tcl_DoWhenIdle(ArrangeGrid, gridPtr);
  2895   2896   	}
  2896   2897       } else if (eventPtr->type == UnmapNotify) {
  2897         -	register Gridder *gridPtr2;
         2898  +	register Gridder *slavePtr;
  2898   2899   
  2899         -	for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL;
  2900         -		gridPtr2 = gridPtr2->nextPtr) {
  2901         -	    Tk_UnmapWindow(gridPtr2->tkwin);
         2900  +	for (slavePtr = gridPtr->slavePtr; slavePtr != NULL;
         2901  +		slavePtr = slavePtr->nextPtr) {
         2902  +	    Tk_UnmapWindow(slavePtr->tkwin);
  2902   2903   	}
  2903   2904       }
  2904   2905   }
  2905   2906   
  2906   2907   /*
  2907   2908    *----------------------------------------------------------------------
  2908   2909    *
................................................................................
  3079   3080   		return TCL_ERROR;
  3080   3081   	    }
  3081   3082   	    defaultRow = tmp;
  3082   3083   	}
  3083   3084       }
  3084   3085   
  3085   3086       /*
  3086         -     * If no -row is given, use the first unoccupied row of the master.
         3087  +     * If no -row is given, use the next row after the highest occupied row
         3088  +     * of the master.
  3087   3089        */
  3088   3090   
  3089   3091       if (defaultRow < 0) {
  3090   3092   	if (masterPtr != NULL && masterPtr->masterDataPtr != NULL) {
  3091   3093   	    SetGridSize(masterPtr);
  3092   3094   	    defaultRow = masterPtr->masterDataPtr->rowEnd;
  3093   3095   	} else {

Changes to generic/tkImgPNG.c.

    31     31       0, 0, 0, 4, 0, 2, 0, 1
    32     32   };
    33     33   
    34     34   /*
    35     35    * Chunk type flags.
    36     36    */
    37     37   
    38         -#define PNG_CF_ANCILLARY 0x10000000L	/* Non-critical chunk (can ignore). */
           38  +#define PNG_CF_ANCILLARY 0x20000000L	/* Non-critical chunk (can ignore). */
    39     39   #define PNG_CF_PRIVATE   0x00100000L	/* Application-specific chunk. */
    40     40   #define PNG_CF_RESERVED  0x00001000L	/* Not used. */
    41     41   #define PNG_CF_COPYSAFE  0x00000010L	/* Opaque data safe for copying. */
    42     42   
    43     43   /*
    44     44    * Chunk types, not all of which have support implemented. Note that there are
    45     45    * others in the official extension set which we will never support (as they
................................................................................
   980    980   		if (chunkType & PNG_INT32(128,128,128,128)) {
   981    981   		    /*
   982    982   		     * No nice ASCII conversion; shouldn't happen either, but
   983    983   		     * we'll be doubly careful.
   984    984   		     */
   985    985   
   986    986   		    Tcl_SetObjResult(interp, Tcl_NewStringObj(
   987         -			    "encountered an unsupported criticial chunk type",
          987  +			    "encountered an unsupported critical chunk type",
   988    988   			    -1));
   989    989   		} else {
   990    990   		    char typeString[5];
   991    991   
   992    992   		    typeString[0] = (char) ((chunkType >> 24) & 255);
   993    993   		    typeString[1] = (char) ((chunkType >> 16) & 255);
   994    994   		    typeString[2] = (char) ((chunkType >> 8) & 255);
   995    995   		    typeString[3] = (char) (chunkType & 255);
   996    996   		    typeString[4] = '\0';
   997    997   		    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
   998         -			    "encountered an unsupported criticial chunk type"
          998  +			    "encountered an unsupported critical chunk type"
   999    999   			    " \"%s\"", typeString));
  1000   1000   		}
  1001   1001   		Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG",
  1002   1002   			"UNSUPPORTED_CRITICAL", NULL);
  1003   1003   		return TCL_ERROR;
  1004   1004   	    }
  1005   1005   

Changes to generic/tkImgPhInstance.c.

   414    414   #define GetRValue(rgb)	(UCHAR(((rgb) & red_mask) >> red_shift))
   415    415   #define GetGValue(rgb)	(UCHAR(((rgb) & green_mask) >> green_shift))
   416    416   #define GetBValue(rgb)	(UCHAR(((rgb) & blue_mask) >> blue_shift))
   417    417   #define RGB(r, g, b)	((unsigned)( \
   418    418   	(UCHAR(r) << red_shift)   | \
   419    419   	(UCHAR(g) << green_shift) | \
   420    420   	(UCHAR(b) << blue_shift)  ))
          421  +#ifdef MAC_OSX_TK
          422  +#define RGBA(r, g, b, a) ((unsigned)( \
          423  +	(UCHAR(r) << red_shift)   | \
          424  +	(UCHAR(g) << green_shift) | \
          425  +	(UCHAR(b) << blue_shift)  | \
          426  +	(UCHAR(a) << alpha_shift) ))
          427  +#endif
   421    428   #define RGB15(r, g, b)	((unsigned)( \
   422    429   	(((r) * red_mask / 255)   & red_mask)   | \
   423    430   	(((g) * green_mask / 255) & green_mask) | \
   424    431   	(((b) * blue_mask / 255)  & blue_mask)  ))
   425    432   #endif /* !_WIN32 */
   426    433   
   427    434   static void
................................................................................
   481    488       }
   482    489       while ((0x0001 & (green_mask >> green_shift)) == 0) {
   483    490   	green_shift++;
   484    491       }
   485    492       while ((0x0001 & (blue_mask >> blue_shift)) == 0) {
   486    493   	blue_shift++;
   487    494       }
          495  +#ifdef MAC_OSX_TK
          496  +    unsigned long alpha_mask = visual->alpha_mask;
          497  +    unsigned long alpha_shift = 0;
          498  +    while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) {
          499  +	alpha_shift++;
          500  +    }
          501  +#endif
   488    502   #endif /* !_WIN32 */
   489    503   
   490    504       /*
   491    505        * Only UNIX requires the special case for <24bpp. It varies with 3 extra
   492    506        * shifts and uses RGB15. The 24+bpp version could also then be further
   493    507        * optimized.
   494    508        */
................................................................................
   581    595   		    ga = GetGValue(pixel);
   582    596   		    ba = GetBValue(pixel);
   583    597   		    unalpha = 255 - alpha;	/* Calculate once. */
   584    598   		    r = ALPHA_BLEND(ra, r, alpha, unalpha);
   585    599   		    g = ALPHA_BLEND(ga, g, alpha, unalpha);
   586    600   		    b = ALPHA_BLEND(ba, b, alpha, unalpha);
   587    601   		}
          602  +#ifndef MAC_OSX_TK
   588    603   		XPutPixel(bgImg, x, y, RGB(r, g, b));
          604  +#else
          605  +		XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha));
          606  +#endif
   589    607   	    }
   590    608   	}
   591    609       }
   592    610   #undef ALPHA_BLEND
   593    611   }
   594    612   
   595    613   /*

Changes to generic/tkImgPhoto.c.

   572    572   		    Tcl_GetString(options.name), NULL);
   573    573   	    return TCL_ERROR;
   574    574   	}
   575    575   	Tk_PhotoGetImage(srcHandle, &block);
   576    576   	if ((options.fromX2 > block.width) || (options.fromY2 > block.height)
   577    577   		|| (options.fromX2 > block.width)
   578    578   		|| (options.fromY2 > block.height)) {
          579  +	    if (options.background) {
          580  +		Tk_FreeColor(options.background);
          581  +	    }
   579    582   	    Tcl_SetObjResult(interp, Tcl_NewStringObj(
   580    583   		    "coordinates for -from option extend outside source image",
   581    584   		    -1));
   582    585   	    Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL);
   583    586   	    return TCL_ERROR;
   584    587   	}
   585    588   
................................................................................
   620    623   	    } else {
   621    624   		height = (height - options.subsampleY - 1)
   622    625   			/ -options.subsampleY;
   623    626   	    }
   624    627   	    options.toY2 = options.toY + height * options.zoomY;
   625    628   	}
   626    629   
   627         -	/*
   628         -	 * Set the destination image size if the -shrink option was specified.
   629         -	 */
   630         -
   631         -	if (options.options & OPT_SHRINK) {
   632         -	    if (ImgPhotoSetSize(masterPtr, options.toX2,
   633         -		    options.toY2) != TCL_OK) {
   634         -		Tcl_SetObjResult(interp, Tcl_NewStringObj(
   635         -			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
   636         -		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
   637         -		return TCL_ERROR;
   638         -	    }
   639         -	}
   640         -
   641    630   	/*
   642    631   	 * Copy the image data over using Tk_PhotoPutZoomedBlock.
   643    632   	 */
   644    633   
   645    634   	block.pixelPtr += options.fromX * block.pixelSize
   646    635   		+ options.fromY * block.pitch;
   647    636   	block.width = options.fromX2 - options.fromX;
   648    637   	block.height = options.fromY2 - options.fromY;
   649         -	return Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
          638  +	result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr,
   650    639   		&block, options.toX, options.toY, options.toX2 - options.toX,
   651    640   		options.toY2 - options.toY, options.zoomX, options.zoomY,
   652    641   		options.subsampleX, options.subsampleY,
   653    642   		options.compositingRule);
   654    643   
          644  +	/*
          645  +	 * Set the destination image size if the -shrink option was specified.
          646  +	 * This has to be done _after_ copying the data. Otherwise, if source
          647  +	 * and destination are the same image, block.pixelPtr would point to
          648  +	 * an invalid memory block (bug [5239fd749b]).
          649  +	 */
          650  +
          651  +	if (options.options & OPT_SHRINK) {
          652  +	    if (ImgPhotoSetSize(masterPtr, options.toX2,
          653  +		    options.toY2) != TCL_OK) {
          654  +		if (options.background) {
          655  +		    Tk_FreeColor(options.background);
          656  +		}
          657  +		Tcl_SetObjResult(interp, Tcl_NewStringObj(
          658  +			TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1));
          659  +		Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL);
          660  +		return TCL_ERROR;
          661  +	    }
          662  +	}
          663  +	Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0,
          664  +		masterPtr->width, masterPtr->height);
          665  +	if (options.background) {
          666  +	    Tk_FreeColor(options.background);
          667  +	}
          668  +	return result;
          669  +
   655    670       case PHOTO_DATA: {
   656    671   	char *data;
   657    672   
   658    673   	/*
   659    674   	 * photo data command - first parse and check any options given.
   660    675   	 */
   661    676   

Changes to generic/tkListbox.c.

  1561   1561       Tcl_Obj *const objv[])	/* Arguments. */
  1562   1562   {
  1563   1563       Tk_SavedOptions savedOptions;
  1564   1564       Tcl_Obj *oldListObj = NULL;
  1565   1565       Tcl_Obj *errorResult = NULL;
  1566   1566       int oldExport, error;
  1567   1567   
  1568         -    oldExport = listPtr->exportSelection;
         1568  +    oldExport = (listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp));
  1569   1569       if (listPtr->listVarName != NULL) {
  1570   1570   	Tcl_UntraceVar2(interp, listPtr->listVarName, NULL,
  1571   1571   		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
  1572   1572   		ListboxListVarProc, listPtr);
  1573   1573       }
  1574   1574   
  1575   1575       for (error = 0; error <= 1; error++) {
................................................................................
  1603   1603   	if (listPtr->highlightWidth < 0) {
  1604   1604   	    listPtr->highlightWidth = 0;
  1605   1605   	}
  1606   1606   	listPtr->inset = listPtr->highlightWidth + listPtr->borderWidth;
  1607   1607   
  1608   1608   	/*
  1609   1609   	 * Claim the selection if we've suddenly started exporting it and
  1610         -	 * there is a selection to export.
         1610  +	 * there is a selection to export and this interp is unsafe.
  1611   1611   	 */
  1612   1612   
  1613         -	if (listPtr->exportSelection && !oldExport
         1613  +	if (listPtr->exportSelection && (!oldExport)
         1614  +		&& (!Tcl_IsSafe(listPtr->interp))
  1614   1615   		&& (listPtr->numSelected != 0)) {
  1615   1616   	    Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY,
  1616   1617   		    ListboxLostSelection, listPtr);
  1617   1618   	}
  1618   1619   
  1619   1620   	/*
  1620   1621   	 * Verify the current status of the list var.
................................................................................
  3075   3076   	}
  3076   3077       }
  3077   3078   
  3078   3079       if (firstRedisplay >= 0) {
  3079   3080   	EventuallyRedrawRange(listPtr, first, last);
  3080   3081       }
  3081   3082       if ((oldCount == 0) && (listPtr->numSelected > 0)
  3082         -	    && listPtr->exportSelection) {
         3083  +	    && (listPtr->exportSelection)
         3084  +	    && (!Tcl_IsSafe(listPtr->interp))) {
  3083   3085   	Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY,
  3084   3086   		ListboxLostSelection, listPtr);
  3085   3087       }
  3086   3088       return TCL_OK;
  3087   3089   }
  3088   3090   
  3089   3091   /*
................................................................................
  3121   3123       register Listbox *listPtr = clientData;
  3122   3124       Tcl_DString selection;
  3123   3125       int length, count, needNewline, stringLen, i;
  3124   3126       Tcl_Obj *curElement;
  3125   3127       const char *stringRep;
  3126   3128       Tcl_HashEntry *entry;
  3127   3129   
  3128         -    if (!listPtr->exportSelection) {
         3130  +    if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) {
  3129   3131   	return -1;
  3130   3132       }
  3131   3133   
  3132   3134       /*
  3133   3135        * Use a dynamic string to accumulate the contents of the selection.
  3134   3136        */
  3135   3137   
................................................................................
  3192   3194   
  3193   3195   static void
  3194   3196   ListboxLostSelection(
  3195   3197       ClientData clientData)	/* Information about listbox widget. */
  3196   3198   {
  3197   3199       register Listbox *listPtr = clientData;
  3198   3200   
  3199         -    if ((listPtr->exportSelection) && (listPtr->nElements > 0)) {
         3201  +    if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp))
         3202  +	    && (listPtr->nElements > 0)) {
  3200   3203   	ListboxSelect(listPtr, 0, listPtr->nElements-1, 0);
  3201   3204           GenerateListboxSelectEvent(listPtr);
  3202   3205       }
  3203   3206   }
  3204   3207   
  3205   3208   /*
  3206   3209    *----------------------------------------------------------------------
................................................................................
  3424   3427    *----------------------------------------------------------------------
  3425   3428    */
  3426   3429   
  3427   3430   static char *
  3428   3431   ListboxListVarProc(
  3429   3432       ClientData clientData,	/* Information about button. */
  3430   3433       Tcl_Interp *interp,		/* Interpreter containing variable. */
  3431         -    const char *name1,		/* Not used. */
  3432         -    const char *name2,		/* Not used. */
         3434  +    const char *name1,		/* Name of variable. */
         3435  +    const char *name2,		/* Second part of variable name. */
  3433   3436       int flags)			/* Information about what happened. */
  3434   3437   {
  3435   3438       Listbox *listPtr = clientData;
  3436   3439       Tcl_Obj *oldListObj, *varListObj;
  3437   3440       int oldLength, i;
  3438   3441       Tcl_HashEntry *entry;
         3442  +
         3443  +    /*
         3444  +     * See ticket [5d991b82].
         3445  +     */
         3446  +
         3447  +    if (listPtr->listVarName == NULL) {
         3448  +	if (!(flags & TCL_INTERP_DESTROYED)) {
         3449  +	    Tcl_UntraceVar2(interp, name1, name2,
         3450  +		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
         3451  +		    ListboxListVarProc, clientData);
         3452  +	}
         3453  +	return NULL;
         3454  +    }
  3439   3455   
  3440   3456       /*
  3441   3457        * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable!
  3442   3458        */
  3443   3459   
  3444   3460       if (flags & TCL_TRACE_UNSETS) {
  3445   3461   	if ((flags & TCL_TRACE_DESTROYED) && !(flags & TCL_INTERP_DESTROYED)) {

Changes to generic/tkMenu.c.

  2491   2491   	 * Do nothing if the interpreter is going away.
  2492   2492   	 */
  2493   2493   
  2494   2494       	return NULL;
  2495   2495       }
  2496   2496   
  2497   2497       menuPtr = mePtr->menuPtr;
         2498  +
         2499  +    if (menuPtr->menuFlags & MENU_DELETION_PENDING) {
         2500  +    	return NULL;
         2501  +    }
         2502  +
         2503  +    /*
         2504  +     * See ticket [5d991b82].
         2505  +     */
         2506  +
         2507  +    if (mePtr->namePtr == NULL) {
         2508  +	Tcl_UntraceVar2(interp, name1, name2,
         2509  +		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
         2510  +		MenuVarProc, clientData);
         2511  +	return NULL;
         2512  +     }
         2513  +
  2498   2514       name = Tcl_GetString(mePtr->namePtr);
  2499   2515   
  2500   2516       /*
  2501   2517        * If the variable is being unset, then re-establish the trace.
  2502   2518        */
  2503   2519   
  2504   2520       if (flags & TCL_TRACE_UNSETS) {

Changes to generic/tkMenubutton.c.

   876    876       const char *name1,		/* Name of variable. */
   877    877       const char *name2,		/* Second part of variable name. */
   878    878       int flags)			/* Information about what happened. */
   879    879   {
   880    880       register TkMenuButton *mbPtr = clientData;
   881    881       const char *value;
   882    882       unsigned len;
          883  +
          884  +    /*
          885  +     * See ticket [5d991b82].
          886  +     */
          887  +
          888  +    if (mbPtr->textVarName == NULL) {
          889  +	if (!(flags & TCL_INTERP_DESTROYED)) {
          890  +	    Tcl_UntraceVar2(interp, name1, name2,
          891  +		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
          892  +		    MenuButtonTextVarProc, clientData);
          893  +	}
          894  +	return NULL;
          895  +    }
   883    896   
   884    897       /*
   885    898        * If the variable is unset, then immediately recreate it unless the whole
   886    899        * interpreter is going away.
   887    900        */
   888    901   
   889    902       if (flags & TCL_TRACE_UNSETS) {

Changes to generic/tkMessage.c.

   833    833       Tcl_Interp *interp,		/* Interpreter containing variable. */
   834    834       const char *name1,		/* Name of variable. */
   835    835       const char *name2,		/* Second part of variable name. */
   836    836       int flags)			/* Information about what happened. */
   837    837   {
   838    838       register Message *msgPtr = clientData;
   839    839       const char *value;
          840  +
          841  +    /*
          842  +     * See ticket [5d991b82].
          843  +     */
          844  +
          845  +    if (msgPtr->textVarName == NULL) {
          846  +	if (!(flags & TCL_INTERP_DESTROYED)) {
          847  +	    Tcl_UntraceVar2(interp, name1, name2,
          848  +		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
          849  +		    MessageTextVarProc, clientData);
          850  +	}
          851  +	return NULL;
          852  +    }
   840    853   
   841    854       /*
   842    855        * If the variable is unset, then immediately recreate it unless the whole
   843    856        * interpreter is going away.
   844    857        */
   845    858   
   846    859       if (flags & TCL_TRACE_UNSETS) {

Changes to generic/tkObj.c.

   149    149   static ThreadSpecificData *
   150    150   GetTypeCache(void)
   151    151   {
   152    152       ThreadSpecificData *tsdPtr =
   153    153   	    Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData));
   154    154   
   155    155       if (tsdPtr->doubleTypePtr == NULL) {
   156         -	tsdPtr->doubleTypePtr = Tcl_GetObjType("double");
   157         -	tsdPtr->intTypePtr = Tcl_GetObjType("int");
          156  +	/* Smart initialization of doubleTypePtr/intTypePtr without
          157  +	 * hash-table lookup or creating complete Tcl_Obj's */
          158  +	Tcl_Obj obj;
          159  +	obj.length = 3;
          160  +	obj.bytes = (char *)"0.0";
          161  +	obj.typePtr = NULL;
          162  +	Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue);
          163  +	tsdPtr->doubleTypePtr = obj.typePtr;
          164  +	obj.bytes += 2;
          165  +	obj.length = 1;
          166  +	obj.typePtr = NULL;
          167  +	Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue);
          168  +	tsdPtr->intTypePtr = obj.typePtr;
   158    169       }
   159    170       return tsdPtr;
   160    171   }
   161    172   
   162    173   /*
   163    174    *----------------------------------------------------------------------
   164    175    *
................................................................................
  1108   1119    *
  1109   1120    *	Registers Tk's Tcl_ObjType structures with the Tcl run-time.
  1110   1121    *
  1111   1122    * Results:
  1112   1123    *	None
  1113   1124    *
  1114   1125    * Side effects:
  1115         - *	All instances of Tcl_ObjType structues used in Tk are registered with
         1126  + *	All instances of Tcl_ObjType structures used in Tk are registered with
  1116   1127    *	Tcl.
  1117   1128    *
  1118   1129    *----------------------------------------------------------------------
  1119   1130    */
  1120   1131   
  1121   1132   void
  1122   1133   TkRegisterObjTypes(void)

Changes to generic/tkPack.c.

  1358   1358       packPtr->masterPtr = NULL;
  1359   1359   
  1360   1360       /*
  1361   1361        * If we have emptied this master from slaves it means we are no longer
  1362   1362        * handling it and should mark it as free.
  1363   1363        */
  1364   1364   
  1365         -    if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) {
         1365  +    if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) {
  1366   1366   	TkFreeGeometryMaster(masterPtr->tkwin, "pack");
  1367   1367   	masterPtr->flags &= ~ALLOCED_MASTER;
  1368   1368       }
  1369   1369   
  1370   1370   }
  1371   1371   
  1372   1372   /*

Changes to generic/tkRectOval.c.

   755    755        * will die if it isn't.
   756    756        */
   757    757   
   758    758       Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0],rectOvalPtr->bbox[1],
   759    759   	    &x1, &y1);
   760    760       Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2],rectOvalPtr->bbox[3],
   761    761   	    &x2, &y2);
   762         -    if (x2 <= x1) {
   763         -	x2 = x1+1;
   764         -    }
   765         -    if (y2 <= y1) {
   766         -	y2 = y1+1;
          762  +    if (x2 == x1) {
          763  +
          764  +        /*
          765  +         * The width of the bounding box corresponds to less than one pixel
          766  +         * on screen. Adjustment is needed to avoid drawing attempts with zero
          767  +         * width items (which would draw nothing). The bounding box spans
          768  +         * either 1 or 2 pixels. Select which pixel will be drawn.
          769  +         */
          770  +
          771  +        short ix1 = (short) (rectOvalPtr->bbox[0]);
          772  +        short ix2 = (short) (rectOvalPtr->bbox[2]);
          773  +
          774  +        if (ix1 == ix2) {
          775  +
          776  +            /*
          777  +             * x1 and x2 are "within the same pixel". Use this pixel.
          778  +             * Note: the degenerated case (bbox[0]==bbox[2]) of a completely
          779  +             * flat box results in arbitrary selection of the pixel at the
          780  +             * right (with positive coordinate) or left (with negative
          781  +             * coordinate) of the box. There is no "best choice" here.
          782  +             */
          783  +
          784  +            if (ix1 > 0) {
          785  +                x2 += 1;
          786  +            } else {
          787  +                x1 -= 1;
          788  +            }
          789  +        } else {
          790  +
          791  +            /*
          792  +             * (x1,x2) span two pixels. Select the one with the larger
          793  +             * covered "area".
          794  +             */
          795  +
          796  +            if (ix1 > 0) {
          797  +                if ((rectOvalPtr->bbox[2] - ix2) > (ix2 - rectOvalPtr->bbox[0])) {
          798  +                    x2 += 1;
          799  +                } else {
          800  +                    x1 -= 1;
          801  +                }
          802  +            } else {
          803  +                if ((rectOvalPtr->bbox[2] - ix1) > (ix1 - rectOvalPtr->bbox[0])) {
          804  +                    x2 += 1;
          805  +                } else {
          806  +                    x1 -= 1;
          807  +                }
          808  +            }
          809  +        }
          810  +    }
          811  +    if (y2 == y1) {
          812  +
          813  +        /*
          814  +         * The height of the bounding box corresponds to less than one pixel
          815  +         * on screen. Adjustment is needed to avoid drawing attempts with zero
          816  +         * height items (which would draw nothing). The bounding box spans
          817  +         * either 1 or 2 pixels. Select which pixel will be drawn.
          818  +         */
          819  +
          820  +        short iy1 = (short) (rectOvalPtr->bbox[1]);
          821  +        short iy2 = (short) (rectOvalPtr->bbox[3]);
          822  +
          823  +        if (iy1 == iy2) {
          824  +
          825  +            /*
          826  +             * y1 and y2 are "within the same pixel". Use this pixel.
          827  +             * Note: the degenerated case (bbox[1]==bbox[3]) of a completely
          828  +             * flat box results in arbitrary selection of the pixel below
          829  +             * (with positive coordinate) or above (with negative coordinate)
          830  +             * the box. There is no "best choice" here.
          831  +             */
          832  +
          833  +            if (iy1 > 0) {
          834  +                y2 += 1;
          835  +            } else {
          836  +                y1 -= 1;
          837  +            }
          838  +        } else {
          839  +
          840  +            /*
          841  +             * (y1,y2) span two pixels. Select the one with the larger
          842  +             * covered "area".
          843  +             */
          844  +
          845  +            if (iy1 > 0) {
          846  +                if ((rectOvalPtr->bbox[3] - iy2) > (iy2 - rectOvalPtr->bbox[1])) {
          847  +                    y2 += 1;
          848  +                } else {
          849  +                    y1 -= 1;
          850  +                }
          851  +            } else {
          852  +                if ((rectOvalPtr->bbox[3] - iy1) > (iy1 - rectOvalPtr->bbox[1])) {
          853  +                    y2 += 1;
          854  +                } else {
          855  +                    y1 -= 1;
          856  +                }
          857  +            }
          858  +        }
   767    859       }
   768    860   
   769    861       /*
   770    862        * Display filled part first (if wanted), then outline. If we're
   771    863        * stippling, then modify the stipple offset in the GC. Be sure to reset
   772    864        * the offset when done, since the GC is supposed to be read-only.
   773    865        */

Changes to generic/tkScale.c.

    17     17    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    18     18    */
    19     19   
    20     20   #include "default.h"
    21     21   #include "tkInt.h"
    22     22   #include "tkScale.h"
    23     23   
           24  +#if defined(_WIN32)
           25  +#define snprintf _snprintf
           26  +#endif
           27  +
    24     28   /*
    25     29    * The following table defines the legal values for the -orient option. It is
    26     30    * used together with the "enum orient" declaration in tkScale.h.
    27     31    */
    28     32   
    29     33   static const char *const orientStrings[] = {
    30     34       "horizontal", "vertical", NULL
................................................................................
   673    677   		TCL_GLOBAL_ONLY);
   674    678   	if ((valuePtr == NULL) || (Tcl_GetDoubleFromObj(NULL,
   675    679   		valuePtr, &varValue) != TCL_OK)) {
   676    680   	    ScaleSetVariable(scalePtr);
   677    681   	} else {
   678    682   	    char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE];
   679    683   
   680         -	    sprintf(varString, scalePtr->format, varValue);
   681         -	    sprintf(scaleString, scalePtr->format, scalePtr->value);
   682         -	    if (strcmp(varString, scaleString)) {
          684  +            Tcl_PrintDouble(NULL, varValue, varString);
          685  +            Tcl_PrintDouble(NULL, scalePtr->value, scaleString);
          686  +            if (strcmp(varString, scaleString)) {
   683    687   		ScaleSetVariable(scalePtr);
   684    688   	    }
   685    689   	}
   686    690   	Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr),
   687    691   		NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
   688    692   		ScaleVarProc, scalePtr);
   689    693       }
................................................................................
   932    936   
   933    937       /*
   934    938        * Vertical scale: compute the amount of space needed to display the
   935    939        * scales value by formatting strings for the two end points; use
   936    940        * whichever length is longer.
   937    941        */
   938    942   
   939         -    sprintf(valueString, scalePtr->format, scalePtr->fromValue);
          943  +    if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format,
          944  +            scalePtr->fromValue) < 0) {
          945  +        valueString[TCL_DOUBLE_SPACE - 1] = '\0';
          946  +    }
   940    947       valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
   941    948   
   942         -    sprintf(valueString, scalePtr->format, scalePtr->toValue);
          949  +    if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format,
          950  +            scalePtr->toValue) < 0) {
          951  +        valueString[TCL_DOUBLE_SPACE - 1] = '\0';
          952  +    }
   943    953       tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1);
   944    954       if (valuePixels < tmp) {
   945    955   	valuePixels = tmp;
   946    956       }
   947    957   
   948    958       /*
   949    959        * Assign x-locations to the elements of the scale, working from left to
................................................................................
  1177   1187       int flags)			/* Information about what happened. */
  1178   1188   {
  1179   1189       register TkScale *scalePtr = clientData;
  1180   1190       const char *resultStr;
  1181   1191       double value;
  1182   1192       Tcl_Obj *valuePtr;
  1183   1193       int result;
         1194  +
         1195  +    /*
         1196  +     * See ticket [5d991b82].
         1197  +     */
         1198  +
         1199  +    if (scalePtr->varNamePtr == NULL) {
         1200  +	if (!(flags & TCL_INTERP_DESTROYED)) {
         1201  +	    Tcl_UntraceVar2(interp, name1, name2,
         1202  +		    TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
         1203  +		    ScaleVarProc, clientData);
         1204  +	}
         1205  +	return NULL;
         1206  +    }
  1184   1207   
  1185   1208       /*
  1186   1209        * If the variable is unset, then immediately recreate it unless the whole
  1187   1210        * interpreter is going away.
  1188   1211        */
  1189   1212   
  1190   1213       if (flags & TCL_TRACE_UNSETS) {
................................................................................
  1310   1333   static void
  1311   1334   ScaleSetVariable(
  1312   1335       register TkScale *scalePtr)	/* Info about widget. */
  1313   1336   {
  1314   1337       if (scalePtr->varNamePtr != NULL) {
  1315   1338   	char string[TCL_DOUBLE_SPACE];
  1316   1339   
  1317         -	sprintf(string, scalePtr->format, scalePtr->value);
         1340  +        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format,
         1341  +                scalePtr->value) < 0) {
         1342  +            string[TCL_DOUBLE_SPACE - 1] = '\0';
         1343  +        }
  1318   1344   	scalePtr->flags |= SETTING_VAR;
  1319   1345   	Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL,
  1320   1346   		Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY);
  1321   1347   	scalePtr->flags &= ~SETTING_VAR;
  1322   1348       }
  1323   1349   }
  1324   1350   

Changes to generic/tkText.c.

  2074   2074       Tcl_Interp *interp,		/* Used for error reporting. */
  2075   2075       register TkText *textPtr,	/* Information about widget; may or may not
  2076   2076   				 * already have values for some fields. */
  2077   2077       int objc,			/* Number of arguments. */
  2078   2078       Tcl_Obj *const objv[])	/* Argument objects. */
  2079   2079   {
  2080   2080       Tk_SavedOptions savedOptions;
  2081         -    int oldExport = textPtr->exportSelection;
         2081  +    int oldExport = (textPtr->exportSelection) && (!Tcl_IsSafe(textPtr->interp));
  2082   2082       int mask = 0;
  2083   2083   
  2084   2084       if (Tk_SetOptions(interp, (char *) textPtr, textPtr->optionTable,
  2085   2085   	    objc, objv, textPtr->tkwin, &savedOptions, &mask) != TCL_OK) {
  2086   2086   	return TCL_ERROR;
  2087   2087       }
  2088   2088   
................................................................................
  2303   2303       TkTextRedrawTag(NULL, textPtr, NULL, NULL, textPtr->selTagPtr, 1);
  2304   2304   
  2305   2305       /*
  2306   2306        * Claim the selection if we've suddenly started exporting it and there
  2307   2307        * are tagged characters.
  2308   2308        */
  2309   2309   
  2310         -    if (textPtr->exportSelection && (!oldExport)) {
         2310  +    if (textPtr->exportSelection && (!oldExport) && (!Tcl_IsSafe(textPtr->interp))) {
  2311   2311   	TkTextSearch search;
  2312   2312   	TkTextIndex first, last;
  2313   2313   
  2314   2314   	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0,
  2315   2315   		&first);
  2316   2316   	TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr,
  2317   2317   		TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr),
................................................................................
  2722   2722   	resetViewCount += 2;
  2723   2723       }
  2724   2724       if (sharedTextPtr->refCount > PIXEL_CLIENTS) {
  2725   2725   	ckfree(lineAndByteIndex);
  2726   2726       }
  2727   2727   
  2728   2728       /*
  2729         -     * Invalidate any selection retrievals in progress.
         2729  +     * Invalidate any selection retrievals in progress, and send an event
         2730  +     * that the selection changed if that is the case.
  2730   2731        */
  2731   2732   
  2732   2733       for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) {
         2734  +        if (TkBTreeCharTagged(indexPtr, tPtr->selTagPtr)) {
         2735  +            TkTextSelectionEvent(tPtr);
         2736  +        }
  2733   2737   	tPtr->abortSelections = 1;
  2734   2738       }
  2735   2739   
  2736   2740       /*
  2737   2741        * For convenience, return the length of the string.
  2738   2742        */
  2739   2743   
................................................................................
  3065   3069   {
  3066   3070       int line1, line2;
  3067   3071       TkTextIndex index1, index2;
  3068   3072       TkText *tPtr;
  3069   3073       int *lineAndByteIndex;
  3070   3074       int resetViewCount;
  3071   3075       int pixels[2*PIXEL_CLIENTS];
         3076  +    Tcl_HashSearch search;
         3077  +    Tcl_HashEntry *hPtr;
         3078  +    int i;
  3072   3079   
  3073   3080       if (sharedTextPtr == NULL) {
  3074   3081   	sharedTextPtr = textPtr->sharedTextPtr;
  3075   3082       }
  3076   3083   
  3077   3084       /*
  3078   3085        * Prepare the starting and stopping indices.
................................................................................
  3129   3136   	    for (i = 0; i < arraySize; i++) {
  3130   3137   		TkBTreeTag(&index2, &oldIndex2, arrayPtr[i], 0);
  3131   3138   	    }
  3132   3139   	    ckfree(arrayPtr);
  3133   3140   	}
  3134   3141       }
  3135   3142   
  3136         -    if (line1 < line2) {
  3137         -	/*
  3138         -	 * We are deleting more than one line. For speed, we remove all tags
  3139         -	 * from the range first. If we don't do this, the code below can (when
  3140         -	 * there are many tags) grow non-linearly in execution time.
  3141         -	 */
  3142         -
  3143         -	Tcl_HashSearch search;
  3144         -	Tcl_HashEntry *hPtr;
  3145         -	int i;
  3146         -
  3147         -	for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
  3148         -		hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
  3149         -	    TkTextTag *tagPtr = Tcl_GetHashValue(hPtr);
  3150         -
  3151         -	    TkBTreeTag(&index1, &index2, tagPtr, 0);
  3152         -	}
  3153         -
  3154         -	/*
  3155         -	 * Special case for the sel tag which is not in the hash table. We
  3156         -	 * need to do this once for each peer text widget.
  3157         -	 */
  3158         -
  3159         -	for (tPtr = sharedTextPtr->peers; tPtr != NULL ;
  3160         -		tPtr = tPtr->next) {
  3161         -	    if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) {
  3162         -		/*
  3163         -		 * Send an event that the selection changed. This is
  3164         -		 * equivalent to:
  3165         -		 *	event generate $textWidget <<Selection>>
  3166         -		 */
  3167         -
  3168         -		TkTextSelectionEvent(textPtr);
  3169         -		tPtr->abortSelections = 1;
  3170         -	    }
  3171         -	}
         3143  +    /*
         3144  +     * For speed, we remove all tags from the range first. If we don't
         3145  +     * do this, the code below can (when there are many tags) grow
         3146  +     * non-linearly in execution time.
         3147  +     */
         3148  +
         3149  +    for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search);
         3150  +	    hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) {
         3151  +        TkTextTag *tagPtr = Tcl_GetHashValue(hPtr);
         3152  +
         3153  +        TkBTreeTag(&index1, &index2, tagPtr, 0);
         3154  +    }
         3155  +
         3156  +    /*
         3157  +     * Special case for the sel tag which is not in the hash table. We
         3158  +     * need to do this once for each peer text widget.
         3159  +     */
         3160  +
         3161  +    for (tPtr = sharedTextPtr->peers; tPtr != NULL ;
         3162  +	    tPtr = tPtr->next) {
         3163  +        if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) {
         3164  +	    /*
         3165  +	     * Send an event that the selection changed. This is
         3166  +	     * equivalent to:
         3167  +	     *	event generate $textWidget <<Selection>>
         3168  +	     */
         3169  +
         3170  +	    TkTextSelectionEvent(textPtr);
         3171  +	    tPtr->abortSelections = 1;
         3172  +        }
  3172   3173       }
  3173   3174   
  3174   3175       /*
  3175   3176        * Tell the display what's about to happen so it can discard obsolete
  3176   3177        * display information, then do the deletion. Also, if the deletion
  3177   3178        * involves the top line on the screen, then we have to reset the view
  3178   3179        * (the deletion will invalidate textPtr->topIndex). Compute what the new
................................................................................
  3374   3375   {
  3375   3376       register TkText *textPtr = clientData;
  3376   3377       TkTextIndex eof;
  3377   3378       int count, chunkSize, offsetInSeg;
  3378   3379       TkTextSearch search;
  3379   3380       TkTextSegment *segPtr;
  3380   3381   
  3381         -    if (!textPtr->exportSelection) {
         3382  +    if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
  3382   3383   	return -1;
  3383   3384       }
  3384   3385   
  3385   3386       /*
  3386   3387        * Find the beginning of the next range of selected text. Note: if the
  3387   3388        * selection is being retrieved in multiple pieces (offset != 0) and some
  3388   3389        * modification has been made to the text that affects the selection then
................................................................................
  3504   3505       ClientData clientData)	/* Information about text widget. */
  3505   3506   {
  3506   3507       register TkText *textPtr = clientData;
  3507   3508   
  3508   3509       if (TkpAlwaysShowSelection(textPtr->tkwin)) {
  3509   3510   	TkTextIndex start, end;
  3510   3511   
  3511         -	if (!textPtr->exportSelection) {
         3512  +	if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) {
  3512   3513   	    return;
  3513   3514   	}
  3514   3515   
  3515   3516   	/*
  3516   3517   	 * On Windows and Mac systems, we want to remember the selection for
  3517   3518   	 * the next time the focus enters the window. On Unix, just remove the
  3518   3519   	 * "sel" tag from everything in the widget.
................................................................................
  3751   3752   
  3752   3753       static const char *const switchStrings[] = {
  3753   3754   	"-hidden",
  3754   3755   	"--", "-all", "-backwards", "-count", "-elide", "-exact", "-forwards",
  3755   3756   	"-nocase", "-nolinestop", "-overlap", "-regexp", "-strictlimits", NULL
  3756   3757       };
  3757   3758       enum SearchSwitches {
  3758         -	SEARCH_HIDDEN,
  3759         -	SEARCH_END, SEARCH_ALL, SEARCH_BACK, SEARCH_COUNT, SEARCH_ELIDE,
  3760         -	SEARCH_EXACT, SEARCH_FWD, SEARCH_NOCASE,
  3761         -	SEARCH_NOLINESTOP, SEARCH_OVERLAP, SEARCH_REGEXP, SEARCH_STRICTLIMITS
         3759  +	TK_TEXT_SEARCH_HIDDEN,
         3760  +	TK_TEXT_SEARCH_END, TK_TEXT_SEARCH_ALL, TK_TEXT_SEARCH_BACK, TK_TEXT_SEARCH_COUNT, TK_TEXT_SEARCH_ELIDE,
         3761  +	TK_TEXT_SEARCH_EXACT, TK_TEXT_SEARCH_FWD, TK_TEXT_SEARCH_NOCASE,
         3762  +	TK_TEXT_SEARCH_NOLINESTOP, TK_TEXT_SEARCH_OVERLAP, TK_TEXT_SEARCH_REGEXP, TK_TEXT_SEARCH_STRICTLIMITS
  3762   3763       };
  3763   3764   
  3764   3765       /*
  3765   3766        * Set up the search specification, including the last 4 fields which are
  3766   3767        * text widget specific.
  3767   3768        */
  3768   3769   
................................................................................
  3804   3805   
  3805   3806   	    (void) Tcl_GetIndexFromObjStruct(interp, objv[i], switchStrings+1,
  3806   3807   		    sizeof(char *), "switch", 0, &index);
  3807   3808   	    return TCL_ERROR;
  3808   3809   	}
  3809   3810   
  3810   3811   	switch ((enum SearchSwitches) index) {
  3811         -	case SEARCH_END:
         3812  +	case TK_TEXT_SEARCH_END:
  3812   3813   	    i++;
  3813   3814   	    goto endOfSwitchProcessing;
  3814         -	case SEARCH_ALL:
         3815  +	case TK_TEXT_SEARCH_ALL:
  3815   3816   	    searchSpec.all = 1;
  3816   3817   	    break;
  3817         -	case SEARCH_BACK:
         3818  +	case TK_TEXT_SEARCH_BACK:
  3818   3819   	    searchSpec.backwards = 1;
  3819   3820   	    break;
  3820         -	case SEARCH_COUNT:
         3821  +	case TK_TEXT_SEARCH_COUNT:
  3821   3822   	    if (i >= objc-1) {
  3822   3823   		Tcl_SetObjResult(interp, Tcl_NewStringObj(
  3823   3824   			"no value given for \"-count\" option", -1));
  3824   3825   		Tcl_SetErrorCode(interp, "TK", "TEXT", "VALUE", NULL);
  3825   3826   		return TCL_ERROR;
  3826   3827   	    }
  3827   3828   	    i++;
................................................................................
  3829   3830   	    /*
  3830   3831   	     * Assumption objv[i] isn't going to disappear on us during this
  3831   3832   	     * function, which is fair.
  3832   3833   	     */
  3833   3834   
  3834   3835   	    searchSpec.varPtr = objv[i];
  3835   3836   	    break;
  3836         -	case SEARCH_ELIDE:
  3837         -	case SEARCH_HIDDEN:
         3837  +	case TK_TEXT_SEARCH_ELIDE:
         3838  +	case TK_TEXT_SEARCH_HIDDEN:
  3838   3839   	    searchSpec.searchElide = 1;
  3839   3840   	    break;
  3840         -	case SEARCH_EXACT:
         3841  +	case TK_TEXT_SEARCH_EXACT:
  3841   3842   	    searchSpec.exact = 1;
  3842   3843   	    break;
  3843         -	case SEARCH_FWD:
         3844  +	case TK_TEXT_SEARCH_FWD:
  3844   3845   	    searchSpec.backwards = 0;
  3845   3846   	    break;
  3846         -	case SEARCH_NOCASE:
         3847  +	case TK_TEXT_SEARCH_NOCASE:
  3847   3848   	    searchSpec.noCase = 1;
  3848   3849   	    break;
  3849         -	case SEARCH_NOLINESTOP:
         3850  +	case TK_TEXT_SEARCH_NOLINESTOP:
  3850   3851   	    searchSpec.noLineStop = 1;
  3851   3852   	    break;
  3852         -	case SEARCH_OVERLAP:
         3853  +	case TK_TEXT_SEARCH_OVERLAP:
  3853   3854   	    searchSpec.overlap = 1;
  3854   3855   	    break;
  3855         -	case SEARCH_STRICTLIMITS:
         3856  +	case TK_TEXT_SEARCH_STRICTLIMITS:
  3856   3857   	    searchSpec.strictLimits = 1;
  3857   3858   	    break;
  3858         -	case SEARCH_REGEXP:
         3859  +	case TK_TEXT_SEARCH_REGEXP:
  3859   3860   	    searchSpec.exact = 0;
  3860   3861   	    break;
  3861   3862   	default:
  3862   3863   	    Tcl_Panic("unexpected switch fallthrough");
  3863   3864   	}
  3864   3865       }
  3865   3866     endOfSwitchProcessing:

Changes to generic/tkTextDisp.c.

  4116   4116        * If drawing is disabled, all we need to do is
  4117   4117        * clear the REDRAW_PENDING flag.
  4118   4118        */
  4119   4119       TkWindow *winPtr = (TkWindow *)(textPtr->tkwin);
  4120   4120       MacDrawable *macWin = winPtr->privatePtr;
  4121   4121       if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){
  4122   4122   	dInfoPtr->flags &= ~REDRAW_PENDING;
  4123         -	return;
  4124         -    }
         4123  +    	return;
         4124  +     }
  4125   4125   #endif
  4126   4126   
  4127   4127       if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) {
  4128   4128   	/*
  4129   4129   	 * The widget has been deleted.	 Don't do anything.
  4130   4130   	 */
  4131   4131   
................................................................................
  4270   4270   
  4271   4271   	    dlPtr->oldY = dlPtr->y;
  4272   4272   	    if (dlPtr->nextPtr == dlPtr2) {
  4273   4273   		break;
  4274   4274   	    }
  4275   4275   	    dlPtr = dlPtr->nextPtr;
  4276   4276   	}
  4277         -
  4278   4277   	/*
  4279   4278   	 * Scan through the lines following the copied ones to see if we are
  4280   4279   	 * going to overwrite them with the copy operation. If so, mark them
  4281   4280   	 * for redisplay.
  4282   4281   	 */
  4283   4282   
  4284   4283   	for ( ; dlPtr2 != NULL; dlPtr2 = dlPtr2->nextPtr) {
................................................................................
  4294   4293   	 * calling TextInvalidateRegion to mark the display blocks as stale.
  4295   4294   	 */
  4296   4295   
  4297   4296   	damageRgn = TkCreateRegion();
  4298   4297   	if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x,
  4299   4298   		oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY,
  4300   4299   		damageRgn)) {
  4301         -#ifndef MAC_OSX_TK
  4302   4300   	    TextInvalidateRegion(textPtr, damageRgn);
  4303         -#endif
  4304   4301   	}
  4305   4302   	numCopies++;
  4306   4303   	TkDestroyRegion(damageRgn);
  4307   4304       }
  4308   4305   
  4309   4306       /*
  4310   4307        * Clear the REDRAW_PENDING flag here. This is actually pretty tricky. We
................................................................................
  4438   4435   #ifndef TK_NO_DOUBLE_BUFFERING
  4439   4436   		    Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
  4440   4437   #endif /* TK_NO_DOUBLE_BUFFERING */
  4441   4438   		    return;
  4442   4439   		}
  4443   4440   		dlPtr->oldY = dlPtr->y;
  4444   4441   		dlPtr->flags &= ~(NEW_LAYOUT | OLD_Y_INVALID);
         4442  +#ifdef MAC_OSX_TK
         4443  +	    } else if (dlPtr->chunkPtr != NULL) {
         4444  +		/*
         4445  +		 * On macOS we need to redisplay all embedded windows which
         4446  +		 * were moved by the call to TkScrollWindows above.  This is
         4447  +		 * not necessary on Unix or Windows because XScrollWindow will
         4448  +		 * have included the bounding rectangles of all of these
         4449  +		 * windows in the damage region.  The macosx implementation of
         4450  +		 * TkScrollWindow does not do this.  It simply generates a
         4451  +		 * damage region which is the scroll source rectangle minus
         4452  +		 * the scroll destination rectangle.  This is because there is
         4453  +		 * no efficient process available for iterating through the
         4454  +		 * subwindows which meet the scrolled area.  (On Unix this is
         4455  +		 * handled by GraphicsExpose events generated by XCopyArea and
         4456  +		 * on Windows by ScrollWindowEx.  On macOS the low level
         4457  +		 * scrolling is accomplished by calling [view scrollRect:by:].
         4458  +		 * This method does not provide any damage information and, in
         4459  +		 * any case, could not be aware of Tk windows which were not
         4460  +		 * based on NSView objects.
         4461  +		 *
         4462  +		 * On the other hand, this loop is already iterating through
         4463  +		 * all embedded windows which could possibly have been moved
         4464  +		 * by the scrolling.  So it is as efficient to redisplay them
         4465  +		 * here as it would have been if they had been redisplayed by
         4466  +		 * the call to TextInvalidateRegion above.
         4467  +		 */
         4468  +#else
  4445   4469   	    } else if (dlPtr->chunkPtr != NULL && ((dlPtr->y < 0)
  4446   4470   		    || (dlPtr->y + dlPtr->height > dInfoPtr->maxY))) {
  4447         -		register TkTextDispChunk *chunkPtr;
  4448         -
  4449   4471   		/*
         4472  +		 * On platforms other than the Mac:
         4473  +		 *
  4450   4474   		 * It's the first or last DLine which are also overlapping the
  4451   4475   		 * top or bottom of the window, but we decided above it wasn't
  4452   4476   		 * necessary to display them (we were able to update them by
  4453   4477   		 * scrolling). This is fine, except that if the lines contain
  4454   4478   		 * any embedded windows, we must still call the display proc
  4455   4479   		 * on them because they might need to be unmapped or they
  4456   4480   		 * might need to be moved to reflect their new position.
  4457   4481   		 * Otherwise, everything else moves, but the embedded window
  4458   4482   		 * doesn't!
  4459   4483   		 *
  4460   4484   		 * So, we loop through all the chunks, calling the display
  4461   4485   		 * proc of embedded windows only.
  4462   4486   		 */
         4487  +#endif
         4488  +		register TkTextDispChunk *chunkPtr;
  4463   4489   
  4464   4490   		for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL);
  4465   4491   			chunkPtr = chunkPtr->nextPtr) {
  4466   4492   		    int x;
  4467   4493   		    if (chunkPtr->displayProc != TkTextEmbWinDisplayProc) {
  4468   4494   			continue;
  4469   4495   		    }
................................................................................
  4478   4504   			 * as being off-screen to the left (the displayProc
  4479   4505   			 * may not be able to tell if something is off to the
  4480   4506   			 * right).
  4481   4507   			 */
  4482   4508   
  4483   4509   			x = -chunkPtr->width;
  4484   4510   		    }
         4511  +		    if (tkTextDebug) {
         4512  +			char string[TK_POS_CHARS];
         4513  +
         4514  +			TkTextPrintIndex(textPtr, &dlPtr->index, string);
         4515  +			LOG("tk_textEmbWinDisplay", string);
         4516  +		    }
  4485   4517   		    TkTextEmbWinDisplayProc(textPtr, chunkPtr, x,
  4486   4518   			    dlPtr->spaceAbove,
  4487   4519   			    dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow,
  4488   4520   			    dlPtr->baseline - dlPtr->spaceAbove, NULL,
  4489   4521   			    (Drawable) None, dlPtr->y + dlPtr->spaceAbove);
  4490   4522   		}
  4491         -
  4492   4523   	    }
  4493   4524   	}
  4494   4525   #ifndef TK_NO_DOUBLE_BUFFERING
  4495   4526   	Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap);
  4496   4527   #endif /* TK_NO_DOUBLE_BUFFERING */
  4497   4528       }
  4498   4529   

Changes to generic/tkTextTag.c.

   239    239   		     * equivalent to:
   240    240   		     *	   event generate $textWidget <<Selection>>
   241    241   		     */
   242    242   
   243    243   		    TkTextSelectionEvent(textPtr);
   244    244   
   245    245   		    if (addTag && textPtr->exportSelection
          246  +			    && (!Tcl_IsSafe(textPtr->interp))
   246    247   			    && !(textPtr->flags & GOT_SELECTION)) {
   247    248   			Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY,
   248    249   				TkTextLostSelection, textPtr);
   249    250   			textPtr->flags |= GOT_SELECTION;
   250    251   		    }
   251    252   		    textPtr->abortSelections = 1;
   252    253   		}

Changes to generic/ttk/ttkButton.c.

   485    485       BaseCleanup(recordPtr);
   486    486   }
   487    487   
   488    488   static int
   489    489   CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
   490    490   {
   491    491       Checkbutton *checkPtr = recordPtr;
   492         -    Ttk_TraceHandle *vt = Ttk_TraceVariable(
   493         -	interp, checkPtr->checkbutton.variableObj,
   494         -	CheckbuttonVariableChanged, checkPtr);
   495         -
   496         -    if (!vt) {
   497         -	return TCL_ERROR;
          492  +    Tcl_Obj *varName = checkPtr->checkbutton.variableObj;
          493  +    Ttk_TraceHandle *vt = NULL;
          494  +        
          495  +    if (varName != NULL && *Tcl_GetString(varName) != '\0') {
          496  +        vt = Ttk_TraceVariable(interp, varName,
          497  +	    CheckbuttonVariableChanged, checkPtr);
          498  +        if (!vt) {
          499  +	    return TCL_ERROR;
          500  +        }
   498    501       }
   499    502   
   500    503       if (BaseConfigure(interp, recordPtr, mask) != TCL_OK){
   501    504   	Ttk_UntraceVariable(vt);
   502    505   	return TCL_ERROR;
   503    506       }
   504    507   
   505         -    Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
          508  +    if (checkPtr->checkbutton.variableTrace) {
          509  +        Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace);
          510  +    }
   506    511       checkPtr->checkbutton.variableTrace = vt;
   507    512   
   508    513       return TCL_OK;
   509    514   }
   510    515   
   511    516   static int
   512    517   CheckbuttonPostConfigure(Tcl_Interp *interp, void *recordPtr, int mask)
................................................................................
   544    549        * Toggle the selected state.
   545    550        */
   546    551       if (corePtr->state & TTK_STATE_SELECTED)
   547    552   	newValue = checkPtr->checkbutton.offValueObj;
   548    553       else
   549    554   	newValue = checkPtr->checkbutton.onValueObj;
   550    555   
   551         -    if (Tcl_ObjSetVar2(interp,
   552         -	    checkPtr->checkbutton.variableObj, NULL, newValue,
   553         -	    TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
   554         -	== NULL)
          556  +    if (checkPtr->checkbutton.variableObj == NULL ||
          557  +        *Tcl_GetString(checkPtr->checkbutton.variableObj) == '\0')
          558  +        CheckbuttonVariableChanged(checkPtr, Tcl_GetString(newValue));
          559  +    else if (Tcl_ObjSetVar2(interp,
          560  +	        checkPtr->checkbutton.variableObj, NULL, newValue,
          561  +	        TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG)
          562  +	    == NULL)
   555    563   	return TCL_ERROR;
   556    564   
   557    565       if (WidgetDestroyed(corePtr))
   558    566   	return TCL_ERROR;
   559    567   
   560    568       return Tcl_EvalObjEx(interp,
   561    569   	checkPtr->checkbutton.commandObj, TCL_EVAL_GLOBAL);

Changes to generic/ttk/ttkEntry.c.

   333    333       ClientData clientData, int offset, char *buffer, int maxBytes)
   334    334   {
   335    335       Entry *entryPtr = (Entry *) clientData;
   336    336       size_t byteCount;
   337    337       const char *string;
   338    338       const char *selStart, *selEnd;
   339    339   
   340         -    if (entryPtr->entry.selectFirst < 0 || !entryPtr->entry.exportSelection) {
          340  +    if (entryPtr->entry.selectFirst < 0 || (!entryPtr->entry.exportSelection)
          341  +	    || Tcl_IsSafe(entryPtr->core.interp)) {
   341    342   	return -1;
   342    343       }
   343    344       string = entryPtr->entry.displayString;
   344    345   
   345    346       selStart = Tcl_UtfAtIndex(string, entryPtr->entry.selectFirst);
   346    347       selEnd = Tcl_UtfAtIndex(selStart,
   347    348   	    entryPtr->entry.selectLast - entryPtr->entry.selectFirst);
................................................................................
   368    369       entryPtr->core.flags &= ~GOT_SELECTION;
   369    370       entryPtr->entry.selectFirst = entryPtr->entry.selectLast = -1;
   370    371       TtkRedisplayWidget(&entryPtr->core);
   371    372   }
   372    373   
   373    374   /* EntryOwnSelection --
   374    375    * 	Assert ownership of the PRIMARY selection,
   375         - * 	if -exportselection set and selection is present.
          376  + * 	if -exportselection set and selection is present and interp is unsafe.
   376    377    */
   377    378   static void EntryOwnSelection(Entry *entryPtr)
   378    379   {
   379    380       if (entryPtr->entry.exportSelection
          381  +	&& (!Tcl_IsSafe(entryPtr->core.interp))
   380    382   	&& !(entryPtr->core.flags & GOT_SELECTION)) {
   381    383   	Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection,
   382    384   		(ClientData) entryPtr);
   383    385   	entryPtr->core.flags |= GOT_SELECTION;
   384    386       }
   385    387   }
   386    388   
................................................................................
   995    997   	if (entryPtr->entry.textVariableTrace)
   996    998   	    Ttk_UntraceVariable(entryPtr->entry.textVariableTrace);
   997    999   	entryPtr->entry.textVariableTrace = vt;
   998   1000       }
   999   1001   
  1000   1002       /* Claim the selection, in case we've suddenly started exporting it.
  1001   1003        */
  1002         -    if (entryPtr->entry.exportSelection && entryPtr->entry.selectFirst != -1) {
         1004  +    if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst != -1)
         1005  +	    && (!Tcl_IsSafe(entryPtr->core.interp))) {
  1003   1006   	EntryOwnSelection(entryPtr);
  1004   1007       }
  1005   1008   
  1006   1009       /* Handle -state compatibility option:
  1007   1010        */
  1008   1011       if (mask & STATE_CHANGED) {
  1009   1012   	TtkCheckStateOption(&entryPtr->core, entryPtr->entry.stateObj);

Changes to generic/ttk/ttkProgress.c.

   417    417       if (pb->progress.mode == TTK_PROGRESSBAR_DETERMINATE) {
   418    418   	double maximum = 100.0;
   419    419   	(void)Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum);
   420    420   	value = fmod(value, maximum);
   421    421       }
   422    422   
   423    423       newValueObj = Tcl_NewDoubleObj(value);
          424  +    Tcl_IncrRefCount(newValueObj);
   424    425   
   425    426       TtkRedisplayWidget(&pb->core);
   426    427   
   427    428       /* Update value by setting the linked -variable, if there is one: 
   428    429        */
   429    430       if (pb->progress.variableTrace) {
   430         -	return Tcl_ObjSetVar2(
   431         -		    interp, pb->progress.variableObj, 0, newValueObj,
   432         -		    TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)
   433         -	    ? TCL_OK : TCL_ERROR;
          431  +	int result = Tcl_ObjSetVar2(
          432  +		        interp, pb->progress.variableObj, 0, newValueObj,
          433  +		        TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG)
          434  +	        ? TCL_OK : TCL_ERROR;
          435  +        Tcl_DecrRefCount(newValueObj);
          436  +        return result;
   434    437       }
   435    438   
   436    439       /* Otherwise, change the -value directly:
   437    440        */
   438         -    Tcl_IncrRefCount(newValueObj);
   439    441       Tcl_DecrRefCount(pb->progress.valueObj);
   440    442       pb->progress.valueObj = newValueObj;
   441    443       CheckAnimation(pb);
   442    444   
   443    445       return TCL_OK;
   444    446   }
   445    447   

Changes to generic/ttk/ttkScale.c.

    11     11   #include "ttkWidget.h"
    12     12   
    13     13   #define DEF_SCALE_LENGTH "100"
    14     14   
    15     15   #define MAX(a,b) ((a) > (b) ? (a) : (b))
    16     16   #define MIN(a,b) ((a) < (b) ? (a) : (b))
    17     17   
           18  +/* Bit fields for OptionSpec mask field:
           19  + */
           20  +#define STATE_CHANGED	 	(0x100)		/* -state option changed */
           21  +
    18     22   /*
    19     23    * Scale widget record
    20     24    */
    21     25   typedef struct
    22     26   {
    23     27       /* slider element options */
    24     28       Tcl_Obj *fromObj;         /* minimum value */
................................................................................
    31     35       /* widget options */
    32     36       Tcl_Obj *commandObj;
    33     37       Tcl_Obj *variableObj;
    34     38   
    35     39       /* internal state */
    36     40       Ttk_TraceHandle *variableTrace;
    37     41   
           42  +    /*
           43  +     * Compatibility/legacy options:
           44  +     */
           45  +    Tcl_Obj *stateObj;
           46  +
    38     47   } ScalePart;
    39     48   
    40     49   typedef struct
    41     50   {
    42     51       WidgetCore core;
    43     52       ScalePart  scale;
    44     53   } Scale;
................................................................................
    61     70       {TK_OPTION_DOUBLE, "-to", "to", "To", "1.0",
    62     71   	Tk_Offset(Scale,scale.toObj), -1, 0, 0, 0},
    63     72       {TK_OPTION_DOUBLE, "-value", "value", "Value", "0",
    64     73   	Tk_Offset(Scale,scale.valueObj), -1, 0, 0, 0},
    65     74       {TK_OPTION_PIXELS, "-length", "length", "Length",
    66     75   	DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0, 
    67     76       	GEOMETRY_CHANGED},
           77  +
           78  +    {TK_OPTION_STRING, "-state", "state", "State",
           79  +	"normal", Tk_Offset(Scale,scale.stateObj), -1,
           80  +        0,0,STATE_CHANGED},
    68     81   
    69     82       WIDGET_TAKEFOCUS_TRUE,
    70     83       WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs)
    71     84   };
    72     85   
    73     86   static XPoint ValueToPoint(Scale *scalePtr, double value);
    74     87   static double PointToValue(Scale *scalePtr, int x, int y);
................................................................................
   134    147   	return TCL_ERROR;
   135    148       }
   136    149   
   137    150       if (scale->scale.variableTrace) {
   138    151   	Ttk_UntraceVariable(scale->scale.variableTrace);
   139    152       }
   140    153       scale->scale.variableTrace = vt;
          154  +
          155  +    if (mask & STATE_CHANGED) {
          156  +	TtkCheckStateOption(&scale->core, scale->scale.stateObj);
          157  +    }
   141    158   
   142    159       return TCL_OK;
   143    160   }
   144    161   
   145    162   /* ScalePostConfigure --
   146    163    * 	Post-configuration hook.
   147    164    */

Changes to generic/ttk/ttkTrace.c.

    22     22   /*
    23     23    * Tcl_VarTraceProc for trace handles.
    24     24    */
    25     25   static char *
    26     26   VarTraceProc(
    27     27       ClientData clientData,	/* Widget record pointer */
    28     28       Tcl_Interp *interp, 	/* Interpreter containing variable. */
    29         -    const char *name1,		/* (unused) */
    30         -    const char *name2,		/* (unused) */
           29  +    const char *name1,		/* Name of variable. */
           30  +    const char *name2,		/* Second part of variable name. */
    31     31       int flags)			/* Information about what happened. */
    32     32   {
    33     33       Ttk_TraceHandle *tracePtr = clientData;
    34     34       const char *name, *value;
    35     35       Tcl_Obj *valuePtr;
    36     36   
    37     37       if (flags & TCL_INTERP_DESTROYED) {
    38     38   	return NULL;
    39     39       }
           40  +
           41  +    /*
           42  +     * See ticket [5d991b82].
           43  +     */
           44  +
           45  +    if (tracePtr->varnameObj == NULL) {
           46  +	Tcl_UntraceVar2(interp, name1, name2,
           47  +		TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS,
           48  +		VarTraceProc, clientData);
           49  +	return NULL;
           50  +    }
    40     51   
    41     52       name = Tcl_GetString(tracePtr->varnameObj);
    42     53   
    43     54       /*
    44     55        * If the variable is being unset, then re-establish the trace:
    45     56        */
    46     57       if (flags & TCL_TRACE_DESTROYED) {

Added library/demos/images/earthmenu.png.

cannot compute difference between binary files

Changes to library/demos/menu.tcl.

   110    110   $m invoke 1
   111    111   $m invoke 7
   112    112   
   113    113   set m $w.menu.icon
   114    114   $w.menu add cascade -label "Icons" -menu $m -underline 0
   115    115   menu $m -tearoff 0
   116    116   # Main widget program sets variable tk_demoDirectory
   117         -$m add command -bitmap @[file join $tk_demoDirectory images pattern.xbm] \
          117  +image create photo lilearth -file [file join $tk_demoDirectory \
          118  +images earthmenu.png]
          119  +$m add command -image lilearth \
   118    120       -hidemargin 1 -command [list \
   119    121   	tk_dialog $w.pattern {Bitmap Menu Entry} \
   120         -		"The menu entry you invoked displays a bitmap rather than\
          122  +		"The menu entry you invoked displays a photoimage rather than\
   121    123   		a text string.  Other than this, it is just like any other\
   122    124   		menu entry." {} 0 OK ]
   123    125   foreach i {info questhead error} {
   124    126       $m add command -bitmap $i -hidemargin 1 -command [list \
   125    127   	    puts "You invoked the $i bitmap" ]
   126    128   }
   127    129   $m entryconfigure 2 -columnbreak 1

Changes to library/demos/twind.tcl.

    79     79   $t insert end "You can also create multiple text widgets each of which "
    80     80   $t insert end "display the same underlying text. Click this button to "
    81     81   $t window create end \
    82     82     -create {button %W.peer -text "Make A Peer" -command "textMakePeer %W" \
    83     83     -cursor top_left_arrow} -padx 3
    84     84   $t insert end " widget.  Notice how peer widgets can have different "
    85     85   $t insert end "font settings, and by default contain all the images "
    86         -$t insert end "of the 'parent', but many of the embedded windows, "
    87         -$t insert end "such as buttons will not be there.  The easiest way "
    88         -$t insert end "to ensure they are in all peers is to use '-create' "
    89         -$t insert end "embedded window creation scripts "
    90         -$t insert end "(the plot above and the 'Make A Peer' button are "
    91         -$t insert end "designed to show up in all peers).  A good use of "
           86  +$t insert end "of the 'parent', but that the embedded windows, "
           87  +$t insert end "such as buttons may not appear in the peer.  To ensure "
           88  +$t insert end "that embedded windows appear in all peers you can set the "
           89  +$t insert end "'-create' option to a script or a string containing %W.  "
           90  +$t insert end "(The plot above and the 'Make A Peer' button are "
           91  +$t insert end "designed to show up in all peers.)  A good use of "
    92     92   $t insert end "peers is for "
    93     93   $t window create end \
    94     94     -create {button %W.split -text "Split Windows" -command "textSplitWindow %W" \
    95     95     -cursor top_left_arrow} -padx 3
    96     96   $t insert end " \n\n"
    97     97   
    98     98   $t insert end "Users of previous versions of Tk will also be interested "
................................................................................
   108    108   $t insert end "text widget (\"Default\" restores the color to "
   109    109   $t insert end "its default).  If you click on the button labeled "
   110    110   $t insert end "\"Short\", it changes to a longer string so that "
   111    111   $t insert end "you can see how the text widget automatically "
   112    112   $t insert end "changes the layout.  Click on the button again "
   113    113   $t insert end "to restore the short string.\n"
   114    114   
          115  +$t insert end "\nNOTE: these buttons will not appear in peers!\n" "peer_warning"
   115    116   button $t.default -text Default -command "embDefBg $t" \
   116    117   	-cursor top_left_arrow
   117    118   $t window create end -window $t.default -padx 3
   118    119   global embToggle
   119    120   set embToggle Short
   120    121   checkbutton $t.toggle -textvariable embToggle -indicatoron 0 \
   121    122   	-variable embToggle -onvalue "A much longer string" \
................................................................................
   159    160   $t window create end -window $t.bigP
   160    161   $t window create end -window $t.smallP
   161    162   
   162    163   $t insert end "\n\nFinally, images fit comfortably in text widgets too:"
   163    164   
   164    165   $t image create end -image \
   165    166       [image create photo -file [file join $tk_demoDirectory images ouster.png]]
   166         -
   167    167   
   168    168   proc textWindBigB w {
   169    169       $w configure -borderwidth 15
   170    170   }
   171    171   
   172    172   proc textWindBigH w {
   173    173       $w configure -highlightthickness 15
................................................................................
   298    298       set n 1
   299    299       while {[winfo exists .peer$n]} { incr n }
   300    300       set w [toplevel .peer$n]
   301    301       wm title $w "Text Peer #$n"
   302    302       frame $w.f -highlightthickness 1 -borderwidth 1 -relief sunken
   303    303       set t [$parent peer create $w.f.text -yscrollcommand "$w.scroll set" \
   304    304   	       -borderwidth 0 -highlightthickness 0]
          305  +    $t tag configure peer_warning -font boldFont
   305    306       pack $t -expand  yes -fill both
   306    307       ttk::scrollbar $w.scroll -command "$t yview"
   307    308       pack $w.scroll -side right -fill y
   308    309       pack $w.f -expand yes -fill both
   309    310   }
   310    311   
   311    312   proc textSplitWindow {textW} {
................................................................................
   313    314   	if {[winfo exists .twind.peer]} {
   314    315   	    destroy .twind.peer
   315    316   	} else {
   316    317   	    set parent [winfo parent $textW]
   317    318   	    set w [winfo parent $parent]
   318    319   	    set t [$textW peer create $w.peer \
   319    320   	      -yscrollcommand "$w.scroll set"]
          321  +	    $t tag configure peer_warning -font boldFont
   320    322   	    $w.pane add $t
   321    323   	}
   322    324       } else {
   323    325           return
   324    326       }
   325    327   }

Changes to library/fontchooser.tcl.

    61     61   proc ::tk::fontchooser::Show {} {
    62     62       variable S
    63     63       if {![winfo exists $S(W)]} {
    64     64           Create
    65     65           wm transient $S(W) [winfo toplevel $S(-parent)]
    66     66           tk::PlaceWindow $S(W) widget $S(-parent)
    67     67       }
           68  +    set S(fonts) [lsort -dictionary [font families]]
           69  +    set S(fonts,lcase) {}
           70  +    foreach font $S(fonts) { lappend S(fonts,lcase) [string tolower $font]}
    68     71       wm deiconify $S(W)
    69     72   }
    70     73   
    71     74   proc ::tk::fontchooser::Hide {} {
    72     75       variable S
    73     76       wm withdraw $S(W)
    74     77   }

Changes to library/text.tcl.

   764    764   	if {[$w compare $new < insert]} {
   765    765   	    $w tag add sel $new insert
   766    766   	} else {
   767    767   	    $w tag add sel insert $new
   768    768   	}
   769    769   	$w mark set $anchorname insert
   770    770       } else {
          771  +        if {[catch {$w index $anchorname}]} {
          772  +            $w mark set $anchorname insert
          773  +        }
   771    774   	if {[$w compare $new < $anchorname]} {
   772    775   	    set first $new
   773    776   	    set last $anchorname
   774    777   	} else {
   775    778   	    set first $anchorname
   776    779   	    set last $new
   777    780   	}
................................................................................
  1051   1054   # w -		Name of a text widget.
  1052   1055   
  1053   1056   proc ::tk_textCut w {
  1054   1057       if {![catch {set data [$w get sel.first sel.last]}]} {
  1055   1058           # make <<Cut>> an atomic operation on the Undo stack,
  1056   1059           # i.e. separate it from other delete operations on either side
  1057   1060   	set oldSeparator [$w cget -autoseparators]
  1058         -	if {$oldSeparator} {
         1061  +	if {([$w cget -state] eq "normal") && $oldSeparator} {
  1059   1062   	    $w edit separator
  1060   1063   	}
  1061   1064   	clipboard clear -displayof $w
  1062   1065   	clipboard append -displayof $w $data
  1063   1066   	$w delete sel.first sel.last
  1064         -	if {$oldSeparator} {
         1067  +	if {([$w cget -state] eq "normal") && $oldSeparator} {
  1065   1068   	    $w edit separator
  1066   1069   	}
  1067   1070       }
  1068   1071   }
  1069   1072   
  1070   1073   # ::tk_textPaste --
  1071   1074   # This procedure pastes the contents of the clipboard to the insertion

Changes to library/tk.tcl.

     7      7   # Copyright (c) 1994-1996 Sun Microsystems, Inc.
     8      8   # Copyright (c) 1998-2000 Ajuba Solutions.
     9      9   #
    10     10   # See the file "license.terms" for information on usage and redistribution of
    11     11   # this file, and for a DISCLAIMER OF ALL WARRANTIES.
    12     12   
    13     13   # Verify that we have Tk binary and script components from the same release
    14         -package require -exact Tk  8.6.7
           14  +package require -exact Tk  8.6.8
    15     15   
    16     16   # Create a ::tk namespace
    17     17   namespace eval ::tk {
    18     18       # Set up the msgcat commands
    19     19       namespace eval msgcat {
    20     20   	namespace export mc mcmax
    21     21           if {[interp issafe] || [catch {package require msgcat}]} {
................................................................................
   596    596       }
   597    597       return $result
   598    598   }
   599    599   
   600    600   # ::tk::AmpMenuArgs --
   601    601   #	Processes arguments for a menu entry, turning -label option into
   602    602   #	-label and -underline options, returned by ::tk::UnderlineAmpersand.
          603  +#      The cmd argument is supposed to be either "add" or "entryconfigure"
   603    604   #
   604         -proc ::tk::AmpMenuArgs {widget add type args} {
          605  +proc ::tk::AmpMenuArgs {widget cmd type args} {
   605    606       set options {}
   606    607       foreach {opt val} $args {
   607    608   	if {$opt eq "-label"} {
   608    609   	    lassign [UnderlineAmpersand $val] newlabel under
   609    610   	    lappend options -label $newlabel -underline $under
   610    611   	} else {
   611    612   	    lappend options $opt $val
   612    613   	}
   613    614       }
   614         -    $widget add $type {*}$options
          615  +    $widget $cmd $type {*}$options
   615    616   }
   616    617   
   617    618   # ::tk::FindAltKeyTarget --
   618    619   #	Search recursively through the hierarchy of visible widgets to find
   619    620   #	button or label which has $char as underlined character.
   620    621   #
   621    622   proc ::tk::FindAltKeyTarget {path char} {

Changes to library/ttk/altTheme.tcl.

    91     91   	    -expand [list selected {2 2 1 0}] \
    92     92   	    ;
    93     93   
    94     94   	# Treeview:
    95     95   	ttk::style configure Heading -font TkHeadingFont -relief raised
    96     96   	ttk::style configure Treeview -background $colors(-window)
    97     97   	ttk::style map Treeview \
    98         -	    -background [list selected $colors(-selectbg)] \
    99         -	    -foreground [list selected $colors(-selectfg)] ;
           98  +	    -background [list disabled $colors(-frame)\
           99  +				{!disabled !selected} $colors(-window) \
          100  +				selected $colors(-selectbg)] \
          101  +	    -foreground [list disabled $colors(-disabledfg) \
          102  +				{!disabled !selected} black \
          103  +				selected $colors(-selectfg)]
   100    104   
   101    105   	ttk::style configure TScale \
   102    106   	    -groovewidth 4 -troughrelief sunken \
   103    107   	    -sliderwidth raised -borderwidth 2
   104    108   	ttk::style configure TProgressbar \
   105    109   	    -background $colors(-selectbg) -borderwidth 0
   106    110       }
   107    111   }

Changes to library/ttk/aquaTheme.tcl.

    37     37   	# Combobox:
    38     38   	ttk::style configure TCombobox -postoffset {5 -2 -10 0}
    39     39   
    40     40   	# Treeview:
    41     41   	ttk::style configure Heading -font TkHeadingFont
    42     42   	ttk::style configure Treeview -rowheight 18 -background White
    43     43   	ttk::style map Treeview \
    44         -	    -background {{selected background} systemHighlightSecondary
    45         -		    selected systemHighlight}
           44  +	    -background [list disabled systemDialogBackgroundInactive \
           45  +				{!disabled !selected} systemWindowBody \
           46  +				{selected background} systemHighlightSecondary \
           47  +				selected systemHighlight] \
           48  +	    -foreground [list disabled systemModelessDialogInactiveText \
           49  +				{!disabled !selected} black \
           50  +				selected systemModelessDialogActiveText]
    46     51   
    47     52   	# Enable animation for ttk::progressbar widget:
    48     53   	ttk::style configure TProgressbar -period 100 -maxphase 255
    49     54   
    50     55   	# For Aqua, labelframe labels should appear outside the border,
    51     56   	# with a 14 pixel inset and 4 pixels spacing between border and label
    52     57   	# (ref: Apple Human Interface Guidelines / Controls / Grouping Controls)

Changes to library/ttk/clamTheme.tcl.

   127    127   	    ;
   128    128   
   129    129   	# Treeview:
   130    130   	ttk::style configure Heading \
   131    131   	    -font TkHeadingFont -relief raised -padding {3}
   132    132   	ttk::style configure Treeview -background $colors(-window)
   133    133   	ttk::style map Treeview \
   134         -	    -background [list selected $colors(-selectbg)] \
   135         -	    -foreground [list selected $colors(-selectfg)] ;
          134  +	    -background [list disabled $colors(-frame)\
          135  +				{!disabled !selected} $colors(-window) \
          136  +				selected $colors(-selectbg)] \
          137  +	    -foreground [list disabled $colors(-disabledfg) \
          138  +				{!disabled !selected} black \
          139  +				selected $colors(-selectfg)]
   136    140   
   137    141       	ttk::style configure TLabelframe \
   138    142   	    -labeloutside true -labelmargins {0 0 0 4} \
   139    143   	    -borderwidth 2 -relief raised
   140    144   
   141    145   	ttk::style configure TProgressbar -background $colors(-frame)
   142    146   
   143    147   	ttk::style configure Sash -sashthickness 6 -gripcount 10
   144    148       }
   145    149   }

Changes to library/ttk/classicTheme.tcl.

    94     94   	    -background $colors(-troughbg)
    95     95   	ttk::style map TNotebook.Tab -background [list selected $colors(-frame)]
    96     96   
    97     97   	# Treeview:
    98     98   	ttk::style configure Heading -font TkHeadingFont -relief raised
    99     99   	ttk::style configure Treeview -background $colors(-window)
   100    100   	ttk::style map Treeview \
   101         -	    -background [list selected $colors(-selectbg)] \
   102         -	    -foreground [list selected $colors(-selectfg)] ;
          101  +	    -background [list disabled $colors(-frame)\
          102  +				{!disabled !selected} $colors(-window) \
          103  +				selected $colors(-selectbg)] \
          104  +	    -foreground [list disabled $colors(-disabledfg) \
          105  +				{!disabled !selected} black \
          106  +				selected $colors(-selectfg)]
   103    107   
   104    108   	#
   105    109   	# Toolbar buttons:
   106    110   	#
   107    111   	ttk::style configure Toolbutton -padding 2 -relief flat -shiftrelief 2
   108    112   	ttk::style map Toolbutton -relief \
   109    113   	    {disabled flat selected sunken pressed sunken active raised}
   110    114   	ttk::style map Toolbutton -background \
   111    115   	    [list pressed $colors(-troughbg)  active $colors(-activebg)]
   112    116       }
   113    117   }

Changes to library/ttk/defaults.tcl.

   106    106   	# Treeview.
   107    107   	#
   108    108   	ttk::style configure Heading -font TkHeadingFont -relief raised
   109    109   	ttk::style configure Treeview \
   110    110   	    -background $colors(-window) \
   111    111   	    -foreground $colors(-text) ;
   112    112   	ttk::style map Treeview \
   113         -	    -background [list selected $colors(-selectbg)] \
   114         -	    -foreground [list selected $colors(-selectfg)] ;
          113  +	    -background [list disabled $colors(-frame)\
          114  +				{!disabled !selected} $colors(-window) \
          115  +				selected $colors(-selectbg)] \
          116  +	    -foreground [list disabled $colors(-disabledfg) \
          117  +				{!disabled !selected} black \
          118  +				selected $colors(-selectfg)]
   115    119   
   116    120   	# Combobox popdown frame
   117    121   	ttk::style layout ComboboxPopdownFrame {
   118    122   	    ComboboxPopdownFrame.border -sticky nswe
   119    123   	}
   120    124    	ttk::style configure ComboboxPopdownFrame \
   121    125   	    -borderwidth 1 -relief solid

Changes to library/ttk/vistaTheme.tcl.

    42     42   	ttk::style map TNotebook.Tab \
    43     43   	    -expand [list selected {2 2 2 2}]
    44     44   
    45     45   	# Treeview:
    46     46   	ttk::style configure Heading -font TkHeadingFont
    47     47   	ttk::style configure Treeview -background SystemWindow
    48     48   	ttk::style map Treeview \
    49         -	    -background [list selected SystemHighlight] \
    50         -	    -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]
    51     55   
    52     56           # Label and Toolbutton
    53     57   	ttk::style configure TLabelframe.Label -foreground "#0046d5"
    54     58   
    55     59   	ttk::style configure Toolbutton -padding {4 4}
    56     60   
    57     61           # Combobox

Changes to library/ttk/winTheme.tcl.

    67     67   	ttk::style configure TNotebook.Tab -padding {3 1} -borderwidth 1
    68     68   	ttk::style map TNotebook.Tab -expand [list selected {2 2 2 0}]
    69     69   
    70     70   	# Treeview:
    71     71   	ttk::style configure Heading -font TkHeadingFont -relief raised
    72     72   	ttk::style configure Treeview -background SystemWindow
    73     73   	ttk::style map Treeview \
    74         -	    -background [list selected SystemHighlight] \
    75         -	    -foreground [list selected SystemHighlightText] ;
           74  +	    -background [list   disabled SystemButtonFace \
           75  +				{!disabled !selected} SystemWindow \
           76  +				selected SystemHighlight] \
           77  +	    -foreground [list   disabled SystemGrayText \
           78  +				{!disabled !selected} SystemWindowText \
           79  +				selected SystemHighlightText]
    76     80   
    77     81           ttk::style configure TProgressbar \
    78     82   	    -background SystemHighlight -borderwidth 0 ;
    79     83       }
    80     84   }

Changes to library/ttk/xpTheme.tcl.

    57     57   	ttk::style map TSpinbox \
    58     58   	    -selectbackground [list !focus SystemWindow] \
    59     59   	    -selectforeground [list !focus SystemWindowText] \
    60     60   	    ;
    61     61   
    62     62   	ttk::style configure Toolbutton -padding {4 4}
    63     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];
    64     74       }
    65     75   }

Changes to macosx/README.

     1         -Tcl/Tk Mac OS X README
            1  +Tcl/Tk macOS README
     2      2   ----------------------
     3      3   
     4         -This is the README file for the Mac OS X/Darwin version of Tcl/Tk.
            4  +This is the README file for the macOS/Darwin version of Tcl/Tk.
     5      5   
     6      6   1. Where to go for support
     7      7   --------------------------
     8      8   
     9      9   - The tcl-mac mailing list on sourceforge is the best place to ask questions
    10         -specific to Tcl & Tk on Mac OS X:
           10  +specific to Tcl & Tk on macOS:
    11     11   	http://lists.sourceforge.net/lists/listinfo/tcl-mac
    12     12   (this page also has a link to searchable archives of the list, please check them
    13     13   before asking on the list, many questions have already been answered).
    14     14   
    15     15   - For general Tcl/Tk questions, the newsgroup comp.lang.tcl is your best bet:
    16     16   	http://groups.google.com/group/comp.lang.tcl/
    17     17   
    18         -- The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on Mac OS X, see
           18  +- The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on macOS, see
    19     19   	http://wiki.tcl.tk/_/ref?N=3753
    20     20   	http://wiki.tcl.tk/_/ref?N=8361
    21     21   
    22         -- Please report bugs with Tk on Mac OS X to the tracker:
           22  +- Please report bugs with Tk on macOS to the tracker:
    23     23   	http://core.tcl.tk/tk/reportlist
    24     24   
    25         -2. Using Tcl/Tk on Mac OS X
           25  +2. Using Tcl/Tk on macOS
    26     26   ---------------------------
    27     27   
    28         -- There are two versions of Tk available on Mac OS X: TkAqua using the native
           28  +- There are two versions of Tk available on macOS: TkAqua using the native
    29     29   aqua widgets and look&feel, and TkX11 using the traditional unix X11 wigets.
    30     30   TkX11 requires an X11 server to be installed, such as Apple's X11 (which is
    31         -available as an optional or default install on recent Mac OS X).
           31  +available as an optional or default install on recent macOS).
    32     32   TkAqua and TkX11 can be distinguished at runtime via [tk windowingsystem].
    33     33   
    34         -- At a minimum, Mac OS X 10.3 is required to run Tcl and TkX11.
    35         -TkAqua requires Mac OS X 10.5 or later (starting with the Cocoa-based Tk 8.5.7).
           34  +- At a minimum, macOS 10.3 is required to run Tcl and TkX11.
           35  +TkAqua requires macOS 10.6 or later.
    36     36   
    37         -- Unless weak-linking is used, Tcl/Tk built on Mac OS X 10.x will not run on
           37  +- Unless weak-linking is used, Tcl/Tk built on macOS 10.x will not run on
    38     38   10.y with y < x; on the other hand Tcl/Tk built on 10.y will always run on 10.x
    39     39   with y <= x (but without any of the fixes and optimizations that would be
    40     40   available in a binary built on 10.x).
    41     41   Weak-linking is available on OS X 10.2 or later, it additionally allows Tcl/Tk
    42     42   built on 10.x to run on any 10.y with x > y >= z (for a chosen z >= 2).
    43     43   
    44     44   - Wish checks the Resources/Scripts directory in its application bundle for a
................................................................................
    58     58   $pkg/Resources/Scripts/pkgIndex.tcl as well as the usual $pkg/pkgIndex.tcl.
    59     59   This allows building extensions as frameworks with all script files contained in
    60     60   the Resources/Scripts directory of the framework.
    61     61   
    62     62   - [load]able binary extensions can linked as either ordinary shared libraries
    63     63   (.dylib) or as MachO bundles (since 8.4.10/8.5a3); bundles have the advantage
    64     64   that they are [load]ed more efficiently from a tcl VFS (no temporary copy to the
    65         -native filesystem required), and prior to Mac OS X 10.5, only bundles can be
    66         -[unload]ed.
           65  +native filesystem required).
    67     66   
    68     67   - The 'deploy' target of macosx/GNUmakefile installs the html manpages into the
    69     68   standard documentation location in the Tcl/Tk frameworks:
    70     69   	Tcl.framework/Resources/Documentation/Reference/Tcl
    71     70   	Tk.framework/Resources/Documentation/Reference/Tk
    72     71   No nroff manpages are installed by default by the GNUmakefile.
    73     72   
................................................................................
   159    158   application's Info.plist (or displaying an alert if no Help Book is set). This
   160    159   action can be customized by defining a procedure named [tk::mac::ShowHelp], if
   161    160   present, this procedure is invoked instead by the standard Help menu item.
   162    161   Support for the Window menu and [tk::mac::ShowHelp] was added with the
   163    162   Cocoa-based Tk 8.5.7.
   164    163   
   165    164   - The TkAqua-specific command [tk::unsupported::MacWindowStyle style] is used to
   166         -get and set Mac OS X-specific toplevel window class and attributes. Note that
          165  +get and set macOS-specific toplevel window class and attributes. Note that
   167    166   the window class and many attributes have to be set before the window is first
   168    167   mapped for the change to have any effect.
   169    168   The command has the following syntax:
   170    169   	tk::unsupported::MacWindowStyle style window ?class? ?attributes?
   171    170   The 2 argument form returns a list of the current class and attributes for the
   172    171   given window. The 3 argument form sets the class for the given window using the
   173    172   default attributes for that class. The 4 argument form sets the class and the
................................................................................
   175    174   Window class names:
   176    175       document, modal, floating, utility, toolbar, simple, help, overlay
   177    176   Window attribute names:
   178    177       standardDocument, standardFloating, resizable, fullZoom, horizontalZoom,
   179    178       verticalZoom, closeBox, collapseBox, toolbarButton, sideTitlebar,
   180    179       noTitleBar, unifiedTitleAndToolbar, metal, hud, noShadow, doesNotCycle,
   181    180       noActivates, hideOnSuspend, inWindowMenu, ignoreClicks, doesNotHide,
   182         -    canJoinAllSpaces, moveToActiveSpace, nonActivating, black, dark, light,
   183         -    gray, red, green, blue, cyan, yellow, magenta, orange, purple,
   184         -    brown, clear, opacity
          181  +    canJoinAllSpaces, moveToActiveSpace, nonActivating
   185    182   
   186    183   Note that not all attributes are valid for all window classes.
   187    184   Support for the 3 argument form was added with the Cocoa-based Tk 8.5.7, at the
   188    185   same time support for some legacy Carbon-specific classes and attributes was
   189    186   removed (they are still accepted by the command but no longer have any effect).
   190    187   
   191         -The color window attributes (black, dark, red, etc.) and the "opacity" allow  one to set the background and opacity of a textured ("metal") window. This allows a Tk window to implement a window without the dividing line between the titlebar and the rest of the window, or the "unified toolbar" effect, which is increasingly standard in Mac applications. An example:
   192         -
   193         -toplevel .f
   194         -tk::unsupported::MacWindowStyle style .f document {metal light opaque closeBox collapseBox resizable standardDocument }
   195         -
   196         -pack [label .f.f -bg  #ababab -text "This is a textured window\nwith opacity and a gray background\nsimilar to other Mac applications"] -fill both -expand yes
   197         -
   198         -The color attributes correspond to system-defined NSColor constants (e.g., red is [NSColor redColor]. The "light" and "dark" attributes correspond to lightGrayColor and darkGrayColor, respectively (because of the way the attributes are parsed, using "lightgray" and "darkgray" would cause a conflict with the core "gray" attribute).
   199         -
   200         -Below are the corresponding hex and/or Tk-defined colors that can be used from Tk widgets to match the NSColor-based attributes:
   201         -
   202         -black	#000000
   203         -dark	#545454
   204         -light	#ababab
   205         -white	#ffffff
   206         -gray	#7f7f7f
   207         -red 	#ff0000
   208         -green	#00ff00
   209         -blue	#0000ff
   210         -cyan	#00ffff
   211         -yellow	#ffff00
   212         -magenta	#ff00ff
   213         -orange	#ff8000
   214         -purple 	#800080
   215         -brown	#996633
   216         -clear	systemTransparent
   217         -
   218         -- The Cocoa-based TkAqua can be distinguished from the older Carbon-based
   219         -version via the [winfo server .] command, example output on Mac OS X 10.5.7:
   220         -    Cocoa-based:	CG409.3 Apple AppKit GC 949.46 Mac OS X 1057
   221         -    Carbon-based:	QD10R30 Apple 1057
   222         -
   223         -- If you want to use Remote Debugging with Xcode, you need to set the
          188  +If you want to use Remote Debugging with Xcode, you need to set the
   224    189   environment variable XCNOSTDIN to 1 in the Executable editor for Wish. That will
   225    190   cause us to force closing stdin & stdout.  Otherwise, given how Xcode launches
   226    191   Wish remotely, they will be left open and then Wish & gdb will fight for stdin.
   227    192   
   228    193   
   229         -3. Building Tcl/Tk on Mac OS X
          194  +3. Building Tcl/Tk on macOS
   230    195   ------------------------------
   231    196   
   232         -- At least Mac OS X 10.3 is required to build Tcl and TkX11, and Mac OS X 10.5
   233         -is required to build TkAqua.
   234         -Apple's Xcode Developer Tools need to be installed (only the most recent version
   235         -matching your OS release is supported), the Xcode installer is available on Mac
   236         -OS X install media or may be present in /Applications/Installers on Macs that
   237         -came with OS X preinstalled. The most recent version can always be downloaded
   238         -from the ADC website http://connect.apple.com (free ADC membership required).
          197  +- At least macOS 10.3 is required to build Tcl and TkX11, and macOS 10.6
          198  +is required to build TkAqua.  The XCode application provides everything
          199  +needed to build Tk, but it is not necessary to install the full XCode.
          200  +It suffices to install the Command Line Tools package, which can be done
          201  +by running the command:
          202  +xcode-selecct --install
   239    203   
   240         -- Tcl/Tk are most easily built as Mac OS X frameworks via GNUmakefile in
          204  +- Tcl/Tk are most easily built as macOS frameworks via GNUmakefile in
   241    205   tcl/macosx and tk/macosx (see below for details), but can also be built with the
   242    206   standard unix configure and make buildsystem in tcl/unix resp. tk/unix as on any
   243    207   other unix platform (indeed, the GNUmakefiles are just wrappers around the unix
   244    208   buildsystem).
   245         -The Mac OS X specific configure flags are --enable-aqua, --enable-framework and
          209  +The macOS specific configure flags are --enable-aqua, --enable-framework and
   246    210   --disable-corefoundation (which disables CF and notably reverts to the standard
   247    211   select based notifier). Note that --enable-aqua is incompatible with
   248    212   --disable-corefoundation (for both Tcl and Tk configure).
   249    213   
   250         -- It is also possible to build with the Xcode IDE via the projects in
   251         -tk/macosx, take care to use the project matching your DevTools and OS version:
          214  +- It was once possible to build with the Xcode IDE via the projects in
          215  +tk/macosx, but this has not been tested recently. Take care to use the
          216  +project matching your DevTools and OS version:
   252    217   	Tk.xcode: 		    for Xcode 3.1 on 10.5
   253    218   	Tk.xcodeproj:		    for Xcode 3.2 on 10.6
   254    219   These have the following targets:
   255    220   	Tk:			    calls through to tk/macosx/GNUMakefile,
   256    221   				    requires a corresponding build of the Tcl
   257    222   				    target of tcl/macosx/Tcl.xcode.
   258    223   	tktest:			    static build of TkAqua tktest for debugging.
................................................................................
   288    253   directories are named differently, e.g. '../../tcl8.6' and '../../tk8.6', you
   289    254   need to manually change the TCL_SRCROOT and TK_SRCROOT settings by editing your
   290    255   ${USER}.pbxuser file (located inside the Tk.xcodeproj bundle directory) with a
   291    256   text editor.
   292    257   
   293    258   - To build universal binaries outside of the Xcode IDE, set CFLAGS as follows:
   294    259   	export CFLAGS="-arch i386 -arch x86_64 -arch ppc"
   295         -This requires Mac OS X 10.4 and Xcode 2.4 (or Xcode 2.2 if -arch x86_64 is
          260  +This requires macOS 10.4 and Xcode 2.4 (or Xcode 2.2 if -arch x86_64 is
   296    261   omitted, but _not_ Xcode 2.1) and will work on any architecture (on PowerPC
   297    262   Tiger you need to add "-isysroot /Developer/SDKs/MacOSX10.4u.sdk").
   298    263   Note that configure requires CFLAGS to contain a least one architecture that can
   299    264   be run on the build machine (i.e. ppc on G3/G4, ppc or ppc64 on G5, ppc or i386
   300    265   on Core and ppc, i386 or x86_64 on Core2/Xeon).
   301    266   Universal builds of Tcl TEA extensions are also possible with CFLAGS set as
   302    267   above, they will be [load]able by universal as well as thin binaries of Tcl.
   303    268   
   304    269   - To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable
   305    270   to the minimal OS version the binaries should be able to run on, e.g:
   306         -	export MACOSX_DEPLOYMENT_TARGET=10.4
          271  +	export MACOSX_DEPLOYMENT_TARGET=10.6
   307    272   This requires at least gcc 3.1; with gcc 4 or later, set/add to CFLAGS instead:
   308         -	export CFLAGS="-mmacosx-version-min=10.4"
          273  +	export CFLAGS="-mmacosx-version-min=10.6"
   309    274   Support for weak-linking was added with 8.4.14/8.5a5.
   310    275   
   311    276   Detailed Instructions for building with macosx/GNUmakefile
   312    277   ----------------------------------------------------------
   313    278   
   314    279   - Unpack the Tcl and Tk source release archives and place the tcl and tk source
   315    280   trees in a common parent directory.
................................................................................
   385    350   make overrides to the tk/macosx GNUmakefile, e.g.
   386    351   	make -C tk${ver}/macosx \
   387    352   	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
   388    353   	sudo make -C tk${ver}/macosx install \
   389    354   	    TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin
   390    355   The Makefile variables TCL_FRAMEWORK_DIR and TCLSH_DIR were added with Tk 8.4.3.
   391    356   
   392         -4. About the event loop in Tk for Mac OSX
   393         ------------------------------------------
          357  +4. Details regarding the macOS port of Tk.
          358  +-------------------------------------------
   394    359   
   395         -The main program in a typical OSX application looks like this (see *)
          360  +4.1 About the event loop
          361  +~~~~~~~~~~~~~~~~~~~~~~~~
          362  +
          363  +The main program in a typical OSX application looks like this (see
          364  +https://developer.apple.com/library/mac/documentation/Cocoa/\
          365  +Reference/ApplicationKit/Classes/NSApplication_Class)
   396    366   
   397    367       void NSApplicationMain(int argc, char *argv[]) {
   398    368           [NSApplication sharedApplication];
   399    369           [NSBundle loadNibNamed:@"myMain" owner:NSApp];
   400    370           [NSApp run];
   401    371       }
          372  +Here NSApp is a standard global variable, initialized by the OS, which
          373  +points to an object in a subclass of NSApplication (called
          374  +TKApplication in the case of the macOS port of Tk).
   402    375   
   403         -The run method implements the event loop for the application.  There
   404         -are three key steps in the run method.  First it calls
   405         -[NSApp finishLaunching], which creates the bouncing application icon
   406         -and does other mysterious things. Second it creates an
          376  +The [NSApp run] method implements the event loop for a typical Mac
          377  +application.  There are three key steps in the run method.  First it
          378  +calls [NSApp finishLaunching], which creates the bouncing application
          379  +icon and does other mysterious things. Second it creates an
   407    380   NSAutoreleasePool.  Third, it starts an event loop which drains the
   408    381   NSAutoreleasePool every time the queue is empty, and replaces the
   409    382   drained pool with a new one.  This third step is essential to
   410    383   preventing memory leaks, since the internal methods of Appkit objects
   411    384   all assume that an autorelease pool is in scope and will be drained
   412    385   when the event processing cycle ends.
   413    386   
   414         -Mac OSX Tk does not call the [NSApp run] method at all.  Instead it
   415         -uses the event loop built in to Tk.  So we must take care to replicate
   416         -the important features of the method ourselves.  Here is how this
   417         -works in outline.
   418         -
   419         -We add a private NSAUtoreleasePool* property to our subclass of
   420         -NSApplication.  (The subclass is called TKApplication but can be
   421         -referenced with the global variable NSApp).  The TkpInit
   422         -function calls [NSApp _setup] which initializes this property by
   423         -creating an NSAutoreleasePool. A bit later on, TkpInit calls
   424         -[NSAPP _setupEventLoop] which in turn calls the
   425         -[NSApp finishLaunching] method.
   426         -
   427         -Each time that Tcl processes an event in its queue, it calls a
   428         -platform specific function which, in the case of Mac OSX, is named
   429         -TkMacOSXEventsCheckProc.  In the unix implementations of Tk, including
   430         -the Mac OSX version, this function collects events from an "event
   431         -source", and transfers them to the Tcl event queue.  In Mac OSX the
   432         -event source is the NSApplication event queue.  Each NSEvent is
   433         -converted to a Tcl event which is added to the Tcl event queue.  The
   434         -NSEvent is also passed to [NSApp sendevent], which sends the event on
   435         -to the application's NSWindows, which send it to their NSViews, etc.
          387  +The macOS Tk application does not call the [NSApp run] method at
          388  +all.  Instead it uses the event loop built in to Tk.  So the
          389  +application must take care to replicate the important features of the
          390  +method ourselves.  The way that autorelease pools are handled is
          391  +discussed in 4.2 below.  Here we discuss the event handling itself.
          392  +
          393  +The Tcl event loop simply consists of repeated calls to TclDoOneEvent.
          394  +Each call to TclDoOneEvent begins by collecting all pending events from
          395  +an "event source", converting them to Tcl events and adding them
          396  +to the Tcl event queue. For macOS, the event source is the NSApp
          397  +object, which maintains an event queue even though its run method
          398  +will never be called to process them.  The NSApp provides methods for
          399  +inspecting the queue and removing events from it as well as the
          400  +[NSApp sendevent] which sends an event to all of the application's
          401  +NSWindows which can then send it to subwindows, etc.
          402  +
          403  +The event collection process consists of first calling a platform
          404  +specific SetupProc and then a platform specific CheckProc.  In
          405  +the macOS port, these are named TkMacOSXEventsSetupProc and
          406  +TkMacOSXEventsCheckProc.
          407  +
          408  +It is important to understand that the Apple window manager does not
          409  +have the concept of an expose event.  Their replacement for an expose
          410  +event is to have the window manager call the [NSView drawRect] method
          411  +in any situation where an expose event for that NSView would be
          412  +generated in X11.  The [NSView drawRect] method is a no-op which is
          413  +expected to be overridden by any application.  In the case of Tcl, the
          414  +replacement [NSView drawRect] method creates a Tcl expose event
          415  +for each dirty rectangle of the NSView, and then adds the expose
          416  +event to the Tcl queue.
          417  +
          418  +
          419  +4.2 Autorelease pools
          420  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          421  +
          422  +In order to carry out the job of managing autorelease pools, which
          423  +would normally be handled by the [NSApp run] method, a private
          424  +NSAUtoreleasePool* property is added to the TkApplication subclass of
          425  +NSApplication. The TkpInit function calls [NSApp _setup] which
          426  +initializes this property by creating an NSAutoreleasePool prior to
          427  +calling [NSApp finishLaunching].  This mimics the behavior of the
          428  +[NSApp run] method, which calls [NSApp finishLaunching] just before
          429  +starting the event loop.
          430  +
   436    431   Since the CheckProc function gets called for every Tk event, it is an
   437    432   appropriate place to drain the main NSAutoreleasePool and replace it
   438         -with a new pool.  This is done by calling the method
   439         -[NSApp _resetAutoreleasePool], where _resetAutoreleasePool is a method
   440         -which we define for the subclass TKApplication.
          433  +with a new pool.  This is done by calling the method [NSApp
          434  +_resetAutoreleasePool], where _resetAutoreleasePool is a method which
          435  +we define for the subclass.  Unfortunately, by itself this is not
          436  +sufficient for safe memory managememt because, as was made painfully
          437  +evident with the release of OS X 10.13, it is possible for calls to
          438  +TclDoOneEvent, and hence to CheckProc, to be nested.  Draining the
          439  +autorelease pool in a nested call leads to crashes as objects in use
          440  +by the outer call can get freed by the inner call and then reused later.
          441  +One particular situation where this happens is when a modal dialogue
          442  +gets posted by a Tk Application.  To address this, the NSApp object
          443  +also implements a semaphore to prevent draining the autorelease pool
          444  +in nested calls to CheckProc.
   441    445   
   442         -One minor caveat is that there are several steps of the Tk
   443         -initialization which precede the call to TkpInit.  Notably, the font
   444         -package is initialized first.  Since there is no NSAUtoreleasePool in
   445         -scope prior to calling TkpInit, the functions called in these
   446         -preliminary stages need to create and drain their own
          446  +One additional minor caveat for developers is that there are several
          447  +steps of the Tk initialization which precede the call to TkpInit.
          448  +Notably, the font package is initialized first.  Since there is no
          449  +NSAUtoreleasePool in scope prior to calling TkpInit, the functions
          450  +called in these preliminary stages need to create and drain their own
   447    451   NSAutoreleasePools whenever they call methods of Appkit objects
   448    452   (e.g. NSFont).
   449    453   
   450         -* https://developer.apple.com/library/mac/documentation/Cocoa/\
   451         -Reference/ApplicationKit/Classes/NSApplication_Class
          454  +4.3 Clipping regions and "ghost windows"
          455  +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
          456  +
          457  +Another unusual aspect of the macOS port is its use of clipping
          458  +regions.  It was part of Daniel Steffen's original design that the
          459  +TkWindowPrivate struct maintains three HIShapeRef regions, named
          460  +visRgn, aboveVisRgn and drawRgn.  These regions are used as clipping
          461  +masks whenever drawing into an NSView.  The visRgn is the bounding box
          462  +of the window with a rectangle removed for each subwindow and for each
          463  +sibling window at a higher stacking level.  The drawRgn is the
          464  +intersection of the visRgn with the clipping rectangle of the
          465  +window. (Normally, the clipping rectangle is the same as the bounding
          466  +rectangle, but drawing can be clipped to a smaller rectangle by
          467  +calling TkpClipDrawableToRect.) The aboveVisRgn is the intersection of
          468  +the window's bounding rectangle with the bounding rectangle of the
          469  +parent window.  Much of the code in tkMacOSXSubindows.c is devoted to
          470  +rebuilding these clipping regions whenever something changes in the
          471  +layout of the windows.  This turns out to be a tricky thing to do and
          472  +it is extremely prone to errors which can be difficult to trace.
          473  +
          474  +It is not entirely clear what the original reason for using these
          475  +clipping regions was.  But one benefit is that if they are correctly
          476  +maintained then it allows windows to be drawn in any order.  You do
          477  +not have to draw them in the order of the window hierarchy.  Each
          478  +window can draw its entire rectangle through its own mask and never
          479  +have to worry about drawing in the wrong place.  It is likely that
          480  +the need for using clipping regions arose because, as Apple explicitly
          481  +states in the documentation for [NSView subviews],
          482  +
          483  +    "The order of the subviews may be considered as being
          484  +    back-to-front, but this does not imply invalidation and drawing
          485  +    behavior."
          486  +
          487  +In the early versions of the macOS port, buttons were implemented as
          488  +subviews of class TkButton.  This probably exacerbated the likelihood
          489  +that Tk windows would need to be drawn in arbitrary order.
          490  +
          491  +The most obvious side effect caused by not maintaining the clipping
          492  +regions is the appearance of so-called "ghost windows".  A common
          493  +situation where these may arise is when a window containing buttons
          494  +is being scrolled.  A user may see two images of the same button on
          495  +the screen, one in the pre-scroll location and one in the post-scroll
          496  +location.
          497  +
          498  +To see how these 'ghost windows' can arise, think about what happens if
          499  +the clipping regions are not maintained correctly.  A window might
          500  +have a rectangle missing from its clipping region because that
          501  +rectangle is the bounding rectangle for a subwindow, say a button.
          502  +The parent should not draw in the missing rectangle since doing so
          503  +would trash the button.  The button is responsible for drawing
          504  +there. Now imagine that the button gets moved, say by a scroll, but
          505  +the missing rectangle in the parent's clipping region does not get
          506  +moved correctly, or it gets moved later on, after the parent has
          507  +redrawn itself.  The parent would still not be allowed to draw in the
          508  +old rectangle, so the user would continue to see the image of the
          509  +button in its old location, as well as another image in the new
          510  +location.  This is a prototypical example of a "ghost window".
          511  +Anytime you see a "ghost window", you should suspect problems with the
          512  +updates to the clipping region visRgn.  It is natural to look for
          513  +timing issues, race conditions, or other "event loop problems".  But
          514  +in fact, the whole design of the code is to make those timing issues
          515  +irrelevant.  As long as the clipping regions are correctly maintained
          516  +the timing does not matter.  And if they are not correctly maintained
          517  +then you will see "ghost windows".
          518  +
          519  +It is worth including a detailed description of one specific place
          520  +where the failure to correctly maintain clipping regions caused "ghost
          521  +window" artifacts that plagued the macOS port for years.  These
          522  +occurred when scrolling a Text widget which contained embedded
          523  +subwindows.  It involved some specific differences between the
          524  +low-level behavior of Apple's window manager versus those of the other
          525  +platforms, and the fix ultimately required changes in the generic Tk
          526  +implementation (documented in the comments in the DisplayText
          527  +function).
          528  +
          529  +The Text widget attempts to improve perfomance when scrolling by
          530  +minimizing the number of text lines which need to be redisplayed.  It
          531  +does this by calling the platform-specific TkScrollWindow function
          532  +which uses a low-level routine to map one rectangle of the window to
          533  +another.  The TkScrollWindow function returns a damage region which is
          534  +then used by the Text widget's DisplayText function to determine which
          535  +text lines need to be redrawn.  On the unix and win platforms, this
          536  +damage region includes bounding rectangles for all embedded windows
          537  +inside the Text widget.  The way that this works is system dependent.
          538  +On unix, the low level scrolling is done by XCopyRegion, which
          539  +generates a GraphicsExpose event for each embedded window.  These
          540  +GraphicsExposed events are processsed within TkScrollWindow, using a
          541  +special handler which adds the bounding rectangle of each subwindow to
          542  +the damage region.  On the win platform the damage region is built by
          543  +the low level function ScrollWindowEx, and it also includes bounding
          544  +rectangles for all embedded windows.  This is possible because on X11
          545  +and Windows every Tk widget is also known to the window manager as a
          546  +window.  The situation is different on macOS.  The underlying object
          547  +for a top level window on macOS is the NSView.  However, Apple
          548  +explicitly warns in its documentation that performance degradation
          549  +occurs when an NSView has more than about 100 subviews.  A Text widget
          550  +with thousands of lines of text could easily contain more than 100
          551  +embedded windows.  In fact, while the original Cocoa port of Tk did
          552  +use the NSButton object, which is derived from NSView, as the basis
          553  +for its Tk Buttons, that was changed in order to improve performance.
          554  +Moreover, the low level routine used for scrolling on macOS, namely
          555  +[NSView scrollrect:by], does not provide any damage information.  So
          556  +TkScrollWindow needs to work differently on macOS.  Since it would be
          557  +inefficient to iterate through all embedded windows in a Text widget,
          558  +looking for those which meet the scrolling area, the damage region
          559  +constructed by TkScrollWindow contains only the difference between the
          560  +source and destination rectangles for the scrolling.  The embedded
          561  +windows are redrawn within the DisplayText function by some
          562  +conditional code which is only used for macOS.
          563  +

Changes to macosx/Tk-Common.xcconfig.

    38     38   TCL_BUILD_DIR = $(OBJROOT)/../tcl/Tcl.build/$(CONFIGURATION)/Tcl.build/Objects
    39     39   TCL_CONFIGURE_ARGS = --enable-threads --enable-dtrace
    40     40   TCL_FRAMEWORK_DIR = $(SYMROOT)/../tcl/$(CONFIGURATION)
    41     41   TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION)
    42     42   TCL_PACKAGE_PATH = "$(LIBDIR)"
    43     43   TCL_DEFS = HAVE_TCL_CONFIG_H
    44     44   TK_LIBRARY = $(LIBDIR)/tk$(VERSION)
    45         -TK_DEFS = HAVE_TK_CONFIG_H TCL_NO_DEPRECATED
           45  +TK_DEFS = HAVE_TK_CONFIG_H
    46     46   VERSION = 8.6

Changes to macosx/Tk.xcode/project.pbxproj.

  1979   1979   		F96D446A08F272B9004A47F5 /* tclUnixThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixThrd.h; sourceTree = "<group>"; };
  1980   1980   		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
  1981   1981   		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
  1982   1982   		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
  1983   1983   		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
  1984   1984   		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
  1985   1985   		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
  1986         -		F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
  1987   1986   		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
  1988   1987   		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
  1989   1988   		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
  1990   1989   		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
  1991   1990   		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
  1992   1991   		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
  1993   1992   		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
................................................................................
  3812   3811   		};
  3813   3812   		F96D446E08F272B9004A47F5 /* win */ = {
  3814   3813   			isa = PBXGroup;
  3815   3814   			children = (
  3816   3815   				F96D447008F272BA004A47F5 /* aclocal.m4 */,
  3817   3816   				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
  3818   3817   				F96D447208F272BA004A47F5 /* cat.c */,
  3819         -				F96D447308F272BA004A47F5 /* coffbase.txt */,
  3820   3818   				F96D447408F272BA004A47F5 /* configure */,
  3821   3819   				F96D447508F272BA004A47F5 /* configure.in */,
  3822   3820   				F96D447708F272BA004A47F5 /* Makefile.in */,
  3823   3821   				F96D447808F272BA004A47F5 /* makefile.vc */,
  3824   3822   				F96D447908F272BA004A47F5 /* nmakehlp.c */,
  3825   3823   				F96D447A08F272BA004A47F5 /* README */,
  3826   3824   				F96D447C08F272BA004A47F5 /* rules.vc */,

Changes to macosx/Tk.xcodeproj/project.pbxproj.

  1979   1979   		F96D446A08F272B9004A47F5 /* tclUnixThrd.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tclUnixThrd.h; sourceTree = "<group>"; };
  1980   1980   		F96D446B08F272B9004A47F5 /* tclUnixTime.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclUnixTime.c; sourceTree = "<group>"; };
  1981   1981   		F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = "<group>"; };
  1982   1982   		F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = "<group>"; };
  1983   1983   		F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = "<group>"; };
  1984   1984   		F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = "<group>"; };
  1985   1985   		F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = "<group>"; };
  1986         -		F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = "<group>"; };
  1987   1986   		F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = "<group>"; };
  1988   1987   		F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = "<group>"; };
  1989   1988   		F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = "<group>"; };
  1990   1989   		F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = "<group>"; };
  1991   1990   		F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = "<group>"; };
  1992   1991   		F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
  1993   1992   		F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = "<group>"; };
................................................................................
  3812   3811   		};
  3813   3812   		F96D446E08F272B9004A47F5 /* win */ = {
  3814   3813   			isa = PBXGroup;
  3815   3814   			children = (
  3816   3815   				F96D447008F272BA004A47F5 /* aclocal.m4 */,
  3817   3816   				F96D447108F272BA004A47F5 /* buildall.vc.bat */,
  3818   3817   				F96D447208F272BA004A47F5 /* cat.c */,
  3819         -				F96D447308F272BA004A47F5 /* coffbase.txt */,
  3820   3818   				F96D447408F272BA004A47F5 /* configure */,
  3821   3819   				F96D447508F272BA004A47F5 /* configure.in */,
  3822   3820   				F96D447708F272BA004A47F5 /* Makefile.in */,
  3823   3821   				F96D447808F272BA004A47F5 /* makefile.vc */,
  3824   3822   				F96D447908F272BA004A47F5 /* nmakehlp.c */,
  3825   3823   				F96D447A08F272BA004A47F5 /* README */,
  3826   3824   				F96D447C08F272BA004A47F5 /* rules.vc */,

Changes to macosx/Wish-Info.plist.in.

    65     65   	<key>CFBundleShortVersionString</key>
    66     66   	<string>@[email protected]@[email protected]</string>
    67     67   	<key>CFBundleSignature</key>
    68     68   	<string>WiSH</string>
    69     69   	<key>CFBundleVersion</key>
    70     70   	<string>@[email protected]@[email protected]</string>
    71     71   	<key>LSMinimumSystemVersion</key>
    72         -	<string>10.5.0</string>
           72  +	<string>10.6.0</string>
    73     73   	<key>LSRequiresCarbon</key>
    74     74   	<true/>
    75     75   	<key>NSAppleScriptEnabled</key>
    76     76   	<true/>
    77     77   	<key>OSAScriptingDefinition</key>
    78     78   	<string>Wish.sdef</string>
    79     79   	<key>NSHighResolutionCapable</key>
    80     80   	<string>True</string>
    81     81   </dict>
    82     82   </plist>

Changes to macosx/tkMacOSXBitmap.c.

     8      8    * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
     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.
    12     12    */
    13     13   
    14     14   #include "tkMacOSXPrivate.h"
    15         -
           15  +#include "tkMacOSXConstants.h"
    16     16   /*
    17     17    * This structure holds information about native bitmaps.
    18     18    */
    19     19   
    20     20   typedef struct {
    21     21       const char *name;		/* Name of icon. */
    22     22       OSType iconType;		/* OSType of icon. */
................................................................................
   294    294   	if (image) {
   295    295   	    [image setSize:size];
   296    296   	}
   297    297       } else {
   298    298   	string = [NSString stringWithUTF8String:name];
   299    299   	image = [NSImage imageNamed:string];
   300    300   	if (!image) {
   301         -	    NSURL *url = [NSURL URLWithString:string];
          301  +	    NSURL *url = [NSURL fileURLWithPath:string];
   302    302   	    if (url) {
   303    303   		image = [[[NSImage alloc] initWithContentsOfURL:url]
   304    304   			autorelease];
   305    305   	    }
   306    306   	}
   307    307   	if (image) {
   308    308   	    size = [image size];

Changes to macosx/tkMacOSXButton.c.

   360    360   	width += butPtr->indicatorSpace;
   361    361   
   362    362       } else if (haveImage) { /* Image only */
   363    363         width = butPtr->width > 0 ? butPtr->width : width + butPtr->indicatorSpace;
   364    364         height = butPtr->height > 0 ? butPtr->height : height;
   365    365   
   366    366       } else { /* Text only */
   367         -        width = txtWidth + butPtr->indicatorSpace;
          367  +      /*Add four pixels of padding to width for text-only buttons to improve appearance.*/
          368  +        width = txtWidth + butPtr->indicatorSpace + 4;
   368    369   	height = txtHeight;
   369    370   	if (butPtr->width > 0) {
   370    371   	   width = butPtr->width * charWidth;
   371    372   	}
   372    373   	if (butPtr->height > 0) {
   373    374   	  height = butPtr->height * fm.linespace;
   374    375   	}

Changes to macosx/tkMacOSXColor.c.

   262    262   	    break;
   263    263   	    }
   264    264   	case TRANSPARENT_PIXEL:
   265    265   	    rgba[3]	= 0.0;
   266    266   	    break;
   267    267   	}
   268    268   
   269         -        // this attempts to find something roughly fitting for any display
   270         -//	*c = CGColorCreateGenericRGB(rgba[0], rgba[1], rgba[2], rgba[3]);
   271         -
   272         -        // may be off for non-main display but in most cases better than prev
   273    269   	static CGColorSpaceRef deviceRGBSpace = NULL;
   274    270   	if (!deviceRGBSpace) {
   275         -	    deviceRGBSpace = CGDisplayCopyColorSpace(CGMainDisplayID());
          271  +	    deviceRGBSpace = CGColorSpaceCreateDeviceRGB();
   276    272   	}
   277    273   	*c = CGColorCreate(deviceRGBSpace, rgba );
   278    274       }
   279    275       return err;
   280    276   }
   281    277   
   282    278   /*

Added macosx/tkMacOSXConstants.h.

            1  +/*
            2  + * tkMacOSXConstants.h --
            3  + *
            4  + *	Macros which map the names of NS constants used in the Tk code to
            5  + *      the new name that Apple came up with for subsequent versions of the
            6  + *      operating system.  (Each new OS release seems to come with a new
            7  + *      naming convention for the same old constants.)
            8  + *
            9  + * Copyright (c) 2017 Marc Culler
           10  + *
           11  + * See the file "license.terms" for information on usage and redistribution
           12  + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
           13  + */
           14  +
           15  +#ifndef _TKMACCONSTANTS
           16  +#define _TKMACCONSTANTS
           17  +
           18  +/*
           19  + * Let's raise a glass for the project manager who improves our lives by
           20  + * generating deprecation warnings about pointless changes of the names
           21  + * of constants.
           22  + */
           23  +
           24  +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000
           25  +#define NSOKButton NSModalResponseOK
           26  +#endif
           27  +
           28  +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
           29  +#define NSAppKitDefined NSEventTypeAppKitDefined
           30  +#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated
           31  +#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated
           32  +#define NSWindowExposedEventType NSEventSubtypeWindowExposed
           33  +#define NSScreenChangedEventType NSEventSubtypeScreenChanged
           34  +#define NSWindowMovedEventType NSEventSubtypeWindowMoved
           35  +#define NSKeyUp NSEventTypeKeyUp
           36  +#define NSKeyDown NSEventTypeKeyDown
           37  +#define NSFlagsChanged NSEventTypeFlagsChanged
           38  +#define NSLeftMouseDown NSEventTypeLeftMouseDown
           39  +#define NSLeftMouseUp NSEventTypeLeftMouseUp
           40  +#define NSRightMouseDown NSEventTypeRightMouseDown
           41  +#define NSRightMouseUp NSEventTypeRightMouseUp
           42  +#define NSLeftMouseDragged NSEventTypeLeftMouseDragged
           43  +#define NSRightMouseDragged NSEventTypeRightMouseDragged
           44  +#define NSMouseMoved NSEventTypeMouseMoved
           45  +#define NSMouseEntered NSEventTypeMouseEntered
           46  +#define NSMouseExited NSEventTypeMouseExited
           47  +#define NSScrollWheel NSEventTypeScrollWheel
           48  +#define NSOtherMouseDown NSEventTypeOtherMouseDown
           49  +#define NSOtherMouseUp NSEventTypeOtherMouseUp
           50  +#define NSOtherMouseDragged NSEventTypeOtherMouseDragged
           51  +#define NSTabletPoint NSEventTypeTabletPoint
           52  +#define NSTabletProximity NSEventTypeTabletProximity
           53  +#define NSDeviceIndependentModifierFlagsMask NSEventModifierFlagDeviceIndependentFlagsMask
           54  +#define NSCommandKeyMask NSEventModifierFlagCommand
           55  +#define NSShiftKeyMask NSEventModifierFlagShift
           56  +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
           57  +#define NSAlternateKeyMask NSEventModifierFlagOption
           58  +#define NSControlKeyMask NSEventModifierFlagControl
           59  +#define NSNumericPadKeyMask NSEventModifierFlagNumericPad
           60  +#define NSFunctionKeyMask NSEventModifierFlagFunction
           61  +#define NSCursorUpdate NSEventTypeCursorUpdate
           62  +#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
           63  +#define NSCompositeCopy NSCompositingOperationCopy
           64  +#define NSWarningAlertStyle NSAlertStyleWarning
           65  +#define NSInformationalAlertStyle NSAlertStyleInformational
           66  +#define NSCriticalAlertStyle NSAlertStyleCritical
           67  +#define NSCenterTextAlignment NSTextAlignmentCenter
           68  +#define NSDeviceIndependentModifierFlagsMask NSEventModifierFlagDeviceIndependentFlagsMask
           69  +#define NSCommandKeyMask NSEventModifierFlagCommand
           70  +#define NSShiftKeyMask NSEventModifierFlagShift
           71  +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
           72  +#define NSAlternateKeyMask NSEventModifierFlagOption
           73  +#define NSControlKeyMask NSEventModifierFlagControl
           74  +#define NSNumericPadKeyMask NSEventModifierFlagNumericPad
           75  +#define NSFunctionKeyMask NSEventModifierFlagFunction
           76  +#define NSKeyUp NSEventTypeKeyUp
           77  +#define NSKeyDown NSEventTypeKeyDown
           78  +#define NSFlagsChanged NSEventTypeFlagsChanged
           79  +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock
           80  +#define NSShiftKeyMask NSEventModifierFlagShift
           81  +#define NSAnyEventMask NSEventMaskAny
           82  +#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground
           83  +#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow
           84  +#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel
           85  +#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow
           86  +#define NSHUDWindowMask NSWindowStyleMaskHUDWindow
           87  +#define NSTitledWindowMask NSWindowStyleMaskTitled
           88  +#define NSClosableWindowMask NSWindowStyleMaskClosable
           89  +#define NSResizableWindowMask NSWindowStyleMaskResizable
           90  +#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar
           91  +#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable
           92  +#define NSBorderlessWindowMask NSWindowStyleMaskBorderless
           93  +#endif
           94  +
           95  +#endif

Changes to macosx/tkMacOSXDefault.h.

   321    321   #define DEF_MENU_FONT			"menu" /* special: see tkMacOSXMenu.c */
   322    322   #define DEF_MENU_FG			"systemMenuText"
   323    323   #define DEF_MENU_POST_COMMAND		""
   324    324   #define DEF_MENU_RELIEF			"flat"
   325    325   #define DEF_MENU_SELECT_COLOR		"systemMenuActive"
   326    326   #define DEF_MENU_SELECT_MONO		BLACK
   327    327   #define DEF_MENU_TAKE_FOCUS		"0"
   328         -
   329         -/*
   330         - * FIXME: Turn the default back to 1 when we make tearoff menus work again.
   331         - */
   332         -
   333    328   #define DEF_MENU_TEAROFF		"0"
   334    329   #define DEF_MENU_TEAROFF_CMD		((char *) NULL)
   335    330   #define DEF_MENU_TITLE			""
   336    331   #define DEF_MENU_TYPE			"normal"
   337    332   
   338    333   /*
   339    334    * Defaults for menubuttons:

Changes to macosx/tkMacOSXDialog.c.

    10     10    *
    11     11    * See the file "license.terms" for information on usage and redistribution of
    12     12    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    13     13    */
    14     14   
    15     15   #include "tkMacOSXPrivate.h"
    16     16   #include "tkFileFilter.h"
           17  +#include "tkMacOSXConstants.h"
    17     18   
    18     19   #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090
    19     20   #define modalOK     NSOKButton
    20     21   #define modalCancel NSCancelButton
    21     22   #else
    22     23   #define modalOK     NSModalResponseOK
    23     24   #define modalCancel NSModalResponseCancel
................................................................................
    26     27   #define modalError  -2
    27     28   
    28     29   /*Vars for filtering in "open file" and "save file" dialogs.*/
    29     30   typedef struct {
    30     31       bool doFileTypes; // show the accessory view which displays the filter menu
    31     32       bool preselectFilter; // a filter was selected by the typevariable
    32     33       bool userHasSelectedFilter; // The user has changed the filter in the accessory view
           34  +
    33     35       NSMutableArray *fileTypeNames; // array of names, e.g. "Text document"
    34     36       NSMutableArray *fileTypeExtensions; // array of allowed extensions per name, e.g. "txt", "doc"
    35     37       NSMutableArray *fileTypeLabels; // displayed string, e.g. "Text document (.txt, .doc)"
    36         -    NSMutableArray *allAllowedExtensions; // set of all allowed extensions
    37         -    NSInteger fileTypeIndex; // index of currently selected filter
           38  +    NSMutableArray *fileTypeAllowsAll; // boolean if the all pattern (*.*) is included
           39  +
           40  +    NSMutableArray *allowedExtensions; // set of all allowed extensions
           41  +    bool allowedExtensionsAllowAll; // set of all allowed extensions includes *.*
           42  +
           43  +    NSUInteger fileTypeIndex; // index of currently selected filter
    38     44   } filepanelFilterInfo;
    39     45   
    40     46   filepanelFilterInfo filterInfo;
    41     47   
    42     48   NSOpenPanel *openpanel;
    43     49   NSSavePanel *savepanel;
    44     50   
................................................................................
   159    165       [TYPE_YESNOCANCEL] =	{5, 6, 4},
   160    166   };
   161    167   
   162    168   /*
   163    169    * Construct a file URL from directory and filename.  Either may
   164    170    * be nil.  If both are nil, returns nil.
   165    171    */
   166         -#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050
   167    172   static NSURL *getFileURL(NSString *directory, NSString *filename) {
   168    173       NSURL *url = nil;
   169    174       if (directory) {
   170    175   	url = [NSURL fileURLWithPath:directory isDirectory:YES];
   171    176       }
   172    177       if (filename) {
   173    178   	url = [NSURL URLWithString:filename relativeToURL:url];
   174    179       }
   175    180       return url;
   176    181   }
   177         -#endif
   178         - 
   179    182   
   180    183   #pragma mark TKApplication(TKDialog)
   181    184   
   182    185   @interface NSColorPanel(TKDialog)
   183    186   - (void) _setUseModalAppearance: (BOOL) flag;
   184    187   @end
   185    188   
................................................................................
   186    189   @implementation TKApplication(TKDialog)
   187    190   
   188    191   - (void) tkFilePanelDidEnd: (NSSavePanel *) panel
   189    192   	returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo
   190    193   {
   191    194       FilePanelCallbackInfo *callbackInfo = contextInfo;
   192    195   
   193         -    if (returnCode == NSFileHandlingPanelOKButton) {
          196  +    if (returnCode == modalOK) {
   194    197   	Tcl_Obj *resultObj;
   195    198   
   196    199   	if (callbackInfo->multiple) {
   197    200   	    resultObj = Tcl_NewListObj(0, NULL);
   198    201   	    for (NSURL *url in [(NSOpenPanel*)panel URLs]) {
   199    202   		Tcl_ListObjAppendElement(callbackInfo->interp, resultObj,
   200    203   			Tcl_NewStringObj([[url path] UTF8String], -1));
................................................................................
   214    217   		TkBackgroundEvalObjv(callbackInfo->interp, objc + 1, tmpv,
   215    218   			TCL_EVAL_GLOBAL);
   216    219   		ckfree(tmpv);
   217    220   	    }
   218    221   	} else {
   219    222   	    Tcl_SetObjResult(callbackInfo->interp, resultObj);
   220    223   	}
   221         -    } else if (returnCode == NSFileHandlingPanelCancelButton) {
          224  +    } else if (returnCode == modalCancel) {
   222    225   	Tcl_ResetResult(callbackInfo->interp);
   223    226       }
   224    227       if (panel == [NSApp modalWindow]) {
   225    228   	[NSApp stopModalWithCode:returnCode];
   226    229       }
   227    230       if (callbackInfo->cmdObj) {
   228    231   	Tcl_DecrRefCount(callbackInfo->cmdObj);
................................................................................
   264    267       if (callbackInfo->cmdObj) {
   265    268   	Tcl_DecrRefCount(callbackInfo->cmdObj);
   266    269   	ckfree(callbackInfo);
   267    270       }
   268    271   }
   269    272   
   270    273   - (void)selectFormat:(id)sender  {
   271         -    NSPopUpButton *button                 = (NSPopUpButton *)sender;
   272         -    filterInfo.fileTypeIndex      = [button indexOfSelectedItem];
   273         -    NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex];
   274         -    [openpanel setAllowedFileTypes:allowedtypes];
          274  +    NSPopUpButton *button      = (NSPopUpButton *)sender;
          275  +    filterInfo.fileTypeIndex   = [button indexOfSelectedItem];
          276  +
          277  +    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
          278  +	[openpanel setAllowsOtherFileTypes:YES];
          279  +	/* setAllowsOtherFileTypes might have no effect; it's inherited from the
          280  +	 * NSSavePanel, where it has the effect that it does not append an extension
          281  +	 * Setting the allowed file types to nil allows selecting any file */
          282  +	[openpanel setAllowedFileTypes:nil];
          283  +    } else {
          284  +	NSMutableArray *allowedtypes = [filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
          285  +	[openpanel setAllowedFileTypes:allowedtypes];
          286  +	[openpanel setAllowsOtherFileTypes:NO];
          287  +    }
          288  +
   275    289       filterInfo.userHasSelectedFilter = true;
   276         -
   277    290   }
   278    291   
   279    292   - (void)saveFormat:(id)sender  {
   280         -    NSPopUpButton *button                 = (NSPopUpButton *)sender;
   281         -    filterInfo.fileTypeIndex      = [button indexOfSelectedItem];
   282         -    NSMutableArray *allowedtypes = filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex];
   283         -    [savepanel setAllowedFileTypes:allowedtypes];
          293  +    NSPopUpButton *button     = (NSPopUpButton *)sender;
          294  +    filterInfo.fileTypeIndex  = [button indexOfSelectedItem];
          295  +
          296  +    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) {
          297  +	[savepanel setAllowsOtherFileTypes:YES];
          298  +	[savepanel setAllowedFileTypes:nil];
          299  +    } else {
          300  +	NSMutableArray *allowedtypes = [filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex];
          301  +	[savepanel setAllowedFileTypes:allowedtypes];
          302  +	[savepanel setAllowsOtherFileTypes:NO];
          303  +    }
          304  +
          305  +    filterInfo.userHasSelectedFilter = true;
   284    306   }
   285    307   
   286    308   @end
   287    309   
   288    310   #pragma mark -
   289    311   
   290    312   /*
................................................................................
   371    393       }
   372    394       if (initialColor) {
   373    395   	[colorPanel setColor:initialColor];
   374    396       }
   375    397       returnCode = [NSApp runModalForWindow:colorPanel];
   376    398       if (returnCode == modalOK) {
   377    399   	color = [[colorPanel color] colorUsingColorSpace:
   378         -		[NSColorSpace genericRGBColorSpace]];
          400  +		[NSColorSpace deviceRGBColorSpace]];
   379    401   	numberOfComponents = [color numberOfComponents];
   380    402       }
   381    403       if (color && numberOfComponents >= 3 && numberOfComponents <= 4) {
   382    404   	CGFloat components[4];
   383    405   	char colorstr[8];
   384    406   
   385    407   	[color getComponents:components];
................................................................................
   415    437   
   416    438       filterInfo.doFileTypes = (fl.filters != NULL);
   417    439   
   418    440       filterInfo.fileTypeIndex = 0;
   419    441       filterInfo.fileTypeExtensions = [NSMutableArray array];
   420    442       filterInfo.fileTypeNames = [NSMutableArray array];
   421    443       filterInfo.fileTypeLabels = [NSMutableArray array];
   422         -    filterInfo.allAllowedExtensions = [NSMutableArray array];
          444  +    filterInfo.fileTypeAllowsAll = [NSMutableArray array];
          445  +
          446  +    filterInfo.allowedExtensions = [NSMutableArray array];
          447  +    filterInfo.allowedExtensionsAllowAll = NO;
   423    448   
   424    449       if (filterInfo.doFileTypes) {
   425    450   	for (FileFilter *filterPtr = fl.filters; filterPtr;
   426    451   		filterPtr = filterPtr->next) {
   427    452   	    NSString * name = [[NSString alloc] initWithUTF8String: filterPtr -> name];
   428    453   	    [filterInfo.fileTypeNames addObject:name];
   429    454   	    [name release];
   430    455   	    NSMutableArray * clauseextensions = [NSMutableArray array];
   431    456   	    NSMutableArray * displayextensions = [NSMutableArray array];
          457  +	    bool allowsAll = NO;
   432    458   
   433    459   	    for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr;
   434    460   		    clausePtr = clausePtr->next) {
          461  +
   435    462   		for (GlobPattern *globPtr = clausePtr->patterns; globPtr;
   436    463   			globPtr = globPtr->next) {
   437    464   		    const char *str = globPtr->pattern;
   438    465   		    while (*str && (*str == '*' || *str == '.')) {
   439    466   		    	str++;
   440    467   		     }
   441    468   		    if (*str) {
   442    469   			NSString *extension = [[NSString alloc] initWithUTF8String:str];
   443         -			if (![filterInfo.allAllowedExtensions containsObject:extension]) {
   444         -			    [filterInfo.allAllowedExtensions addObject:extension];
          470  +			if (![filterInfo.allowedExtensions containsObject:extension]) {
          471  +			    [filterInfo.allowedExtensions addObject:extension];
   445    472   			}
   446    473   
   447    474   			[clauseextensions addObject:extension];
   448    475   			[displayextensions addObject:[@"." stringByAppendingString:extension]];
   449    476   
   450    477   			[extension release];
          478  +		    } else {
          479  +			// it is the all pattern (*, .* or *.*)
          480  +			allowsAll = YES;
          481  +			filterInfo.allowedExtensionsAllowAll = YES;
          482  +			[displayextensions addObject:@"*"];
   451    483   		    }
   452    484   		}
   453    485   	    }
   454    486   	    [filterInfo.fileTypeExtensions addObject:clauseextensions];
          487  +	    [filterInfo.fileTypeAllowsAll addObject:[NSNumber numberWithBool:allowsAll]];
   455    488   
   456    489   	    NSMutableString * label = [[NSMutableString alloc] initWithString:name];
   457    490   	    [label appendString:@" ("];
   458    491   	    [label appendString:[displayextensions componentsJoinedByString:@", "]];
   459    492   	    [label appendString:@")"];
   460    493   	    [filterInfo.fileTypeLabels addObject:label];
   461    494   	    [label release];
................................................................................
   483    516   	}
   484    517   
   485    518       }
   486    519   
   487    520       TkFreeFileFilters(&fl);
   488    521       return TCL_OK;
   489    522   }
          523  +
          524  +bool filterCompatible(NSString *extension, int filterIndex) {
          525  +    NSMutableArray *allowedExtensions = [filterInfo.fileTypeExtensions objectAtIndex: filterIndex];
          526  +
          527  +    /* If this contains the all pattern, accept any extension */
          528  +    if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterIndex] boolValue]) {
          529  +	return true;
          530  +    }
          531  +
          532  +    return [allowedExtensions containsObject: extension];
          533  +}
   490    534   
   491    535   
   492    536   /*
   493    537    *----------------------------------------------------------------------
   494    538    *
   495    539    * Tk_GetOpenFileObjCmd --
   496    540    *
................................................................................
   614    658       [openpanel setAllowsMultipleSelection:multiple];
   615    659   
   616    660       if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
   617    661   	goto end;
   618    662       }
   619    663   
   620    664       if (filterInfo.doFileTypes) {
   621         -	NSView  *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
          665  +	NSView  *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];
   622    666   	NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
   623    667   	[label setEditable:NO];
   624         -	[label setStringValue:@"Enable:"];
          668  +	[label setStringValue:@"Filter:"];
   625    669   	[label setBordered:NO];
   626    670   	[label setBezeled:NO];
   627    671   	[label setDrawsBackground:NO];
   628    672   
   629         -	NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
          673  +	NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 240, 22.0) pullsDown:NO];
   630    674   	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
   631    675   	[popupButton setAction:@selector(selectFormat:)];
   632    676   
   633    677   	[accessoryView addSubview:label];
   634    678   	[accessoryView addSubview:popupButton];
   635    679   
   636    680   	if (filterInfo.preselectFilter) {
   637    681   	    /* A specific filter was selected from the typevariable. Select it and
   638    682   	     * open the accessory view */
   639    683   	    [popupButton selectItemAtIndex:filterInfo.fileTypeIndex];
   640    684   	    /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types
   641    685   	    [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
   642    686   	    */
   643         -	    [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions];
          687  +	    [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
          688  +	} else {
          689  +	    [openpanel setAllowedFileTypes:filterInfo.allowedExtensions];
          690  +	}
          691  +
          692  +	if (filterInfo.allowedExtensionsAllowAll) {
          693  +	    [openpanel setAllowsOtherFileTypes:YES];
   644    694   	} else {
   645         -	    [openpanel setAllowedFileTypes:filterInfo.allAllowedExtensions];
          695  +	    [openpanel setAllowsOtherFileTypes:NO];
   646    696   	}
   647    697   
   648         -	[openpanel setAllowsOtherFileTypes:NO];
   649         -
   650    698   	[openpanel setAccessoryView:accessoryView];
   651    699       } else {
   652    700   	/* No filters are given. Allow picking all files */
   653    701   	[openpanel setAllowsOtherFileTypes:YES];
   654    702       }
   655    703   
   656    704       if (cmdObj) {
................................................................................
   662    710       }
   663    711   
   664    712       callbackInfo->cmdObj = cmdObj;
   665    713       callbackInfo->interp = interp;
   666    714       callbackInfo->multiple = multiple;
   667    715       parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
   668    716       if (haveParentOption && parent && ![parent attachedSheet]) {
   669         -	    parentIsKey = [parent isKeyWindow];
   670         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
   671         -	[openpanel beginSheetForDirectory:directory
   672         -	       file:filename
   673         -	       types:openFileTypes
   674         -	       modalForWindow:parent
   675         -	       modalDelegate:NSApp
   676         -	       didEndSelector:
   677         -		   @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
   678         -	       contextInfo:callbackInfo];
   679         -#else
          717  +	parentIsKey = [parent isKeyWindow];
   680    718   	if (directory || filename ) {
   681    719   	    NSURL * fileURL = getFileURL(directory, filename);
   682    720   	    [openpanel setDirectoryURL:fileURL];
   683    721   	}
   684    722   
   685    723   	[openpanel beginSheetModalForWindow:parent
   686    724   	       completionHandler:^(NSInteger returnCode)
   687    725   	       { [NSApp tkFilePanelDidEnd:openpanel
   688    726   		       returnCode:returnCode
   689    727   		       contextInfo:callbackInfo ]; } ];
   690         -#endif
   691    728   	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:openpanel];
   692    729       } else {
   693         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
   694         -	modalReturnCode = [openpanel runModalForDirectory:directory
   695         -				 file:filename];
   696         -#else
   697    730   	if (directory || filename ) {
   698    731   	    NSURL * fileURL = getFileURL(directory, filename);
   699    732   	    [openpanel setDirectoryURL:fileURL];
   700    733   	}
   701    734   
   702    735   	modalReturnCode = [openpanel runModal];
   703         -#endif
   704    736   	[NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode
   705    737   		contextInfo:callbackInfo];
   706    738       }
   707    739       result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
   708    740       if (parentIsKey) {
   709    741   	[parent makeKeyWindow];
   710    742       }
   711    743   
   712    744       if ((typeVariablePtr && (modalReturnCode == NSOKButton)) &&
   713         -	filterInfo.doFileTypes && filterInfo.userHasSelectedFilter) {
          745  +	filterInfo.doFileTypes) {
   714    746   	/*
   715    747   	 * The -typevariable must be set to the selected file type, if the dialog was not cancelled
   716    748   	 */
   717         -	#if 0
   718         -	NSLog(@"result: %i modal: %li", result, (long)modalReturnCode);
   719         -	#endif
   720         -	NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex];
          749  +	NSInteger selectedFilterIndex = filterInfo.fileTypeIndex;
          750  +	NSString *selectedFilter = NULL;
          751  +	if (filterInfo.userHasSelectedFilter) {
          752  +	    selectedFilterIndex = filterInfo.fileTypeIndex;
          753  +	    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
          754  +	} else {
          755  +	    /* Difficult case: the user has not touched the filter settings, but we must
          756  +	     * return something in the typevariable. First check if the preselected type is compatible
          757  +	     * with the selected file, otherwise choose the first compatible type from the list,
          758  +	     * finally fall back to the empty string */
          759  +	    NSURL *selectedFile;
          760  +	    if (multiple) {
          761  +		// Use the first file in the case of multiple selection
          762  +		// Anyway it is not overly useful here
          763  +		selectedFile = [[openpanel URLs] objectAtIndex:0];
          764  +	    } else {
          765  +		selectedFile = [openpanel URL];
          766  +	    }
          767  +
          768  +	    NSString *extension = [selectedFile pathExtension];
          769  +	    if (filterInfo.preselectFilter &&
          770  +		filterCompatible(extension, filterInfo.fileTypeIndex)) {
          771  +		selectedFilterIndex = filterInfo.fileTypeIndex;  // The preselection from the typevariable
          772  +		selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
          773  +	    } else {
          774  +		// scan the list
          775  +		int i;
          776  +		for (i = 0; i < [filterInfo.fileTypeNames count]; i++) {
          777  +		    if (filterCompatible(extension, i)) {
          778  +			selectedFilterIndex = i;
          779  +			break;
          780  +		    }
          781  +		}
          782  +		if (i == selectedFilterIndex) {
          783  +		    selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex];
          784  +		} else {
          785  +		    selectedFilter = @"";
          786  +		}
          787  +
          788  +	    }
          789  +	}
          790  +
   721    791   	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
   722    792   		Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY);
   723    793       }
   724    794   
   725    795   
   726    796     end:
   727    797       return result;
................................................................................
   862    932       }
   863    933   
   864    934       if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) {
   865    935   	goto end;
   866    936       }
   867    937   
   868    938       if (filterInfo.doFileTypes) {
   869         -	NSView  *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 200, 32.0)];
          939  +	NSView  *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)];
   870    940   	NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)];
   871    941   	[label setEditable:NO];
   872    942   	[label setStringValue:NSLocalizedString(@"Format:", nil)];
   873    943   	[label setBordered:NO];
   874    944   	[label setBezeled:NO];
   875    945   	[label setDrawsBackground:NO];
   876    946   
   877         -	NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 140, 22.0) pullsDown:NO];
          947  +	NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 340, 22.0) pullsDown:NO];
   878    948   	[popupButton addItemsWithTitles:filterInfo.fileTypeLabels];
   879    949   	[popupButton selectItemAtIndex:filterInfo.fileTypeIndex];
   880    950   	[popupButton setAction:@selector(saveFormat:)];
   881    951   
   882    952   	[accessoryView addSubview:label];
   883    953   	[accessoryView addSubview:popupButton];
   884    954   
   885    955   	[savepanel setAccessoryView:accessoryView];
   886    956   
   887         -	[savepanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]];
   888         -	[savepanel setAllowsOtherFileTypes:NO];
          957  +	[savepanel setAllowedFileTypes:[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]];
          958  +	[savepanel setAllowsOtherFileTypes:filterInfo.allowedExtensionsAllowAll];
   889    959       } else if (defaultType) {
   890    960   	/* If no filetypes are given, defaultextension is an alternative way
   891    961   	 * to specify the attached extension. Just propose this extension,
   892    962   	 * but don't display an accessory view */
   893    963   	NSMutableArray *AllowedFileTypes = [NSMutableArray array];
   894    964   	[AllowedFileTypes addObject:defaultType];
   895    965   	[savepanel setAllowedFileTypes:AllowedFileTypes];
................................................................................
   909    979       callbackInfo->cmdObj = cmdObj;
   910    980       callbackInfo->interp = interp;
   911    981       callbackInfo->multiple = 0;
   912    982   
   913    983       parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
   914    984       if (haveParentOption && parent && ![parent attachedSheet]) {
   915    985          parentIsKey = [parent isKeyWindow];
   916         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
   917         -	[savepanel beginSheetForDirectory:directory
   918         -	       file:filename
   919         -	       modalForWindow:parent
   920         -	       modalDelegate:NSApp
   921         -	       didEndSelector:
   922         -		   @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
   923         -	       contextInfo:callbackInfo];
   924         -#else
   925         -	if (directory) {
          986  +       if (directory) {
   926    987   	    [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
   927    988   	}
   928    989   	   /*check for file name, otherwise set to empty string; crashes with uncaught exception if set to nil*/
   929    990   	if (filename) {
   930    991   	    [savepanel setNameFieldStringValue:filename];
   931    992   	} else {
   932    993   	    [savepanel setNameFieldStringValue:@""];
   933    994   	}
   934    995   	[savepanel beginSheetModalForWindow:parent
   935    996   	       completionHandler:^(NSInteger returnCode)
   936    997   	       { [NSApp tkFilePanelDidEnd:savepanel
   937    998   		       returnCode:returnCode
   938    999   		       contextInfo:callbackInfo ]; } ];
   939         -#endif
   940   1000   	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:savepanel];
   941   1001       } else {
   942         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
   943         -	modalReturnCode = [savepanel runModalForDirectory:directory file:filename];
   944         -#else
   945   1002   	if (directory) {
   946   1003   	    [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
   947   1004   	}
   948   1005   	 /*check for file name, otherwise set to empty string; crashes with uncaught exception if set to nil*/
   949   1006   	if (filename) {
   950   1007   	    [savepanel setNameFieldStringValue:filename];
   951   1008   	} else {
   952   1009   	    [savepanel setNameFieldStringValue:@""];
   953   1010   	}
   954   1011   	modalReturnCode = [savepanel runModal];
   955         -	#if 0
   956         -	NSLog(@"modal: %li", modalReturnCode);
   957         -	#endif
   958         -#endif
   959   1012   	[NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode
   960   1013   		contextInfo:callbackInfo];
   961   1014       }
   962   1015       result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
   963   1016       if (parentIsKey) {
   964   1017   	[parent makeKeyWindow];
   965   1018       }
   966   1019   
   967   1020       if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes) {
   968   1021   	/*
   969   1022   	 * The -typevariable must be set to the selected file type, if the dialog was not cancelled
   970   1023   	 */
   971         -	#if 0
   972         -	NSLog(@"result: %i modal: %li", result, (long)modalReturnCode);
   973         -	#endif
   974         -	NSString * selectedFilter = filterInfo.fileTypeNames[filterInfo.fileTypeIndex];
         1024  +	NSString * selectedFilter = [filterInfo.fileTypeNames objectAtIndex:filterInfo.fileTypeIndex];
   975   1025   	Tcl_ObjSetVar2(interp, typeVariablePtr, NULL,
   976   1026   		Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY);
   977   1027       }
   978   1028   
   979   1029   
   980   1030     end:
   981   1031       return result;
................................................................................
  1086   1136       callbackInfo->multiple = 0;
  1087   1137       /*check for directory value, set to root if not specified; otherwise crashes with exception because of nil string parameter*/
  1088   1138       if (!directory) {
  1089   1139   	directory = @"/";
  1090   1140       }
  1091   1141       parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window);
  1092   1142       if (haveParentOption && parent && ![parent attachedSheet]) {
  1093         -      parentIsKey = [parent isKeyWindow];
  1094         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
  1095         -	[panel beginSheetForDirectory:directory
  1096         -		file:nil
  1097         -		modalForWindow:parent
  1098         -		modalDelegate:NSApp
  1099         -		didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:)
  1100         -		contextInfo:callbackInfo];
  1101         -#else
         1143  +	parentIsKey = [parent isKeyWindow];
  1102   1144   	[panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
  1103   1145   	[panel beginSheetModalForWindow:parent
  1104   1146   	       completionHandler:^(NSInteger returnCode)
  1105   1147   	       { [NSApp tkFilePanelDidEnd:panel
  1106   1148   		       returnCode:returnCode
  1107   1149   		       contextInfo:callbackInfo ]; } ];
  1108         -#endif
  1109   1150   	modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel];
  1110   1151       } else {
  1111         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
  1112         -	modalReturnCode = [panel runModalForDirectory:directory file:nil];
  1113         -#else
  1114   1152   	[panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]];
  1115   1153   	modalReturnCode = [panel runModal];
  1116         -#endif
  1117   1154   	[NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode
  1118   1155   		contextInfo:callbackInfo];
  1119   1156       }
  1120   1157       result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR;
  1121   1158       if (parentIsKey) {
  1122   1159   	[parent makeKeyWindow];
  1123   1160       }

Changes to macosx/tkMacOSXDraw.c.

    12     12    *
    13     13    * See the file "license.terms" for information on usage and redistribution
    14     14    * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    15     15    */
    16     16   
    17     17   #include "tkMacOSXPrivate.h"
    18     18   #include "tkMacOSXDebug.h"
    19         -#include "xbytes.h"
    20     19   #include "tkButton.h"
    21     20   
    22     21   /*
    23     22   #ifdef TK_MAC_DEBUG
    24     23   #define TK_MAC_DEBUG_DRAWING
    25     24   #define TK_MAC_DEBUG_IMAGE_DRAWING
    26     25   #endif
................................................................................
    41     40   static int useThemedFrame = 0;
    42     41   
    43     42   /*
    44     43    * Prototypes for functions used only in this file.
    45     44    */
    46     45   
    47     46   static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr);
    48         -static CGImageRef CreateCGImageWithXImage(XImage *ximage);
    49         -static CGContextRef GetCGContextForDrawable(Drawable d);
    50         -static void DrawCGImage(Drawable d, GC gc, CGContextRef context, CGImageRef image,
    51         -	unsigned long imageForeground, unsigned long imageBackground,
    52         -	CGRect imageBounds, CGRect srcBounds, CGRect dstBounds);
    53         -
    54     47   
    55     48   /*
    56     49    *----------------------------------------------------------------------
    57     50    *
    58     51    * TkMacOSXInitCGDrawing --
    59     52    *
    60     53    *	Initializes link vars that control CG drawing.
................................................................................
   104     97       }
   105     98       return TCL_OK;
   106     99   }
   107    100   
   108    101   /*
   109    102    *----------------------------------------------------------------------
   110    103    *
   111         - * BitmapRepFromDrawableRect
          104  + * TkMacOSXBitmapRepFromDrawableRect
   112    105    *
   113    106    *	Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep.
   114    107    *
   115    108    * Results:
   116         - *	Returns an autoreleased NSBitmapRep representing the image of the given
   117         - *      rectangle of the given drawable.
          109  + *	Returns an NSBitmapRep representing the image of the given
          110  + *      rectangle of the given drawable.  This object is retained.
          111  + *      The caller is responsible for releasing it.
   118    112    *
   119    113    *      NOTE: The x,y coordinates should be relative to a coordinate system with
   120    114    *      origin at the top left, as used by XImage and CGImage, not bottom
   121    115    *      left as used by NSView.
   122    116    *
   123    117    * Side effects:
   124    118    *     None
   125    119    *
   126    120    *----------------------------------------------------------------------
   127    121    */
   128    122   NSBitmapImageRep*
   129         -BitmapRepFromDrawableRect(
          123  +TkMacOSXBitmapRepFromDrawableRect(
   130    124           Drawable drawable,
   131    125   	int x,
   132    126   	int y,
   133    127   	unsigned int width,
   134    128   	unsigned int height)
   135    129   {
   136    130       MacDrawable *mac_drawable = (MacDrawable *) drawable;
   137    131       CGContextRef cg_context=NULL;
   138    132       CGImageRef cg_image=NULL, sub_cg_image=NULL;
   139    133       NSBitmapImageRep *bitmap_rep=NULL;
   140    134       NSView *view=NULL;
   141    135       if ( mac_drawable->flags & TK_IS_PIXMAP ) {
   142    136   	/*
   143         -	   This means that the MacDrawable is functioning as a Tk Pixmap, so its view
   144         -	   field is NULL.
          137  +	 * This means that the MacDrawable is functioning as a
          138  +	 * Tk Pixmap, so its view field is NULL.
   145    139   	*/
   146         -	cg_context = GetCGContextForDrawable(drawable);
          140  +	cg_context = TkMacOSXGetCGContextForDrawable(drawable);
   147    141   	CGRect image_rect = CGRectMake(x, y, width, height);
   148    142   	cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context);
   149    143   	sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect);
   150    144   	if ( sub_cg_image ) {
   151         -	    /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/
   152    145   	    bitmap_rep = [NSBitmapImageRep alloc];
   153    146   	    [bitmap_rep initWithCGImage:sub_cg_image];
   154    147   	}
   155    148   	if ( cg_image ) {
   156    149   	    CGImageRelease(cg_image);
   157    150   	}
   158    151       } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) {
   159         -	/* convert top-left coordinates to NSView coordinates */
          152  +	/*
          153  +	 * Convert Tk top-left to NSView bottom-left coordinates.
          154  +	 */
   160    155   	int view_height = [view bounds].size.height;
   161    156   	NSRect view_rect = NSMakeRect(x + mac_drawable->xOff,
   162         -				      view_height - height - y - mac_drawable->yOff,
   163         -				      width,height);
          157  +			       view_height - height - y - mac_drawable->yOff,
          158  +			       width, height);
   164    159   
   165    160   	if ( [view lockFocusIfCanDraw] ) {
   166         -	    /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/
   167    161   	    bitmap_rep = [NSBitmapImageRep alloc];
   168    162   	    bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect];
   169    163   	    [view unlockFocus];
   170    164   	} else {
   171    165   	    TkMacOSXDbgMsg("Could not lock focus on view.");
   172    166   	}
   173    167   
................................................................................
   226    220   	/*TkMacOSXDbgMsg("Failed to setup drawing context.");*/
   227    221       }
   228    222   
   229    223       if ( dc.context ) {
   230    224   	if (srcDraw->flags & TK_IS_PIXMAP) {
   231    225   	    img = TkMacOSXCreateCGImageWithDrawable(src);
   232    226   	}else if (TkMacOSXDrawableWindow(src)) {
   233         -	    bitmap_rep =  BitmapRepFromDrawableRect(src, src_x, src_y, width, height);
          227  +	    bitmap_rep =  TkMacOSXBitmapRepFromDrawableRect(src, src_x, src_y, width, height);
   234    228   	    if ( bitmap_rep ) {
   235    229   		img = [bitmap_rep CGImage];
   236    230   	    }
   237    231   	} else {
   238    232   	    TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap.");
   239    233   	}
   240    234   
   241    235   	if (img) {
   242         -	    DrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
          236  +	    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background,
   243    237   			CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
   244    238   			CGRectMake(src_x, src_y, width, height),
   245    239   			CGRectMake(dest_x, dest_y, width, height));
   246    240   	    CFRelease(img);
   247    241   
   248    242   
   249    243   	} else {
................................................................................
   335    329   		    CGContextFillRect(context, rect);
   336    330   		    CGContextRestoreGState(context);
   337    331   		    CGImageRelease(img);
   338    332   		    CGImageRelease(mask);
   339    333   		    CGImageRelease(submask);
   340    334   		    CGImageRelease(subimage);
   341    335   		} else {
   342         -		    DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
          336  +		    TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground,
   343    337   				CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height),
   344    338   				CGRectMake(src_x, src_y, width, height),
   345    339   				CGRectMake(dest_x, dest_y, width, height));
   346    340   		    CGImageRelease(img);
   347    341   		}
   348    342   	    } else { /* no image */
   349    343   		TkMacOSXDbgMsg("Invalid source drawable");
................................................................................
   352    346   	    TkMacOSXDbgMsg("Invalid destination drawable - could not get a bitmap context.");
   353    347   	}
   354    348   	TkMacOSXRestoreDrawingContext(&dc);
   355    349       } else { /* source drawable is a window, not a Pixmap */
   356    350   	XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x, dest_y);
   357    351       }
   358    352   }
   359         -
   360         -/*
   361         - *----------------------------------------------------------------------
   362         - *
   363         - * TkPutImage --
   364         - *
   365         - *	Copies a subimage from an in-memory image to a rectangle of
   366         - *	of the specified drawable.
   367         - *
   368         - * Results:
   369         - *	None.
   370         - *
   371         - * Side effects:
   372         - *	Draws the image on the specified drawable.
   373         - *
   374         - *----------------------------------------------------------------------
   375         - */
   376         -
   377         -int
   378         -TkPutImage(
   379         -    unsigned long *colors,	/* Unused on Macintosh. */
   380         -    int ncolors,			/* Unused on Macintosh. */
   381         -    Display* display,		/* Display. */
   382         -    Drawable d,			/* Drawable to place image on. */
   383         -    GC gc,				/* GC to use. */
   384         -    XImage* image,		/* Image to place. */
   385         -    int src_x,			/* Source X & Y. */
   386         -    int src_y,
   387         -    int dest_x,			/* Destination X & Y. */
   388         -    int dest_y,
   389         -    unsigned int width,	/* Same width & height for both */
   390         -    unsigned int height)	/* distination and source. */
   391         -{
   392         -    TkMacOSXDrawingContext dc;
   393         -
   394         -    display->request++;
   395         -    if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) {
   396         -	return BadDrawable;
   397         -    }
   398         -    if (dc.context) {
   399         -	CGImageRef img = CreateCGImageWithXImage(image);
   400         -
   401         -	if (img) {
   402         -	    /* If the XImage has big pixels, rescale the source dimensions.*/
   403         -	    int pp = image->pixelpower;
   404         -	    DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background,
   405         -		    CGRectMake(0, 0, image->width<<pp, image->height<<pp),
   406         -		    CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
   407         -		    CGRectMake(dest_x, dest_y, width, height));
   408         -	    CFRelease(img);
   409         -	} else {
   410         -	    TkMacOSXDbgMsg("Invalid source drawable");
   411         -	}
   412         -    } else {
   413         -	TkMacOSXDbgMsg("Invalid destination drawable");
   414         -    }
   415         -    TkMacOSXRestoreDrawingContext(&dc);
   416         -    return Success;
   417         -}
   418         -
   419         -/*
   420         - *----------------------------------------------------------------------
   421         - *
   422         - * CreateCGImageWithXImage --
   423         - *
   424         - *	Create CGImage from XImage, copying the image data.
   425         - *
   426         - * Results:
   427         - *	CGImage, release after use.
   428         - *
   429         - * Side effects:
   430         - *	None.
   431         - *
   432         - *----------------------------------------------------------------------
   433         - */
   434         -
   435         -static void ReleaseData(void *info, const void *data, size_t size) {
   436         -    ckfree(info);
   437         -}
   438         -
   439         -CGImageRef
   440         -CreateCGImageWithXImage(
   441         -    XImage *image)
   442         -{
   443         -    CGImageRef img = NULL;
   444         -    size_t bitsPerComponent, bitsPerPixel;
   445         -    size_t len = image->bytes_per_line * image->height;
   446         -    const CGFloat *decode = NULL;
   447         -    CGBitmapInfo bitmapInfo;
   448         -    CGDataProviderRef provider = NULL;
   449         -    char *data = NULL;
   450         -    CGDataProviderReleaseDataCallback releaseData = ReleaseData;
   451         -
   452         -    if (image->bits_per_pixel == 1) {
   453         -	/*
   454         -	 * BW image
   455         -	 */
   456         -
   457         -	/* Reverses the sense of the bits */
   458         -	static const CGFloat decodeWB[2] = {1, 0};
   459         -	decode = decodeWB;
   460         -
   461         -	bitsPerComponent = 1;
   462         -	bitsPerPixel = 1;
   463         -	if (image->bitmap_bit_order != MSBFirst) {
   464         -	    char *srcPtr = image->data + image->xoffset;
   465         -	    char *endPtr = srcPtr + len;
   466         -	    char *destPtr = (data = ckalloc(len));
   467         -
   468         -	    while (srcPtr < endPtr) {
   469         -		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
   470         -	    }
   471         -	} else {
   472         -	    data = memcpy(ckalloc(len), image->data + image->xoffset, len);
   473         -	}
   474         -	if (data) {
   475         -	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
   476         -	}
   477         -	if (provider) {
   478         -	    img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
   479         -				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
   480         -	}
   481         -    } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
   482         -	/*
   483         -	 * Color image
   484         -	 */
   485         -
   486         -	CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB);
   487         -
   488         -	bitsPerComponent = 8;
   489         -	bitsPerPixel = 32;
   490         -	bitmapInfo = (image->byte_order == MSBFirst ?
   491         -		kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little) |
   492         -		kCGImageAlphaNoneSkipFirst;
   493         -	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
   494         -	if (data) {
   495         -	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
   496         -	}
   497         -	if (provider) {
   498         -	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
   499         -		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
   500         -		    provider, decode, 0, kCGRenderingIntentDefault);
   501         -	    CFRelease(provider);
   502         -	}
   503         -	if (colorspace) {
   504         -	    CFRelease(colorspace);
   505         -	}
   506         -    } else {
   507         -	TkMacOSXDbgMsg("Unsupported image type");
   508         -    }
   509         -    return img;
   510         -}
   511    353   
   512    354   /*
   513    355    *----------------------------------------------------------------------
   514    356    *
   515    357    * TkMacOSXCreateCGImageWithDrawable --
   516    358    *
   517    359    *	Create a CGImage from the given Drawable.
................................................................................
   526    368    */
   527    369   
   528    370   CGImageRef
   529    371   TkMacOSXCreateCGImageWithDrawable(
   530    372       Drawable drawable)
   531    373   {
   532    374       CGImageRef img = NULL;
   533         -    CGContextRef context = GetCGContextForDrawable(drawable);
          375  +    CGContextRef context = TkMacOSXGetCGContextForDrawable(drawable);
   534    376   
   535    377       if (context) {
   536    378   	img = CGBitmapContextCreateImage(context);
   537    379       }
   538    380       return img;
   539    381   }
   540    382   
................................................................................
   594    436   TkMacOSXGetNSImageWithTkImage(
   595    437       Display *display,
   596    438       Tk_Image image,
   597    439       int width,
   598    440       int height)
   599    441   {
   600    442       Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0);
          443  +    MacDrawable *macDraw = (MacDrawable *) pixmap;
   601    444       NSImage *nsImage;
   602    445   
          446  +    macDraw->flags |= TK_USE_XIMAGE_ALPHA;
   603    447       Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0);
   604    448       nsImage = CreateNSImageWithPixmap(pixmap, width, height);
   605    449       Tk_FreePixmap(display, pixmap);
   606    450   
   607    451       return [nsImage autorelease];
   608    452   }
   609    453   
................................................................................
   645    489   
   646    490       return [nsImage autorelease];
   647    491   }
   648    492   
   649    493   /*
   650    494    *----------------------------------------------------------------------
   651    495    *
   652         - * GetCGContextForDrawable --
          496  + * TkMacOSXGetCGContextForDrawable --
   653    497    *
   654    498    *	Get CGContext for given Drawable, creating one if necessary.
   655    499    *
   656    500    * Results:
   657    501    *	CGContext.
   658    502    *
   659    503    * Side effects:
   660    504    *	None.
   661    505    *
   662    506    *----------------------------------------------------------------------
   663    507    */
   664    508   
   665    509   CGContextRef
   666         -GetCGContextForDrawable(
   667         -    Drawable d)
          510  +TkMacOSXGetCGContextForDrawable(
          511  +    Drawable drawable)
   668    512   {
   669         -    MacDrawable *macDraw = (MacDrawable *) d;
          513  +    MacDrawable *macDraw = (MacDrawable *) drawable;
   670    514   
   671    515       if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) {
   672    516   	const size_t bitsPerComponent = 8;
   673    517   	size_t bitsPerPixel, bytesPerRow, len;
   674    518   	CGColorSpaceRef colorspace = NULL;
   675    519   	CGBitmapInfo bitmapInfo =
   676    520   #ifdef __LITTLE_ENDIAN__
................................................................................
   681    525   	char *data;
   682    526   	CGRect bounds = CGRectMake(0, 0, macDraw->size.width, macDraw->size.height);
   683    527   
   684    528   	if (macDraw->flags & TK_IS_BW_PIXMAP) {
   685    529   	    bitsPerPixel = 8;
   686    530   	    bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly;
   687    531   	} else {
   688         -	    colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
          532  +	    colorspace = CGColorSpaceCreateDeviceRGB();
   689    533   	    bitsPerPixel = 32;
   690    534   	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
   691    535   	}
   692    536   	bytesPerRow = ((size_t) macDraw->size.width * bitsPerPixel + 127) >> 3
   693    537   		& ~15;
   694    538   	len = macDraw->size.height * bytesPerRow;
   695    539   	data = ckalloc(len);
................................................................................
   707    551   
   708    552       return (macDraw ? macDraw->context : NULL);
   709    553   }
   710    554   
   711    555   /*
   712    556    *----------------------------------------------------------------------
   713    557    *
   714         - * DrawCGImage --
          558  + * TkMacOSXDrawCGImage --
   715    559    *
   716    560    *	Draw CG image into drawable.
   717    561    *
   718    562    * Results:
   719    563    *	None.
   720    564    *
   721    565    * Side effects:
   722    566    *	None.
   723    567    *
   724    568    *----------------------------------------------------------------------
   725    569    */
   726    570   
   727    571   void
   728         -DrawCGImage(
          572  +TkMacOSXDrawCGImage(
   729    573       Drawable d,
   730    574       GC gc,
   731    575       CGContextRef context,
   732    576       CGImageRef image,
   733    577       unsigned long imageForeground,
   734    578       unsigned long imageBackground,
   735    579       CGRect imageBounds,
................................................................................
  1482   1326    *
  1483   1327    * TkScrollWindow --
  1484   1328    *
  1485   1329    *	Scroll a rectangle of the specified window and accumulate
  1486   1330    *	a damage region.
  1487   1331    *
  1488   1332    * Results:
  1489         - *	Returns 0 if the scroll genereated no additional damage.
         1333  + *	Returns 0 if the scroll generated no additional damage.
  1490   1334    *	Otherwise, sets the region that needs to be repainted after
  1491   1335    *	scrolling and returns 1.
  1492   1336    *
  1493   1337    * Side effects:
  1494   1338    *	Scrolls the bits in the window.
  1495   1339    *
  1496   1340    *----------------------------------------------------------------------
................................................................................
  1512   1356       HIShapeRef dmgRgn = NULL, extraRgn = NULL;
  1513   1357       NSRect bounds, visRect, scrollSrc, scrollDst;
  1514   1358       int result = 0;
  1515   1359   
  1516   1360       if ( view ) {
  1517   1361     	/*  Get the scroll area in NSView coordinates (origin at bottom left). */
  1518   1362     	bounds = [view bounds];
  1519         - 	scrollSrc = NSMakeRect(
  1520         -			       macDraw->xOff + x,
         1363  + 	scrollSrc = NSMakeRect(macDraw->xOff + x,
  1521   1364   			       bounds.size.height - height - (macDraw->yOff + y),
  1522   1365   			       width, height);
  1523   1366    	scrollDst = NSOffsetRect(scrollSrc, dx, -dy);
  1524   1367   
  1525   1368     	/* Limit scrolling to the window content area. */
  1526   1369    	visRect = [view visibleRect];
  1527   1370    	scrollSrc = NSIntersectionRect(scrollSrc, visRect);
  1528   1371    	scrollDst = NSIntersectionRect(scrollDst, visRect);
  1529   1372    	if ( !NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst) ) {
  1530         -
  1531   1373     	    /*
  1532   1374     	     * Mark the difference between source and destination as damaged.
  1533   1375   	     * This region is described in NSView coordinates (y=0 at the bottom)
  1534   1376   	     * and converted to Tk coordinates later.
  1535   1377     	     */
  1536   1378   
  1537   1379   	    srcRect = CGRectMake(x, y, width, height);
................................................................................
  1539   1381   
  1540   1382   	    /* Compute the damage. */
  1541   1383     	    dmgRgn = HIShapeCreateMutableWithRect(&srcRect);
  1542   1384    	    extraRgn = HIShapeCreateWithRect(&dstRect);
  1543   1385    	    ChkErr(HIShapeDifference, dmgRgn, extraRgn, (HIMutableShapeRef) dmgRgn);
  1544   1386   	    result = HIShapeIsEmpty(dmgRgn) ? 0 : 1;
  1545   1387   
  1546         -	    /* Convert to Tk coordinates. */
         1388  +	    /* Convert to Tk coordinates, offset by the window origin. */
  1547   1389   	    TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
  1548   1390   	    if (extraRgn) {
  1549   1391   		CFRelease(extraRgn);
  1550   1392   	    }
  1551   1393   
  1552   1394    	    /* Scroll the rectangle. */
  1553   1395    	    [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)];
  1554         -
  1555         -	    /* Shift the Tk children which meet the source rectangle. */
  1556         -	    TkWindow *winPtr = (TkWindow *)tkwin;
  1557         -	    TkWindow *childPtr;
  1558         -	    CGRect childBounds;
  1559         -	    for (childPtr = winPtr->childList; childPtr != NULL; childPtr = childPtr->nextPtr) {
  1560         -		if (Tk_IsMapped(childPtr) && !Tk_IsTopLevel(childPtr)) {
  1561         -		    TkMacOSXWinCGBounds(childPtr, &childBounds);
  1562         -		    if (CGRectIntersectsRect(srcRect, childBounds)) {
  1563         -			MacDrawable *macChild = childPtr->privatePtr;
  1564         -			if (macChild) {
  1565         -			    macChild->yOff += dy;
  1566         -			    macChild->xOff += dx;
  1567         -			    childPtr->changes.y = macChild->yOff;
  1568         -			    childPtr->changes.x = macChild->xOff;
  1569         -			}
  1570         -		    }
  1571         -		}
  1572         -	    }
  1573         -
  1574         -	    /* Queue up Expose events for the damage region. */
  1575         -	    int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
  1576         -	    [view generateExposeEvents:dmgRgn childrenOnly:1];
  1577         -	    Tcl_SetServiceMode(oldMode);
  1578   1396     	}
  1579   1397       } else {
  1580   1398   	dmgRgn = HIShapeCreateEmpty();
  1581   1399   	TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn);
  1582   1400       }
  1583   1401   
  1584   1402       if (dmgRgn) {
................................................................................
  1647   1465   	ClipToGC(d, gc, &dc.clipRgn);
  1648   1466   	dontDraw = dc.clipRgn ? HIShapeIsEmpty(dc.clipRgn) : 0;
  1649   1467       }
  1650   1468       if (dontDraw) {
  1651   1469   	goto end;
  1652   1470       }
  1653   1471       if (useCG) {
  1654         -	dc.context = GetCGContextForDrawable(d);
         1472  +	dc.context = TkMacOSXGetCGContextForDrawable(d);
  1655   1473       }
  1656   1474       if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) {
  1657   1475   	isWin = (TkMacOSXDrawableWindow(d) != nil);
  1658   1476       }
  1659   1477       if (dc.context) {
  1660   1478   	dc.portBounds = clipBounds = CGContextGetClipBoundingBox(dc.context);
  1661   1479       } else if (isWin) {

Changes to macosx/tkMacOSXEmbed.c.

   189    189    *
   190    190    *----------------------------------------------------------------------
   191    191    */
   192    192   
   193    193   int
   194    194   TkpScanWindowId(
   195    195       Tcl_Interp *interp,
   196         -    CONST char * string,
          196  +    const char * string,
   197    197       Window *idPtr)
   198    198   {
   199    199       int code;
   200    200       Tcl_Obj obj;
   201    201   
   202    202       obj.refCount = 1;
   203    203       obj.bytes = (char *) string;	/* DANGER?! */
................................................................................
   795    795       ClientData clientData,	/* Token for container window. */
   796    796       XEvent *eventPtr)		/* ResizeRequest event. */
   797    797   {
   798    798       TkWindow *winPtr = clientData;
   799    799       Container *containerPtr;
   800    800       Tk_ErrorHandler errHandler;
   801    801   
          802  +    if (!firstContainerPtr) {
          803  +	/*
          804  +	 * When the interpreter is being dismantled this can be nil.
          805  +	 */
          806  +	return;
          807  +    }
          808  +    
   802    809       /*
   803    810        * Ignore any X protocol errors that happen in this procedure (almost any
   804    811        * operation could fail, for example, if the embedded application has
   805    812        * deleted its window).
   806    813        */
   807    814   
   808    815       errHandler = Tk_CreateErrorHandler(eventPtr->xfocus.display, -1,

Changes to macosx/tkMacOSXEvent.c.

    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.
    12     12    */
    13     13   
    14     14   #include "tkMacOSXPrivate.h"
    15     15   #include "tkMacOSXEvent.h"
    16     16   #include "tkMacOSXDebug.h"
           17  +#include "tkMacOSXConstants.h"
    17     18   
    18     19   #pragma mark TKApplication(TKEvent)
    19     20   
    20     21   enum {
    21     22       NSWindowWillMoveEventType = 20
    22     23   };
    23     24   
................................................................................
    84     85       case NSApplicationDefined: {
    85     86   	id win;
    86     87   	win = [theEvent window];
    87     88   	break;
    88     89   	}
    89     90       case NSCursorUpdate:
    90     91           break;
    91         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
    92     92       case NSEventTypeGesture:
    93     93       case NSEventTypeMagnify:
    94     94       case NSEventTypeRotate:
    95     95       case NSEventTypeSwipe:
    96     96       case NSEventTypeBeginGesture:
    97     97       case NSEventTypeEndGesture:
    98     98           break;
    99         -#endif
   100     99   #endif
   101    100   
   102    101       default:
   103    102   	break; /* return theEvent */
   104    103       }
   105    104       return processedEvent;
   106    105   }

Changes to macosx/tkMacOSXFont.c.

   255    255       if (reqFaPtr) {
   256    256   	*faPtr = *reqFaPtr;
   257    257       } else {
   258    258   	TkInitFontAttributes(faPtr);
   259    259       }
   260    260       fontPtr->nsFont = nsFont;
   261    261       // some don't like antialiasing on fixed-width even if bigger than limit
   262         -//    dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10;
          262  +    // dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10;
   263    263       if (antialiasedTextEnabled >= 0/* || dontAA*/) {
   264    264   	renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ?
   265    265   		NSFontIntegerAdvancementsRenderingMode :
   266    266   		NSFontAntialiasedRenderingMode;
   267    267       }
   268    268       nsFont = [nsFont screenFontWithRenderingMode:renderingMode];
   269    269       GetTkFontAttributesForNSFont(nsFont, faPtr);
................................................................................
   815    815   
   816    816       if (rangeStart < 0 || rangeLength <= 0 ||
   817    817   	    rangeStart + rangeLength > numBytes ||
   818    818   	    (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) {
   819    819   	*lengthPtr = 0;
   820    820   	return 0;
   821    821       }
   822         -#if 0
   823         -    /* Back-compatibility with ATSUI renderer, appears not to be needed */
   824         -    if (rangeStart == 0 && maxLength == 1 && (flags & TK_ISOLATE_END) &&
   825         -	    !(flags & TK_AT_LEAST_ONE)) {
   826         -	length = 0;
   827         -	fit = 0;
   828         -	goto done;
   829         -    }
   830         -#endif
   831    822       if (maxLength > 32767) {
   832    823   	maxLength = 32767;
   833    824       }
   834    825       string = [[NSString alloc] initWithBytesNoCopy:(void*)source
   835    826   		length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO];
   836    827       if (!string) {
   837    828   	length = 0;
................................................................................
   917    908   	    "flags='%s%s%s%s' -> width=%d bytesFit=%d\n", source, rangeLength,
   918    909   	    source+rangeStart, maxLength,
   919    910   	    flags & TK_PARTIAL_OK   ? "partialOk "  : "",
   920    911   	    flags & TK_WHOLE_WORDS  ? "wholeWords " : "",
   921    912   	    flags & TK_AT_LEAST_ONE ? "atLeastOne " : "",
   922    913   	    flags & TK_ISOLATE_END  ? "isolateEnd " : "",
   923    914   	    length, fit);
   924         -//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);
   925    915   #endif
   926    916       *lengthPtr = length;
   927    917       return fit;
   928    918   }
   929    919   
   930    920   /*
   931    921    *---------------------------------------------------------------------------

Changes to macosx/tkMacOSXHLEvents.c.

    32     32   /*
    33     33    * Static functions used only in this file.
    34     34    */
    35     35   
    36     36   static void tkMacOSXProcessFiles(NSAppleEventDescriptor* event,
    37     37   				 NSAppleEventDescriptor* replyEvent,
    38     38   				 Tcl_Interp *interp,
    39         -				 char* procedure);
           39  +				 const char* procedure);
    40     40   static int  MissedAnyParameters(const AppleEvent *theEvent);
    41     41   static int  ReallyKillMe(Tcl_Event *eventPtr, int flags);
    42     42   
    43     43   #pragma mark TKApplication(TKHLEvents)
    44     44   
    45     45   @implementation TKApplication(TKHLEvents)
    46     46   - (void) terminate: (id) sender
................................................................................
   273    273    */
   274    274   
   275    275   static void
   276    276   tkMacOSXProcessFiles(
   277    277       NSAppleEventDescriptor* event,
   278    278       NSAppleEventDescriptor* replyEvent,
   279    279       Tcl_Interp *interp,
   280         -    char* procedure)
          280  +    const char* procedure)
   281    281   {
   282         -    Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8");
          282  +    Tcl_Encoding utf8;
   283    283       const AEDesc *fileSpecDesc = nil;
   284    284       AEDesc contents;
   285    285       char URLString[1 + URL_MAX_LENGTH];
   286    286       NSURL *fileURL;
   287    287       DescType type;
   288    288       Size actual;
   289    289       long count, index;
................................................................................
   327    327       /*
   328    328        * Construct a Tcl command which calls the procedure, passing the
   329    329        * paths contained in the AppleEvent as arguments.
   330    330        */
   331    331   
   332    332       Tcl_DStringInit(&command);
   333    333       Tcl_DStringAppend(&command, procedure, -1);
          334  +    utf8 = Tcl_GetEncoding(NULL, "utf-8");
   334    335   
   335    336       for (index = 1; index <= count; index++) {
   336    337   	if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword,
   337    338   				 &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) {
   338    339   	    continue;
   339    340   	}
   340    341   	if (type != typeFileURL) {
................................................................................
   345    346   	if (fileURL == nil) {
   346    347   	    continue;
   347    348   	}
   348    349   	Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName);
   349    350   	Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName));
   350    351   	Tcl_DStringFree(&pathName);
   351    352       }
          353  +
          354  +    Tcl_FreeEncoding(utf8);
   352    355       AEDisposeDesc(&contents);
   353    356   
   354    357       /*
   355    358        * Handle the event by evaluating the Tcl expression we constructed.
   356    359        */
   357    360   
   358    361       code = Tcl_EvalEx(interp, Tcl_DStringValue(&command),
   359    362   	    Tcl_DStringLength(&command), TCL_EVAL_GLOBAL);
   360    363       if (code != TCL_OK) {
   361    364   	Tcl_BackgroundException(interp, code);
   362    365       }
   363    366       Tcl_DStringFree(&command);
   364         -    return;
   365    367   }
   366    368   
   367    369   /*
   368    370    *----------------------------------------------------------------------
   369    371    *
   370    372    * TkMacOSXInitAppleEvents --
   371    373    *

Added macosx/tkMacOSXImage.c.

            1  +/*
            2  + * tkMacOSXImage.c --
            3  + *
            4  + *	The code in this file provides an interface for XImages,
            5  + *
            6  + * Copyright (c) 1995-1997 Sun Microsystems, Inc.
            7  + * Copyright 2001-2009, Apple Inc.
            8  + * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
            9  + * Copyright 2017 Marc Culler.
           10  + *
           11  + * See the file "license.terms" for information on usage and redistribution
           12  + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
           13  + */
           14  +
           15  +#include "tkMacOSXPrivate.h"
           16  +#include "xbytes.h"
           17  +
           18  +#pragma mark XImage handling
           19  +
           20  +int
           21  +_XInitImageFuncPtrs(
           22  +    XImage *image)
           23  +{
           24  +    return 0;
           25  +}
           26  +
           27  +/*
           28  + *----------------------------------------------------------------------
           29  + *
           30  + * TkMacOSXCreateCGImageWithXImage --
           31  + *
           32  + *	Create CGImage from XImage, copying the image data.
           33  + *
           34  + * Results:
           35  + *	CGImage, release after use.
           36  + *
           37  + * Side effects:
           38  + *	None.
           39  + *
           40  + *----------------------------------------------------------------------
           41  + */
           42  +
           43  +static void ReleaseData(void *info, const void *data, size_t size) {
           44  +    ckfree(info);
           45  +}
           46  +
           47  +CGImageRef
           48  +TkMacOSXCreateCGImageWithXImage(
           49  +    XImage *image,
           50  +    int use_ximage_alpha)
           51  +{
           52  +    CGImageRef img = NULL;
           53  +    size_t bitsPerComponent, bitsPerPixel;
           54  +    size_t len = image->bytes_per_line * image->height;
           55  +    const CGFloat *decode = NULL;
           56  +    CGBitmapInfo bitmapInfo;
           57  +    CGDataProviderRef provider = NULL;
           58  +    char *data = NULL;
           59  +    CGDataProviderReleaseDataCallback releaseData = ReleaseData;
           60  +
           61  +    if (image->bits_per_pixel == 1) {
           62  +	/*
           63  +	 * BW image
           64  +	 */
           65  +
           66  +	/* Reverses the sense of the bits */
           67  +	static const CGFloat decodeWB[2] = {1, 0};
           68  +	decode = decodeWB;
           69  +
           70  +	bitsPerComponent = 1;
           71  +	bitsPerPixel = 1;
           72  +	if (image->bitmap_bit_order != MSBFirst) {
           73  +	    char *srcPtr = image->data + image->xoffset;
           74  +	    char *endPtr = srcPtr + len;
           75  +	    char *destPtr = (data = ckalloc(len));
           76  +
           77  +	    while (srcPtr < endPtr) {
           78  +		*destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))];
           79  +	    }
           80  +	} else {
           81  +	    data = memcpy(ckalloc(len), image->data + image->xoffset, len);
           82  +	}
           83  +	if (data) {
           84  +	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
           85  +	}
           86  +	if (provider) {
           87  +	    img = CGImageMaskCreate(image->width, image->height, bitsPerComponent,
           88  +				    bitsPerPixel, image->bytes_per_line, provider, decode, 0);
           89  +	}
           90  +    } else if (image->format == ZPixmap && image->bits_per_pixel == 32) {
           91  +	/*
           92  +	 * Color image
           93  +	 */
           94  +
           95  +	CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
           96  +
           97  +	bitsPerComponent = 8;
           98  +	bitsPerPixel = 32;
           99  +	bitmapInfo = (image->byte_order == MSBFirst ?
          100  +		      kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little);
          101  +	if (use_ximage_alpha) {
          102  +	    bitmapInfo |= kCGImageAlphaPremultipliedFirst;
          103  +	} else {
          104  +	    bitmapInfo |= kCGImageAlphaNoneSkipFirst;
          105  +	}
          106  +	data = memcpy(ckalloc(len), image->data + image->xoffset, len);
          107  +	if (data) {
          108  +	    provider = CGDataProviderCreateWithData(data, data, len, releaseData);
          109  +	}
          110  +	if (provider) {
          111  +	    img = CGImageCreate(image->width, image->height, bitsPerComponent,
          112  +		    bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo,
          113  +		    provider, decode, 0, kCGRenderingIntentDefault);
          114  +	    CFRelease(provider);
          115  +	}
          116  +	if (colorspace) {
          117  +	    CFRelease(colorspace);
          118  +	}
          119  +    } else {
          120  +	TkMacOSXDbgMsg("Unsupported image type");
          121  +    }
          122  +    return img;
          123  +}
          124  +
          125  +
          126  +/*
          127  + *----------------------------------------------------------------------
          128  + *
          129  + * XGetImage --
          130  + *
          131  + *	This function copies data from a pixmap or window into an XImage.
          132  + *
          133  + * Results:
          134  + *	Returns a newly allocated XImage containing the data from the given
          135  + *	rectangle of the given drawable, or NULL if the XImage could not be
          136  + *	constructed.  NOTE: If we are copying from a window on a Retina
          137  + *	display, the dimensions of the XImage will be 2*width x 2*height.
          138  + *
          139  + * Side effects:
          140  + *	None.
          141  + *
          142  + *----------------------------------------------------------------------
          143  + */
          144  +struct pixel_fmt {int r; int g; int b; int a;};
          145  +static struct pixel_fmt bgra = {2, 1, 0, 3};
          146  +static struct pixel_fmt abgr = {3, 2, 1, 0};
          147  +
          148  +XImage *
          149  +XGetImage(
          150  +    Display *display,
          151  +    Drawable drawable,
          152  +    int x,
          153  +    int y,
          154  +    unsigned int width,
          155  +    unsigned int height,
          156  +    unsigned long plane_mask,
          157  +    int format)
          158  +{
          159  +    NSBitmapImageRep* bitmap_rep = NULL;
          160  +    NSUInteger bitmap_fmt = 0;
          161  +    XImage* imagePtr = NULL;
          162  +    char* bitmap = NULL;
          163  +    char R, G, B, A;
          164  +    int depth = 32, offset = 0, bitmap_pad = 0;
          165  +    unsigned int bytes_per_row, size, row, n, m;
          166  +    unsigned int scalefactor=1, scaled_height=height, scaled_width=width;
          167  +    NSWindow *win = TkMacOSXDrawableWindow(drawable);
          168  +    MacDrawable *macDraw = ((MacDrawable*)drawable);
          169  +    static enum {unknown, no, yes} has_retina = unknown;
          170  +
          171  +    if (win && has_retina == unknown) {
          172  +#ifdef __clang__
          173  +	has_retina = [win respondsToSelector:@selector(backingScaleFactor)]?
          174  +	    yes : no;
          175  +#else
          176  +	has_retina = no;
          177  +#endif
          178  +    }
          179  +
          180  +    if (has_retina == yes) {
          181  +	/*
          182  +	 * We only allow scale factors 1 or 2, as Apple currently does.
          183  +	 */
          184  +#ifdef __clang__
          185  +	scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1;
          186  +#endif
          187  +	scaled_height *= scalefactor;
          188  +	scaled_width *= scalefactor;
          189  +    }
          190  +
          191  +    if (format == ZPixmap) {
          192  +	if (width == 0 || height == 0) {
          193  +	    return NULL;
          194  +	}
          195  +	bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable,
          196  +		         x, y, width, height);
          197  +	if (!bitmap_rep) {
          198  +	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
          199  +	    return NULL;
          200  +	}
          201  +	bitmap_fmt = [bitmap_rep bitmapFormat];
          202  +	size = [bitmap_rep bytesPerPlane];
          203  +	bytes_per_row = [bitmap_rep bytesPerRow];
          204  +	bitmap = ckalloc(size);
          205  +	if (!bitmap                              ||
          206  +	    (bitmap_fmt != 0 && bitmap_fmt != 1) ||
          207  +	    [bitmap_rep samplesPerPixel] != 4    ||
          208  +	    [bitmap_rep isPlanar] != 0           ||
          209  +	    bytes_per_row != 4 * scaled_width    ||
          210  +	    size != bytes_per_row*scaled_height  ) {
          211  +	    TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format");
          212  +	    CFRelease(bitmap_rep);
          213  +	    return NULL;
          214  +	}
          215  +
          216  +	if (macDraw->flags & TK_USE_XIMAGE_ALPHA) {
          217  +	    /*
          218  +	     * When called by TkImgPhotoDisplay we are being asked to return a
          219  +	     * background image to be blended with the photoimage using its
          220  +	     * alpha channel, if it has one.  Returning a black pixmap here
          221  +	     * makes TkImgPhotoDisplay create an XImage with a premultiplied
          222  +	     * alpha channel, as favored by Apple.  When TkImgPhotoDisplay
          223  +	     * passes this XImage to TkPutImage, targeting a pixmap, it creates
          224  +	     * an image with correct transparency.  This is used, for example,
          225  +	     * when creating an iconphoto or a menu image from a PNG
          226  +	     * photoimage.
          227  +	     */
          228  +	    bzero(bitmap, size);
          229  +	} else {
          230  +	    memcpy(bitmap, (char *)[bitmap_rep bitmapData], size);
          231  +	}
          232  +	CFRelease(bitmap_rep);
          233  +
          234  +	/*
          235  +	 * When Apple extracts a bitmap from an NSView, it may be in
          236  +	 * either BGRA or ABGR format.  For an XImage we need RGBA.
          237  +	 */
          238  +	struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr;
          239  +
          240  +	for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
          241  +	    for (m=n; m<n+bytes_per_row; m+=4) {
          242  +		R = *(bitmap + m + pixel.r);
          243  +		G = *(bitmap + m + pixel.g);
          244  +		B = *(bitmap + m + pixel.b);
          245  +		A = *(bitmap + m + pixel.a);
          246  +
          247  +		*(bitmap + m)     = R;
          248  +		*(bitmap + m + 1) = G;
          249  +		*(bitmap + m + 2) = B;
          250  +		*(bitmap + m + 3) = A;
          251  +	    }
          252  +	}
          253  +	imagePtr = XCreateImage(display, NULL, depth, format, offset,
          254  +				(char*)bitmap, scaled_width, scaled_height,
          255  +				bitmap_pad, bytes_per_row);
          256  +	if (scalefactor == 2) {
          257  +	    imagePtr->pixelpower = 1;
          258  +	}
          259  +    } else {
          260  +	/*
          261  +	 * There are some calls to XGetImage in the generic Tk
          262  +	 * code which pass an XYPixmap rather than a ZPixmap.
          263  +	 * XYPixmaps should be handled here.
          264  +	 */
          265  +	TkMacOSXDbgMsg("XGetImage does not handle XYPixmaps at the moment.");
          266  +    }
          267  +    return imagePtr;
          268  +}
          269  +
          270  +/*
          271  + *----------------------------------------------------------------------
          272  + *
          273  + * DestroyImage --
          274  + *
          275  + *	Destroys storage associated with an image.
          276  + *
          277  + * Results:
          278  + *	None.
          279  + *
          280  + * Side effects:
          281  + *	Deallocates the image.
          282  + *
          283  + *----------------------------------------------------------------------
          284  + */
          285  +
          286  +static int
          287  +DestroyImage(
          288  +    XImage *image)
          289  +{
          290  +    if (image) {
          291  +	if (image->data) {
          292  +	    ckfree(image->data);
          293  +	}
          294  +	ckfree(image);
          295  +    }
          296  +    return 0;
          297  +}
          298  +
          299  +/*
          300  + *----------------------------------------------------------------------
          301  + *
          302  + * ImageGetPixel --
          303  + *
          304  + *	Get a single pixel from an image.
          305  + *
          306  + * Results:
          307  + *	Returns the 32 bit pixel value.
          308  + *
          309  + * Side effects:
          310  + *	None.
          311  + *
          312  + *----------------------------------------------------------------------
          313  + */
          314  +
          315  +static unsigned long
          316  +ImageGetPixel(
          317  +    XImage *image,
          318  +    int x,
          319  +    int y)
          320  +{
          321  +    unsigned char r = 0, g = 0, b = 0;
          322  +
          323  +    if (image && image->data) {
          324  +	unsigned char *srcPtr = ((unsigned char*) image->data)
          325  +		+ (y * image->bytes_per_line)
          326  +		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
          327  +
          328  +	switch (image->bits_per_pixel) {
          329  +	    case 32: {
          330  +		r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
          331  +		g = (*((unsigned int*) srcPtr) >>  8) & 0xff;
          332  +		b = (*((unsigned int*) srcPtr)      ) & 0xff;
          333  +		/*if (image->byte_order == LSBFirst) {
          334  +		    r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
          335  +		} else {
          336  +		    r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
          337  +		}*/
          338  +		break;
          339  +	    }
          340  +	    case 16:
          341  +		r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
          342  +		g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
          343  +		b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
          344  +		break;
          345  +	    case 8:
          346  +		r = (*srcPtr << 2) & 0xc0;
          347  +		g = (*srcPtr << 4) & 0xc0;
          348  +		b = (*srcPtr << 6) & 0xc0;
          349  +		r |= r >> 2 | r >> 4 | r >> 6;
          350  +		g |= g >> 2 | g >> 4 | g >> 6;
          351  +		b |= b >> 2 | b >> 4 | b >> 6;
          352  +		break;
          353  +	    case 4: {
          354  +		unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);
          355  +		r = (c & 0x04) ? 0xff : 0;
          356  +		g = (c & 0x02) ? 0xff : 0;
          357  +		b = (c & 0x01) ? 0xff : 0;
          358  +		break;
          359  +		}
          360  +	    case 1:
          361  +		r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
          362  +		break;
          363  +	}
          364  +    }
          365  +    return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b;
          366  +}
          367  +
          368  +/*
          369  + *----------------------------------------------------------------------
          370  + *
          371  + * ImagePutPixel --
          372  + *
          373  + *	Set a single pixel in an image.
          374  + *
          375  + * Results:
          376  + *	None.
          377  + *
          378  + * Side effects:
          379  + *	None.
          380  + *
          381  + *----------------------------------------------------------------------
          382  + */
          383  +
          384  +static int
          385  +ImagePutPixel(
          386  +    XImage *image,
          387  +    int x,
          388  +    int y,
          389  +    unsigned long pixel)
          390  +{
          391  +    if (image && image->data) {
          392  +	unsigned char *dstPtr = ((unsigned char*) image->data)
          393  +		+ (y * image->bytes_per_line)
          394  +		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
          395  +	if (image->bits_per_pixel == 32) {
          396  +	    *((unsigned int*) dstPtr) = pixel;
          397  +	} else {
          398  +	    unsigned char r = ((pixel & image->red_mask)   >> 16) & 0xff;
          399  +	    unsigned char g = ((pixel & image->green_mask) >>  8) & 0xff;
          400  +	    unsigned char b = ((pixel & image->blue_mask)       ) & 0xff;
          401  +	    switch (image->bits_per_pixel) {
          402  +	    case 16:
          403  +		*((unsigned short*) dstPtr) = ((r & 0xf8) << 7) |
          404  +			((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
          405  +		break;
          406  +	    case 8:
          407  +		*dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
          408  +			((b & 0xc0) >> 6);
          409  +		break;
          410  +	    case 4: {
          411  +		unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) |
          412  +			((b & 0x80) >> 7);
          413  +		*dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) :
          414  +			((*dstPtr & 0x0f) | ((c << 4) & 0xf0));
          415  +		break;
          416  +		}
          417  +	    case 1:
          418  +		*dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
          419  +			(*dstPtr & ~(0x80 >> (x % 8)));
          420  +		break;
          421  +	    }
          422  +	}
          423  +    }
          424  +    return 0;
          425  +}
          426  +
          427  +/*
          428  + *----------------------------------------------------------------------
          429  + *
          430  + * XCreateImage --
          431  + *
          432  + *	Allocates storage for a new XImage.
          433  + *
          434  + * Results:
          435  + *	Returns a newly allocated XImage.
          436  + *
          437  + * Side effects:
          438  + *	None.
          439  + *
          440  + *----------------------------------------------------------------------
          441  + */
          442  +
          443  +XImage *
          444  +XCreateImage(
          445  +    Display* display,
          446  +    Visual* visual,
          447  +    unsigned int depth,
          448  +    int format,
          449  +    int offset,
          450  +    char* data,
          451  +    unsigned int width,
          452  +    unsigned int height,
          453  +    int bitmap_pad,
          454  +    int bytes_per_line)
          455  +{
          456  +    XImage *ximage;
          457  +    display->request++;
          458  +    ximage = ckalloc(sizeof(XImage));
          459  +
          460  +    ximage->height = height;
          461  +    ximage->width = width;
          462  +    ximage->depth = depth;
          463  +    ximage->xoffset = offset;
          464  +    ximage->format = format;
          465  +    ximage->data = data;
          466  +    ximage->obdata = NULL;
          467  +    /* The default pixelpower is 0.  This must be explicitly set to 1 in the
          468  +     * case of an XImage extracted from a Retina display.
          469  +     */
          470  +    ximage->pixelpower = 0;
          471  +
          472  +    if (format == ZPixmap) {
          473  +	ximage->bits_per_pixel = 32;
          474  +	ximage->bitmap_unit = 32;
          475  +    } else {
          476  +	ximage->bits_per_pixel = 1;
          477  +	ximage->bitmap_unit = 8;
          478  +    }
          479  +    if (bitmap_pad) {
          480  +	ximage->bitmap_pad = bitmap_pad;
          481  +    } else {
          482  +	/* Use 16 byte alignment for best Quartz perfomance */
          483  +	ximage->bitmap_pad = 128;
          484  +    }
          485  +    if (bytes_per_line) {
          486  +	ximage->bytes_per_line = bytes_per_line;
          487  +    } else {
          488  +	ximage->bytes_per_line = ((width * ximage->bits_per_pixel +
          489  +		(ximage->bitmap_pad - 1)) >> 3) &
          490  +		~((ximage->bitmap_pad >> 3) - 1);
          491  +    }
          492  +#ifdef WORDS_BIGENDIAN
          493  +    ximage->byte_order = MSBFirst;
          494  +    ximage->bitmap_bit_order = MSBFirst;
          495  +#else
          496  +    ximage->byte_order = LSBFirst;
          497  +    ximage->bitmap_bit_order = LSBFirst;
          498  +#endif
          499  +    ximage->red_mask = 0x00FF0000;
          500  +    ximage->green_mask = 0x0000FF00;
          501  +    ximage->blue_mask = 0x000000FF;
          502  +    ximage->f.create_image = NULL;
          503  +    ximage->f.destroy_image = DestroyImage;
          504  +    ximage->f.get_pixel = ImageGetPixel;
          505  +    ximage->f.put_pixel = ImagePutPixel;
          506  +    ximage->f.sub_image = NULL;
          507  +    ximage->f.add_pixel = NULL;
          508  +
          509  +    return ximage;
          510  +}
          511  +
          512  +/*
          513  + *----------------------------------------------------------------------
          514  + *
          515  + * TkPutImage --
          516  + *
          517  + *	Copies a subimage from an in-memory image to a rectangle of
          518  + *	of the specified drawable.
          519  + *
          520  + * Results:
          521  + *	None.
          522  + *
          523  + * Side effects:
          524  + *	Draws the image on the specified drawable.
          525  + *
          526  + *----------------------------------------------------------------------
          527  + */
          528  +
          529  +int
          530  +TkPutImage(
          531  +    unsigned long *colors,	/* Unused on Macintosh. */
          532  +    int ncolors,		/* Unused on Macintosh. */
          533  +    Display* display,		/* Display. */
          534  +    Drawable drawable,		/* Drawable to place image on. */
          535  +    GC gc,			/* GC to use. */
          536  +    XImage* image,		/* Image to place. */
          537  +    int src_x,			/* Source X & Y. */
          538  +    int src_y,
          539  +    int dest_x,			/* Destination X & Y. */
          540  +    int dest_y,
          541  +    unsigned int width,	        /* Same width & height for both */
          542  +    unsigned int height)	/* distination and source. */
          543  +{
          544  +    TkMacOSXDrawingContext dc;
          545  +    MacDrawable *macDraw = ((MacDrawable*)drawable);
          546  +
          547  +    display->request++;
          548  +    if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) {
          549  +	return BadDrawable;
          550  +    }
          551  +    if (dc.context) {
          552  +	CGImageRef img = TkMacOSXCreateCGImageWithXImage(image,
          553  +			     macDraw->flags & TK_USE_XIMAGE_ALPHA);
          554  +	if (img) {
          555  +	    /* If the XImage has big pixels, rescale the source dimensions.*/
          556  +	    int pp = image->pixelpower;
          557  +	    TkMacOSXDrawCGImage(drawable, gc, dc.context,
          558  +		    img, gc->foreground, gc->background,
          559  +		    CGRectMake(0, 0, image->width<<pp, image->height<<pp),
          560  +		    CGRectMake(src_x<<pp, src_y<<pp, width<<pp, height<<pp),
          561  +		    CGRectMake(dest_x, dest_y, width, height));
          562  +	    CFRelease(img);
          563  +	} else {
          564  +	    TkMacOSXDbgMsg("Invalid source drawable");
          565  +	}
          566  +    } else {
          567  +	TkMacOSXDbgMsg("Invalid destination drawable");
          568  +    }
          569  +    TkMacOSXRestoreDrawingContext(&dc);
          570  +    return Success;
          571  +}
          572  +
          573  +/*
          574  + * Local Variables:
          575  + * mode: objc
          576  + * c-basic-offset: 4
          577  + * fill-column: 79
          578  + * coding: utf-8
          579  + * End:
          580  + */

Changes to macosx/tkMacOSXInit.c.

     3      3    *
     4      4    *	This file contains Mac OS X -specific interpreter initialization
     5      5    *	functions.
     6      6    *
     7      7    * Copyright (c) 1995-1997 Sun Microsystems, Inc.
     8      8    * Copyright 2001-2009, Apple Inc.
     9      9    * Copyright (c) 2005-2009 Daniel A. Steffen <[email protected]>
           10  + * Copyright (c) 2017 Marc Culler
    10     11    *
    11     12    * See the file "license.terms" for information on usage and redistribution of
    12     13    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    13     14    */
    14     15   
    15     16   #include "tkMacOSXPrivate.h"
    16     17   
................................................................................
    28     29   
    29     30   static char scriptPath[PATH_MAX + 1] = "";
    30     31   
    31     32   long tkMacOSXMacOSXVersion = 0;
    32     33   
    33     34   #pragma mark TKApplication(TKInit)
    34     35   
    35         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    36         -#define NSTextInputContextKeyboardSelectionDidChangeNotification @"NSTextInputContextKeyboardSelectionDidChangeNotification"
    37         -static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) {
    38         -    [[NSNotificationCenter defaultCenter] postNotificationName:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil userInfo:nil];
    39         -}
    40         -#endif
    41         -
    42     36   @interface TKApplication(TKKeyboard)
    43     37   - (void) keyboardChanged: (NSNotification *) notification;
    44     38   @end
    45     39   
    46         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
    47     40   #define TKApplication_NSApplicationDelegate <NSApplicationDelegate>
    48         -#else
    49         -#define TKApplication_NSApplicationDelegate
    50         -#endif
    51     41   @interface TKApplication(TKWindowEvent) TKApplication_NSApplicationDelegate
    52     42   - (void) _setupWindowNotifications;
    53     43   @end
    54     44   
    55     45   @interface TKApplication(TKMenus)
    56     46   - (void) _setupMenus;
    57     47   @end
    58     48   
    59     49   @implementation TKApplication
    60         -@synthesize poolProtected = _poolProtected;
           50  +@synthesize poolLock = _poolLock;
    61     51   @end
    62     52   
           53  +/*
           54  + * #define this to see a message on stderr whenever _resetAutoreleasePool is
           55  + * called while the pool is locked.
           56  + */
           57  +#undef DEBUG_LOCK
           58  +
    63     59   @implementation TKApplication(TKInit)
    64     60   - (void) _resetAutoreleasePool
    65     61   {
    66         -    if(![self poolProtected]) {
           62  +    if([self poolLock] == 0) {
    67     63   	[_mainPool drain];
    68     64   	_mainPool = [NSAutoreleasePool new];
           65  +    } else {
           66  +#ifdef DEBUG_LOCK
           67  +	fprintf(stderr, "Pool is locked with count %d!!!!\n", [self poolLock]);
           68  +#endif
    69     69       }
    70     70   }
           71  +- (void) _lockAutoreleasePool
           72  +{
           73  +    [self setPoolLock:[self poolLock] + 1];
           74  +}
           75  +- (void) _unlockAutoreleasePool
           76  +{
           77  +    [self setPoolLock:[self poolLock] - 1];
           78  +}
    71     79   #ifdef TK_MAC_DEBUG_NOTIFICATIONS
    72     80   - (void) _postedNotification: (NSNotification *) notification
    73     81   {
    74     82       TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
    75     83   }
    76     84   #endif
    77     85   
................................................................................
    83     91       observe(NSApplicationDidBecomeActiveNotification, applicationActivate:);
    84     92       observe(NSApplicationDidResignActiveNotification, applicationDeactivate:);
    85     93       observe(NSApplicationDidUnhideNotification, applicationShowHide:);
    86     94       observe(NSApplicationDidHideNotification, applicationShowHide:);
    87     95       observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:);
    88     96       observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:);
    89     97   #undef observe
    90         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    91         -    CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), NULL, &keyboardChanged, kTISNotifySelectedKeyboardInputSourceChanged, NULL, CFNotificationSuspensionBehaviorCoalesce);
    92         -#endif
    93     98   }
    94     99   
    95         -- (void) _setupEventLoop
          100  +-(void)applicationWillFinishLaunching:(NSNotification *)aNotification
    96    101   {
    97         -    NSAutoreleasePool *pool = [NSAutoreleasePool new];
    98         -    [self finishLaunching];
    99         -    [self setWindowsNeedUpdate:YES];
   100         -    [pool drain];
   101         -}
   102    102   
   103         -- (void) _setup: (Tcl_Interp *) interp
   104         -{
   105         -    _eventInterp = interp;
   106         -    _mainPool = [NSAutoreleasePool new];
   107         -    [NSApp setPoolProtected:NO];
   108         -    _defaultMainMenu = nil;
   109         -    [self _setupMenus];
   110         -    [self setDelegate:self];
          103  +    /*
          104  +     * Initialize notifications.
          105  +     */
   111    106   #ifdef TK_MAC_DEBUG_NOTIFICATIONS
   112    107       [[NSNotificationCenter defaultCenter] addObserver:self
   113    108   	    selector:@selector(_postedNotification:) name:nil object:nil];
   114    109   #endif
   115    110       [self _setupWindowNotifications];
   116    111       [self _setupApplicationNotifications];
          112  +
          113  +    /*
          114  +     * Construct the menu bar.
          115  +     */
          116  +    _defaultMainMenu = nil;
          117  +    [self _setupMenus];
          118  +
          119  +
          120  +    /*
          121  +     * Initialize event processing.
          122  +     */
          123  +    TkMacOSXInitAppleEvents(_eventInterp);
          124  +
          125  +    /*
          126  +     * Initialize the graphics context.
          127  +     */
          128  +    TkMacOSXUseAntialiasedText(_eventInterp, -1);
          129  +    TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0);
          130  +}
          131  +
          132  +-(void)applicationDidFinishLaunching:(NSNotification *)notification
          133  +{
          134  +    /*
          135  +     * It is not safe to force activation of the NSApp until this
          136  +     * method is called.  Activating too early can cause the menu
          137  +     * bar to be unresponsive.
          138  +     */
          139  +    [NSApp activateIgnoringOtherApps: YES];
          140  +}
          141  +
          142  +- (void) _setup: (Tcl_Interp *) interp
          143  +{
          144  +    /*
          145  +     * Remember our interpreter.
          146  +     */
          147  +    _eventInterp = interp;
          148  +
          149  +    /*
          150  +     * Install the global autoreleasePool.
          151  +     */
          152  +    _mainPool = [NSAutoreleasePool new];
          153  +    [NSApp setPoolLock:0];
          154  +
          155  +    /*
          156  +     * Be our own delegate.
          157  +     */
          158  +    [self setDelegate:self];
          159  +
          160  +    /*
          161  +     * Make sure we are allowed to open windows.
          162  +     */
          163  +    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
          164  +
          165  +    /*
          166  +     * If no icon has been set from an Info.plist file, use the Wish icon from
          167  +     * the Tk framework.
          168  +     */
          169  +    NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey:
          170  +						    @"CFBundleIconFile"];
          171  +    if (!iconFile) {
          172  +	NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
          173  +	if (path) {
          174  +	    NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
          175  +	    if (image) {
          176  +		[NSApp setApplicationIconImage:image];
          177  +		[image release];
          178  +	    }
          179  +	}
          180  +    }
   117    181   }
   118    182   
   119    183   - (NSString *) tkFrameworkImagePath: (NSString *) image
   120    184   {
   121    185       NSString *path = nil;
   122    186       NSAutoreleasePool *pool = [NSAutoreleasePool new];
   123    187       if (tkLibPath[0] != '\0') {
................................................................................
   159    223   @end
   160    224   
   161    225   #pragma mark -
   162    226   
   163    227   /*
   164    228    *----------------------------------------------------------------------
   165    229    *
   166         - * DoWindowActivate --
   167         - *
   168         - *	Idle handler that sets the application icon to the generic Tk icon.
   169         - *
   170         - * Results:
   171         - *	None.
   172         - *
   173         - * Side effects:
   174         - *	None.
   175         - *
   176         - *----------------------------------------------------------------------
   177         - */
   178         -
   179         -static void
   180         -SetApplicationIcon(
   181         -    ClientData clientData)
   182         -{
   183         -    NSAutoreleasePool *pool = [NSAutoreleasePool new];
   184         -    NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"];
   185         -    if (path) {
   186         -	NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
   187         -	if (image) {
   188         -	    [NSApp setApplicationIconImage:image];
   189         -	    [image release];
   190         -	}
   191         -    }
   192         -    [pool drain];
   193         -}
   194         -
   195         -/*
   196         - *----------------------------------------------------------------------
   197         - *
   198    230    * TkpInit --
   199    231    *
   200    232    *	Performs Mac-specific interpreter initialization related to the
   201    233    *	tk_library variable.
   202    234    *
   203    235    * Results:
   204    236    *	Returns a standard Tcl result. Leaves an error message or result in
................................................................................
   219    251       /*
   220    252        * Since it is possible for TkInit to be called multiple times and we
   221    253        * don't want to do the following initialization multiple times we protect
   222    254        * against doing it more than once.
   223    255        */
   224    256   
   225    257       if (!initialized) {
   226         -	int bundledExecutable = 0;
   227         -	CFBundleRef bundleRef;
   228         -	CFURLRef bundleUrl = NULL;
   229    258   	struct utsname name;
   230    259   	struct stat st;
   231    260   
   232    261   	initialized = 1;
   233    262   
   234    263   	/*
   235    264   	 * Initialize/check OS version variable for runtime checks.
   236    265   	 */
   237    266   
   238         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050
   239         -#   error Mac OS X 10.5 required
          267  +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
          268  +#   error Mac OS X 10.6 required
   240    269   #endif
   241    270   
   242    271   	if (!uname(&name)) {
   243    272   	    tkMacOSXMacOSXVersion = (strtod(name.release, NULL) + 96) * 10;
   244    273   	}
   245    274          /*Check for new versioning scheme on Yosemite (10.10) and later.*/
   246    275   	if (MAC_OS_X_VERSION_MIN_REQUIRED > 100000) {
................................................................................
   259    288   	 * framework scripts directory.
   260    289   	 * FIXME: Should we come up with a more generic way of doing this?
   261    290   	 */
   262    291   
   263    292   	if (Tcl_MacOSXOpenVersionedBundleResources(interp,
   264    293   		"com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX,
   265    294   		tkLibPath) != TCL_OK) {
          295  +            # if 0 /* This is not really an error.  Wish still runs fine. */
   266    296   	    TkMacOSXDbgMsg("Tcl_MacOSXOpenVersionedBundleResources failed");
          297  +	    # endif
   267    298   	}
   268    299   #endif
   269    300   
   270         -	{
   271         -	    NSAutoreleasePool *pool = [NSAutoreleasePool new];
   272         -		[[NSUserDefaults standardUserDefaults] registerDefaults:
   273         -		     [NSDictionary dictionaryWithObjectsAndKeys:
   274         -		     [NSNumber numberWithBool:YES],
   275         -		     @"_NSCanWrapButtonTitles",
   276         -		     [NSNumber numberWithInt:-1],
   277         -		     @"NSStringDrawingTypesetterBehavior",
   278         -		     nil]];
   279         -	    [TKApplication sharedApplication];
   280         -	    [pool drain];
   281         -	    [NSApp _setup:interp];
   282         -	}
   283         -
   284         -	/* Check whether we are a bundled executable: */
   285         -	bundleRef = CFBundleGetMainBundle();
   286         -	if (bundleRef) {
   287         -	    bundleUrl = CFBundleCopyBundleURL(bundleRef);
   288         -	}
   289         -	if (bundleUrl) {
   290         -	    /*
   291         -	     * A bundled executable is two levels down from its main bundle
   292         -	     * directory (e.g. Wish.app/Contents/MacOS/Wish), whereas an
   293         -	     * unbundled executable's main bundle directory is just the
   294         -	     * directory containing the executable. So to check whether we are
   295         -	     * bundled, we delete the last three path components of the
   296         -	     * executable's url and compare the resulting url with the main
   297         -	     * bundle url.
   298         -	     */
   299         -
   300         -	    int j = 3;
   301         -	    CFURLRef url = CFBundleCopyExecutableURL(bundleRef);
   302         -
   303         -	    while (url && j--) {
   304         -		CFURLRef parent =
   305         -			CFURLCreateCopyDeletingLastPathComponent(NULL, url);
   306         -
   307         -		CFRelease(url);
   308         -		url = parent;
   309         -	    }
   310         -	    if (url) {
   311         -		bundledExecutable = CFEqual(bundleUrl, url);
   312         -		CFRelease(url);
   313         -	    }
   314         -	    CFRelease(bundleUrl);
   315         -	}
   316         -
   317         -	if (!bundledExecutable) {
   318         -	    /*
   319         -	     * If we are loaded into an executable that is not a bundled
   320         -	     * application, the window server does not let us come to the
   321         -	     * foreground. For such an executable, notify the window server
   322         -	     * that we are now a full GUI application.
   323         -	     */
   324         -
   325         -	    OSStatus err = procNotFound;
   326         -	    ProcessSerialNumber psn = { 0, kCurrentProcess };
   327         -
   328         -	    err = ChkErr(TransformProcessType, &psn,
   329         -		    kProcessTransformToForegroundApplication);
   330         -
   331         -	    /*
   332         -	     * Set application icon to generic Tk icon, do it at idle time
   333         -	     * instead of now to ensure tk_library is setup.
   334         -	     */
   335         -
   336         -	    Tcl_DoWhenIdle(SetApplicationIcon, NULL);
   337         -	}
   338         -
   339         -	{
   340         -	    NSAutoreleasePool *pool = [NSAutoreleasePool new];
   341         -	    [NSApp _setupEventLoop];
   342         -	    TkMacOSXInitAppleEvents(interp);
   343         -	    TkMacOSXUseAntialiasedText(interp, -1);
   344         -	    TkMacOSXInitCGDrawing(interp, TRUE, 0);
   345         -	    [pool drain];
   346         -	}
   347         -
   348    301   	/*
   349    302   	 * FIXME: Close stdin & stdout for remote debugging otherwise we will
   350    303   	 * fight with gdb for stdin & stdout
   351    304   	 */
   352    305   
   353    306   	if (getenv("XCNOSTDIN") != NULL) {
   354    307   	    close(0);
   355    308   	    close(1);
   356    309   	}
   357    310   
          311  +	/*
          312  +	 * Instantiate our NSApplication object. This needs to be
          313  +	 * done before we check whether to open a console window.
          314  +	 */
          315  +
          316  +	NSAutoreleasePool *pool = [NSAutoreleasePool new];
          317  +	[[NSUserDefaults standardUserDefaults] registerDefaults:
          318  +		[NSDictionary dictionaryWithObjectsAndKeys:
          319  +				  [NSNumber numberWithBool:YES],
          320  +			      @"_NSCanWrapButtonTitles",
          321  +				   [NSNumber numberWithInt:-1],
          322  +			      @"NSStringDrawingTypesetterBehavior",
          323  +			      nil]];
          324  +	[TKApplication sharedApplication];
          325  +	[pool drain];
          326  +	[NSApp _setup:interp];
          327  +	[NSApp finishLaunching];
          328  +
   358    329   	/*
   359    330   	 * If we don't have a TTY and stdin is a special character file of
   360    331   	 * length 0, (e.g. /dev/null, which is what Finder sets when double
   361    332   	 * clicking Wish) then use the Tk based console interpreter.
   362    333   	 */
   363    334   
   364    335   	if (getenv("TK_CONSOLE") ||
................................................................................
   383    354   			    TCL_GLOBAL_ONLY);
   384    355   		}
   385    356   	    }
   386    357   	    if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) {
   387    358   		return TCL_ERROR;
   388    359   	    }
   389    360   	}
          361  +
   390    362       }
   391    363   
   392    364       Tk_MacOSXSetupTkNotifier();
   393    365   
   394    366       if (tkLibPath[0] != '\0') {
   395    367   	Tcl_SetVar2(interp, "tk_library", NULL, tkLibPath, TCL_GLOBAL_ONLY);
   396    368       }

Changes to macosx/tkMacOSXInt.h.

    83     83   #define TK_CLIP_INVALID		0x02
    84     84   #define TK_HOST_EXISTS		0x04
    85     85   #define TK_DRAWN_UNDER_MENU	0x08
    86     86   #define TK_FOCUSED_VIEW		0x10
    87     87   #define TK_IS_PIXMAP		0x20
    88     88   #define TK_IS_BW_PIXMAP		0x40
    89     89   #define TK_DO_NOT_DRAW          0x80
           90  +#define TK_USE_XIMAGE_ALPHA     0x100
    90     91   /*
    91     92    * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags
    92     93    * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the
    93     94    * TkWindow structure for the window, but in the MacWin. This way we can
    94     95    * still tell what the correct port is after the TKWindow structure has been
    95     96    * freed. This actually happens when you bind destroy of a toplevel to
    96     97    * Destroy of a child.

Changes to macosx/tkMacOSXKeyEvent.c.

    11     11    *
    12     12    * See the file "license.terms" for information on usage and redistribution of
    13     13    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14     14    */
    15     15   
    16     16   #include "tkMacOSXPrivate.h"
    17     17   #include "tkMacOSXEvent.h"
           18  +#include "tkMacOSXConstants.h"
    18     19   
    19     20   /*
    20     21   #ifdef TK_MAC_DEBUG
    21     22   #define TK_MAC_DEBUG_KEYBOARD
    22     23   #endif
    23     24   */
    24     25   #define NS_KEYLOG 0

Changes to macosx/tkMacOSXKeyboard.c.

     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.
    12     12    */
    13     13   
    14     14   #include "tkMacOSXPrivate.h"
    15     15   #include "tkMacOSXEvent.h"
    16         -
           16  +#include "tkMacOSXConstants.h"
    17     17   /*
    18     18    * A couple of simple definitions to make code a bit more self-explaining.
    19     19    *
    20     20    * For the assignments of Mod1==meta==command and Mod2==alt==option, see also
    21     21    * tkMacOSXMouseEvent.c.
    22     22    */
    23     23   
................................................................................
    91     91       {103,	XK_F11},
    92     92       {111,	XK_F12},
    93     93       {105,	XK_F13},
    94     94       {107,	XK_F14},
    95     95       {113,	XK_F15},
    96     96       {0,		0}
    97     97   };
           98  +
           99  +#define NUM_MOD_KEYCODES 14
          100  +static KeyCode modKeyArray[NUM_MOD_KEYCODES] = {
          101  +    XK_Shift_L,
          102  +    XK_Shift_R,
          103  +    XK_Control_L,
          104  +    XK_Control_R,
          105  +    XK_Caps_Lock,
          106  +    XK_Shift_Lock,
          107  +    XK_Meta_L,
          108  +    XK_Meta_R,
          109  +    XK_Alt_L,
          110  +    XK_Alt_R,
          111  +    XK_Super_L,
          112  +    XK_Super_R,
          113  +    XK_Hyper_L,
          114  +    XK_Hyper_R,
          115  +};
    98    116   
    99    117   static int initialized = 0;
   100    118   static Tcl_HashTable keycodeTable;	/* keyArray hashed by keycode value. */
   101    119   static Tcl_HashTable vkeyTable;		/* virtualkeyArray hashed by virtual
   102    120   					 * keycode value. */
   103    121   
   104    122   static int latin1Table[LATIN1_MAX+1];	/* Reverse mapping table for
................................................................................
   453    471   
   454    472       (void) display; /*unused*/
   455    473   
   456    474       /*
   457    475        * MacOSX doesn't use the key codes for the modifiers for anything, and we
   458    476        * don't generate them either. So there is no modifier map.
   459    477        */
   460         -
   461    478       modmap = ckalloc(sizeof(XModifierKeymap));
   462    479       modmap->max_keypermod = 0;
   463    480       modmap->modifiermap = NULL;
   464    481       return modmap;
   465    482   }
   466    483   
   467    484   /*
................................................................................
   544    561   
   545    562   static int
   546    563   XKeysymToMacKeycode(
   547    564       Display *display,
   548    565       KeySym keysym)
   549    566   {
   550    567       KeyInfo *kPtr;
   551         -
   552    568       if (keysym <= LATIN1_MAX) {
   553    569   	/*
   554    570   	 * Handle keysyms in the Latin-1 range where keysym and Unicode
   555    571   	 * character code point are the same.
   556    572   	 */
   557    573   
   558    574   	if (keyboardChanged) {
................................................................................
   574    590   	}
   575    591       }
   576    592       for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) {
   577    593   	if (kPtr->keysym == keysym) {
   578    594   	    return kPtr->keycode;
   579    595   	}
   580    596       }
          597  +
          598  +    /*
          599  +     * Modifier keycodes only come from generated events.  No translation
          600  +     * is needed.
          601  +     */
          602  +
          603  +    for (int i=0; i < NUM_MOD_KEYCODES; i++) {
          604  +	if (keysym == modKeyArray[i]) {
          605  +	    return keysym;
          606  +	}
          607  +    }
   581    608   
   582    609       /*
   583    610        * For other keysyms (not Latin-1 and not special keys), we'd need a
   584    611        * generic keysym-to-unicode table. We don't have that, so we give up here.
   585    612        */
   586    613   
   587    614       return 0;
................................................................................
   657    684   TkpSetKeycodeAndState(
   658    685       Tk_Window tkwin,
   659    686       KeySym keysym,
   660    687       XEvent *eventPtr)
   661    688   {
   662    689       if (keysym == NoSymbol) {
   663    690   	eventPtr->xkey.keycode = 0;
          691  +    } else if ( modKeyArray[0] <= keysym &&
          692  +		keysym <= modKeyArray[NUM_MOD_KEYCODES - 1]) {
          693  +	/* 
          694  +	 * Keysyms for pure modifiers only arise in generated events.
          695  +	 * We should just copy them to the keycode.
          696  +	 */
          697  +	eventPtr->xkey.keycode = keysym;
   664    698       } else {
   665    699   	Display *display = Tk_Display(tkwin);
   666    700   	int macKeycode = XKeysymToMacKeycode(display, keysym);
   667    701   
   668    702   	/*
   669    703   	 * See also XKeysymToKeycode.
   670    704   	 */
   671         -
   672    705   	if ((keysym >= XK_F1) && (keysym <= XK_F35)) {
   673    706   	    eventPtr->xkey.keycode = 0x0010;
   674    707   	} else {
   675    708   	    eventPtr->xkey.keycode = 0x00FF & keysym;
   676    709   	}
   677    710   	eventPtr->xkey.keycode |= (macKeycode & MAC_KEYCODE_MASK) << 16;
   678    711   
................................................................................
   730    763   
   731    764       /*
   732    765        * Handle pure modifier keys specially. We use -1 as a signal for
   733    766        * this.
   734    767        */
   735    768   
   736    769       if (eventPtr->xany.send_event == -1) {
   737         -
   738    770   	int modifier = eventPtr->xkey.keycode & NSDeviceIndependentModifierFlagsMask;
   739    771   
   740    772   	if (modifier == NSCommandKeyMask) {
   741    773   	    return XK_Meta_L;
   742    774   	} else if (modifier == NSShiftKeyMask) {
   743    775   	    return XK_Shift_L;
   744    776   	} else if (modifier == NSAlphaShiftKeyMask) {
................................................................................
   887    919       dispPtr->metaModMask = COMMAND_MASK;
   888    920   #else
   889    921       dispPtr->altModMask = 0;
   890    922       dispPtr->metaModMask = 0;
   891    923   #endif
   892    924   
   893    925       /*
   894         -     * MacOSX doesn't use the keycodes for the modifiers for anything, and we
   895         -     * don't generate them either (the keycodes actually given in the simulated
   896         -     * modifier events are bogus). So there is no modifier map. If we ever want
   897         -     * to simulate real modifier keycodes, the list will be constant in the
   898         -     * Carbon implementation.
          926  +     * MacOSX doesn't create a key event when a modifier key is pressed or
          927  +     * released.  However, it is possible to generate key events for
          928  +     * modifier keys, and this is done in the tests.  So we construct an array
          929  +     * containing the keycodes of the standard modifier keys from static data.
   899    930        */
   900    931   
   901    932       if (dispPtr->modKeyCodes != NULL) {
   902    933   	ckfree(dispPtr->modKeyCodes);
   903    934       }
   904         -    dispPtr->numModKeyCodes = 0;
   905         -    dispPtr->modKeyCodes = NULL;
          935  +    dispPtr->numModKeyCodes = NUM_MOD_KEYCODES;
          936  +    dispPtr->modKeyCodes = (KeyCode *)ckalloc(NUM_MOD_KEYCODES * sizeof(KeyCode));
          937  +    for (int i = 0; i < NUM_MOD_KEYCODES; i++) {
          938  +	dispPtr->modKeyCodes[i] = modKeyArray[i];
          939  +    }
   906    940   }
   907    941   
   908    942   /*
   909    943    * Local Variables:
   910    944    * mode: objc
   911    945    * c-basic-offset: 4
   912    946    * fill-column: 79
   913    947    * coding: utf-8
   914    948    * End:
   915    949    */

Changes to macosx/tkMacOSXMenu.c.

    15     15   #include "tkMacOSXPrivate.h"
    16     16   #include "tkMenubutton.h"
    17     17   #include "tkMenu.h"
    18     18   #include "tkColor.h"
    19     19   #include "tkFont.h"
    20     20   #include "tkMacOSXWm.h"
    21     21   #include "tkMacOSXDebug.h"
           22  +#include "tkMacOSXConstants.h"
    22     23   
    23     24   /*
    24     25   #ifdef TK_MAC_DEBUG
    25     26   #define TK_MAC_DEBUG_MENUS
    26     27   #endif
    27     28   */
    28     29   
................................................................................
   112    113   @interface TKMenu(TKMenuPrivate)
   113    114   - (id) initWithTkMenu: (TkMenu *) tkMenu;
   114    115   - (TkMenu *) tkMenu;
   115    116   - (int) tkIndexOfItem: (NSMenuItem *) menuItem;
   116    117   - (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index;
   117    118   @end
   118    119   
   119         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
   120    120   #define TKMenu_NSMenuDelegate <NSMenuDelegate>
   121         -#else
   122         -#define TKMenu_NSMenuDelegate
   123         -#endif
   124    121   @interface TKMenu(TKMenuDelegate) TKMenu_NSMenuDelegate
   125    122   @end
   126    123   
   127    124   @implementation TKMenu
   128    125   - (void) setSpecial: (NSUInteger) special
   129    126   {
   130    127       NSAssert(!_tkSpecial, @"Cannot change specialness of a special menu");
................................................................................
   769    766       if (root == NULL) {
   770    767   	return TCL_ERROR;
   771    768       }
   772    769   
   773    770       Drawable d = Tk_WindowId(root);
   774    771       NSView *rootview = TkMacOSXGetRootControl(d);
   775    772       NSWindow *win = [rootview window];
          773  +    int result;
   776    774   
   777    775       inPostMenu = 1;
          776  +    
          777  +    result = TkPreprocessMenu(menuPtr);
          778  +    if (result != TCL_OK) {
          779  +        inPostMenu = 0;
          780  +        return result;
          781  +    }
   778    782   
   779    783       int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE);
   780    784       NSView *view = [win contentView];
   781    785       NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1);
   782    786   
   783    787       frame.origin = [view convertPoint:
   784    788   	    [win convertPointFromScreen:frame.origin] fromView:nil];

Changes to macosx/tkMacOSXMenus.c.

     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.
    12     12    */
    13     13   
    14     14   #include "tkMacOSXPrivate.h"
    15     15   #include "tkMenu.h"
           16  +#include "tkMacOSXConstants.h"
    16     17   
    17     18   static void		GenerateEditEvent(const char *name);
    18     19   static Tcl_Obj *	GetWidgetDemoPath(Tcl_Interp *interp);
    19     20   
    20     21   #pragma mark TKApplication(TKMenus)
    21     22   
    22     23   @implementation TKApplication(TKMenus)

Changes to macosx/tkMacOSXMouseEvent.c.

    11     11    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    12     12    */
    13     13   
    14     14   #include "tkMacOSXPrivate.h"
    15     15   #include "tkMacOSXWm.h"
    16     16   #include "tkMacOSXEvent.h"
    17     17   #include "tkMacOSXDebug.h"
           18  +#include "tkMacOSXConstants.h"
    18     19   
    19     20   typedef struct {
    20     21       unsigned int state;
    21     22       long delta;
    22     23       Window window;
    23     24       Point global;
    24     25       Point local;

Changes to macosx/tkMacOSXNotify.c.

    11     11    *
    12     12    * See the file "license.terms" for information on usage and redistribution
    13     13    * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14     14    */
    15     15   
    16     16   #include "tkMacOSXPrivate.h"
    17     17   #include "tkMacOSXEvent.h"
           18  +#include "tkMacOSXConstants.h"
    18     19   #include <tclInt.h>
    19         -#include <pthread.h>
    20     20   #import <objc/objc-auto.h>
    21     21   
    22     22   /* This is not used for anything at the moment. */
    23     23   typedef struct ThreadSpecificData {
    24     24       int initialized;
    25     25   } ThreadSpecificData;
    26     26   static Tcl_ThreadDataKey dataKey;
................................................................................
   136    136   	tsdPtr->initialized = 1;
   137    137   
   138    138   	/*
   139    139   	 * Install TkAqua event source in main event loop thread.
   140    140   	 */
   141    141   
   142    142   	if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) {
   143         -	    if (!pthread_main_np()) {
          143  +	    if (![NSThread isMainThread]) {
   144    144   		/*
   145    145   		 * Panic if main runloop is not on the main application thread.
   146    146   		 */
   147    147   
   148    148   		Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s",
   149    149   		    "first [load] of TkAqua has to occur in the main thread!");
   150    150   	    }
   151    151   	    Tcl_CreateEventSource(TkMacOSXEventsSetupProc,
   152    152   				  TkMacOSXEventsCheckProc,
   153         -				  GetMainEventQueue());
          153  +				  NULL);
   154    154   	    TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL);
   155    155   	    Tcl_SetServiceMode(TCL_SERVICE_ALL);
   156    156   	    TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode);
   157    157   	    TclMacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode);
   158    158   	}
   159    159       }
   160    160   }
................................................................................
   180    180   TkMacOSXNotifyExitHandler(
   181    181       ClientData clientData)	/* Not used. */
   182    182   {
   183    183       TSD_INIT();
   184    184   
   185    185       Tcl_DeleteEventSource(TkMacOSXEventsSetupProc,
   186    186   			  TkMacOSXEventsCheckProc,
   187         -			  GetMainEventQueue());
          187  +			  NULL);
   188    188       tsdPtr->initialized = 0;
   189    189   }
   190    190   
   191    191   /*
   192    192    *----------------------------------------------------------------------
   193    193    *
   194    194    * TkMacOSXEventsSetupProc --
................................................................................
   212    212   
   213    213   static void
   214    214   TkMacOSXEventsSetupProc(
   215    215       ClientData clientData,
   216    216       int flags)
   217    217   {
   218    218       NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
   219         -    /* runloopMode will be nil if we are in the Tcl event loop. */
          219  +    /* runloopMode will be nil if we are in a Tcl event loop. */
   220    220       if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
   221    221   	static const Tcl_Time zeroBlockTime = { 0, 0 };
          222  +	[NSApp _resetAutoreleasePool];
   222    223   	/* Call this with dequeue=NO -- just checking if the queue is empty. */
   223    224   	NSEvent *currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
   224    225   				       untilDate:[NSDate distantPast]
   225    226   				       inMode:GetRunLoopMode(TkMacOSXGetModalSession())
   226    227   				       dequeue:NO];
   227    228   	if (currentEvent) {
   228    229   	    if (currentEvent.type > 0) {
................................................................................
   252    253    */
   253    254   static void
   254    255   TkMacOSXEventsCheckProc(
   255    256       ClientData clientData,
   256    257       int flags)
   257    258   {
   258    259       NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode];
   259         -    /* runloopMode will be nil if we are in the Tcl event loop. */
          260  +    /* runloopMode will be nil if we are in a Tcl event loop. */
   260    261       if (flags & TCL_WINDOW_EVENTS && !runloopMode) {
   261    262   	NSEvent *currentEvent = nil;
   262    263   	NSEvent *testEvent = nil;
   263    264   	NSModalSession modalSession;
   264         -
          265  +	/* It is possible for the SetupProc to be called before this function
          266  +	 * returns.  This happens, for example, when we process an event which
          267  +	 * opens a modal window.  To prevent premature release of our
          268  +	 * application-wide autorelease pool by a nested call to the SetupProc,
          269  +	 * we must lock it here.
          270  +	 */
          271  +	[NSApp _lockAutoreleasePool];
   265    272   	do {
   266         -	    [NSApp _resetAutoreleasePool];
   267    273   	    modalSession = TkMacOSXGetModalSession();
   268         -	    testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
          274  +	    	    testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
   269    275   					      untilDate:[NSDate distantPast]
   270    276   						 inMode:GetRunLoopMode(modalSession)
   271    277   						dequeue:NO];
   272    278   	    /* We must not steal any events during LiveResize. */
   273         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
   274    279   	    if (testEvent && [[testEvent window] inLiveResize]) {
   275    280   		break;
   276    281   	    }
   277         -#else
   278         -	    if (testEvent && [[[testEvent window] contentView] inLiveResize]) {
   279         -		break;
   280         -	    }
   281         -#endif
   282    282   	    currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask
   283    283   					      untilDate:[NSDate distantPast]
   284    284   						 inMode:GetRunLoopMode(modalSession)
   285    285   						dequeue:YES];
   286    286   	    if (currentEvent) {
   287    287   		/* Generate Xevents. */
   288    288   		int oldServiceMode = Tcl_SetServiceMode(TCL_SERVICE_ALL);
................................................................................
   299    299   		    }
   300    300   		}
   301    301   		[currentEvent release];
   302    302   	    } else {
   303    303   		break;
   304    304   	    }
   305    305   	} while (1);
          306  +	/* Now we can unlock the pool. */
          307  +	[NSApp _unlockAutoreleasePool];
   306    308       }
   307    309   }
   308    310   
   309    311   
   310    312   /*
   311    313    * Local Variables:
   312    314    * mode: objc
   313    315    * c-basic-offset: 4
   314    316    * fill-column: 79
   315    317    * coding: utf-8
   316    318    * End:
   317    319    */

Changes to macosx/tkMacOSXPrivate.h.

    55     55   	if ((chk) && (cond)) { __VA_ARGS__
    56     56   #define tk_else_mac_os_x_chk(...) \
    57     57   	} else { __VA_ARGS__
    58     58   #define tk_if_mac_os_x_no(chk, cond, ...) \
    59     59   	if (0) {
    60     60   #define tk_else_mac_os_x_no(...) \
    61     61   	} else { __VA_ARGS__
    62         -/* Private mapping macros defined according to Mac OS X version requirements */
    63         -/* 10.5 Leopard */
    64         -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050
    65         -#define tk_if_mac_os_x_min_10_5		tk_if_mac_os_x_yes
    66         -#define tk_else_mac_os_x_min_10_5	tk_else_mac_os_x_yes
    67         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
    68         -#define tk_if_mac_os_x_10_5		tk_if_mac_os_x_yes
    69         -#define tk_else_mac_os_x_10_5		tk_else_mac_os_x_yes
    70         -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
    71         -#else /* MAC_OS_X_VERSION_MIN_REQUIRED */
    72         -#define tk_if_mac_os_x_min_10_5		tk_if_mac_os_x_chk
    73         -#define tk_else_mac_os_x_min_10_5	tk_else_mac_os_x_chk
    74         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050
    75         -#define tk_if_mac_os_x_10_5		tk_if_mac_os_x_chk
    76         -#define tk_else_mac_os_x_10_5		tk_else_mac_os_x_chk
    77         -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
    78         -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED */
    79         -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050
    80         -#define tk_if_mac_os_x_10_5		tk_if_mac_os_x_no
    81         -#define tk_else_mac_os_x_10_5		tk_else_mac_os_x_no
    82         -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */
    83     62   
    84     63   /*
    85     64    * Macros for DEBUG_ASSERT_MESSAGE et al from Debugging.h.
    86     65    */
    87     66   
    88     67   #undef kComponentSignatureString
    89     68   #undef COMPONENT_SIGNATURE
................................................................................
   205    184   			    int antiAlias);
   206    185   MODULE_SCOPE int	TkMacOSXGenerateFocusEvent(TkWindow *winPtr,
   207    186   			    int activeFlag);
   208    187   MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr);
   209    188   MODULE_SCOPE int	TkMacOSXIsWindowZoomed(TkWindow *winPtr);
   210    189   MODULE_SCOPE int	TkGenerateButtonEventForXPointer(Window window);
   211    190   MODULE_SCOPE EventModifiers TkMacOSXModifierState(void);
   212         -MODULE_SCOPE NSBitmapImageRep* BitmapRepFromDrawableRect(Drawable drawable,
          191  +MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable,
   213    192   			    int x, int y, unsigned int width, unsigned int height);
          193  +MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image,
          194  +			    int use_ximage_alpha);
          195  +MODULE_SCOPE void       TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context,
          196  +			    CGImageRef image, unsigned long imageForeground,
          197  +			    unsigned long imageBackground, CGRect imageBounds,
          198  +			    CGRect srcBounds, CGRect dstBounds);
   214    199   MODULE_SCOPE int	TkMacOSXSetupDrawingContext(Drawable d, GC gc,
   215    200   			    int useCG, TkMacOSXDrawingContext *dcPtr);
   216    201   MODULE_SCOPE void	TkMacOSXRestoreDrawingContext(
   217    202   			    TkMacOSXDrawingContext *dcPtr);
   218    203   MODULE_SCOPE void	TkMacOSXSetColorInContext(GC gc, unsigned long pixel,
   219    204   			    CGContextRef context);
   220    205   MODULE_SCOPE int	TkMacOSXMakeFullscreen(TkWindow *winPtr,
................................................................................
   224    209   			    int active);
   225    210   MODULE_SCOPE NSWindow*	TkMacOSXDrawableWindow(Drawable drawable);
   226    211   MODULE_SCOPE NSView*	TkMacOSXDrawableView(MacDrawable *macWin);
   227    212   MODULE_SCOPE void	TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds);
   228    213   MODULE_SCOPE HIShapeRef	TkMacOSXGetClipRgn(Drawable drawable);
   229    214   MODULE_SCOPE void	TkMacOSXInvalidateViewRegion(NSView *view,
   230    215   			    HIShapeRef rgn);
          216  +MODULE_SCOPE CGContextRef TkMacOSXGetCGContextForDrawable(Drawable drawable);
   231    217   MODULE_SCOPE CGImageRef	TkMacOSXCreateCGImageWithDrawable(Drawable drawable);
   232    218   MODULE_SCOPE NSImage*	TkMacOSXGetNSImageWithTkImage(Display *display,
   233    219   			    Tk_Image image, int width, int height);
   234    220   MODULE_SCOPE NSImage*	TkMacOSXGetNSImageWithBitmap(Display *display,
   235    221   			    Pixmap bitmap, GC gc, int width, int height);
   236    222   MODULE_SCOPE CGColorRef	TkMacOSXCreateCGColor(GC gc, unsigned long pixel);
   237    223   MODULE_SCOPE NSColor*	TkMacOSXGetNSColor(GC gc, unsigned long pixel);
................................................................................
   274    260       TKMenu *_defaultMainMenu, *_defaultApplicationMenu;
   275    261       NSArray *_defaultApplicationMenuItems, *_defaultWindowsMenuItems;
   276    262       NSArray *_defaultHelpMenuItems;
   277    263       NSWindow *_windowWithMouse;
   278    264       NSAutoreleasePool *_mainPool;
   279    265   #ifdef __i386__
   280    266       /* The Objective C runtime used on i386 requires this. */
   281         -    BOOL _poolProtected;
          267  +    int _poolLock;
   282    268   #endif
   283    269   }
   284         -@property BOOL poolProtected;
          270  +@property int poolLock;
          271  +
   285    272   @end
   286    273   @interface TKApplication(TKInit)
   287    274   - (NSString *)tkFrameworkImagePath:(NSString*)image;
   288    275   - (void)_resetAutoreleasePool;
          276  +- (void)_lockAutoreleasePool;
          277  +- (void)_unlockAutoreleasePool;
   289    278   @end
   290    279   @interface TKApplication(TKEvent)
   291    280   - (NSEvent *)tkProcessEvent:(NSEvent *)theEvent;
   292    281   @end
   293    282   @interface TKApplication(TKMouseEvent)
   294    283   - (NSEvent *)tkProcessMouseEvent:(NSEvent *)theEvent;
   295    284   @end
................................................................................
   337    326   @interface TKContentView(TKKeyEvent)
   338    327   - (void) deleteWorkingText;
   339    328   @end
   340    329   
   341    330   @interface TKContentView(TKWindowEvent)
   342    331   - (void) drawRect: (NSRect) rect;
   343    332   - (void) generateExposeEvents: (HIShapeRef) shape;
   344         -- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly;
   345    333   - (void) viewDidEndLiveResize;
   346    334   - (void) tkToolbarButton: (id) sender;
   347    335   - (BOOL) isOpaque;
   348    336   - (BOOL) wantsDefaultClipping;
   349    337   - (BOOL) acceptsFirstResponder;
   350    338   - (void) keyDown: (NSEvent *) theEvent;
   351    339   @end

Changes to macosx/tkMacOSXScale.c.

   167    167       /*
   168    168        * Invoke the scale's command if needed.
   169    169        */
   170    170   
   171    171       Tcl_Preserve((ClientData) scalePtr);
   172    172       if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) {
   173    173   	Tcl_Preserve((ClientData) interp);
   174         -	sprintf(string, scalePtr->format, scalePtr->value);
          174  +        if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format,
          175  +                scalePtr->value) < 0) {
          176  +            string[TCL_DOUBLE_SPACE - 1] = '\0';
          177  +        }
   175    178   	Tcl_DStringInit(&buf);
   176    179   	Tcl_DStringAppend(&buf, scalePtr->command, -1);
   177    180   	Tcl_DStringAppend(&buf, " ", -1);
   178    181   	Tcl_DStringAppend(&buf, string, -1);
   179    182   	result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0);
   180    183   	Tcl_DStringFree(&buf);
   181    184   	if (result != TCL_OK) {

Changes to macosx/tkMacOSXSubwindows.c.

   145    145       }
   146    146   
   147    147       display->request++;
   148    148       macWin->winPtr->flags |= TK_MAPPED;
   149    149       if (Tk_IsTopLevel(macWin->winPtr)) {
   150    150   	if (!Tk_IsEmbedded(macWin->winPtr)) {
   151    151   	    NSWindow *win = TkMacOSXDrawableWindow(window);
   152         -	    [NSApp activateIgnoringOtherApps:YES];
          152  +	    /*
          153  +	     * We want to activate Tk when a toplevel is mapped
          154  +	     * but we must not supply YES here.  This is because
          155  +	     * during Tk initialization the root window is mapped
          156  +	     * before applicationDidFinishLaunching returns. Forcing
          157  +	     * the app to activate too early can make the menu bar
          158  +	     * unresponsive.
          159  +	     */
          160  +	    [NSApp activateIgnoringOtherApps:NO];
   153    161   	    if ( [win canBecomeKeyWindow] ) {
   154    162   		[win makeKeyAndOrderFront:NSApp];
   155    163   	    }
   156    164   	    TkMacOSXApplyWindowAttributes(macWin->winPtr, win);
          165  +	} else {
          166  +	    /*
          167  +	     * Rebuild the container's clipping region and display
          168  +	     * the window.
          169  +	     */
          170  +	    TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr);
          171  +	    TkMacOSXInvalClipRgns((Tk_Window)contWinPtr);
          172  +	    TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
   157    173   	}
   158    174   	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr);
   159    175   
   160    176   	/*
   161    177   	 * We only need to send the MapNotify event for toplevel windows.
   162    178   	 */
   163    179   
................................................................................
   168    184   	event.xmap.window = window;
   169    185   	event.xmap.type = MapNotify;
   170    186   	event.xmap.event = window;
   171    187   	event.xmap.override_redirect = macWin->winPtr->atts.override_redirect;
   172    188   	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
   173    189       } else {
   174    190   	/*
   175         -	 * Generate damage for that area of the window.
          191  +	 * Rebuild the parent's clipping region and display the window.
          192  +	 *
   176    193   	 */
   177    194   
   178    195   	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
   179    196   	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
   180    197       }
   181    198   
   182    199       /*
................................................................................
   243    260   
   244    261   void
   245    262   XUnmapWindow(
   246    263       Display *display,		/* Display. */
   247    264       Window window)		/* Window. */
   248    265   {
   249    266       MacDrawable *macWin = (MacDrawable *) window;
          267  +    TkWindow *winPtr = macWin->winPtr;
          268  +    TkWindow *parentPtr = winPtr->parentPtr;
   250    269       XEvent event;
   251    270   
   252    271       display->request++;
   253         -    macWin->winPtr->flags &= ~TK_MAPPED;
   254         -    if (Tk_IsTopLevel(macWin->winPtr)) {
   255         -	if (!Tk_IsEmbedded(macWin->winPtr) &&
   256         -		macWin->winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
          272  +    if (Tk_IsTopLevel(winPtr)) {
          273  +	if (!Tk_IsEmbedded(winPtr) &&
          274  +		winPtr->wmInfoPtr->hints.initial_state!=IconicState) {
   257    275   	    NSWindow *win = TkMacOSXDrawableWindow(window);
   258    276   
   259    277   	    if ([win isVisible]) {
   260    278   		[[win parentWindow] removeChildWindow:win];
   261    279   		[win orderOut:NSApp];
   262    280   	    }
   263    281   	}
   264         -	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr);
          282  +	TkMacOSXInvalClipRgns((Tk_Window) winPtr);
   265    283   
   266    284   	/*
   267    285   	 * We only need to send the UnmapNotify event for toplevel windows.
   268    286   	 */
   269    287   
   270    288   	event.xany.serial = LastKnownRequestProcessed(display);
   271    289   	event.xany.send_event = False;
................................................................................
   274    292   	event.xunmap.type = UnmapNotify;
   275    293   	event.xunmap.window = window;
   276    294   	event.xunmap.event = window;
   277    295   	event.xunmap.from_configure = false;
   278    296   	Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
   279    297       } else {
   280    298   	/*
   281         -	 * Generate damage for that area of the window.
          299  +	 * Rebuild the visRgn clip region for the parent so it will be allowed
          300  +	 * to draw in the space from which this subwindow was removed.
   282    301   	 */
   283         -
   284         -	TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW);
   285         -	TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr);
          302  +	if (parentPtr && parentPtr->privatePtr->visRgn) {
          303  +	    TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(parentPtr->privatePtr),
          304  +					 parentPtr->privatePtr->visRgn);
          305  +	}
          306  +	TkMacOSXInvalClipRgns((Tk_Window) parentPtr);
          307  +	TkMacOSXUpdateClipRgn(parentPtr);
   286    308       }
          309  +    winPtr->flags &= ~TK_MAPPED;
   287    310   }
   288    311   
   289    312   /*
   290    313    *----------------------------------------------------------------------
   291    314    *
   292    315    * XResizeWindow --
   293    316    *
................................................................................
   765    788   	     * the stacking order. For an embedded toplevel, just clip to the
   766    789   	     * container's visible clip region. Remember, we only allow one
   767    790   	     * contained window in a frame, and don't support any other widgets
   768    791   	     * in the frame either. This is not currently enforced, however.
   769    792   	     */
   770    793   
   771    794   	    if (!Tk_IsTopLevel(winPtr)) {
   772         -		TkMacOSXUpdateClipRgn(winPtr->parentPtr);
   773    795   		if (winPtr->parentPtr) {
          796  +		    TkMacOSXUpdateClipRgn(winPtr->parentPtr);
   774    797   		    ChkErr(HIShapeIntersect,
   775    798   			    winPtr->parentPtr->privatePtr->aboveVisRgn,
   776    799   			    rgn, rgn);
   777    800   		}
   778    801   		win2Ptr = winPtr;
   779    802   		while ((win2Ptr = win2Ptr->nextPtr)) {
   780    803   		    if (Tk_IsTopLevel(win2Ptr) || !Tk_IsMapped(win2Ptr)) {

Changes to macosx/tkMacOSXWindowEvent.c.

    13     13    * this file, and for a DISCLAIMER OF ALL WARRANTIES.
    14     14    */
    15     15   
    16     16   #include "tkMacOSXPrivate.h"
    17     17   #include "tkMacOSXWm.h"
    18     18   #include "tkMacOSXEvent.h"
    19     19   #include "tkMacOSXDebug.h"
           20  +#include "tkMacOSXConstants.h"
    20     21   
    21     22   /*
    22     23   #ifdef TK_MAC_DEBUG
    23     24   #define TK_MAC_DEBUG_EVENTS
    24     25   #define TK_MAC_DEBUG_DRAWING
    25     26   #endif
    26     27   */
................................................................................
    37     38   
    38     39   #pragma mark TKApplication(TKWindowEvent)
    39     40   
    40     41   #ifdef TK_MAC_DEBUG_NOTIFICATIONS
    41     42   extern NSString *NSWindowWillOrderOnScreenNotification;
    42     43   extern NSString *NSWindowDidOrderOnScreenNotification;
    43     44   extern NSString *NSWindowDidOrderOffScreenNotification;
           45  +#endif
    44     46   
    45         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
    46         -#define NSWindowWillStartLiveResizeNotification @"NSWindowWillStartLiveResizeNotification"
    47         -#define NSWindowDidEndLiveResizeNotification  @"NSWindowDidEndLiveResizeNotification"
    48         -#endif
    49         -#endif
    50         -
    51         -extern BOOL opaqueTag;
    52     47   
    53     48   @implementation TKApplication(TKWindowEvent)
    54     49   
    55     50   - (void) windowActivation: (NSNotification *) notification
    56     51   {
    57     52   #ifdef TK_MAC_DEBUG_NOTIFICATIONS
    58     53       TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification);
................................................................................
   353    348       CFRelease(boundsRgn);
   354    349   
   355    350       event.xany.serial = LastKnownRequestProcessed(Tk_Display(winPtr));
   356    351       event.xany.send_event = false;
   357    352       event.xany.window = Tk_WindowId(winPtr);
   358    353       event.xany.display = Tk_Display(winPtr);
   359    354       event.type = Expose;
   360         -    event.xexpose.x = damageBounds.origin.x;
   361         -    event.xexpose.y = damageBounds.origin.y;
          355  +    event.xexpose.x = damageBounds.origin.x - bounds.origin.x;
          356  +    event.xexpose.y = damageBounds.origin.y - bounds.origin.y;
   362    357       event.xexpose.width = damageBounds.size.width;
   363    358       event.xexpose.height = damageBounds.size.height;
   364    359       event.xexpose.count = 0;
   365         -    Tk_HandleEvent(&event);
          360  +    Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
   366    361   
   367    362   #ifdef TK_MAC_DEBUG_DRAWING
   368    363       NSLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x,
   369    364   	event.xexpose.y, event.xexpose.width, event.xexpose.height);
   370    365   #endif
   371    366   
   372    367       /*
................................................................................
   745    740    *
   746    741    *----------------------------------------------------------------------
   747    742    */
   748    743   
   749    744   int
   750    745   Tk_MacOSXIsAppInFront(void)
   751    746   {
   752         -    Boolean isFrontProcess = true;
   753         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
   754         -    ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess};
   755         -
   756         -    if (noErr == GetFrontProcess(&frontPsn)){
   757         -	SameProcess(&frontPsn, &ourPsn, &isFrontProcess);
   758         -    }
   759         -#else
   760         -    isFrontProcess = [NSRunningApplication currentApplication].active;
   761         -#endif
   762         -    return (isFrontProcess == true);
          747  +    return ([NSRunningApplication currentApplication].active == true);
   763    748   }
   764    749   
   765    750   #pragma mark TKContentView
   766    751   
   767    752   #import <ApplicationServices/ApplicationServices.h>
   768    753   
   769    754   /*
................................................................................
   854    839   	ClientData oldArg;
   855    840       	Tk_RestrictProc *oldProc;
   856    841   
   857    842   	/* This can be called from outside the Tk event loop.
   858    843   	 * Since it calls Tcl_DoOneEvent, we need to make sure we
   859    844   	 * don't clobber the AutoreleasePool set up by the caller.
   860    845   	 */
   861         -	[NSApp setPoolProtected:YES];
          846  +	[NSApp _lockAutoreleasePool];
   862    847   
   863    848   	/*
   864    849   	 * Try to prevent flickers and flashes.
   865    850   	 */
   866    851   	[w disableFlushWindow];
   867    852   	NSDisableScreenUpdates();
   868    853   
................................................................................
   885    870   	HIRect bounds = NSRectToCGRect([self bounds]);
   886    871   	HIShapeRef shape = HIShapeCreateWithRect(&bounds);
   887    872   	[self generateExposeEvents: shape];
   888    873   	while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {}
   889    874   	[w enableFlushWindow];
   890    875   	[w flushWindowIfNeeded];
   891    876   	NSEnableScreenUpdates();
   892         -	[NSApp setPoolProtected:NO];
          877  +	[NSApp _unlockAutoreleasePool];
   893    878       }
   894    879   }
   895    880   
   896    881   /*
   897    882    * As insurance against bugs that might cause layout glitches during a live
   898    883    * resize, we redraw the window one more time at the end of the resize
   899    884    * operation.
................................................................................
   910    895   /* Core method of this class: generates expose events for redrawing.  If the
   911    896    * Tcl_ServiceMode is set to TCL_SERVICE_ALL then the expose events will be
   912    897    * immediately removed from the Tcl event loop and processed.  Typically, they
   913    898    * should be queued, however.
   914    899    */
   915    900   - (void) generateExposeEvents: (HIShapeRef) shape
   916    901   {
   917         -    [self generateExposeEvents:shape childrenOnly:0];
   918         -}
   919         -
   920         -- (void) generateExposeEvents: (HIShapeRef) shape
   921         -		 childrenOnly: (int) childrenOnly
   922         -{
   923         -    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
   924    902       unsigned long serial;
   925    903       CGRect updateBounds;
   926    904       int updatesNeeded;
          905  +    TkWindow *winPtr = TkMacOSXGetTkWindow([self window]);
   927    906   
   928    907       if (!winPtr) {
   929    908   		return;
   930    909       }
   931    910   
   932    911       /* Generate Tk Expose events. */
   933    912       HIShapeGetBounds(shape, &updateBounds);
................................................................................
   975    954       Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL);
   976    955   }
   977    956   
   978    957   - (BOOL) isOpaque
   979    958   {
   980    959       NSWindow *w = [self window];
   981    960   
   982         -    if (opaqueTag) {
   983         -      return YES;
   984         -	} else {
   985         -
   986         -     return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) ||
          961  +      return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) ||
   987    962       	    ![w isOpaque]) ? NO : YES);
   988         -    }
   989    963   }
   990    964   
   991    965   - (BOOL) wantsDefaultClipping
   992    966   {
   993    967       return NO;
   994    968   }
   995    969   

Changes to macosx/tkMacOSXWm.c.

     6      6    *	the "wm" command and passes geometry information to the window
     7      7    *	manager.
     8      8    *
     9      9    * Copyright (c) 1994-1997 Sun Microsystems, Inc.
    10     10    * Copyright 2001-2009, Apple Inc.
    11     11    * Copyright (c) 2006-2009 Daniel A. Steffen <[email protected]>
    12     12    * Copyright (c) 2010 Kevin Walzer/WordTech Communications LLC.
           13  + * Copyright (c) 2017 Marc Culler.
    13     14    *
    14     15    * See the file "license.terms" for information on usage and redistribution
    15     16    * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    16     17    */
    17     18   
    18     19   #include "tkMacOSXPrivate.h"
    19     20   #include "tkScrollbar.h"
    20     21   #include "tkMacOSXWm.h"
    21     22   #include "tkMacOSXEvent.h"
    22     23   #include "tkMacOSXDebug.h"
           24  +#include "tkMacOSXConstants.h"
    23     25   
    24     26   #define DEBUG_ZOMBIES 0
    25     27   
    26     28   /*
    27     29   #ifdef TK_MAC_DEBUG
    28     30   #define TK_MAC_DEBUG_WINDOWS
    29     31   #endif
................................................................................
    49     51   	| kWindowHideOnFullScreenAttribute  | kWindowNoConstrainAttribute \
    50     52   	| kWindowNoShadowAttribute	    | kWindowLiveResizeAttribute \
    51     53   	| kWindowOpaqueForEventsAttribute   | kWindowIgnoreClicksAttribute \
    52     54   	| kWindowDoesNotCycleAttribute	    | tkWindowDoesNotHideAttribute \
    53     55   	| tkCanJoinAllSpacesAttribute	    | tkMoveToActiveSpaceAttribute \
    54     56   	| tkNonactivatingPanelAttribute	    | tkHUDWindowAttribute)
    55     57   
    56         -/*Objects for use in setting background color and opacity of window.*/
    57         -NSColor *colorName = NULL;
    58         -BOOL opaqueTag = FALSE;
    59     58   
    60     59   static const struct {
    61     60       const UInt64 validAttrs, defaultAttrs, forceOnAttrs, forceOffAttrs;
    62     61       int flags; NSUInteger styleMask;
    63     62   } macClassAttrs[] = {
    64     63       [kAlertWindowClass] = {
    65     64   	.defaultAttrs = kWindowDoesNotCycleAttribute, },
................................................................................
   193    192    * Hash table for Mac Window -> TkWindow mapping.
   194    193    */
   195    194   
   196    195   static Tcl_HashTable windowTable;
   197    196   static int windowHashInit = false;
   198    197   
   199    198   
   200         -
   201    199   #pragma mark NSWindow(TKWm)
   202    200   
   203    201   /*
   204    202    * Conversion of coordinates between window and screen.
   205    203    */
   206    204   
   207    205   @implementation NSWindow(TKWm)
................................................................................
   210    208   {
   211    209       return [self convertBaseToScreen:point];
   212    210   }
   213    211   - (NSPoint) convertPointFromScreen: (NSPoint)point
   214    212   {
   215    213       return [self convertScreenToBase:point];
   216    214   }
   217         -@end
   218    215   #else
   219    216   - (NSPoint) convertPointToScreen: (NSPoint) point
   220    217   {
   221    218       NSRect pointrect;
   222    219       pointrect.origin = point;
   223    220       pointrect.size.width = 0;
   224    221       pointrect.size.height = 0;
................................................................................
   228    225   {
   229    226       NSRect pointrect;
   230    227       pointrect.origin = point;
   231    228       pointrect.size.width = 0;
   232    229       pointrect.size.height = 0;
   233    230       return [self convertRectFromScreen:pointrect].origin;
   234    231   }
   235         -@end
   236    232   #endif
          233  +
          234  +@end
   237    235   
   238    236   #pragma mark -
   239    237   
   240    238   
   241    239   /*
   242    240    * Forward declarations for procedures defined in this file:
   243    241    */
................................................................................
   360    358   static void		GetMinSize(TkWindow *winPtr, int *minWidthPtr,
   361    359   			    int *minHeightPtr);
   362    360   static void		GetMaxSize(TkWindow *winPtr, int *maxWidthPtr,
   363    361   			    int *maxHeightPtr);
   364    362   static void		RemapWindows(TkWindow *winPtr,
   365    363   			    MacDrawable *parentWin);
   366    364   
   367         -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060
   368         -#define TK_GOT_AT_LEAST_SNOW_LEOPARD 1
   369         -#endif
   370         -
   371    365   #pragma mark TKWindow(TKWm)
   372    366   
   373         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
   374         -@interface NSWindow(TkWm)
   375         -- (void) setCanCycle: (BOOL) canCycleFlag;
   376         -@end
   377         -#endif
   378         -
   379    367   @interface NSDrawerWindow : NSWindow
   380    368   {
   381    369       id _i1, _i2;
   382    370   }
   383    371   @end
   384    372   
   385         -@implementation TKWindow
          373  +
          374  +@implementation TKWindow: NSWindow
          375  +#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12
          376  +/*
          377  + * Override automatic fullscreen button on >10.12 because system fullscreen API
          378  + * confuses Tk window geometry.
          379  + */
          380  +- (void)toggleFullScreen:(id)sender
          381  +{
          382  +    if ([self isZoomed]) {
          383  +	TkMacOSXZoomToplevel(self, inZoomIn);
          384  +    } else {
          385  +	TkMacOSXZoomToplevel(self, inZoomOut);
          386  +    }
          387  +}
          388  +#endif
   386    389   @end
   387    390   
   388    391   @implementation TKWindow(TKWm)
   389    392   
   390    393   - (BOOL) canBecomeKeyWindow
   391    394   {
   392    395       TkWindow *winPtr = TkMacOSXGetTkWindow(self);
   393    396   
   394    397       return (winPtr && winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass ==
   395    398   	    kHelpWindowClass || winPtr->wmInfoPtr->attributes &
   396    399   	    kWindowNoActivatesAttribute)) ? NO : YES;
   397    400   }
          401  +
          402  +
   398    403   
   399    404   #if DEBUG_ZOMBIES
   400    405   - (id) retain
   401    406   {
   402    407       id result = [super retain];
   403    408       const char *title = [[self title] UTF8String];
   404    409       if (title == nil) {
................................................................................
   408    413   	printf("Retained <%s>. Count is: %lu\n", title, [self retainCount]);
   409    414       }
   410    415       return result;
   411    416   }
   412    417   
   413    418   - (id) autorelease
   414    419   {
   415         -    static int xcount = 0;
   416    420       id result = [super autorelease];
   417    421       const char *title = [[self title] UTF8String];
   418    422       if (title == nil) {
   419    423   	title = "unnamed window";
   420    424       }
   421    425       if (DEBUG_ZOMBIES > 1){
   422    426   	printf("Autoreleased <%s>. Count is %lu\n", title, [self retainCount]);
................................................................................
   763    767   
   764    768       /*
   765    769        * Map the window.
   766    770        */
   767    771   
   768    772       XMapWindow(winPtr->display, winPtr->window);
   769    773   
          774  +    /*Add window to Window menu.*/
          775  +    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
          776  +    [win setExcludedFromWindowsMenu:NO];
          777  +
   770    778   }
   771    779   
   772    780   /*
   773    781    *----------------------------------------------------------------------
   774    782    *
   775    783    * TkWmUnmapWindow --
   776    784    *
................................................................................
   873    881       NSWindow *window = wmPtr->window;
   874    882   
   875    883       if (window && !Tk_IsEmbedded(winPtr) ) {
   876    884   	NSWindow *parent = [window parentWindow];
   877    885   	if (parent) {
   878    886   	    [parent removeChildWindow:window];
   879    887   	}
   880         -	[window close];
   881         -	TkMacOSXUnregisterMacWindow(window);
   882         -        if (winPtr->window) {
   883         -            ((MacDrawable *) winPtr->window)->view = nil;
   884         -        }
   885    888   #if DEBUG_ZOMBIES > 0
   886    889   	{
   887    890   	    const char *title = [[window title] UTF8String];
   888    891   	    if (title == nil) {
   889    892   		title = "unnamed window";
   890    893   	    }
   891    894   	    printf(">>>> Closing <%s>. Count is: %lu\n", title, [window retainCount]);
   892    895   	}
   893    896   #endif
   894         -        [window release];
          897  +	[window close];
          898  +	TkMacOSXUnregisterMacWindow(window);
          899  +        if (winPtr->window) {
          900  +            ((MacDrawable *) winPtr->window)->view = nil;
          901  +        }
   895    902   	wmPtr->window = NULL;
          903  +        [window release];
   896    904   
   897    905   	/* Activate the highest window left on the screen. */
   898    906   	NSArray *windows = [NSApp orderedWindows];
   899         -	if ( [windows count] > 0 ) {
   900         -	    NSWindow *front = [windows objectAtIndex:0];
   901         -	    if ( front && [front canBecomeKeyWindow] ) {
   902         -		[front makeKeyAndOrderFront:NSApp];
          907  +	for (id nswindow in windows) {
          908  +	    TkWindow *winPtr2 = TkMacOSXGetTkWindow(nswindow);
          909  +	    if (winPtr2 && nswindow != window) {
          910  +		WmInfo *wmPtr = winPtr2->wmInfoPtr;
          911  +		BOOL minimized = (wmPtr->hints.initial_state == IconicState ||
          912  +				  wmPtr->hints.initial_state == WithdrawnState);
          913  +		/*
          914  +		 * If no windows are left on the screen and the next
          915  +		 * window is iconified or withdrawn, we don't want to
          916  +		 * make it be the KeyWindow because that would cause
          917  +		 * it to be displayed on the screen.
          918  +		 */
          919  +		if ([nswindow canBecomeKeyWindow] && !minimized) {
          920  +		    [nswindow makeKeyAndOrderFront:NSApp];
          921  +		    break;
          922  +		}
   903    923   	    }
   904    924   	}
          925  +	/*
          926  +	 * Process all window events immediately to force the closed window to
          927  +	 * be deallocated.  But don't do this for the root window as that is
          928  +	 * unnecessary and can lead to segfaults.
          929  +	 */
          930  +	if (winPtr->parentPtr) {
          931  +	    while (Tk_DoOneEvent(TK_WINDOW_EVENTS|TK_DONT_WAIT)) {}
          932  +	}
   905    933   	[NSApp _resetAutoreleasePool];
   906    934   
   907    935   #if DEBUG_ZOMBIES > 0
   908    936   	fprintf(stderr, "================= Pool dump ===================\n");
   909    937   	[NSAutoreleasePool showPools];
   910    938   #endif
   911    939       }
................................................................................
  1931   1959       TkWindow *winPtr,		/* Toplevel to work with */
  1932   1960       Tcl_Interp *interp,		/* Current interpreter. */
  1933   1961       int objc,			/* Number of arguments. */
  1934   1962       Tcl_Obj *const objv[])	/* Argument objects. */
  1935   1963   {
  1936   1964       register WmInfo *wmPtr = winPtr->wmInfoPtr;
  1937   1965       int reqWidth, reqHeight, widthInc, heightInc;
  1938         -    char *errorMsg;
         1966  +    const char *errorMsg;
  1939   1967   
  1940   1968       if ((objc != 3) && (objc != 7)) {
  1941   1969   	Tcl_WrongNumArgs(interp, 2, objv,
  1942   1970   		"window ?baseWidth baseHeight widthInc heightInc?");
  1943   1971   	return TCL_ERROR;
  1944   1972       }
  1945   1973       if (objc == 3) {
................................................................................
  2310   2338   
  2311   2339   /*
  2312   2340    *----------------------------------------------------------------------
  2313   2341    *
  2314   2342    * WmIconphotoCmd --
  2315   2343    *
  2316   2344    *	This procedure is invoked to process the "wm iconphoto" Tcl command.
  2317         - *	See the user documentation for details on what it does. Not yet
  2318         - *	implemented for OS X.
         2345  + *	See the user documentation for details on what it does.
  2319   2346    *
  2320   2347    * Results:
  2321   2348    *	A standard Tcl result.
  2322   2349    *
  2323   2350    * Side effects:
  2324   2351    *	See the user documentation.
         2352  + *
  2325   2353    *
  2326   2354    *----------------------------------------------------------------------
  2327   2355    */
  2328   2356   
  2329   2357   static int
  2330   2358   WmIconphotoCmd(
  2331   2359       Tk_Window tkwin,		/* Main window of the application. */
  2332   2360       TkWindow *winPtr,		/* Toplevel to work with */
  2333   2361       Tcl_Interp *interp,		/* Current interpreter. */
  2334   2362       int objc,			/* Number of arguments. */
  2335   2363       Tcl_Obj *const objv[])	/* Argument objects. */
  2336   2364   {
  2337         -    Tk_PhotoHandle photo;
  2338         -    int i, width, height, isDefault = 0;
         2365  +    Tk_Image tk_icon;
         2366  +    int width, height, isDefault = 0;
  2339   2367   
  2340   2368       if (objc < 4) {
  2341   2369   	Tcl_WrongNumArgs(interp, 2, objv,
  2342         -		"window ?-default? image1 ?image2 ...?");
         2370  +			 "window ?-default? image1 ?image2 ...?");
  2343   2371   	return TCL_ERROR;
  2344   2372       }
         2373  +
         2374  +    /*Parse args.*/
  2345   2375       if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
  2346   2376   	isDefault = 1;
  2347   2377   	if (objc == 4) {
  2348   2378   	    Tcl_WrongNumArgs(interp, 2, objv,
  2349         -		    "window ?-default? image1 ?image2 ...?");
  2350         -	    return TCL_ERROR;
  2351         -	}
  2352         -    }
  2353         -
  2354         -    /*
  2355         -     * Iterate over all images to retrieve their sizes, in order to allocate a
  2356         -     * buffer large enough to hold all images.
  2357         -     */
  2358         -
  2359         -    for (i = 3 + isDefault; i < objc; i++) {
  2360         -	photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i]));
  2361         -	if (photo == NULL) {
  2362         -	    Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  2363         -		    "can't use \"%s\" as iconphoto: not a photo image",
  2364         -		    Tcl_GetString(objv[i])));
  2365         -	    Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL);
  2366         -	    return TCL_ERROR;
  2367         -	}
  2368         -	Tk_PhotoGetSize(photo, &width, &height);
  2369         -    }
  2370         -
  2371         -    /*
  2372         -     * TODO: This requires implementation for OS X, but we silently return for
  2373         -     * now.
  2374         -     */
  2375         -
         2379  +			     "window ?-default? image1 ?image2 ...?");
         2380  +	    return TCL_ERROR;
         2381  +	}
         2382  +    }
         2383  +
         2384  +    /*Get icon name. We only use the first icon name because macOS does not
         2385  +      support multiple images in Tk photos.*/
         2386  +    char *icon;
         2387  +    if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) {
         2388  +	icon = Tcl_GetString(objv[4]);
         2389  +    }	else {
         2390  +	icon = Tcl_GetString(objv[3]);
         2391  +    }
         2392  +
         2393  +    /*Get image and convert to NSImage that can be displayed as icon.*/
         2394  +    tk_icon = Tk_GetImage(interp, tkwin, icon, NULL, NULL);
         2395  +    if (tk_icon == NULL) {
         2396  +    	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
         2397  +	      "can't use \"%s\" as iconphoto: not a photo image",
         2398  +	      icon));
         2399  +	Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL);
         2400  +	return TCL_ERROR;
         2401  +    }
         2402  +
         2403  +    NSImage *newIcon;
         2404  +    Tk_SizeOfImage(tk_icon, &width, &height);
         2405  +    newIcon = TkMacOSXGetNSImageWithTkImage(winPtr->display, tk_icon, width, height);
         2406  +    Tk_FreeImage(tk_icon);
         2407  +    if (newIcon == NULL) {
         2408  +	return TCL_ERROR;
         2409  +    }
         2410  +    [NSApp setApplicationIconImage: newIcon];
  2376   2411       return TCL_OK;
  2377   2412   }
  2378   2413   
  2379   2414   /*
  2380   2415    *----------------------------------------------------------------------
  2381   2416    *
  2382   2417    * WmIconpositionCmd --
................................................................................
  3471   3506   	Tcl_SetObjResult(interp, Tcl_ObjPrintf(
  3472   3507   		"can't withdraw %s: it is an icon for %s",
  3473   3508   		Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor)));
  3474   3509   	Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL);
  3475   3510   	return TCL_ERROR;
  3476   3511       }
  3477   3512       TkpWmSetState(winPtr, WithdrawnState);
         3513  +    /*Remove window from Window menu.*/
         3514  +    NSWindow *win = TkMacOSXDrawableWindow(winPtr->window);
         3515  +    [win setExcludedFromWindowsMenu:YES];
         3516  +
  3478   3517       return TCL_OK;
  3479   3518   }
  3480   3519   
  3481   3520   /*
  3482   3521    * Invoked by those wm subcommands that affect geometry.
  3483   3522    * Schedules a geometry update.
  3484   3523    */
................................................................................
  4631   4670       int aboveBelow,		/* Gives relative position for restacking;
  4632   4671   				 * must be Above or Below. */
  4633   4672       TkWindow *otherPtr)		/* Window relative to which to restack; if
  4634   4673   				 * NULL, then winPtr gets restacked above or
  4635   4674   				 * below *all* siblings. */
  4636   4675   {
  4637   4676       NSWindow *macWindow;
  4638         -    NSInteger otherMacWindowNumber;
         4677  +    NSWindow *otherMacWindow;
         4678  +    WmInfo *wmPtr = winPtr->wmInfoPtr;
         4679  +    int macAboveBelow = (aboveBelow == Above ? NSWindowAbove : NSWindowBelow);
         4680  +    int otherNumber = 0; /* 0 will be used when otherPtr is NULL. */
  4639   4681   
  4640   4682       /*
  4641         -     * Get the mac window. Make sure it exists & is mapped.
         4683  +     * If the Tk windows has no drawable, or is withdrawn do nothing.
  4642   4684        */
  4643         -
  4644         -    if (winPtr->window == None) {
  4645         -	Tk_MakeWindowExist((Tk_Window) winPtr);
  4646         -    }
  4647         -    if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
  4648         -	/*
  4649         -	 * Can't set stacking order properly until the window is on the screen
  4650         -	 * (mapping it may give it a reparent window), so make sure it's on
  4651         -	 * the screen.
  4652         -	 */
  4653         -
  4654         -	TkWmMapWindow(winPtr);
         4685  +    if (winPtr->window == None ||
         4686  +	wmPtr == NULL          ||
         4687  +	wmPtr->hints.initial_state == WithdrawnState) {
         4688  +	return;
  4655   4689       }
  4656   4690       macWindow = TkMacOSXDrawableWindow(winPtr->window);
  4657         -
  4658         -    /*
  4659         -     * Get the window in which a raise or lower is in relation to.
  4660         -     */
  4661         -
  4662         -    if (otherPtr != NULL) {
  4663         -	if (otherPtr->window == None) {
  4664         -	    Tk_MakeWindowExist((Tk_Window) otherPtr);
  4665         -	}
  4666         -	if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) {
  4667         -	    TkWmMapWindow(otherPtr);
  4668         -	}
  4669         -	otherMacWindowNumber = [TkMacOSXDrawableWindow(otherPtr->window)
  4670         -		windowNumber];
  4671         -    } else {
  4672         -	otherMacWindowNumber = 0;
  4673         -    }
  4674         -    [macWindow orderWindow:(aboveBelow == Above ? NSWindowAbove : NSWindowBelow)
  4675         -	    relativeTo:otherMacWindowNumber];
         4691  +    if (macWindow == nil) {
         4692  +	return;
         4693  +    }
         4694  +    if (otherPtr) {
         4695  +	/*
         4696  +	 * When otherPtr is non-NULL, if the other window has no
         4697  +	 * drawable or is withdrawn, do nothing.
         4698  +	 */
         4699  +	WmInfo *otherWmPtr = otherPtr->wmInfoPtr;
         4700  +	if (winPtr->window == None ||
         4701  +	    otherWmPtr == NULL     ||
         4702  +	    otherWmPtr->hints.initial_state == WithdrawnState) {
         4703  +	return;
         4704  +	}
         4705  +	otherMacWindow = TkMacOSXDrawableWindow(otherPtr->window);
         4706  +	if (otherMacWindow == nil) {
         4707  +	    return;
         4708  +	} else {
         4709  +	    /*
         4710  +	     * If the other window is OK, get its number.
         4711  +	     */
         4712  +	    otherNumber = [otherMacWindow windowNumber];
         4713  +	}
         4714  +    }
         4715  +
         4716  +    /*
         4717  +     * Just let the Mac window manager deal with all the subtleties
         4718  +     * of keeping track of off-screen windows, etc.
         4719  +     */
         4720  +    [macWindow orderWindow:macAboveBelow relativeTo:otherNumber];
  4676   4721   }
  4677   4722   
  4678   4723   /*
  4679   4724    *----------------------------------------------------------------------
  4680   4725    *
  4681   4726    * TkWmAddToColormapWindows --
  4682   4727    *
................................................................................
  5088   5133   }
  5089   5134   
  5090   5135   /*
  5091   5136    *----------------------------------------------------------------------
  5092   5137    *
  5093   5138    * TkMacOSXIsWindowZoomed --
  5094   5139    *
  5095         - *	Ask Carbon if the given window is in the zoomed out state. Because
  5096         - *	dragging & growing a window can change the Carbon zoom state, we
         5140  + *	Ask Cocoa if the given window is in the zoomed out state. Because
         5141  + *	dragging & growing a window can change the Cocoa zoom state, we
  5097   5142    *	cannot rely on wmInfoPtr->hints.initial_state for this information.
  5098   5143    *
  5099   5144    * Results:
  5100   5145    *	True if window is zoomed out, false otherwise.
  5101   5146    *
  5102   5147    * Side effects:
  5103   5148    *	None.
................................................................................
  5107   5152   
  5108   5153   MODULE_SCOPE int
  5109   5154   TkMacOSXIsWindowZoomed(
  5110   5155       TkWindow *winPtr)
  5111   5156   {
  5112   5157       return [TkMacOSXDrawableWindow(winPtr->window) isZoomed];
  5113   5158   }
         5159  +
  5114   5160   
  5115   5161   /*
  5116   5162    *----------------------------------------------------------------------
  5117   5163    *
  5118   5164    * TkMacOSXZoomToplevel --
  5119   5165    *
  5120   5166    *	The function is invoked when the user clicks in the zoom region of a
................................................................................
  5149   5195   	return false;
  5150   5196       }
  5151   5197   
  5152   5198       /*
  5153   5199        * Do nothing if already in desired zoom state.
  5154   5200        */
  5155   5201   
  5156         -    if (![window isZoomed] == (zoomPart == inZoomIn)) {
         5202  +    if ((![window isZoomed] == (zoomPart == inZoomIn))) {
  5157   5203   	return false;
  5158   5204       }
  5159         -    [window zoom:NSApp];
  5160         -    wmPtr->hints.initial_state =
  5161         -	    (zoomPart == inZoomIn ? NormalState : ZoomState);
         5205  +      [window zoom:NSApp];
         5206  +
         5207  +     wmPtr->hints.initial_state =
         5208  +    	    (zoomPart == inZoomIn ? NormalState : ZoomState);
  5162   5209       return true;
  5163   5210   }
  5164   5211   
  5165   5212   /*
  5166   5213    *----------------------------------------------------------------------
  5167   5214    *
  5168   5215    * TkUnsupported1Cmd --
................................................................................
  5192   5239   	"style", NULL
  5193   5240       };
  5194   5241       enum SubCmds {
  5195   5242   	TKMWS_STYLE
  5196   5243       };
  5197   5244       Tk_Window tkwin = clientData;
  5198   5245       TkWindow *winPtr;
  5199         -    int index, i;
         5246  +    int index;
  5200   5247   
  5201   5248       if (objc < 3) {
  5202   5249   	Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?");
  5203   5250   	return TCL_ERROR;
  5204   5251       }
  5205   5252   
  5206         -    /*
  5207         -     * Iterate through objc/objv to set correct background color and toggle
  5208         -     * opacity of window.
  5209         -     */
  5210         -
  5211         -    for (i= 0; i < objc; i++) {
  5212         -    	if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*black*")) {
  5213         -    	    colorName = [NSColor blackColor];	// use #000000 in Tk scripts to match
  5214         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*dark*")) {
  5215         -    	    colorName = [NSColor darkGrayColor]; //use #545454 in Tk scripts to match
  5216         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*light*")) {
  5217         -    	    colorName = [NSColor lightGrayColor]; //use #ababab in Tk scripts to match
  5218         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*white*")) {
  5219         -    	    colorName = [NSColor whiteColor];	//use #ffffff in Tk scripts to match
  5220         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "gray*")) {
  5221         -    	    colorName = [NSColor grayColor];	//use #7f7f7f in Tk scripts to match
  5222         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*red*")) {
  5223         -    	    colorName = [NSColor redColor];	//use #ff0000 in Tk scripts to match
  5224         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*green*")) {
  5225         -    	    colorName = [NSColor greenColor];	//use #00ff00 in Tk scripts to match
  5226         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*blue*")) {
  5227         -    	    colorName = [NSColor blueColor];	//use #0000ff in Tk scripts to match
  5228         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*cyan*")) {
  5229         -    	    colorName = [NSColor cyanColor];	//use #00ffff in Tk scripts to match
  5230         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*yellow*")) {
  5231         -    	    colorName = [NSColor yellowColor];	//use #ffff00 in Tk scripts to match
  5232         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*magenta*")) {
  5233         -    	    colorName = [NSColor magentaColor];	//use #ff00ff in Tk scripts to match
  5234         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*orange*")) {
  5235         -    	    colorName = [NSColor orangeColor];	//use #ff8000 in Tk scripts to match
  5236         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*purple*")) {
  5237         -    	    colorName = [NSColor purpleColor];	//use #800080 in Tk scripts to match
  5238         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*brown*")){
  5239         -    	    colorName = [NSColor brownColor];	//use #996633 in Tk scripts to match
  5240         -    	} else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*clear*")) {
  5241         -    	    colorName = [NSColor clearColor];	//use systemTransparent in Tk scripts to match
  5242         -    	}
  5243         -    	if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*opacity*")) {
  5244         -    	    opaqueTag = YES;
  5245         -    	}
  5246         -    }
  5247   5253   
  5248   5254       winPtr = (TkWindow *)
  5249   5255   	    Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin);
  5250   5256       if (winPtr == NULL) {
  5251   5257   	return TCL_ERROR;
  5252   5258       }
  5253   5259       if (!(winPtr->flags & TK_TOP_LEVEL)) {
................................................................................
  5602   5608       NSWindow *window = [[winClass alloc] initWithContentRect:contentRect
  5603   5609   	    styleMask:styleMask backing:NSBackingStoreBuffered defer:YES];
  5604   5610       if (!window) {
  5605   5611       	Tcl_Panic("couldn't allocate new Mac window");
  5606   5612       }
  5607   5613       TKContentView *contentView = [[TKContentView alloc]
  5608   5614   				     initWithFrame:NSZeroRect];
         5615  +    [window setColorSpace:[NSColorSpace deviceRGBColorSpace]];
  5609   5616       [window setContentView:contentView];
  5610   5617       [contentView release];
  5611   5618       [window setDelegate:NSApp];
  5612   5619       [window setAcceptsMouseMovedEvents:YES];
  5613   5620       [window setReleasedWhenClosed:NO];
  5614   5621       [window setAutodisplay:NO];
  5615   5622       if (styleMask & NSUtilityWindowMask) {
................................................................................
  5620   5627           /*
  5621   5628   	 * Workaround for [Bug 2824538]: Texured windows are draggable
  5622   5629   	 *                               from opaque content.
  5623   5630   	 */
  5624   5631   	[window setMovableByWindowBackground:NO];
  5625   5632       }
  5626   5633   
  5627         -
  5628         -    /* Set background color and opacity of window if those flags are set.  */
  5629         -    if (colorName != NULL) {
  5630         -    	[window setBackgroundColor: colorName];
  5631         -    }
  5632         -
  5633         -    if (opaqueTag) {
  5634         -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
  5635         -    	[window setOpaque: opaqueTag];
  5636         -#else
  5637         -	[window setOpaque: YES];
  5638         -#endif
  5639         -    }
  5640         -
  5641   5634       [window setDocumentEdited:NO];
  5642   5635       wmPtr->window = window;
  5643   5636       macWin->view = window.contentView;
  5644   5637       TkMacOSXApplyWindowAttributes(winPtr, window);
  5645   5638   
  5646   5639       NSRect geometry = InitialWindowBounds(winPtr, window);
  5647   5640       geometry.size.width +=  structureRect.size.width;
................................................................................
  6324   6317   		initial) {
  6325   6318   	    NSWindowCollectionBehavior b = NSWindowCollectionBehaviorDefault;
  6326   6319   	    if (newAttributes & tkCanJoinAllSpacesAttribute) {
  6327   6320   		b |= NSWindowCollectionBehaviorCanJoinAllSpaces;
  6328   6321   	    } else if (newAttributes & tkMoveToActiveSpaceAttribute) {
  6329   6322   		b |= NSWindowCollectionBehaviorMoveToActiveSpace;
  6330   6323   	    }
  6331         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
  6332   6324   	    if (newAttributes & kWindowDoesNotCycleAttribute) {
  6333   6325   		b |= NSWindowCollectionBehaviorIgnoresCycle;
  6334   6326   	    } else {
  6335   6327   		b |= NSWindowCollectionBehaviorParticipatesInCycle;
  6336   6328   	    }
  6337         -#endif
  6338   6329   	    [macWindow setCollectionBehavior:b];
  6339         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060
  6340         -	    if (((changedAttributes & kWindowDoesNotCycleAttribute) || initial)
  6341         -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060
  6342         -		    && tkMacOSXMacOSXVersion < 1060
  6343         -#endif
  6344         -	    ) {
  6345         -		[macWindow setCanCycle:
  6346         -			!(newAttributes & kWindowDoesNotCycleAttribute)];
  6347         -	    }
  6348         -#endif
  6349   6330   	}
  6350   6331   	if ((wmPtr->flags & WM_TOPMOST) != (oldFlags & WM_TOPMOST)) {
  6351   6332   	    [macWindow setLevel:(wmPtr->flags & WM_TOPMOST) ?
  6352   6333   		    kCGUtilityWindowLevel : ([macWindow isKindOfClass:
  6353   6334   		    [NSPanel class]] && [macWindow isFloatingPanel] ?
  6354   6335   		    kCGFloatingWindowLevel : kCGNormalWindowLevel)];
  6355   6336   	}
................................................................................
  6473   6454       TkWindow *winPtr,
  6474   6455       NSWindow *window,
  6475   6456       int fullscreen,
  6476   6457       Tcl_Interp *interp)
  6477   6458   {
  6478   6459       WmInfo *wmPtr = winPtr->wmInfoPtr;
  6479   6460       int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN);
  6480         -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
  6481   6461       static unsigned long prevMask = 0, prevPres = 0;
  6482         -#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/
  6483   6462   
  6484   6463       if (fullscreen) {
  6485   6464   	int screenWidth =  WidthOfScreen(Tk_Screen(winPtr));
  6486   6465   	int screenHeight = HeightOfScreen(Tk_Screen(winPtr));
  6487   6466   
  6488   6467   	/*
  6489   6468   	 * Check max width and height if set by the user.
................................................................................
  6497   6476   			" width/height is too small", winPtr->pathName));
  6498   6477   		Tcl_SetErrorCode(interp, "TK", "FULLSCREEN",
  6499   6478   			"CONSTRAINT_FAILURE", NULL);
  6500   6479   	    }
  6501   6480   	    result = TCL_ERROR;
  6502   6481   	    wmPtr->flags &= ~WM_FULLSCREEN;
  6503   6482   	} else {
         6483  +	    Tk_UnmapWindow((Tk_Window) winPtr);
  6504   6484   	    NSRect bounds = [window contentRectForFrameRect:[window frame]];
  6505   6485   	    NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight);
  6506   6486   
  6507   6487   	    if (!NSEqualRects(bounds, screenBounds) && !wasFullscreen) {
  6508   6488   		wmPtr->configX = wmPtr->x;
  6509   6489   		wmPtr->configY = wmPtr->y;
  6510   6490   		wmPtr->configAttributes = wmPtr->attributes;
................................................................................
  6515   6495   		[window setFrame:[window frameRectForContentRect:
  6516   6496   			screenBounds] display:YES];
  6517   6497   		wmPtr->flags &= ~WM_SYNC_PENDING;
  6518   6498   	    }
  6519   6499   	    wmPtr->flags |= WM_FULLSCREEN;
  6520   6500   	}
  6521   6501   
  6522         -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
  6523         -	/*
  6524         -	 * We can't set these features on Leopard or earlier, as they don't
  6525         -	 * exist (neither options nor API that uses them). This formally means
  6526         -	 * that there's a bug with full-screen windows with Tk on old OSX, but
  6527         -	 * it isn't worth blocking a build just for this.
  6528         -	 */
  6529         -
  6530   6502   	prevMask = [window styleMask];
  6531   6503   	prevPres = [NSApp presentationOptions];
  6532   6504   	[window setStyleMask: NSBorderlessWindowMask];
  6533   6505   	[NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock
  6534   6506   	                          | NSApplicationPresentationAutoHideMenuBar];
  6535         -#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/
         6507  +	Tk_MapWindow((Tk_Window) winPtr);
  6536   6508       } else {
  6537   6509   	wmPtr->flags &= ~WM_FULLSCREEN;
  6538         -
  6539         -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD
  6540   6510   	[NSApp setPresentationOptions: prevPres];
  6541   6511   	[window setStyleMask: prevMask];
  6542         -#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/
  6543   6512       }
  6544   6513   
  6545   6514       if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) {
         6515  +	Tk_UnmapWindow((Tk_Window) winPtr);
  6546   6516   	UInt64 oldAttributes = wmPtr->attributes;
  6547   6517   	NSRect bounds = NSMakeRect(wmPtr->configX, tkMacOSXZeroScreenHeight -
  6548   6518   		(wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight),
  6549   6519   		wmPtr->xInParent + wmPtr->configWidth,
  6550   6520   		wmPtr->yInParent + wmPtr->configHeight);
  6551   6521   
  6552   6522   	wmPtr->attributes |= wmPtr->configAttributes &
  6553   6523   		kWindowResizableAttribute;
  6554   6524   	ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes,
  6555   6525   		wmPtr->flags, 1, 0);
  6556   6526   	wmPtr->flags |= WM_SYNC_PENDING;
  6557   6527   	[window setFrame:[window frameRectForContentRect:bounds] display:YES];
  6558   6528   	wmPtr->flags &= ~WM_SYNC_PENDING;
         6529  +       Tk_MapWindow((Tk_Window) winPtr);
  6559   6530       }
  6560   6531       return result;
  6561   6532   }
  6562   6533   
  6563   6534   /*
  6564   6535    *----------------------------------------------------------------------
  6565   6536    *

Changes to macosx/tkMacOSXXStubs.c.

    49     49    * Forward declarations of procedures used in this file.
    50     50    */
    51     51   
    52     52   static XID		MacXIdAlloc(Display *display);
    53     53   static int		DefaultErrorHandler(Display *display,
    54     54   			    XErrorEvent *err_evt);
    55     55   
    56         -/*
    57         - * Other declarations
    58         - */
    59         -
    60         -static int		DestroyImage(XImage *image);
    61         -static unsigned long	ImageGetPixel(XImage *image, int x, int y);
    62         -static int		ImagePutPixel(XImage *image, int x, int y,
    63         -			    unsigned long pixel);
    64     56   
    65     57   /*
    66     58    *----------------------------------------------------------------------
    67     59    *
    68     60    * TkMacOSXDisplayChanged --
    69     61    *
    70     62    *	Called to set up initial screen info or when an event indicated
................................................................................
   179    171   	snprintf(vendor, sizeof(vendor), "Apple AppKit %g",
   180    172   		NSAppKitVersionNumber);
   181    173       }
   182    174       display->vendor = vendor;
   183    175       {
   184    176   	int major, minor, patch;
   185    177   
   186         -#if MAC_OS_X_VERSION_MIN_REQUIRED < 10100
          178  +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080
   187    179   	Gestalt(gestaltSystemVersionMajor, (SInt32*)&major);
   188    180   	Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor);
   189    181   	Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch);
   190    182   #else
   191    183   	NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion];
   192    184   	major = systemVersion.majorVersion;
   193    185   	minor = systemVersion.minorVersion;
................................................................................
   204    196       screen->black_pixel = 0x00000000 | PIXEL_MAGIC << 24;
   205    197       screen->white_pixel = 0x00FFFFFF | PIXEL_MAGIC << 24;
   206    198       screen->ext_data	= (XExtData *) &maxBounds;
   207    199   
   208    200       screen->root_visual = ckalloc(sizeof(Visual));
   209    201       screen->root_visual->visualid     = 0;
   210    202       screen->root_visual->class	      = TrueColor;
          203  +    screen->root_visual->alpha_mask   = 0xFF000000;
   211    204       screen->root_visual->red_mask     = 0x00FF0000;
   212    205       screen->root_visual->green_mask   = 0x0000FF00;
   213    206       screen->root_visual->blue_mask    = 0x000000FF;
   214    207       screen->root_visual->bits_per_rgb = 24;
   215    208       screen->root_visual->map_entries  = 256;
   216    209   
   217    210       /*
................................................................................
   379    372       Display * display,
   380    373       Atom atom)
   381    374   {
   382    375       display->request++;
   383    376       return NULL;
   384    377   }
   385    378   
   386         -int
   387         -_XInitImageFuncPtrs(
   388         -    XImage *image)
   389         -{
   390         -    return 0;
   391         -}
   392         -
   393    379   XErrorHandler
   394    380   XSetErrorHandler(
   395    381       XErrorHandler handler)
   396    382   {
   397    383       return DefaultErrorHandler;
   398    384   }
   399    385   
................................................................................
   758    744   	    ProtocolVersion(Tk_Display(tkwin)),
   759    745   	    ProtocolRevision(Tk_Display(tkwin)));
   760    746       snprintf(buffer2, sizeof(buffer2), " Mac OS X %x",
   761    747   	    VendorRelease(Tk_Display(tkwin)));
   762    748       Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)),
   763    749   	    buffer2, NULL);
   764    750   }
   765         -
   766         -#pragma mark XImage handling
   767         -
   768         -/*
   769         - *----------------------------------------------------------------------
   770         - *
   771         - * XCreateImage --
   772         - *
   773         - *	Allocates storage for a new XImage.
   774         - *
   775         - * Results:
   776         - *	Returns a newly allocated XImage.
   777         - *
   778         - * Side effects:
   779         - *	None.
   780         - *
   781         - *----------------------------------------------------------------------
   782         - */
   783         -
   784         -XImage *
   785         -XCreateImage(
   786         -    Display* display,
   787         -    Visual* visual,
   788         -    unsigned int depth,
   789         -    int format,
   790         -    int offset,
   791         -    char* data,
   792         -    unsigned int width,
   793         -    unsigned int height,
   794         -    int bitmap_pad,
   795         -    int bytes_per_line)
   796         -{
   797         -    XImage *ximage;
   798         -    display->request++;
   799         -    ximage = ckalloc(sizeof(XImage));
   800         -
   801         -    ximage->height = height;
   802         -    ximage->width = width;
   803         -    ximage->depth = depth;
   804         -    ximage->xoffset = offset;
   805         -    ximage->format = format;
   806         -    ximage->data = data;
   807         -    ximage->obdata = NULL;
   808         -    /* The default pixelpower is 0.  This must be explicitly set to 1 in the
   809         -     * case of an XImage extracted from a Retina display.
   810         -     */
   811         -    ximage->pixelpower = 0;
   812         -
   813         -    if (format == ZPixmap) {
   814         -	ximage->bits_per_pixel = 32;
   815         -	ximage->bitmap_unit = 32;
   816         -    } else {
   817         -	ximage->bits_per_pixel = 1;
   818         -	ximage->bitmap_unit = 8;
   819         -    }
   820         -    if (bitmap_pad) {
   821         -	ximage->bitmap_pad = bitmap_pad;
   822         -    } else {
   823         -	/* Use 16 byte alignment for best Quartz perfomance */
   824         -	ximage->bitmap_pad = 128;
   825         -    }
   826         -    if (bytes_per_line) {
   827         -	ximage->bytes_per_line = bytes_per_line;
   828         -    } else {
   829         -	ximage->bytes_per_line = ((width * ximage->bits_per_pixel +
   830         -		(ximage->bitmap_pad - 1)) >> 3) &
   831         -		~((ximage->bitmap_pad >> 3) - 1);
   832         -    }
   833         -#ifdef WORDS_BIGENDIAN
   834         -    ximage->byte_order = MSBFirst;
   835         -    ximage->bitmap_bit_order = MSBFirst;
   836         -#else
   837         -    ximage->byte_order = LSBFirst;
   838         -    ximage->bitmap_bit_order = LSBFirst;
   839         -#endif
   840         -    ximage->red_mask = 0x00FF0000;
   841         -    ximage->green_mask = 0x0000FF00;
   842         -    ximage->blue_mask = 0x000000FF;
   843         -    ximage->f.create_image = NULL;
   844         -    ximage->f.destroy_image = DestroyImage;
   845         -    ximage->f.get_pixel = ImageGetPixel;
   846         -    ximage->f.put_pixel = ImagePutPixel;
   847         -    ximage->f.sub_image = NULL;
   848         -    ximage->f.add_pixel = NULL;
   849         -
   850         -    return ximage;
   851         -}
   852         -
   853         -/*
   854         - *----------------------------------------------------------------------
   855         - *
   856         - * XGetImage --
   857         - *
   858         - *	This function copies data from a pixmap or window into an XImage.
   859         - *
   860         - * Results:
   861         - *	Returns a newly allocated XImage containing the data from the given
   862         - *	rectangle of the given drawable, or NULL if the XImage could not be
   863         - *	constructed.  NOTE: If we are copying from a window on a Retina
   864         - *	display, the dimensions of the XImage will be 2*width x 2*height.
   865         - *
   866         - * Side effects:
   867         - *	None.
   868         - *
   869         - *----------------------------------------------------------------------
   870         - */
   871         -
   872         -XImage *
   873         -XGetImage(
   874         -    Display *display,
   875         -    Drawable d,
   876         -    int x,
   877         -    int y,
   878         -    unsigned int width,
   879         -    unsigned int height,
   880         -    unsigned long plane_mask,
   881         -    int format)
   882         -{
   883         -    NSBitmapImageRep *bitmap_rep;
   884         -    NSUInteger         bitmap_fmt;
   885         -    XImage *       imagePtr = NULL;
   886         -    char *           bitmap = NULL;
   887         -    char *           image_data=NULL;
   888         -    int	        depth = 32;
   889         -    int	        offset = 0;
   890         -    int	        bitmap_pad = 0;
   891         -    int	        bytes_per_row = 4*width;
   892         -    int                size;
   893         -    MacDrawable *macDraw = (MacDrawable *) d; // Where is this variable used? May it be removed?
   894         -    int scalefactor = 1;
   895         -#if __MAC_OS_X_VERSION_MAX_ALLOWED >= 1070
   896         -    NSWindow *win = TkMacOSXDrawableWindow(d);
   897         -    /* This code assumes that backing scale factors are integers.  Currently
   898         -     * Retina displays use a scale factor of 2.0 and normal displays use 1.0.
   899         -     * We do not support any other values here.
   900         -     */
   901         -    if (win && [win respondsToSelector:@selector(backingScaleFactor)]) {
   902         -	scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1;
   903         -    }
   904         -#endif
   905         -    int scaled_height = height * scalefactor;
   906         -    int scaled_width = width * scalefactor;
   907         -
   908         -    if (format == ZPixmap) {
   909         -	if (width == 0 || height == 0) {
   910         -	    /* This happens all the time.
   911         -	    TkMacOSXDbgMsg("XGetImage: empty image requested");
   912         -	    */
   913         -	    return NULL;
   914         -	}
   915         -
   916         -	bitmap_rep =  BitmapRepFromDrawableRect(d, x, y, width, height);
   917         -	bitmap_fmt = [bitmap_rep bitmapFormat];
   918         -
   919         -	if ( bitmap_rep == Nil                        ||
   920         -	     (bitmap_fmt != 0 && bitmap_fmt != 1)     ||
   921         -	     [bitmap_rep samplesPerPixel] != 4 ||
   922         -	     [bitmap_rep isPlanar] != 0               ) {
   923         -	    TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep");
   924         -	    return NULL;
   925         -	}
   926         -
   927         -	NSSize image_size = NSMakeSize(width, height);
   928         -	NSImage* ns_image = [[NSImage alloc]initWithSize:image_size];
   929         -	[ns_image addRepresentation:bitmap_rep];
   930         -
   931         -	/* Assume premultiplied nonplanar data with 4 bytes per pixel.*/
   932         -	if ( [bitmap_rep isPlanar ] == 0 &&
   933         -	     [bitmap_rep samplesPerPixel] == 4 ) {
   934         -	    bytes_per_row = [bitmap_rep bytesPerRow];
   935         -	    assert(bytes_per_row == 4 * scaled_width);
   936         -	    assert([bitmap_rep bytesPerPlane] == bytes_per_row * scaled_height);
   937         -	    size = bytes_per_row*scaled_height;
   938         -	    image_data = (char*)[bitmap_rep bitmapData];
   939         -	    if ( image_data ) {
   940         -		int row, n, m;
   941         -		bitmap = ckalloc(size);
   942         -		/*
   943         -		  Oddly enough, the bitmap has the top row at the beginning,
   944         -		  and the pixels are in BGRA or ABGR format.
   945         -		*/
   946         -		if (bitmap_fmt == 0) {
   947         -		    /* BGRA */
   948         -		    for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
   949         -			for (m=n; m<n+bytes_per_row; m+=4) {
   950         -			    *(bitmap+m)   = *(image_data+m+2);
   951         -			    *(bitmap+m+1) = *(image_data+m+1);
   952         -			    *(bitmap+m+2) = *(image_data+m);
   953         -			    *(bitmap+m+3) = *(image_data+m+3);
   954         -			}
   955         -		    }
   956         -		} else {
   957         -		    /* ABGR */
   958         -		    for (row=0, n=0; row<scaled_height; row++, n+=bytes_per_row) {
   959         -			for (m=n; m<n+bytes_per_row; m+=4) {
   960         -			    *(bitmap+m)   = *(image_data+m+3);
   961         -			    *(bitmap+m+1) = *(image_data+m+2);
   962         -			    *(bitmap+m+2) = *(image_data+m+1);
   963         -			    *(bitmap+m+3) = *(image_data+m);
   964         -			}
   965         -		    }
   966         -		}
   967         -	    }
   968         -	}
   969         -	if (bitmap) {
   970         -	    imagePtr = XCreateImage(display, NULL, depth, format, offset,
   971         -				    (char*)bitmap, scaled_width, scaled_height,
   972         -				    bitmap_pad, bytes_per_row);
   973         -	    if (scalefactor == 2) {
   974         -	    	imagePtr->pixelpower = 1;
   975         -	     }
   976         -	    [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/
   977         -	    [ns_image release];
   978         -	}
   979         -    } else {
   980         -	TkMacOSXDbgMsg("Could not extract image from drawable.");
   981         -    }
   982         -    return imagePtr;
   983         -}
   984         -
   985         -/*
   986         - *----------------------------------------------------------------------
   987         - *
   988         - * DestroyImage --
   989         - *
   990         - *	Destroys storage associated with an image.
   991         - *
   992         - * Results:
   993         - *	None.
   994         - *
   995         - * Side effects:
   996         - *	Deallocates the image.
   997         - *
   998         - *----------------------------------------------------------------------
   999         - */
  1000         -
  1001         -static int
  1002         -DestroyImage(
  1003         -    XImage *image)
  1004         -{
  1005         -    if (image) {
  1006         -	if (image->data) {
  1007         -	    ckfree(image->data);
  1008         -	}
  1009         -	ckfree(image);
  1010         -    }
  1011         -    return 0;
  1012         -}
  1013         -
  1014         -/*
  1015         - *----------------------------------------------------------------------
  1016         - *
  1017         - * ImageGetPixel --
  1018         - *
  1019         - *	Get a single pixel from an image.
  1020         - *
  1021         - * Results:
  1022         - *	Returns the 32 bit pixel value.
  1023         - *
  1024         - * Side effects:
  1025         - *	None.
  1026         - *
  1027         - *----------------------------------------------------------------------
  1028         - */
  1029         -
  1030         -static unsigned long
  1031         -ImageGetPixel(
  1032         -    XImage *image,
  1033         -    int x,
  1034         -    int y)
  1035         -{
  1036         -    unsigned char r = 0, g = 0, b = 0;
  1037         -
  1038         -    if (image && image->data) {
  1039         -	unsigned char *srcPtr = ((unsigned char*) image->data)
  1040         -		+ (y * image->bytes_per_line)
  1041         -		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
  1042         -
  1043         -	switch (image->bits_per_pixel) {
  1044         -	    case 32: {
  1045         -		r = (*((unsigned int*) srcPtr) >> 16) & 0xff;
  1046         -		g = (*((unsigned int*) srcPtr) >>  8) & 0xff;
  1047         -		b = (*((unsigned int*) srcPtr)      ) & 0xff;
  1048         -		/*if (image->byte_order == LSBFirst) {
  1049         -		    r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0];
  1050         -		} else {
  1051         -		    r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3];
  1052         -		}*/
  1053         -		break;
  1054         -	    }
  1055         -	    case 16:
  1056         -		r = (*((unsigned short*) srcPtr) >> 7) & 0xf8;
  1057         -		g = (*((unsigned short*) srcPtr) >> 2) & 0xf8;
  1058         -		b = (*((unsigned short*) srcPtr) << 3) & 0xf8;
  1059         -		break;
  1060         -	    case 8:
  1061         -		r = (*srcPtr << 2) & 0xc0;
  1062         -		g = (*srcPtr << 4) & 0xc0;
  1063         -		b = (*srcPtr << 6) & 0xc0;
  1064         -		r |= r >> 2 | r >> 4 | r >> 6;
  1065         -		g |= g >> 2 | g >> 4 | g >> 6;
  1066         -		b |= b >> 2 | b >> 4 | b >> 6;
  1067         -		break;
  1068         -	    case 4: {
  1069         -		unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4);
  1070         -		r = (c & 0x04) ? 0xff : 0;
  1071         -		g = (c & 0x02) ? 0xff : 0;
  1072         -		b = (c & 0x01) ? 0xff : 0;
  1073         -		break;
  1074         -		}
  1075         -	    case 1:
  1076         -		r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0;
  1077         -		break;
  1078         -	}
  1079         -    }
  1080         -    return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b;
  1081         -}
  1082         -
  1083         -/*
  1084         - *----------------------------------------------------------------------
  1085         - *
  1086         - * ImagePutPixel --
  1087         - *
  1088         - *	Set a single pixel in an image.
  1089         - *
  1090         - * Results:
  1091         - *	None.
  1092         - *
  1093         - * Side effects:
  1094         - *	None.
  1095         - *
  1096         - *----------------------------------------------------------------------
  1097         - */
  1098         -
  1099         -static int
  1100         -ImagePutPixel(
  1101         -    XImage *image,
  1102         -    int x,
  1103         -    int y,
  1104         -    unsigned long pixel)
  1105         -{
  1106         -    if (image && image->data) {
  1107         -	unsigned char r = ((pixel & image->red_mask)   >> 16) & 0xff;
  1108         -	unsigned char g = ((pixel & image->green_mask) >>  8) & 0xff;
  1109         -	unsigned char b = ((pixel & image->blue_mask)       ) & 0xff;
  1110         -	unsigned char *dstPtr = ((unsigned char*) image->data)
  1111         -		+ (y * image->bytes_per_line)
  1112         -		+ (((image->xoffset + x) * image->bits_per_pixel) / NBBY);
  1113         -
  1114         -	switch (image->bits_per_pixel) {
  1115         -	    case 32:
  1116         -		*((unsigned int*) dstPtr) = (0xff << 24) | (r << 16) |
  1117         -			(g << 8) | b;
  1118         -		/*if (image->byte_order == LSBFirst) {
  1119         -		    dstPtr[3] = 0xff; dstPtr[2] = r; dstPtr[1] = g; dstPtr[0] = b;
  1120         -		} else {
  1121         -		    dstPtr[0] = 0xff; dstPtr[1] = r; dstPtr[2] = g; dstPtr[3] = b;
  1122         -		}*/
  1123         -		break;
  1124         -	    case 16:
  1125         -		*((unsigned short*) dstPtr) = ((r & 0xf8) << 7) |
  1126         -			((g & 0xf8) << 2) | ((b & 0xf8) >> 3);
  1127         -		break;
  1128         -	    case 8:
  1129         -		*dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) |
  1130         -			((b & 0xc0) >> 6);
  1131         -		break;
  1132         -	    case 4: {
  1133         -		unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) |
  1134         -			((b & 0x80) >> 7);
  1135         -		*dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) :
  1136         -			((*dstPtr & 0x0f) | ((c << 4) & 0xf0));
  1137         -		break;
  1138         -		}
  1139         -	    case 1:
  1140         -		*dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) :
  1141         -			(*dstPtr & ~(0x80 >> (x % 8)));
  1142         -		break;
  1143         -	}
  1144         -    }
  1145         -    return 0;
  1146         -}
  1147    751   
  1148    752   /*
  1149    753    *----------------------------------------------------------------------
  1150    754    *
  1151    755    * XChangeWindowAttributes, XSetWindowBackground,
  1152    756    * XSetWindowBackgroundPixmap, XSetWindowBorder, XSetWindowBorderPixmap,
  1153    757    * XSetWindowBorderWidth, XSetWindowColormap
................................................................................
  1365    969    *----------------------------------------------------------------------
  1366    970    */
  1367    971   
  1368    972   void
  1369    973   Tk_ResetUserInactiveTime(
  1370    974       Display *dpy)
  1371    975   {
  1372         -    IOGPoint loc;
          976  +    IOGPoint loc = {0, 0};
  1373    977       kern_return_t kr;
  1374    978       NXEvent nullEvent = {NX_NULLEVENT, {0, 0}, 0, -1, 0};
  1375    979       enum { kNULLEventPostThrottle = 10 };
  1376    980       static io_connect_t io_connection = MACH_PORT_NULL;
  1377    981   
  1378    982       if (io_connection == MACH_PORT_NULL) {
  1379    983   	io_service_t service = IOServiceGetMatchingService(

Changes to tests/bind.test.

    29     29       bind all <Enter> {}
    30     30       bind Test <Enter> {}
    31     31       bind Toplevel <Enter> {}
    32     32       bind xyz <Enter> {}
    33     33       bind {a b} <Enter> {}
    34     34       bind .t <Enter> {}
    35     35   }
           36  +
           37  +# This function fills the pattern matcher's ring buffer with events of
           38  +# the specified type.  This can be used when testing with generated
           39  +# events to make sure that there are no stray events in the ring
           40  +# buffer which might cause the pattern matcher to find unintended
           41  +# matches.  The size of the ring buffer is EVENT_BUFFER_SIZE, which is
           42  +# currently set to 30.  If this changes, the code below will need to
           43  +# change.
           44  +proc clearRingBuffer {{event}} {
           45  +    for {set i 0} {$i < 30} {incr i} {
           46  +	event generate . $event
           47  +    }
           48  +}
    36     49   
    37     50   # move the mouse pointer away of the testing area
    38     51   # otherwise some spurious events may pollute the tests
    39     52   toplevel .top
    40     53   wm geometry .top 50x50-50-50
    41     54   update
    42     55   event generate .top <Button-1> -warp 1
................................................................................
   644    657       pack .t.f
   645    658       focus -force .t.f
   646    659       update
   647    660       set x {}
   648    661   } -body {
   649    662       bind .t.f <Key> "lappend x Key%K"
   650    663       bind .t.f <KeyRelease> "lappend x Release%K"
   651         -    event generate .t.f <Key> -keycode 0
   652         -    event generate .t.f <KeyRelease> -keycode 0
          664  +    event generate .t.f <Key> -keycode -1
          665  +    event generate .t.f <KeyRelease> -keycode -1
   653    666       return $x
   654    667   } -cleanup {
   655    668       destroy .t.f
   656    669   } -result {Key?? Release??}
   657    670   test bind-13.15 {Tk_BindEvent procedure: button detail} -setup {
   658    671       frame .t.f -class Test -width 150 -height 100
   659    672       pack .t.f
................................................................................
  1378   1391       destroy .t.f
  1379   1392   } -result {0}
  1380   1393   test bind-15.22 {MatchPatterns procedure, time wrap-around} -setup {
  1381   1394       frame .t.f -class Test -width 150 -height 100
  1382   1395       pack .t.f
  1383   1396       focus -force .t.f
  1384   1397       update
         1398  +    clearRingBuffer <Key>
  1385   1399   } -body {
  1386   1400       bind .t.f <Double-1> {set x 1}
  1387   1401       set x 0
  1388         -    event generate .t.f <Button-1> -time [expr -100]
         1402  +    event generate .t.f <Button-1> -time -100
  1389   1403       event generate .t.f <Button-1> -time 200
  1390   1404       event generate .t.f <ButtonRelease-1>
  1391   1405       return $x
  1392   1406   } -cleanup {
  1393   1407       destroy .t.f
  1394   1408   } -result {1}
  1395   1409   test bind-15.23 {MatchPatterns procedure, time wrap-around} -setup {
  1396   1410       frame .t.f -class Test -width 150 -height 100
  1397   1411       pack .t.f
  1398   1412       focus -force .t.f
  1399   1413       update
         1414  +    clearRingBuffer <Key>
  1400   1415   } -body {
  1401   1416       bind .t.f <Double-1> {set x 1}
  1402   1417       set x 0
  1403   1418       event generate .t.f <Button-1> -time -100
  1404   1419       event generate .t.f <Button-1> -time 500
  1405   1420       event generate .t.f <ButtonRelease-1>
  1406   1421       return $x
  1407   1422   } -cleanup {
  1408   1423       destroy .t.f
  1409   1424   } -result {0}
  1410         -
  1411   1425   test bind-15.24 {MatchPatterns procedure, virtual event} -setup {
  1412   1426       frame .t.f -class Test -width 150 -height 100
  1413   1427       pack .t.f
  1414   1428       focus -force .t.f
  1415   1429       update
  1416   1430       set x {}
         1431  +    clearRingBuffer <Key>
  1417   1432   } -body {
  1418   1433       event add <<Paste>> <Button-1>
  1419   1434       bind .t.f <<Paste>> {lappend x paste}
  1420   1435       event generate .t.f <Button-1>
  1421   1436       event generate .t.f <ButtonRelease-1>
  1422   1437       set x
  1423   1438   } -cleanup {
................................................................................
  1426   1441   } -result {paste}
  1427   1442   test bind-15.25 {MatchPatterns procedure, reject a  virtual event} -setup {
  1428   1443       frame .t.f -class Test -width 150 -height 100
  1429   1444       pack .t.f
  1430   1445       focus -force .t.f
  1431   1446       update
  1432   1447       set x {}
         1448  +    clearRingBuffer <Key>
  1433   1449   } -body {
  1434   1450       event add <<Paste>> <Shift-Button-1>
  1435   1451       bind .t.f <<Paste>> {lappend x paste}
  1436   1452       event generate .t.f <Button-1>
  1437   1453       event generate .t.f <ButtonRelease-1>
  1438   1454       set x
  1439   1455   } -cleanup {
................................................................................
  1442   1458   } -result {}
  1443   1459   test bind-15.26 {MatchPatterns procedure, reject a virtual event} -setup {
  1444   1460       frame .t.f -class Test -width 150 -height 100
  1445   1461       pack .t.f
  1446   1462       focus -force .t.f
  1447   1463       update
  1448   1464       set x {}
         1465  +    clearRingBuffer <Key>
  1449   1466   } -body {
  1450   1467       event add <<V1>> <Button>
  1451   1468       event add <<V2>> <Button-1>
  1452   1469       event add <<V3>> <Shift-Button-1>
  1453   1470       bind .t.f <<V2>> "lappend x V2%#"
  1454   1471       event generate .t.f <Button> -serial 101
  1455   1472       event generate .t.f <Button-1> -serial 102
................................................................................
  1468   1485       event delete <<V3>> <Shift-Button-1>
  1469   1486   } -result {V2102 V2103 V2105 Shift-Button-1}
  1470   1487   test bind-15.27 {MatchPatterns procedure, conflict resolution} -setup {
  1471   1488       frame .t.f -class Test -width 150 -height 100
  1472   1489       pack .t.f
  1473   1490       focus -force .t.f
  1474   1491       update
         1492  +    clearRingBuffer <Button>
  1475   1493   } -body {
  1476   1494       bind .t.f <KeyPress> {set x 0}
  1477   1495       bind .t.f 1 {set x 1}
  1478   1496       set x none
  1479   1497       event generate .t.f <Key-1>
  1480   1498       return $x
  1481   1499   } -cleanup {
................................................................................
  1482   1500       destroy .t.f
  1483   1501   } -result {1}
  1484   1502   test bind-15.28 {MatchPatterns procedure, conflict resolution} -setup {
  1485   1503       frame .t.f -class Test -width 150 -height 100
  1486   1504       pack .t.f
  1487   1505       focus -force .t.f
  1488   1506       update
         1507  +    clearRingBuffer <Button>
  1489   1508   } -body {
  1490   1509       bind .t.f <KeyPress> {set x 0}
  1491   1510       bind .t.f 1 {set x 1}
  1492   1511       set x none
  1493   1512       event generate .t.f <Key-2>
  1494   1513       return $x
  1495   1514   } -cleanup {
................................................................................
  1496   1515       destroy .t.f
  1497   1516   } -result {0}
  1498   1517   test bind-15.29 {MatchPatterns procedure, conflict resolution} -setup {
  1499   1518       frame .t.f -class Test -width 150 -height 100
  1500   1519       pack .t.f
  1501   1520       focus -force .t.f
  1502   1521       update
         1522  +    clearRingBuffer <Button>
  1503   1523   } -body {
  1504   1524       bind .t.f <KeyPress> {lappend x 0}
  1505   1525       bind .t.f 1 {lappend x 1}
  1506   1526       bind .t.f 21 {lappend x 2}
  1507   1527       set x none
  1508   1528       event generate .t.f <Key-2>
  1509   1529       event generate .t.f <KeyRelease-2>
................................................................................
  1513   1533       destroy .t.f
  1514   1534   } -result {none 0 2}
  1515   1535   test bind-15.30 {MatchPatterns procedure, conflict resolution} -setup {
  1516   1536       frame .t.f -class Test -width 150 -height 100
  1517   1537       pack .t.f
  1518   1538       focus -force .t.f
  1519   1539       update
         1540  +    clearRingBuffer <Key>
  1520   1541   } -body {
  1521   1542       bind .t.f <ButtonPress> {set x 0}
  1522   1543       bind .t.f <1> {set x 1}
  1523   1544       set x none
  1524   1545       event generate .t.f <Button-1>
  1525   1546       event generate .t.f <ButtonRelease-1>
  1526   1547       return $x
................................................................................
  1529   1550   } -result {1}
  1530   1551   test bind-15.31 {MatchPatterns procedure, conflict resolution} -setup {
  1531   1552       frame .t.f -class Test -width 150 -height 100
  1532   1553       pack .t.f
  1533   1554       focus -force .t.f
  1534   1555       update
  1535   1556       set x {}
         1557  +    clearRingBuffer <Button>
  1536   1558   } -body {
  1537   1559       bind .t.f <M1-Key> {set x 0}
  1538   1560       bind .t.f <M2-Key> {set x 1}
  1539   1561       event generate .t.f <Key-a> -state 0x18
  1540   1562       return $x
  1541   1563   } -cleanup {
  1542   1564       destroy .t.f
  1543   1565   } -result {1}
  1544   1566   test bind-15.32 {MatchPatterns procedure, conflict resolution} -setup {
  1545   1567       frame .t.f -class Test -width 150 -height 100
  1546   1568       pack .t.f
  1547   1569       focus -force .t.f
  1548   1570       update
         1571  +    clearRingBuffer <Button>
  1549   1572   } -body {
  1550   1573       bind .t.f <M2-Key> {set x 0}
  1551   1574       bind .t.f <M1-Key> {set x 1}
  1552   1575       set x none
  1553   1576       event generate .t.f <Key-a> -state 0x18
  1554   1577       return $x
  1555   1578   } -cleanup {
................................................................................
  1557   1580   } -result {1}
  1558   1581   test bind-15.33 {MatchPatterns procedure, conflict resolution} -setup {
  1559   1582       frame .t.f -class Test -width 150 -height 100
  1560   1583       pack .t.f
  1561   1584       focus -force .t.f
  1562   1585       update
  1563   1586       set x {}
         1587  +    clearRingBuffer <Key>
  1564   1588   } -body {
  1565   1589       bind .t.f <1> {lappend x single}
  1566   1590       bind Test <1> {lappend x single(Test)}
  1567   1591       bind Test <Double-1> {lappend x double(Test)}
  1568   1592       event generate .t.f <Button-1>
  1569   1593       event generate .t.f <Button-1>
  1570   1594       event generate .t.f <Button-1>
................................................................................
  2204   2228       set savedBind(All) [bind all <Key>]
  2205   2229       set savedBind(Entry) [bind Entry <Key>]
  2206   2230       entry .t.e
  2207   2231       pack .t.e
  2208   2232       focus -force .t.e
  2209   2233       foreach p [event info] {event delete $p}
  2210   2234       update
         2235  +    clearRingBuffer <Button>
  2211   2236   } -body {
  2212   2237       bind all <Key> {set z "%M"}
  2213   2238       bind Entry <Key> {set y "%M"}
  2214   2239       bind .t.e <Key> {set x "%M"}
  2215   2240       set x none; set y none; set z none
  2216   2241       event gen .t.e <Key-a>
  2217   2242       list $x $y $z

Changes to tests/busy.test.

    89     89       update
    90     90   } -cleanup {
    91     91       tk busy forget .
    92     92   } -result {}
    93     93   test busy-2.12 {tk busy hold root window, invalid cursor} -body {
    94     94       tk busy hold . -cursor nonExistingCursor
    95     95       update
    96         -} -constraints tempNotMac -returnCodes error -cleanup {
           96  +} -returnCodes error -cleanup {
    97     97       tk busy forget .
    98     98   } -result {bad cursor spec "nonExistingCursor"}
    99     99   test busy-2.13 {tk busy hold (shortcut) root window, invalid cursor} -body {
   100    100       tk busy . -cursor nonExistingCursor
   101    101       update
   102         -} -constraints tempNotMac -returnCodes error -cleanup {
          102  +} -returnCodes error -cleanup {
   103    103       tk busy forget .
   104    104   } -result {bad cursor spec "nonExistingCursor"}
   105    105   test busy-2.14 {tk busy hold root window, invalid option} -body {
   106    106       tk busy hold . -invalidOption 1
   107    107       update
   108         -} -constraints tempNotMac -returnCodes error -cleanup {
          108  +} -returnCodes error -cleanup {
   109    109       tk busy forget .
   110    110   } -result {unknown option "-invalidOption"}
   111    111   test busy-2.15 {tk busy hold (shortcut) root window, invalid option} -body {
   112    112       tk busy . -invalidOption 1
   113    113       update
   114         -} -constraints tempNotMac -returnCodes error -cleanup {
          114  +} -returnCodes error -cleanup {
   115    115       tk busy forget .
   116    116   } -result {unknown option "-invalidOption"}
   117    117   
   118    118   test busy-3.1 {tk busy cget no window} -returnCodes error -body {
   119    119       tk busy cget
   120    120   } -result {wrong # args: should be "tk busy cget window option"}
   121    121   test busy-3.2 {tk busy cget no option} -returnCodes error -body {
................................................................................
   166    166       tk busy hold .f -cursor hand1
   167    167       update
   168    168   } -body {
   169    169       tk busy cget .f -cursor
   170    170   } -cleanup {
   171    171       tk busy forget .f
   172    172       destroy .f
   173         -} -result {hand1} -constraints tempNotMac
          173  +} -result {hand1}
   174    174   
   175    175   test busy-4.1 {tk busy configure no window} -returnCodes error -body {
   176    176       tk busy configure
   177    177   } -result {wrong # args: should be "tk busy configure window ?option? ?value ...?"}
   178    178   
   179    179   test busy-4.2 {tk busy configure invalid window} -body {
   180    180       tk busy configure .f
................................................................................
   206    206   } -body {
   207    207       tk busy configure .f
   208    208   } -cleanup {
   209    209       tk busy forget .f
   210    210       destroy .f
   211    211   } -result {{-cursor cursor Cursor wait wait}}
   212    212   
   213         -test busy-4.5 {tk busy configure} -constraints {nonwin tempNotMac} -setup {
          213  +test busy-4.5 {tk busy configure} -constraints {nonwin} -setup {
   214    214       pack [frame .f]
   215    215       tk busy hold .f -cursor hand2
   216    216       update
   217    217   } -body {
   218    218       tk busy configure .f
   219    219   } -cleanup {
   220    220       tk busy forget .f
................................................................................
   262    262       tk busy configure .f -cursor
   263    263   } -cleanup {
   264    264       tk busy forget .f
   265    265       destroy .f
   266    266   } -result {-cursor cursor Cursor wait wait}
   267    267   
   268    268   test busy-4.8 {tk busy configure valid option} -constraints {
   269         -    nonwin tempNotMac
          269  +    nonwin
   270    270   } -setup {
   271    271       pack [frame .f]
   272    272       tk busy hold .f -cursor circle
   273    273       update
   274    274   } -body {
   275    275       tk busy configure .f -cursor
   276    276   } -cleanup {
................................................................................
   295    295       update
   296    296   } -body {
   297    297       tk busy configure .f -cursor pencil
   298    298       tk busy cget .f -cursor
   299    299   } -cleanup {
   300    300       tk busy forget .f
   301    301       destroy .f
   302         -} -result {pencil} -constraints tempNotMac
          302  +} -result {pencil}
   303    303   
   304    304   test busy-4.10 {tk busy configure valid option with invalid value} -setup {
   305    305       pack [frame .f]
   306    306       tk busy hold .f
   307    307       update
   308    308   } -body {
   309    309       tk busy configure .f -cursor nonExistingCursor
   310         -} -constraints tempNotMac -returnCodes error -cleanup {
          310  +} -returnCodes error -cleanup {
   311    311       tk busy forget .f
   312    312       destroy .f
   313    313   } -result {bad cursor spec "nonExistingCursor"}
   314    314   
   315    315   test busy-5.1 {tk busy forget} -returnCodes error -body {
   316    316       tk busy forget
   317    317   } -result {wrong # args: should be "tk busy forget window"}

Changes to tests/canvas.test.

   945    945       canvas .c
   946    946   } -body {
   947    947       set id [.c create line 0 0 1 1]
   948    948       .c rchars $id 1 foo {2 2}
   949    949   } -cleanup {
   950    950       destroy .c
   951    951   } -returnCodes error -result {bad index "foo"}
          952  +
          953  +# Procedure used in test cases 20.1 20.2 20.3
          954  +proc matchPixels {pixels expected} {
          955  +    set matched 1
          956  +    foreach pline $pixels eline $expected {
          957  +        foreach ppixel $pline epixel $eline {
          958  +            if {$ppixel != $epixel} {
          959  +                set matched 0
          960  +                break
          961  +            }
          962  +        }
          963  +    }
          964  +    return $matched
          965  +}
          966  +
          967  +test canvas-20.1 {canvas image} -setup {
          968  +    canvas .c
          969  +    image create photo testimage
          970  +} -body  {
          971  +    .c configure -background #c0c0c0 -scrollregion {0 0 9 9}
          972  +    .c create rectangle 0 0 0 9 -fill #000080 -outline #000080
          973  +    .c image testimage
          974  +    matchPixels [testimage data] { \
          975  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          976  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          977  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          978  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          979  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          980  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          981  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          982  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          983  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          984  +            {#000080 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0}}
          985  +} -cleanup {
          986  +    destroy .c
          987  +    image delete testimage
          988  +} -result 1
          989  +
          990  +test canvas-20.2 {canvas image with subsample} -setup {
          991  +    canvas .c
          992  +    image create photo testimage
          993  +} -body  {
          994  +    .c configure -background #c0c0c0 -scrollregion {0 0 9 9}
          995  +    .c create rectangle 0 0 1 9 -fill #008000 -outline #008000
          996  +    .c image testimage 2
          997  +    matchPixels [testimage data] { \
          998  +        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
          999  +        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1000  +        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1001  +        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1002  +        {#008000 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0}}
         1003  +} -cleanup {
         1004  +    destroy .c
         1005  +    image delete testimage
         1006  +} -result 1
         1007  +
         1008  +test canvas-20.3 {canvas image with subsample and zoom} -setup {
         1009  +    canvas .c
         1010  +    image create photo testimage
         1011  +} -body  {
         1012  +    .c configure -background #c0c0c0 -scrollregion {0 0 9 9}
         1013  +    .c create rectangle 0 0 9 0 -fill #800000 -outline #800000
         1014  +    .c image testimage 1 2
         1015  +    matchPixels [testimage data] { \
         1016  +        {#800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000} \
         1017  +        {#800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000 #800000} \
         1018  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1019  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1020  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1021  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1022  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1023  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1024  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1025  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1026  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1027  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1028  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1029  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1030  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1031  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1032  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1033  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1034  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0} \
         1035  +        {#c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0 #c0c0c0}}
         1036  +} -cleanup {
         1037  +    destroy .c
         1038  +    image delete testimage
         1039  +} -result 1
   952   1040   
   953   1041   # cleanup
   954   1042   imageCleanup
   955   1043   cleanupTests
   956   1044   return
   957   1045   
   958   1046   # Local Variables:
   959   1047   # mode: tcl
   960   1048   # End:

Changes to tests/entry.test.

   347    347   } -body {
   348    348       .e configure -insertbackground non-existent
   349    349   } -cleanup {
   350    350       destroy .e
   351    351   } -returnCodes {error} -result {unknown color name "non-existent"}
   352    352   
   353    353   test entry-1.32 {configuration option: "insertborderwidth" for entry} -setup {
   354         -    entry .e -borderwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
          354  +    entry .e -borderwidth 2 -insertwidth 2 -highlightthickness 2 -font {Helvetica -12 bold}
   355    355       pack .e
   356    356       update
   357    357   } -body {
   358    358       .e configure -insertborderwidth 1.3
   359    359       .e cget -insertborderwidth
   360    360   } -cleanup {
   361    361       destroy .e
................................................................................
  2566   2566   } -result {1 6}
  2567   2567   
  2568   2568   
  2569   2569   
  2570   2570   
  2571   2571   
  2572   2572   
  2573         -test entry-13.10 {GetEntryIndex procedure} -constraints unix -body {
         2573  +test entry-13.10 {GetEntryIndex procedure} -constraints x11 -body {
  2574   2574   # On unix, when selection is cleared, entry widget's internal 
  2575   2575   # selection range is reset.
  2576   2576   # Previous settings:
  2577   2577   	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
  2578   2578   	pack .e
  2579   2579   	.e insert 0 012345678901234567890
  2580   2580   	.e xview 4
................................................................................
  2585   2585   # Testing:
  2586   2586       selection clear .e
  2587   2587       .e index sel.first
  2588   2588   } -cleanup {
  2589   2589       destroy .e
  2590   2590   } -returnCodes error -result {selection isn't in widget .e}
  2591   2591   
  2592         -test entry-13.11 {GetEntryIndex procedure} -constraints win -body {
         2592  +test entry-13.11 {GetEntryIndex procedure} -constraints aquaOrWin32 -body {
  2593   2593   # On mac and pc, when selection is cleared, entry widget remembers
  2594   2594   # last selected range.  When selection ownership is restored to 
  2595   2595   # entry, the old range will be rehighlighted.
  2596   2596   # Previous settings:
  2597   2597   	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
  2598   2598   	pack .e
  2599   2599   	.e insert 0 012345678901234567890
................................................................................
  2606   2606       selection clear .e
  2607   2607       catch {selection get}
  2608   2608       .e index sel.first
  2609   2609   } -cleanup {
  2610   2610       destroy .e
  2611   2611   } -result {1}           
  2612   2612   
  2613         -test entry-13.12 {GetEntryIndex procedure} -constraints unix -body {
         2613  +test entry-13.12 {GetEntryIndex procedure} -constraints x11 -body {
  2614   2614   # Previous settings:
  2615   2615   	entry .e -font {Courier -12} -width 5 -bd 2 -relief sunken
  2616   2616   	pack .e
  2617   2617   	.e insert 0 012345678901234567890
  2618   2618   	.e xview 4
  2619   2619   	update
  2620   2620       .e select from 1

Changes to tests/font.test.

  1952   1952   test font-31.6 {Tk_IntersectTextLayout procedure: ignore spaces at eol} -body {
  1953   1953       csetup "000\n000      000000000"
  1954   1954       .t.c itemconfig text -width [expr $ax*10]
  1955   1955       set x [.t.c find overlapping [expr $ax*5] $ay [expr $ax*5] $ay]
  1956   1956       .t.c itemconfig text -width 0
  1957   1957       return $x
  1958   1958   } -result {}
         1959  +test font-31.7 {TkIntersectAngledTextLayout procedure: bug [514ff64dd0]} -body {
         1960  +    csetup "This is line one\nand line two\nand line three here"
         1961  +    .t.c itemconfigure text -angle 90
         1962  +    # Coordinates of the rectangle to check can be hardcoded:
         1963  +    # The goal of this test is to check whether the overlap detection algorithm
         1964  +    # works when the rectangle is entirely included in a chunk of the text layout.
         1965  +    # The text has been rotated 90 degrees around it's upper left corner,
         1966  +    # so it's enough to check with a small rectangle with small negative y coords.
         1967  +    .t.c find overlapping 5 -7 7 -5
         1968  +} -result {1}
  1959   1969   destroy .t.c
  1960   1970   
  1961   1971   
  1962   1972   test font-32.1 {Tk_TextLayoutToPostscript: ensure buffer doesn't overflow} -setup {
  1963   1973   	destroy .t.c
  1964   1974   	canvas .t.c -closeenough 0 
  1965   1975   	.t.c create text 0 0 -tags text -anchor nw -just left -font "Courier -12"

Added tests/iDOT.png.

cannot compute difference between binary files

Changes to tests/imgPNG.test.

  1099   1099       set i [image create photo]
  1100   1100   } -body {
  1101   1101       $i put $encoded(MultiIDAT)
  1102   1102       return [image width $i]x[image height $i]
  1103   1103   } -cleanup {
  1104   1104       image delete $i
  1105   1105   } -result 223x212
         1106  +
         1107  +test imgPNG-3.1 {reading image with unknown ancillary chunk - bug [1c659ef0f1]} -setup {
         1108  +    set fileName [file join [file dirname [info script]] iDOT.png]
         1109  +} -body {
         1110  +    # the image contains an unknown chunk iDOT
         1111  +    # since the name of this chunk starts with a lowercase letter,
         1112  +    # it's an ancillary chunk that shall not trigger an error
         1113  +    catch {set i [image create photo -file $fileName]}
         1114  +} -cleanup {
         1115  +    image delete $i
         1116  +} -result {0}
  1106   1117   
  1107   1118   }
  1108   1119   namespace delete png
  1109   1120   imageFinish
  1110   1121   cleanupTests
  1111   1122   return
  1112   1123   
  1113   1124   # Local Variables:
  1114   1125   # mode: tcl
  1115   1126   # fill-column: 78
  1116   1127   # End:

Changes to tests/imgPhoto.test.

   815    815   } -body {
   816    816       file copy -force $teapotPhotoFile -teapotPhotoFile
   817    817       image create photo photo1
   818    818       photo1 read -teapotPhotoFile
   819    819   } -cleanup {
   820    820       image delete photo1
   821    821       file delete ./-teapotPhotoFile
          822  +} -result {}
          823  +test imgPhoto-4.76 {ImgPhotoCmd procedure: copy to same image} -constraints {
          824  +    hasTeapotPhoto 
          825  +} -setup {
          826  +    imageCleanup
          827  +    image create photo photo1 -file $teapotPhotoFile
          828  +} -body {
          829  +    # non-regression test for bug [5239fd749b] - shall just not crash
          830  +    photo1 copy photo1 -to 0 0 2000 1000
          831  +    photo1 copy photo1 -subsample 2 2 -shrink
          832  +} -cleanup {
          833  +    imageCleanup
   822    834   } -result {}
   823    835   
   824    836   test imgPhoto-5.1 {ImgPhotoGet/Free procedures, shared instances} -constraints {
   825    837       hasTeapotPhoto
   826    838   } -setup {
   827    839       destroy .c
   828    840       pack [canvas .c]

Changes to tests/menu.test.

   275    275   
   276    276   # We need to test all of the options with all of the different types of
   277    277   # menu entries. The following code sets up .m1 with 6 items. It then
   278    278   # runs through the 2.31 - 2.228 tests below
   279    279   # index 0 is tearoff, 1 command, 2 cascade, 3 separator, 4 checkbutton, 
   280    280   # 5 radiobutton
   281    281   deleteWindows
   282         -menu .m1
          282  +menu .m1 -tearoff 1
   283    283   .m1 add command -label "command"
   284         -menu .m2
          284  +menu .m2 -tearoff 1
   285    285   .m2 add command -label "test"
   286    286   .m1 add cascade -label "cascade" -menu .m2
   287    287   .m1 add separator
   288    288   .m1 add checkbutton -label "checkbutton" -variable check -onvalue on -offvalue off
   289    289   .m1 add radiobutton -label "radiobutton" -variable radio
   290    290   
   291    291   if {[testConstraint hasEarthPhoto]} {
................................................................................
  1394   1394   } -body {
  1395   1395       menu .m1
  1396   1396       .m1 delete foo
  1397   1397   } -returnCodes error -result {bad menu entry index "foo"}
  1398   1398   test menu-3.24 {MenuWidgetCmd procedure, "delete" option} -setup {
  1399   1399   	destroy .m1
  1400   1400   } -body {
  1401         -    menu .m1
         1401  +    menu .m1 -tearoff 1
  1402   1402       .m1 delete 0 "foo"
  1403   1403   } -returnCodes error -result {bad menu entry index "foo"}
  1404   1404   test menu-3.25 {MenuWidgetCmd procedure, "delete" option} -setup {
  1405   1405   	destroy .m1
  1406   1406   } -body {
  1407   1407       menu .m1
  1408   1408       .m1 delete 0
................................................................................
  1542   1542   } -body {
  1543   1543       menu .m1
  1544   1544       .m1 index foo
  1545   1545   } -returnCodes error -result {bad menu entry index "foo"}
  1546   1546   test menu-3.41 {MenuWidgetCmd procedure, "index" option} -setup {
  1547   1547   	destroy .m1
  1548   1548   } -body {
  1549         -    menu .m1
         1549  +    menu .m1 -tearoff 1
  1550   1550       .m1 add command -label "test"
  1551   1551       .m1 add command -label "3"
  1552   1552       .m1 add command -label "another label"
  1553   1553       .m1 add command -label "end"
  1554   1554       .m1 add command -label "3a"
  1555   1555       .m1 add command -label "final entry"
  1556   1556       list [.m1 index "test"] [.m1 index "3"] [.m1 index "3a"] [.m1 index "end"]
................................................................................
  1735   1735       .m1 type 1
  1736   1736   } -cleanup {
  1737   1737   	destroy .m1
  1738   1738   } -result {cascade}
  1739   1739   test menu-3.62 {MenuWidgetCmd procedure, "type" option} -setup {
  1740   1740   	destroy .m1
  1741   1741   } -body {
  1742         -    menu .m1
         1742  +    menu .m1 -tearoff 1
  1743   1743       .m1 type 0
  1744   1744   } -cleanup {
  1745   1745   	destroy .m1
  1746   1746   } -result {tearoff}
  1747   1747   test menu-3.63 {MenuWidgetCmd procedure, "unpost" option} -setup {
  1748   1748   	destroy .m1
  1749   1749   } -body {
................................................................................
  1768   1768   	destroy .m1
  1769   1769   } -body {
  1770   1770       menu .m1
  1771   1771       .m1 yposition
  1772   1772   } -cleanup {
  1773   1773   	destroy .m1
  1774   1774   } -returnCodes error -result {wrong # args: should be ".m1 yposition index"}
  1775         -test menu-3.66 {MenuWidgetCmd procedure, "yposition" option} -setup {
         1775  +test menu-3.66a {MenuWidgetCmd procedure, "yposition" option, no tearoff} -setup {
  1776   1776   	destroy .m1
  1777   1777   } -body {
  1778         -    menu .m1
         1778  +    menu .m1 -tearoff 0
         1779  +    .m1 yposition 1
         1780  +} -cleanup {
         1781  +	destroy .m1
         1782  +} -result {0}
         1783  +test menu-3.66b {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
         1784  +    notAqua
         1785  +} -setup {
         1786  +	destroy .m1
         1787  +} -body {
         1788  +    # on Win or Linux, tearoff menus are supported
         1789  +    # see menu-3.66c for aqua
         1790  +    menu .m1 -tearoff 1
  1779   1791       .m1 yposition 1
  1780   1792   } -cleanup {
  1781   1793   	destroy .m1
  1782   1794   } -result {1}
         1795  +test menu-3.66c {MenuWidgetCmd procedure, "yposition" option, with tearoff} -constraints {
         1796  +    aqua
         1797  +} -setup {
         1798  +	destroy .m1
         1799  +} -body {
         1800  +    # on OS X, tearoff menus are not supported
         1801  +    # see menu-3.66b for win or linux
         1802  +    menu .m1 -tearoff 1
         1803  +    .m1 yposition 1
         1804  +} -cleanup {
         1805  +	destroy .m1
         1806  +} -result {0}
  1783   1807   test menu-3.67 {MenuWidgetCmd procedure, bad option} -setup {
  1784   1808   	destroy .m1
  1785   1809   } -body {
  1786   1810       menu .m1
  1787   1811       .m1 foo
  1788   1812   } -cleanup {
  1789   1813   	destroy .m1
................................................................................
  1879   1903   } -cleanup {
  1880   1904   	destroy .m1
  1881   1905   } -result {0 {} 0 on 0 {}}
  1882   1906   test menu-4.6 {TkInvokeMenu: radiobutton} -setup {
  1883   1907       destroy .m1
  1884   1908   } -body {
  1885   1909       catch {unset foo}
  1886         -    menu .m1
         1910  +    menu .m1 -tearoff 1
  1887   1911       .m1 add radiobutton -label "1" -variable foo -value one
  1888   1912       .m1 add radiobutton -label "2" -variable foo -value two
  1889   1913       .m1 add radiobutton -label "3" -variable foo -value three
  1890   1914       list [catch {.m1 invoke 1} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
  1891   1915   } -cleanup {
  1892   1916   	destroy .m1
  1893   1917   } -result {0 {} 0 one 0 {}}
  1894   1918   test menu-4.7 {TkInvokeMenu: radiobutton} -setup {
  1895   1919       destroy .m1
  1896   1920   } -body {
  1897   1921       catch {unset foo}
  1898         -    menu .m1
         1922  +    menu .m1 -tearoff 1
  1899   1923       .m1 add radiobutton -label "1" -variable foo -value one
  1900   1924       .m1 add radiobutton -label "2" -variable foo -value two
  1901   1925       .m1 add radiobutton -label "3" -variable foo -value three
  1902   1926       list [catch {.m1 invoke 2} msg] $msg [catch {set foo} msg2] $msg2 [catch {unset foo} msg3] $msg3
  1903   1927   } -cleanup {
  1904   1928   	destroy .m1
  1905   1929   } -result {0 {} 0 two 0 {}}
................................................................................
  1945   1969       list [catch {.m1 invoke 1} msg] $msg 
  1946   1970   } -cleanup {
  1947   1971   	destroy .m1
  1948   1972   } -result {0 {}}
  1949   1973   test menu-4.12 {TkInvokeMenu} -setup {
  1950   1974       destroy .m1
  1951   1975   } -body {
  1952         -    menu .m1
         1976  +    menu .m1 -tearoff 1
  1953   1977       .m1 add command -label "test" -command ".m1 delete 1"
  1954   1978       list [catch {.m1 invoke 1} msg] $msg [catch {.m1 type "test"} msg2] $msg2
  1955   1979   } -cleanup {
  1956   1980   	destroy .m1
  1957   1981   } -result {0 {} 1 {bad menu entry index "test"}}
  1958   1982   
  1959   1983   test menu-5.1 {DestroyMenuInstance} -setup {
................................................................................
  2333   2357       menu .m1
  2334   2358       .m1 add command -label "test"
  2335   2359       list [.m1 delete 1] [destroy .m1]
  2336   2360   } -result {{} {}}
  2337   2361   test menu-8.6 {DestroyMenuEntry} -setup {
  2338   2362       destroy .m1
  2339   2363   } -body {
  2340         -    menu .m1
         2364  +    menu .m1 -tearoff 1
  2341   2365       .m1 add command -label "one"
  2342   2366       .m1 add command -label "two"
  2343   2367       list [.m1 delete 1] [.m1 entrycget 1 -label] [destroy .m1]
  2344   2368   } -result {{} two {}}
  2345   2369   test menu-8.7 {DestroyMenuEntry} -setup {
  2346   2370   	deleteWindows
  2347   2371   } -body {
................................................................................
  2733   2757       deleteWindows
  2734   2758   } -result {}
  2735   2759   
  2736   2760   
  2737   2761   test menu-13.1 {TkGetMenuIndex} -setup {
  2738   2762       deleteWindows
  2739   2763   } -body {
  2740         -    menu .m1
         2764  +    menu .m1 -tearoff 1
  2741   2765       .m1 add command -label "active"
  2742   2766       .m1 add command -label "test2"
  2743   2767       .m1 add command -label "test3"
  2744   2768       .m1 activate 2
  2745   2769       .m1 entrycget active -label
  2746   2770   } -cleanup {
  2747   2771       deleteWindows
................................................................................
  2800   2824   } -cleanup {
  2801   2825       deleteWindows
  2802   2826   } -result {}
  2803   2827   #test menu-13.7 - Need to add @test here.
  2804   2828   test menu-13.7 {TkGetMenuIndex} -setup {
  2805   2829       deleteWindows
  2806   2830   } -body {
  2807         -    menu .m1
         2831  +    menu .m1 -tearoff 1
  2808   2832       .m1 add command -label "active"
  2809   2833       .m1 add command -label "test2"
  2810   2834       .m1 add command -label "test3"
  2811   2835       .m1 entrycget 1 -label
  2812   2836   } -cleanup {
  2813   2837       deleteWindows
  2814   2838   } -result {active}
................................................................................
  2933   2957   } -body {
  2934   2958       menu .m1
  2935   2959       .m1 insert -1 command -label "test"
  2936   2960   } -returnCodes error -result {bad menu entry index "-1"}
  2937   2961   test menu-16.4 {MenuAddOrInsert} -setup {
  2938   2962   	deleteWindows
  2939   2963   } -body {
  2940         -    menu .m1
         2964  +    menu .m1 -tearoff 1
  2941   2965       .m1 add command -label "test"
  2942   2966       .m1 insert 0 command -label "test2"
  2943   2967       .m1 entrycget 1 -label
  2944   2968   } -cleanup {
  2945   2969   	deleteWindows
  2946   2970   } -result {test2}
  2947   2971   test menu-16.5 {MenuAddOrInsert} -setup {
................................................................................
  3273   3297       .m1 clone .foo
  3274   3298   } -cleanup {
  3275   3299   	deleteWindows
  3276   3300   } -result {}
  3277   3301   test menu-20.10 {CloneMenu - tearoff fields} -setup {
  3278   3302   	deleteWindows
  3279   3303   } -body {
  3280         -    menu .m1
         3304  +    menu .m1 -tearoff 1
  3281   3305       list [.m1 clone .m2 normal] [.m2 cget -tearoff]
  3282   3306   } -cleanup {
  3283   3307   	deleteWindows
  3284   3308   } -result {{} 1}
  3285   3309   test menu-20.11 {CloneMenu} -setup {
  3286   3310   	deleteWindows
  3287   3311   } -body {
................................................................................
  3324   3348       .m1 configure -tearoff 0
  3325   3349       .m1 index @5,5
  3326   3350   } -cleanup {
  3327   3351   	deleteWindows
  3328   3352   } -result {0}
  3329   3353   test menu-22.3 {GetIndexFromCoords: mapped window, y only} -setup {
  3330   3354   	deleteWindows
  3331         -} -constraints {unix} -body {
         3355  +} -constraints {x11} -body {
  3332   3356       menu .m1
  3333   3357       .m1 add command -label "test"
  3334   3358       .m1 configure -tearoff 0
  3335   3359       tk_popup .m1 0 0
  3336   3360       tkwait visibility .m1
  3337   3361       .m1 index @5
  3338   3362   } -cleanup {
  3339   3363   	deleteWindows
  3340   3364   } -result {0}
  3341   3365   test menu-22.4 {GetIndexFromCoords: mapped window x,y} -setup {
  3342   3366   	deleteWindows
  3343         -} -constraints {unix} -body {
         3367  +} -constraints {x11} -body {
  3344   3368       menu .m1
  3345   3369       .m1 add command -label "test"
  3346   3370       .m1 configure -tearoff 0
  3347   3371       tk_popup .m1 0 0
  3348   3372       tkwait visibility .m1
  3349   3373       update
  3350   3374       set x [expr {[winfo width .m1] - [.m1 cget -borderwidth] - 1}]
  3351   3375       .m1 index @$x,5
  3352   3376   } -cleanup {
  3353   3377   	deleteWindows
  3354   3378   } -result {0}
  3355   3379   test menu-22.5 {GetIndexFromCoords: mapped wide window} -setup {
  3356   3380   	deleteWindows
  3357         -} -constraints {unix} -body {
         3381  +} -constraints {x11} -body {
  3358   3382       menu .m1
  3359   3383       .m1 add command -label "test"
  3360   3384       .m1 configure -tearoff 0
  3361   3385       tk_popup .m1 0 0
  3362   3386       tkwait visibility .m1
  3363   3387       wm geometry .m1 200x100
  3364   3388       update

Changes to tests/menuDraw.test.

   643    643       menu .m1
   644    644       .m1 add cascade -label test
   645    645       set tearoff [tk::TearOffMenu .m1 40 40]
   646    646       $tearoff postcascade 0
   647    647   } -cleanup {
   648    648       deleteWindows
   649    649   } -result {}
   650         -test menuDraw-16.5 {TkPostSubMenu} -constraints unix -setup {
          650  +test menuDraw-16.5 {TkPostSubMenu} -setup {
   651    651       deleteWindows
   652    652   } -body {
   653    653       menu .m1
   654    654       .m1 add cascade -label test -menu .m2
   655    655       menu .m2 -postcommand "glorp"
   656    656       set tearoff [tk::TearOffMenu .m1 40 40]
   657    657       $tearoff postcascade test

Changes to tests/packgrid.test.

   241    241       pack .g
   242    242       pack .p
   243    243       grid .g
   244    244   }  -returnCodes error -cleanup {
   245    245       destroy .p
   246    246       destroy .g
   247    247   } -result {cannot use geometry manager grid inside . which already has slaves managed by pack}
          248  +
          249  +test packgrid-4.1 {slave stolen after master destruction - bug [aa7679685e]} -setup {
          250  +    frame .f
          251  +    button .b -text hello
          252  +} -body {
          253  +    pack .f
          254  +    grid .b -in .f
          255  +    destroy .f
          256  +    set res [winfo manager .b]
          257  +    # shall not crash
          258  +    pack .b
          259  +    set res
          260  +} -cleanup {
          261  +    destroy .b
          262  +} -result {}
          263  +
          264  +test packgrid-4.2 {slave stolen after master destruction - bug [aa7679685e]} -setup {
          265  +    frame .f
          266  +    button .b -text hello
          267  +} -body {
          268  +    pack .f
          269  +    pack .b -in .f
          270  +    destroy .f
          271  +    set res [winfo manager .b]
          272  +    # shall not crash
          273  +    grid .b
          274  +    set res
          275  +} -cleanup {
          276  +    destroy .b
          277  +} -result {}
   248    278   
   249    279   cleanupTests
   250    280   return

Added tests/safePrimarySelection.test.

            1  +# This file is a Tcl script to test entry widgets in Tk.  It is
            2  +# organized in the standard fashion for Tcl tests.
            3  +#
            4  +# Copyright (c) 1994 The Regents of the University of California.
            5  +# Copyright (c) 1994-1997 Sun Microsystems, Inc.
            6  +# Copyright (c) 1998-1999 by Scriptics Corporation.
            7  +# All rights reserved.
            8  +
            9  +package require tcltest 2.2
           10  +namespace import ::tcltest::*
           11  +eval tcltest::configure $argv
           12  +tcltest::loadTestedCommands
           13  +
           14  +# ------------------------------------------------------------------------------
           15  +# Tests that a Safe Base interpreter cannot write to the PRIMARY selection.
           16  +# ------------------------------------------------------------------------------
           17  +# - Tests 3.*, 6.* test that the fix for ticket de156e9efe implemented in branch
           18  +#   bug-de156e9efe has been applied and still works.  They test that a Safe Base
           19  +#   slave interpreter cannot write to the PRIMARY selection.
           20  +# - The other tests verify that the master interpreter and an unsafe slave CAN
           21  +#   write to the PRIMARY selection, and therefore that the test scripts
           22  +#   themselves are valid.
           23  +# - A text, entry, ttk::entry, listbox, spinbox or ttk::spinbox widget can have
           24  +#   option -exportselection 1, meaning (in an unsafe interpreter) that a
           25  +#   selection made in one of these widgets is automatically written to the
           26  +#   PRIMARY selection.
           27  +# - A safe interpreter must not write to the PRIMARY selection.
           28  +# - The spinbox, ttk::spinbox are variants of entry, ttk::entry respectively.
           29  +# ------------------------------------------------------------------------------
           30  +
           31  +namespace eval ::_test_tmp {}
           32  +
           33  +# ------------------------------------------------------------------------------
           34  +#  Proc ::_test_tmp::unsafeInterp
           35  +# ------------------------------------------------------------------------------
           36  +# Command that creates an unsafe child interpreter and tries to load Tk.
           37  +# - This is necessary for loading Tk if the tests are done in the build
           38  +#   directory without installing Tk.  In that case the usual auto_path loading
           39  +#   mechanism cannot work because the tk binary is not where pkgIndex.tcl says
           40  +#   it is.
           41  +# - This command is not needed for Safe Base slaves because safe::loadTk does
           42  +#   something similar and works correctly.
           43  +# - Based on scripts in winSend.test.
           44  +# ------------------------------------------------------------------------------
           45  +
           46  +namespace eval ::_test_tmp {
           47  +    variable TkLoadCmd
           48  +}
           49  +
           50  +foreach pkg [info loaded] {
           51  +    if {[lindex $pkg 1] eq "Tk"} {
           52  +	set ::_test_tmp::TkLoadCmd [list load {*}$pkg]
           53  +	break
           54  +    }
           55  +}
           56  +
           57  +proc ::_test_tmp::unsafeInterp {name} {
           58  +    variable TkLoadCmd
           59  +    interp create $name
           60  +    $name eval [list set argv [list -name $name]]
           61  +    catch {{*}$TkLoadCmd $name}
           62  +}
           63  +
           64  +
           65  +set ::_test_tmp::script {
           66  +    package require Tk
           67  +    namespace eval ::_test_tmp {}
           68  +
           69  +    proc ::_test_tmp::getPrimarySelection {} {
           70  +        if {[catch {::tk::GetSelection . PRIMARY} sel]} {
           71  +            set sel {}
           72  +        }
           73  +        return $sel
           74  +    }
           75  +
           76  +    proc ::_test_tmp::setPrimarySelection {} {
           77  +        destroy .preset
           78  +        text .preset -exportselection 1
           79  +        .preset insert end OLD_VALUE
           80  +        # pack .preset
           81  +        .preset tag add sel 1.0 end-1c
           82  +        update
           83  +        return
           84  +    }
           85  +
           86  +    # Clearing the PRIMARY selection is troublesome.
           87  +    # The window need not be mapped.
           88  +    # However, the window must continue to exist, or some X11 servers
           89  +    # will set the PRIMARY selection to something else.
           90  +    proc ::_test_tmp::clearPrimarySelection {} {
           91  +        destroy .clear
           92  +        text .clear -exportselection 1
           93  +        .clear insert end TMP_VALUE
           94  +        # pack .clear
           95  +        .clear tag add sel 1.0 end-1c
           96  +        update
           97  +        .clear tag remove sel 1.0 end-1c
           98  +        update
           99  +        return
          100  +    }
          101  +
          102  +    # If this interpreter can write to the PRIMARY
          103  +    # selection, the commands below will do so.
          104  +
          105  +    proc ::_test_tmp::tryText {} {
          106  +        text .t -exportselection 1
          107  +        .t insert end PAYLOAD
          108  +        pack .t
          109  +        .t tag add sel 1.0 end-1c
          110  +        update
          111  +        return
          112  +    }
          113  +
          114  +    proc ::_test_tmp::tryEntry {} {
          115  +        entry .t -exportselection 1
          116  +        .t insert end PAYLOAD
          117  +        pack .t
          118  +        .t selection range 0 end
          119  +        update
          120  +        return
          121  +    }
          122  +
          123  +    proc ::_test_tmp::tryTtkEntry {} {
          124  +        ::ttk::entry .t -exportselection 1
          125  +        .t insert end PAYLOAD
          126  +        pack .t
          127  +        .t selection range 0 end
          128  +        update
          129  +        return
          130  +    }
          131  +
          132  +    proc ::_test_tmp::tryListbox {} {
          133  +        listbox .t -exportselection 1
          134  +        .t insert end list1 PAYLOAD list3
          135  +        pack .t
          136  +        .t selection set 1
          137  +        update
          138  +        return
          139  +    }
          140  +
          141  +    proc ::_test_tmp::trySpinbox {ver} {
          142  +        if {$ver == 1} {
          143  +            # spinbox as entry
          144  +            spinbox .t -exportselection 1 -values {1 2 3 4 5}
          145  +            .t delete 0 end
          146  +            .t insert end PAYLOAD
          147  +            pack .t
          148  +            .t selection range 0 end
          149  +            update
          150  +            return
          151  +            # selects PAYLOAD
          152  +        } elseif {$ver == 2} {
          153  +            # spinbox spun
          154  +            spinbox .t -exportselection 1 -values {1 2 3 4 5}
          155  +            .t invoke buttonup
          156  +            pack .t
          157  +            .t selection range 0 end
          158  +            update
          159  +            return
          160  +            # selects 2
          161  +        } else {
          162  +            # spinbox spun/selected/spun
          163  +            spinbox .t -exportselection 1 -values {1 2 3 4 5}
          164  +            .t invoke buttonup
          165  +            pack .t
          166  +            .t selection range 0 end
          167  +            update
          168  +            .t invoke buttonup
          169  +            update
          170  +            return
          171  +            # selects 3
          172  +        }
          173  +    }
          174  +
          175  +    proc ::_test_tmp::tryTtkSpinbox {ver} {
          176  +        if {$ver == 1} {
          177  +            # ttk::spinbox as entry
          178  +            ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5}
          179  +            .t delete 0 end
          180  +            .t insert end PAYLOAD
          181  +            pack .t
          182  +            .t selection range 0 end
          183  +            update
          184  +            return
          185  +        } elseif {$ver == 2} {
          186  +            # ttk::spinbox spun
          187  +            ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5}
          188  +            ::ttk::spinbox::Spin .t +1
          189  +            ::ttk::spinbox::Spin .t +1
          190  +            pack .t
          191  +            # ttk::spinbox::Spin sets selection
          192  +            update
          193  +            return
          194  +            # selects 2
          195  +        } else {
          196  +            # ttk::spinbox spun/selected/spun
          197  +            ::ttk::spinbox .t -exportselection 1 -values {1 2 3 4 5}
          198  +            ::ttk::spinbox::Spin .t +1
          199  +            ::ttk::spinbox::Spin .t +1
          200  +            pack .t
          201  +            # ttk::spinbox::Spin sets selection
          202  +            update
          203  +            ::ttk::spinbox::Spin .t +1
          204  +            update
          205  +            return
          206  +            # selects 3
          207  +        }
          208  +    }
          209  +}
          210  +
          211  +# Do this once for the master interpreter.
          212  +eval $::_test_tmp::script
          213  +
          214  +test safePrimarySelection-1.1 {master interpreter, text, no existing selection} -setup {
          215  +    catch {interp delete slave2}
          216  +    destroy {*}[winfo children .]
          217  +    ::_test_tmp::clearPrimarySelection
          218  +} -body {
          219  +    ::_test_tmp::tryText
          220  +    ::_test_tmp::getPrimarySelection
          221  +} -cleanup {
          222  +    destroy {*}[winfo children .]
          223  +    ::_test_tmp::clearPrimarySelection
          224  +} -result {PAYLOAD}
          225  +
          226  +test safePrimarySelection-1.2 {master interpreter, entry, no existing selection} -setup {
          227  +    catch {interp delete slave2}
          228  +    destroy {*}[winfo children .]
          229  +    ::_test_tmp::clearPrimarySelection
          230  +} -body {
          231  +    ::_test_tmp::tryEntry
          232  +    ::_test_tmp::getPrimarySelection
          233  +} -cleanup {
          234  +    destroy {*}[winfo children .]
          235  +    ::_test_tmp::clearPrimarySelection
          236  +} -result {PAYLOAD}
          237  +
          238  +test safePrimarySelection-1.3 {master interpreter, ttk::entry, no existing selection} -setup {
          239  +    catch {interp delete slave2}
          240  +    destroy {*}[winfo children .]
          241  +    ::_test_tmp::clearPrimarySelection
          242  +} -body {
          243  +    ::_test_tmp::tryTtkEntry
          244  +    ::_test_tmp::getPrimarySelection
          245  +} -cleanup {
          246  +    destroy {*}[winfo children .]
          247  +    ::_test_tmp::clearPrimarySelection
          248  +} -result {PAYLOAD}
          249  +
          250  +test safePrimarySelection-1.4 {master interpreter, listbox, no existing selection} -setup {
          251  +    catch {interp delete slave2}
          252  +    destroy {*}[winfo children .]
          253  +    ::_test_tmp::clearPrimarySelection
          254  +} -body {
          255  +    ::_test_tmp::tryListbox
          256  +    ::_test_tmp::getPrimarySelection
          257  +} -cleanup {
          258  +    destroy {*}[winfo children .]
          259  +    ::_test_tmp::clearPrimarySelection
          260  +} -result {PAYLOAD}
          261  +
          262  +test safePrimarySelection-1.5 {master interpreter, spinbox as entry, no existing selection} -setup {
          263  +    catch {interp delete slave2}
          264  +    destroy {*}[winfo children .]
          265  +    ::_test_tmp::clearPrimarySelection
          266  +} -body {
          267  +    ::_test_tmp::trySpinbox 1
          268  +    ::_test_tmp::getPrimarySelection
          269  +} -cleanup {
          270  +    destroy {*}[winfo children .]
          271  +    ::_test_tmp::clearPrimarySelection
          272  +} -result {PAYLOAD}
          273  +
          274  +test safePrimarySelection-1.6 {master interpreter, spinbox spun, no existing selection} -setup {
          275  +    catch {interp delete slave2}
          276  +    destroy {*}[winfo children .]
          277  +    ::_test_tmp::clearPrimarySelection
          278  +} -body {
          279  +    ::_test_tmp::trySpinbox 2
          280  +    ::_test_tmp::getPrimarySelection
          281  +} -cleanup {
          282  +    destroy {*}[winfo children .]
          283  +    ::_test_tmp::clearPrimarySelection
          284  +} -result {2}
          285  +
          286  +test safePrimarySelection-1.7 {master interpreter, spinbox spun/selected/spun, no existing selection} -setup {
          287  +    catch {interp delete slave2}
          288  +    destroy {*}[winfo children .]
          289  +    ::_test_tmp::clearPrimarySelection
          290  +} -body {
          291  +    ::_test_tmp::trySpinbox 3
          292  +    ::_test_tmp::getPrimarySelection
          293  +} -cleanup {
          294  +    destroy {*}[winfo children .]
          295  +    ::_test_tmp::clearPrimarySelection
          296  +} -result {3}
          297  +
          298  +test safePrimarySelection-1.8 {master interpreter, ttk::spinbox as entry, no existing selection} -setup {
          299  +    catch {interp delete slave2}
          300  +    destroy {*}[winfo children .]
          301  +    ::_test_tmp::clearPrimarySelection
          302  +} -body {
          303  +    ::_test_tmp::tryTtkSpinbox 1
          304  +    ::_test_tmp::getPrimarySelection
          305  +} -cleanup {
          306  +    destroy {*}[winfo children .]
          307  +    ::_test_tmp::clearPrimarySelection
          308  +} -result {PAYLOAD}
          309  +
          310  +test safePrimarySelection-1.9 {master interpreter, ttk::spinbox spun, no existing selection} -setup {
          311  +    catch {interp delete slave2}
          312  +    destroy {*}[winfo children .]
          313  +    ::_test_tmp::clearPrimarySelection
          314  +} -body {
          315  +    ::_test_tmp::tryTtkSpinbox 2
          316  +    ::_test_tmp::getPrimarySelection
          317  +} -cleanup {
          318  +    destroy {*}[winfo children .]
          319  +    ::_test_tmp::clearPrimarySelection
          320  +} -result {2}
          321  +
          322  +test safePrimarySelection-1.10 {master interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
          323  +    catch {interp delete slave2}
          324  +    destroy {*}[winfo children .]
          325  +    ::_test_tmp::clearPrimarySelection
          326  +} -body {
          327  +    ::_test_tmp::tryTtkSpinbox 3
          328  +    ::_test_tmp::getPrimarySelection
          329  +} -cleanup {
          330  +    destroy {*}[winfo children .]
          331  +    ::_test_tmp::clearPrimarySelection
          332  +} -result {3}
          333  +
          334  +test safePrimarySelection-2.1 {unsafe slave interpreter, text, no existing selection} -setup {
          335  +    catch {interp delete slave2}
          336  +    destroy {*}[winfo children .]
          337  +    ::_test_tmp::clearPrimarySelection
          338  +} -body {
          339  +    set int2 slave2
          340  +    ::_test_tmp::unsafeInterp $int2
          341  +    $int2 eval $::_test_tmp::script
          342  +    $int2 eval ::_test_tmp::tryText
          343  +    $int2 eval ::_test_tmp::getPrimarySelection
          344  +} -cleanup {
          345  +    interp delete $int2
          346  +    destroy {*}[winfo children .]
          347  +    unset int2
          348  +    ::_test_tmp::clearPrimarySelection
          349  +} -result {PAYLOAD}
          350  +
          351  +test safePrimarySelection-2.2 {unsafe slave interpreter, entry, no existing selection} -setup {
          352  +    catch {interp delete slave2}
          353  +    destroy {*}[winfo children .]
          354  +    ::_test_tmp::clearPrimarySelection
          355  +} -body {
          356  +    set int2 slave2
          357  +    ::_test_tmp::unsafeInterp $int2
          358  +    $int2 eval $::_test_tmp::script
          359  +    $int2 eval ::_test_tmp::tryEntry
          360  +    $int2 eval ::_test_tmp::getPrimarySelection
          361  +} -cleanup {
          362  +    interp delete $int2
          363  +    destroy {*}[winfo children .]
          364  +    unset int2
          365  +    ::_test_tmp::clearPrimarySelection
          366  +} -result {PAYLOAD}
          367  +
          368  +test safePrimarySelection-2.3 {unsafe slave interpreter, ttk::entry, no existing selection} -setup {
          369  +    catch {interp delete slave2}
          370  +    destroy {*}[winfo children .]
          371  +    ::_test_tmp::clearPrimarySelection
          372  +} -body {
          373  +    set int2 slave2
          374  +    ::_test_tmp::unsafeInterp $int2
          375  +    $int2 eval $::_test_tmp::script
          376  +    $int2 eval ::_test_tmp::tryTtkEntry
          377  +    $int2 eval ::_test_tmp::getPrimarySelection
          378  +} -cleanup {
          379  +    interp delete $int2
          380  +    destroy {*}[winfo children .]
          381  +    unset int2
          382  +    ::_test_tmp::clearPrimarySelection
          383  +} -result {PAYLOAD}
          384  +
          385  +test safePrimarySelection-2.4 {unsafe slave interpreter, listbox, no existing selection} -setup {
          386  +    catch {interp delete slave2}
          387  +    destroy {*}[winfo children .]
          388  +    ::_test_tmp::clearPrimarySelection
          389  +} -body {
          390  +    set int2 slave2
          391  +    ::_test_tmp::unsafeInterp $int2
          392  +    $int2 eval $::_test_tmp::script
          393  +    $int2 eval ::_test_tmp::tryListbox
          394  +    $int2 eval ::_test_tmp::getPrimarySelection
          395  +} -cleanup {
          396  +    interp delete $int2
          397  +    destroy {*}[winfo children .]
          398  +    unset int2
          399  +    ::_test_tmp::clearPrimarySelection
          400  +} -result {PAYLOAD}
          401  +
          402  +test safePrimarySelection-2.5 {unsafe slave interpreter, spinbox as entry, no existing selection} -setup {
          403  +    catch {interp delete slave2}
          404  +    destroy {*}[winfo children .]
          405  +    ::_test_tmp::clearPrimarySelection
          406  +} -body {
          407  +    set int2 slave2
          408  +    ::_test_tmp::unsafeInterp $int2
          409  +    $int2 eval $::_test_tmp::script
          410  +    $int2 eval ::_test_tmp::trySpinbox 1
          411  +    $int2 eval ::_test_tmp::getPrimarySelection
          412  +} -cleanup {
          413  +    interp delete $int2
          414  +    destroy {*}[winfo children .]
          415  +    unset int2
          416  +    ::_test_tmp::clearPrimarySelection
          417  +} -result {PAYLOAD}
          418  +
          419  +test safePrimarySelection-2.6 {unsafe slave interpreter, spinbox spun, no existing selection} -setup {
          420  +    catch {interp delete slave2}
          421  +    destroy {*}[winfo children .]
          422  +    ::_test_tmp::clearPrimarySelection
          423  +} -body {
          424  +    set int2 slave2
          425  +    ::_test_tmp::unsafeInterp $int2
          426  +    $int2 eval $::_test_tmp::script
          427  +    $int2 eval ::_test_tmp::trySpinbox 2
          428  +    $int2 eval ::_test_tmp::getPrimarySelection
          429  +} -cleanup {
          430  +    interp delete $int2
          431  +    destroy {*}[winfo children .]
          432  +    unset int2
          433  +    ::_test_tmp::clearPrimarySelection
          434  +} -result {2}
          435  +
          436  +test safePrimarySelection-2.7 {unsafe slave interpreter, spinbox spun/selected/spun, no existing selection} -setup {
          437  +    catch {interp delete slave2}
          438  +    destroy {*}[winfo children .]
          439  +    ::_test_tmp::clearPrimarySelection
          440  +} -body {
          441  +    set int2 slave2
          442  +    ::_test_tmp::unsafeInterp $int2
          443  +    $int2 eval $::_test_tmp::script
          444  +    $int2 eval ::_test_tmp::trySpinbox 3
          445  +    $int2 eval ::_test_tmp::getPrimarySelection
          446  +} -cleanup {
          447  +    interp delete $int2
          448  +    destroy {*}[winfo children .]
          449  +    unset int2
          450  +    ::_test_tmp::clearPrimarySelection
          451  +} -result {3}
          452  +
          453  +test safePrimarySelection-2.8 {unsafe slave interpreter, ttk::spinbox as entry, no existing selection} -setup {
          454  +    catch {interp delete slave2}
          455  +    destroy {*}[winfo children .]
          456  +    ::_test_tmp::clearPrimarySelection
          457  +} -body {
          458  +    set int2 slave2
          459  +    ::_test_tmp::unsafeInterp $int2
          460  +    $int2 eval $::_test_tmp::script
          461  +    $int2 eval ::_test_tmp::tryTtkSpinbox 1
          462  +    $int2 eval ::_test_tmp::getPrimarySelection
          463  +} -cleanup {
          464  +    interp delete $int2
          465  +    destroy {*}[winfo children .]
          466  +    unset int2
          467  +    ::_test_tmp::clearPrimarySelection
          468  +} -result {PAYLOAD}
          469  +
          470  +test safePrimarySelection-2.9 {unsafe slave interpreter, ttk::spinbox spun, no existing selection} -setup {
          471  +    catch {interp delete slave2}
          472  +    destroy {*}[winfo children .]
          473  +    ::_test_tmp::clearPrimarySelection
          474  +} -body {
          475  +    set int2 slave2
          476  +    ::_test_tmp::unsafeInterp $int2
          477  +    $int2 eval $::_test_tmp::script
          478  +    $int2 eval ::_test_tmp::tryTtkSpinbox 2
          479  +    $int2 eval ::_test_tmp::getPrimarySelection
          480  +} -cleanup {
          481  +    interp delete $int2
          482  +    destroy {*}[winfo children .]
          483  +    unset int2
          484  +    ::_test_tmp::clearPrimarySelection
          485  +} -result {2}
          486  +
          487  +test safePrimarySelection-2.10 {unsafe slave interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
          488  +    catch {interp delete slave2}
          489  +    destroy {*}[winfo children .]
          490  +    ::_test_tmp::clearPrimarySelection
          491  +} -body {
          492  +    set int2 slave2
          493  +    ::_test_tmp::unsafeInterp $int2
          494  +    $int2 eval $::_test_tmp::script
          495  +    $int2 eval ::_test_tmp::tryTtkSpinbox 3
          496  +    $int2 eval ::_test_tmp::getPrimarySelection
          497  +} -cleanup {
          498  +    interp delete $int2
          499  +    destroy {*}[winfo children .]
          500  +    unset int2
          501  +    ::_test_tmp::clearPrimarySelection
          502  +} -result {3}
          503  +
          504  +test safePrimarySelection-3.1 {IMPORTANT, safe slave interpreter, text, no existing selection} -setup {
          505  +    catch {interp delete slave2}
          506  +    destroy {*}[winfo children .]
          507  +    ::_test_tmp::clearPrimarySelection
          508  +} -body {
          509  +    set res0 [::_test_tmp::getPrimarySelection]
          510  +    set int2 slave2
          511  +    ::safe::interpCreate $int2
          512  +    ::safe::loadTk $int2
          513  +    $int2 eval $::_test_tmp::script
          514  +    $int2 eval ::_test_tmp::tryText
          515  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          516  +    set res2 [::_test_tmp::getPrimarySelection]
          517  +    set res3 $res0--$res1--$res2
          518  +} -cleanup {
          519  +    interp delete $int2
          520  +    destroy {*}[winfo children .]
          521  +    unset int2 res0 res1 res2 res3
          522  +    ::_test_tmp::clearPrimarySelection
          523  +} -result {----}
          524  +
          525  +test safePrimarySelection-3.2 {IMPORTANT, safe slave interpreter, entry, no existing selection} -setup {
          526  +    catch {interp delete slave2}
          527  +    destroy {*}[winfo children .]
          528  +    ::_test_tmp::clearPrimarySelection
          529  +} -body {
          530  +    set res0 [::_test_tmp::getPrimarySelection]
          531  +    set int2 slave2
          532  +    ::safe::interpCreate $int2
          533  +    ::safe::loadTk $int2
          534  +    $int2 eval $::_test_tmp::script
          535  +    $int2 eval ::_test_tmp::tryEntry
          536  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          537  +    set res2 [::_test_tmp::getPrimarySelection]
          538  +    set res3 $res0--$res1--$res2
          539  +} -cleanup {
          540  +    interp delete $int2
          541  +    destroy {*}[winfo children .]
          542  +    unset int2 res0 res1 res2 res3
          543  +    ::_test_tmp::clearPrimarySelection
          544  +} -result {----}
          545  +
          546  +test safePrimarySelection-3.3 {IMPORTANT, safe slave interpreter, ttk::entry, no existing selection} -setup {
          547  +    catch {interp delete slave2}
          548  +    destroy {*}[winfo children .]
          549  +    ::_test_tmp::clearPrimarySelection
          550  +} -body {
          551  +    set res0 [::_test_tmp::getPrimarySelection]
          552  +    set int2 slave2
          553  +    ::safe::interpCreate $int2
          554  +    ::safe::loadTk $int2
          555  +    $int2 eval $::_test_tmp::script
          556  +    $int2 eval ::_test_tmp::tryTtkEntry
          557  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          558  +    set res2 [::_test_tmp::getPrimarySelection]
          559  +    set res3 $res0--$res1--$res2
          560  +} -cleanup {
          561  +    interp delete $int2
          562  +    destroy {*}[winfo children .]
          563  +    unset int2 res0 res1 res2 res3
          564  +    ::_test_tmp::clearPrimarySelection
          565  +} -result {----}
          566  +
          567  +test safePrimarySelection-3.4 {IMPORTANT, safe slave interpreter, listbox, no existing selection} -setup {
          568  +    catch {interp delete slave2}
          569  +    destroy {*}[winfo children .]
          570  +    ::_test_tmp::clearPrimarySelection
          571  +} -body {
          572  +    set res0 [::_test_tmp::getPrimarySelection]
          573  +    set int2 slave2
          574  +    ::safe::interpCreate $int2
          575  +    ::safe::loadTk $int2
          576  +    $int2 eval $::_test_tmp::script
          577  +    $int2 eval ::_test_tmp::tryListbox
          578  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          579  +    set res2 [::_test_tmp::getPrimarySelection]
          580  +    set res3 $res0--$res1--$res2
          581  +} -cleanup {
          582  +    interp delete $int2
          583  +    destroy {*}[winfo children .]
          584  +    unset int2 res0 res1 res2 res3
          585  +    ::_test_tmp::clearPrimarySelection
          586  +} -result {----}
          587  +
          588  +test safePrimarySelection-3.5 {IMPORTANT, safe slave interpreter, spinbox as entry, no existing selection} -setup {
          589  +    catch {interp delete slave2}
          590  +    destroy {*}[winfo children .]
          591  +    ::_test_tmp::clearPrimarySelection
          592  +} -body {
          593  +    set res0 [::_test_tmp::getPrimarySelection]
          594  +    set int2 slave2
          595  +    ::safe::interpCreate $int2
          596  +    ::safe::loadTk $int2
          597  +    $int2 eval $::_test_tmp::script
          598  +    $int2 eval ::_test_tmp::trySpinbox 1
          599  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          600  +    set res2 [::_test_tmp::getPrimarySelection]
          601  +    set res3 $res0--$res1--$res2
          602  +} -cleanup {
          603  +    interp delete $int2
          604  +    destroy {*}[winfo children .]
          605  +    unset int2 res0 res1 res2 res3
          606  +    ::_test_tmp::clearPrimarySelection
          607  +} -result {----}
          608  +
          609  +test safePrimarySelection-3.6 {IMPORTANT, safe slave interpreter, spinbox spun, no existing selection} -setup {
          610  +    catch {interp delete slave2}
          611  +    destroy {*}[winfo children .]
          612  +    ::_test_tmp::clearPrimarySelection
          613  +} -body {
          614  +    set res0 [::_test_tmp::getPrimarySelection]
          615  +    set int2 slave2
          616  +    ::safe::interpCreate $int2
          617  +    ::safe::loadTk $int2
          618  +    $int2 eval $::_test_tmp::script
          619  +    $int2 eval ::_test_tmp::trySpinbox 2
          620  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          621  +    set res2 [::_test_tmp::getPrimarySelection]
          622  +    set res3 $res0--$res1--$res2
          623  +} -cleanup {
          624  +    interp delete $int2
          625  +    destroy {*}[winfo children .]
          626  +    unset int2 res0 res1 res2 res3
          627  +    ::_test_tmp::clearPrimarySelection
          628  +} -result {----}
          629  +
          630  +test safePrimarySelection-3.7 {IMPORTANT, safe slave interpreter, spinbox spun/selected/spun, no existing selection} -setup {
          631  +    catch {interp delete slave2}
          632  +    destroy {*}[winfo children .]
          633  +    ::_test_tmp::clearPrimarySelection
          634  +} -body {
          635  +    set res0 [::_test_tmp::getPrimarySelection]
          636  +    set int2 slave2
          637  +    ::safe::interpCreate $int2
          638  +    ::safe::loadTk $int2
          639  +    $int2 eval $::_test_tmp::script
          640  +    $int2 eval ::_test_tmp::trySpinbox 3
          641  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          642  +    set res2 [::_test_tmp::getPrimarySelection]
          643  +    set res3 $res0--$res1--$res2
          644  +} -cleanup {
          645  +    interp delete $int2
          646  +    destroy {*}[winfo children .]
          647  +    unset int2 res0 res1 res2 res3
          648  +    ::_test_tmp::clearPrimarySelection
          649  +} -result {----}
          650  +
          651  +test safePrimarySelection-3.8 {IMPORTANT, safe slave interpreter, ttk::spinbox as entry, no existing selection} -setup {
          652  +    catch {interp delete slave2}
          653  +    destroy {*}[winfo children .]
          654  +    ::_test_tmp::clearPrimarySelection
          655  +} -body {
          656  +    set res0 [::_test_tmp::getPrimarySelection]
          657  +    set int2 slave2
          658  +    ::safe::interpCreate $int2
          659  +    ::safe::loadTk $int2
          660  +    $int2 eval $::_test_tmp::script
          661  +    $int2 eval ::_test_tmp::tryTtkSpinbox 1
          662  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          663  +    set res2 [::_test_tmp::getPrimarySelection]
          664  +    set res3 $res0--$res1--$res2
          665  +} -cleanup {
          666  +    interp delete $int2
          667  +    destroy {*}[winfo children .]
          668  +    unset int2 res0 res1 res2 res3
          669  +    ::_test_tmp::clearPrimarySelection
          670  +} -result {----}
          671  +
          672  +test safePrimarySelection-3.9 {IMPORTANT, safe slave interpreter, ttk::spinbox spun, no existing selection} -setup {
          673  +    catch {interp delete slave2}
          674  +    destroy {*}[winfo children .]
          675  +    ::_test_tmp::clearPrimarySelection
          676  +} -body {
          677  +    set res0 [::_test_tmp::getPrimarySelection]
          678  +    set int2 slave2
          679  +    ::safe::interpCreate $int2
          680  +    ::safe::loadTk $int2
          681  +    $int2 eval $::_test_tmp::script
          682  +    $int2 eval ::_test_tmp::tryTtkSpinbox 2
          683  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          684  +    set res2 [::_test_tmp::getPrimarySelection]
          685  +    set res3 $res0--$res1--$res2
          686  +} -cleanup {
          687  +    interp delete $int2
          688  +    destroy {*}[winfo children .]
          689  +    unset int2 res0 res1 res2 res3
          690  +    ::_test_tmp::clearPrimarySelection
          691  +} -result {----}
          692  +
          693  +test safePrimarySelection-3.10 {IMPORTANT, safe slave interpreter, ttk::spinbox spun/selected/spun, no existing selection} -setup {
          694  +    catch {interp delete slave2}
          695  +    destroy {*}[winfo children .]
          696  +    ::_test_tmp::clearPrimarySelection
          697  +} -body {
          698  +    set res0 [::_test_tmp::getPrimarySelection]
          699  +    set int2 slave2
          700  +    ::safe::interpCreate $int2
          701  +    ::safe::loadTk $int2
          702  +    $int2 eval $::_test_tmp::script
          703  +    $int2 eval ::_test_tmp::tryTtkSpinbox 3
          704  +    set res1 [$int2 eval ::_test_tmp::getPrimarySelection]
          705  +    set res2 [::_test_tmp::getPrimarySelection]
          706  +    set res3 $res0--$res1--$res2
          707  +} -cleanup {
          708  +    interp delete $int2
          709  +    destroy {*}[winfo children .]
          710  +    unset int2 res0 res1 res2 res3
          711  +    ::_test_tmp::clearPrimarySelection
          712  +} -result {----}
          713  +
          714  +test safePrimarySelection-4.1 {master interpreter, text, existing selection} -setup {
          715  +    catch {interp delete slave2}
          716  +    destroy {*}[winfo children .]
          717  +    ::_test_tmp::setPrimarySelection
          718  +} -body {
          719  +    ::_test_tmp::tryText
          720  +    ::_test_tmp::getPrimarySelection
          721  +} -cleanup {
          722  +    destroy {*}[winfo children .]
          723  +    ::_test_tmp::clearPrimarySelection
          724  +} -result {PAYLOAD}
          725  +
          726  +test safePrimarySelection-4.2 {master interpreter, entry, existing selection} -setup {
          727  +    catch {interp delete slave2}
          728  +    destroy {*}[winfo children .]
          729  +    ::_test_tmp::setPrimarySelection
          730  +} -body {
          731  +    ::_test_tmp::tryEntry
          732  +    ::_test_tmp::getPrimarySelection
          733  +} -cleanup {
          734  +    destroy {*}[winfo children .]
          735  +    ::_test_tmp::clearPrimarySelection
          736  +} -result {PAYLOAD}
          737  +
          738  +test safePrimarySelection-4.3 {master interpreter, ttk::entry, existing selection} -setup {
          739  +    catch {interp delete slave2}
          740  +    destroy {*}[winfo children .]
          741  +    ::_test_tmp::setPrimarySelection
          742  +} -body {
          743  +    ::_test_tmp::tryTtkEntry
          744  +    ::_test_tmp::getPrimarySelection
          745  +} -cleanup {
          746  +    destroy {*}[winfo children .]
          747  +    ::_test_tmp::clearPrimarySelection
          748  +} -result {PAYLOAD}
          749  +
          750  +test safePrimarySelection-4.4 {master interpreter, listbox, existing selection} -setup {
          751  +    catch {interp delete slave2}
          752  +    destroy {*}[winfo children .]
          753  +    ::_test_tmp::setPrimarySelection
          754  +} -body {
          755  +    ::_test_tmp::tryListbox
          756  +    ::_test_tmp::getPrimarySelection
          757  +} -cleanup {
          758  +    destroy {*}[winfo children .]
          759  +    ::_test_tmp::clearPrimarySelection
          760  +} -result {PAYLOAD}
          761  +
          762  +test safePrimarySelection-4.5 {master interpreter, spinbox as entry, existing selection} -setup {
          763  +    catch {interp delete slave2}
          764  +    destroy {*}[winfo children .]
          765  +    ::_test_tmp::setPrimarySelection
          766  +} -body {
          767  +    ::_test_tmp::trySpinbox 1
          768  +    ::_test_tmp::getPrimarySelection
          769  +} -cleanup {
          770  +    destroy {*}[winfo children .]
          771  +    ::_test_tmp::clearPrimarySelection
          772  +} -result {PAYLOAD}
          773  +
          774  +test safePrimarySelection-4.6 {master interpreter, spinbox spun, existing selection} -setup {
          775  +    catch {interp delete slave2}
          776  +    destroy {*}[winfo children .]
          777  +    ::_test_tmp::setPrimarySelection
          778  +} -body {
          779  +    ::_test_tmp::trySpinbox 2
          780  +    ::_test_tmp::getPrimarySelection
          781  +} -cleanup {
          782  +    destroy {*}[winfo children .]
          783  +    ::_test_tmp::clearPrimarySelection
          784  +} -result {2}
          785  +
          786  +test safePrimarySelection-4.7 {master interpreter, spinbox spun/selected/spun, existing selection} -setup {
          787  +    catch {interp delete slave2}
          788  +    destroy {*}[winfo children .]
          789  +    ::_test_tmp::setPrimarySelection
          790  +} -body {
          791  +    ::_test_tmp::trySpinbox 3
          792  +    ::_test_tmp::getPrimarySelection
          793  +} -cleanup {
          794  +    destroy {*}[winfo children .]
          795  +    ::_test_tmp::clearPrimarySelection
          796  +} -result {3}
          797  +
          798  +test safePrimarySelection-4.8 {master interpreter, ttk::spinbox as entry, existing selection} -setup {
          799  +    catch {interp delete slave2}
          800  +    destroy {*}[winfo children .]
          801  +    ::_test_tmp::setPrimarySelection
          802  +} -body {
          803  +    ::_test_tmp::tryTtkSpinbox 1
          804  +    ::_test_tmp::getPrimarySelection
          805  +} -cleanup {
          806  +    destroy {*}[winfo children .]
          807  +    ::_test_tmp::clearPrimarySelection
          808  +} -result {PAYLOAD}
          809  +
          810  +test safePrimarySelection-4.9 {master interpreter, ttk::spinbox spun, existing selection} -setup {
          811  +    catch {interp delete slave2}
          812  +    destroy {*}[winfo children .]
          813  +    ::_test_tmp::setPrimarySelection
          814  +} -body {
          815  +    ::_test_tmp::tryTtkSpinbox 2
          816  +    ::_test_tmp::getPrimarySelection
          817  +} -cleanup {
          818  +    destroy {*}[winfo children .]
          819  +    ::_test_tmp::clearPrimarySelection
          820  +} -result {2}
          821  +
          822  +test safePrimarySelection-4.10 {master interpreter, ttk::spinbox spun/selected/spun, existing selection} -setup {
          823  +    catch {interp delete slave2}
          824  +    destroy {*}[winfo children .]
          825  +    ::_test_tmp::setPrimarySelection
          826  +} -body {
          827  +    ::_test_tmp::tryTtkSpinbox 3
          828  +    ::_test_tmp::getPrimarySelection
          829  +} -cleanup {
          830  +    destroy {*}[winfo children .]
          831  +    ::_test_tmp::clearPrimarySelection
          832  +} -result {3}
          833  +
          834  +test safePrimarySelection-5.1 {unsafe slave interpreter, text, existing selection} -setup {
          835  +    catch {interp delete slave2}
          836  +    destroy {*}[winfo children .]
          837  +    ::_test_tmp::setPrimarySelection
          838  +} -body {
          839  +    set int2 slave2
          840  +    ::_test_tmp::unsafeInterp $int2
          841  +    $int2 eval $::_test_tmp::script
          842  +    $int2 eval ::_test_tmp::tryText
          843  +    $int2 eval ::_test_tmp::getPrimarySelection
          844  +} -cleanup {
          845  +    interp delete $int2
          846  +    destroy {*}[winfo children .]
          847  +    unset int2
          848  +    ::_test_tmp::clearPrimarySelection
          849  +} -result {PAYLOAD}
          850  +
          851  +test safePrimarySelection-5.2 {unsafe slave interpreter, entry, existing selection} -setup {
          852  +    catch {interp delete slave2}
          853  +    destroy {*}[winfo children .]
          854  +    ::_test_tmp::setPrimarySelection
          855  +} -body {
          856  +    set int2 slave2
          857  +    ::_test_tmp::unsafeInterp $int2
          858  +    $int2 eval $::_test_tmp::script
          859  +    $int2 eval ::_test_tmp::tryEntry
          860  +    $int2 eval ::_test_tmp::getPrimarySelection
          861  +} -cleanup {
          862  +    interp