ADDED .fossil-settings/crlf-glob Index: .fossil-settings/crlf-glob ================================================================== --- /dev/null +++ .fossil-settings/crlf-glob @@ -0,0 +1,2 @@ +win/*.bat +win/*.vc Index: .fossil-settings/crnl-glob ================================================================== --- .fossil-settings/crnl-glob +++ .fossil-settings/crnl-glob @@ -1,6 +1,2 @@ -win/buildall.vc.bat -win/makefile.bc -win/makefile.vc -win/mkd.bat -win/rmd.bat -win/rules.vc +win/*.bat +win/*.vc Index: .fossil-settings/encoding-glob ================================================================== --- .fossil-settings/encoding-glob +++ .fossil-settings/encoding-glob @@ -1,6 +1,3 @@ win/buildall.vc.bat -win/makefile.bc win/makefile.vc -win/mkd.bat -win/rmd.bat win/rules.vc Index: .fossil-settings/ignore-glob ================================================================== --- .fossil-settings/ignore-glob +++ .fossil-settings/ignore-glob @@ -4,10 +4,11 @@ *.exe *.exp *.lib *.o *.obj +*.pdb *.res *.sl *.so */Makefile */config.cache @@ -16,6 +17,11 @@ */tkConfig.sh */wish* */tktest* */versions.vc doc/man.macros +win/Debug* +win/Release* +win/nmhlp-out.txt +win/nmakehlp.out unix/tk.pc +html/* Index: .project ================================================================== --- .project +++ .project @@ -1,8 +1,8 @@ - tk8.6 + tk8.7 Index: ChangeLog.2002 ================================================================== --- ChangeLog.2002 +++ ChangeLog.2002 @@ -2236,11 +2236,11 @@ * unix/tkUnixWm.c (CreateWrapper): Removed redundat setting of inputContext to null. * win/Makefile.in: changed gdb and shell targets to properly build - all binaries before running (otherwise an error often occured). + all binaries before running (otherwise an error often occurred). 2002-03-28 David Gravereaux * win/.cvsignore (new): * win/lamp.bmp (new): Index: ChangeLog.2004 ================================================================== --- ChangeLog.2004 +++ ChangeLog.2004 @@ -809,11 +809,11 @@ default canvas origin. [Bug 956681] 2004-07-05 George Peter Staplin * generic/tkEvent.c: TK_XIM_SPOT preprocessor usage was modified - slightly to fix a bug that occured when TK_XIM_SPOT was defined as 0. + slightly to fix a bug that occurred when TK_XIM_SPOT was defined as 0. Thanks to Joe Mistachkin for reporting this bug. 2004-07-05 Donal K. Fellows TIP#158 IMPLEMENTATION Index: README ================================================================== --- README +++ README @@ -1,7 +1,7 @@ README: Tk - This is the Tk 8.6.6 source distribution. + This is the Tk 8.7a2 source distribution. http://sourceforge.net/projects/tcl/files/Tcl/ You can get any source release of Tk from the URL above. 1. Introduction --------------- @@ -8,13 +8,13 @@ This directory contains the sources and documentation for Tk, an X11 toolkit implemented with the Tcl scripting language. For details on features, incompatibilities, and potential problems with -this release, see the Tcl/Tk 8.6 Web page at +this release, see the Tcl/Tk 8.7 Web page at - http://www.tcl.tk/software/tcltk/8.6.html + http://www.tcl.tk/software/tcltk/8.7.html or refer to the "changes" file in this directory, which contains a historical record of all changes to Tk. Tk is maintained, enhanced, and distributed freely by the Tcl community. Index: changes ================================================================== --- changes +++ changes @@ -1313,11 +1313,11 @@ 2/19/94 (bug fix) Modified tkBind.c to save and restore the interpreter's result across the execution of binding scripts. Otherwise if an event triggers in the middle of some other script (e.g. a destroy event during window creation, because there was an error in the creation command), -the intepreter's result gets lost. +the interpreter's result gets lost. 2/19/94 (bug fix) Fixed bug in dealing with results of sent command that could cause them to get lost in some situations. 2/21/94 (bug fix) Don't let user close a dialog window created by @@ -5097,11 +5097,11 @@ 2001-08-28 (bug fix) fixed tk_chooseDirectory crash on Win95. (baker) 2001-08-28 (bug fix) removed 2 second 'raise' delay seen by some Unix window managers. (hobbs, baker) -2001-09-14 (bug fix) fixed memory leaks that occured if errors were +2001-09-14 (bug fix) fixed memory leaks that occurred if errors were thrown while initializing the channel for an image. (darley) 2001-09-20 (new feature) --enable-64bit support was added for HP 11 when using the native compiler. @@ -7311,5 +7311,216 @@ 2016-07-17 (bug)[c84f66] Aqua: crash: overflow in geometry calc (culler,walzer) 2016-07-21 (bug)[450bb0] Aqua: memory corruption from [tk busy] (porter) --- Released 8.6.6, July 27, 2016 --- http://core.tcl.tk/tk/ for details + +2016-08-23 (bug)[a2abc4] Wrong warp cursor position on 2nd display (vogel) + +2016-08-29 (bug)[fa3229] menu-38.1 (calvo,vogel) + +2016-08-29 (bug)[2cf3d6] button-5.24 (vogel) + +2016-09-04 (bug)[1534455,2945130] Key release events get _L vs _R right. (vogel) + +2016-09-10 (bug)[8c4216] listbox-4.1 (vogel) + +2016-09-10 (bug)[eb2681] listbox-13.1 (vogel) + +2016-09-21 (bug)[3126428] ttk::button react to image change (thoyts) + +2016-10-09 (bug)[1082213] wrapped text don't start lines with whitespace (vogel) + +2016-10-12 (bug)[3217462] tri-state button on non-native theme (vogel) + +2016-10-30 (bug)[3588460] Fix file dialog -typevariable (vogel) + +2016-11-01 (bug)[e36963] event generate .e (matthias,vogel) + +2016-11-05 (bug)[6aea69] grid-23 (danckaert,vogel) + +2016-11-18 (bug)[f60c54] combobox-3 (panza,vogel) + +2017-01-03 (bug)[f32502] crash drawing many dashed objects (reithofer,werner) + +2017-01-05 (bug)[dac92f] text-2.[89] (vogel) + +2017-01-07 (bug)[3df559] OSX: Negative bbox width (vogel) + +2017-01-07 (bug)[28a453] OSX: text widget index OBOE (vogel) + +2017-01-07 (bug)[c12af7] OSX: text-21.1 (vogel) + +2017-01-08 (bug)[7a838c] X11 ring buffer overflow (werner) + +2017-01-11 (bug)[d4fb4e] imgPhoto-4.75 (nijtmans) + +2017-01-18 (bug)[fab5fe] OSX: repair textDisp failures (vogel) + +2017-01-23 (bug)[89a638] OSX: textDisp-15.8 (vogel) + +2017-01-25 (bug)[1403ea] Limits on text line size on Windows (spjuth) + +2017-02-05 (bug)[ae32eb] textDisp fails in text custom config (vogel) + +2017-02-05 (bug)[7d967c] crash after IME restart (lanam,nijtmans) + +2017-02-22 (bug)[c492c9] disabled combobox arrow appearance (danckaert) + +2017-03-06 (bug)[6b3644] Fix -alpha for 16-bit color PNG (LemonMan) + +2017-03-11 (bug)[775273] artifacts on Ubuntu 16.10+ (nemethi) + +2017-03-26 (TIP 464) Win multimedia keys support (fassel,vogel) + +2017-03-29 (bug)[28a3c3] test BTree memleaks plugged (anonymous) + +2017-04-06 (bug)[db8c54] Stop freed mem access in warp pointer callback (porter) + +2017-04-07 (bugs) Fix calculation of ttk::notebook tab widths (vogel) + +2017-04-07 (bug)[291296] notebook tab management (decoster) + +2017-04-08 (bug)[f0188a] Win reject invalid hex color codes (bachmann) + +2017-04-10 (bug)[3f323b] variable struct size on XCode 8.3.1 (auriocus) + +2017-04-20 (bug)[061bf9] OSX scrollbar draw position (reincke,walzer,joye) + +2017-05-01 (bug) restore -initialfile for OSX file dialogs (reincke,gollwitzer) + +2017-05-06 (bug) OSX file dialog type filters (walzer) + +2017-05-10 (bug)[a5ba1c] race condition on Win clipboard cleanup (donchenko) + +2017-05-18 (bug)[2433781] center image on button (cramer) + +2017-05-19 (bug)[434d29] type mismatch with recent Xft (nijtmans,werner) + +2017-06-02 (bug)[bc43fd] paneconfigure get pane heights right (vogel) + +2017-06-21 (bug)[adc028] menu avoid unreleasable global grab (nash) + +2017-06-30 (bug)[92e028,c5eb90] User switch forced theme reset (lanam) + +2017-06-30 (bug)[62c5b7] segfault in [text] replace (werner) + +2017-07-03 (bug)[8afc6c] OSX crash in save/open dialogs (simpson,walzer) + +2017-08-02 (bug)[b601ce] Resource exhaustion processing corrupt GIF (nash) + +2017-08-03 (bug)[9eab54] Fix -initialdir for OSX file dialogs (gollwitzer) + +2017-08-08 (bug)[28d0b8] Follow ICCCM advice on X selection protocol (donchenko) + +2017-08-08 (bug)[4966ca] Scidb race in notebook tab selection (cramer) + +--- Released 8.6.7, August 9, 2017 --- http://core.tcl.tk/tk/ for details + +2017-08-24 (bug)[f1a3ca] Memory leak in [text] B-tree (edhume3) + +2017-08-24 (bug)[ee40fd] Report [console] init errors (the) + +2017-08-24 (bug)[3295446] Improve history visibility in [console] (goth) + +2017-08-24 (bug) canvas closed polylines fully honor -joinstyle (vogel) + +2017-08-24 (bug)[cc42cc] out of mem crash in tests imgPhoto-18.* (vogel) + +2017-09-16 (bug)[3406785] fix coords rounding when drawing canvas items (vogel) + +2017-09-24 (bug)[8277e1] linux fontchooser sync with available fonts (vogel) + +2017-09-24 (bug)[5239fd] Segfault copying a photo image to itself (bachmann) + +2017-09-24 (bug)[514ff6] canvas rotated text overlap detection (vogel) + +2017-09-24 (bug)[1e0db2] canvas rchars artifacts (bruchie,vogel) + +2017-10-07 (bug)[d9fdfa] display of Long non-wrapped lines in text (cramer) + +2017-10-07 (bug)[dd9667] text anchor not set (vogel) + +2017-10-11 (bugs) memleaks and other changes for macOS 10.13 support (culler) + +2017-10-11 (bug)[111de2] macOS colorspace improvement (walzer,culler) + +2017-10-13 (bug) macOS scrolling issues (culler) + +2017-10-15 (bug) clipping regions in scrolling and drawing on macOS (culler) + +2017-10-15 (bug) macOS redraw artifacts (culler) + +2017-10-22 (bug)[bb6b40] ::tk::AmpMenuArgs and 'entryconf' (vogel) + +2017-10-22 (bug)[55b95f] Crash [scale] with a bignum value (vogel) + +2017-10-28 (bug)[ce62c8] text-37.1 fails (vogel) + +2017-11-03 (bug)[0ef1c5] OS X - tests menu-22.[345] hang (vogel) + +2017-11-04 (bug)[c8c52b] repair OBOE in menu.test on macOS (vogel) + +2017-11-11 (feature) Implement [wm_iconphoto] on macOS (walzer) + +2017-11-11 (bug) display of embedded toplevels (culler) + +2017-11-19 (bug)[73ba07] Correct property type for MULTIPLE conversion (dpb) + +2017-11-20 (bug) Memory leak in tkImgPhoto.c. (werner) + +2017-11-21 (bug) Defeat zombie toplevels (culler) + +2017-11-25 (bug) macOS resposive menu bar for command line apps (culler) + +2017-11-25 (bug)[1c659e] support png from mac screenshots (vogel) + +2017-11-25 (bug)[de4af1] macOS file selector "all types" setting (culler) + +2017-11-26 (bug) [wm withdraw] on Window and Dock menus (walzer) + +2017-11-27 (feature) Drop support for macOS 10.5 (culler) + +2017-11-30 (bug)[164c1b] Fixes [raise] on macOS (culler) + +2017-11-30 (bug)[13d63d] macOS support of menu -postcommand (culler) + +2017-12-05 (bug) enable custom icon display on macOS (walzer) + +2017-12-05 (bug)[1088805,0feb63] macOS bind failures (culler) + +2017-12-05 (bug)[3382424] Suppress noisy messages on macOS (culler) + +2017-12-08 (new)[TIP 477] nmake build system reform (nadkarni) + +2017-12-18 (bug)[b77626] Make [tk busy -cursor] silent no-op on macOS (vogel) + +--- Released 8.6.8, December 22, 2017 --- http://core.tcl.tk/tk/ for details + +Changes to 8.7a1 include all changes to the 8.6 line through 8.6.7, +plus the following, which focuses on the high-level feature changes +in this changeset (new minor version) rather than bug fixes: + +2016-03-07 (feature)[841280] spinbox autoswap -to/-from to get ordering (vogel) + +2016-03-27 (feature)[38dc27] Support & (nijtmans) + +2016-08-29 (TIP 449) [text] undo/redo return character range (vogel) + +2016-11-02 (feature) Removed undocumented command [tk_getFileType] (vogel) + *** POTENTIAL INCOMPATIBILITY *** + +2017-02-05 (bug)[c0dbdd] Compatibility fonts shadowed system fonts (vogel) + +2017-03-21 (TIP 442) display text in a progressbar (zaumseil) + +2017-04-13 \u escaped content in msg files converted to true utf-8 (nijtmans) + +2017-08-24 (bug)[f1a3ca] Memleak in text operations (hume) + +2017-08-24 (bug)[ee40fd] Error reporting from failed console init (the) + +2017-08-24 (bug)[3295446] Keep console cursor visible when using history (goth) + +2017-08-28 (TIP 166) Extended color notation for alpha channel (bachmann) + +--- Released 8.7a1, September 8, 2017 --- http://core.tcl.tk/tk/ for details Index: doc/3DBorder.3 ================================================================== --- doc/3DBorder.3 +++ doc/3DBorder.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1993 The Regents of the University of California. '\" Copyright (c) 1994-1998 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_Alloc3DBorderFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_Alloc3DBorderFromObj, Tk_Get3DBorder, Tk_Get3DBorderFromObj, Tk_Draw3DRectangle, Tk_Fill3DRectangle, Tk_Draw3DPolygon, Tk_Fill3DPolygon, Tk_3DVerticalBevel, Tk_3DHorizontalBevel, Tk_SetBackgroundFromBorder, Tk_NameOf3DBorder, Tk_3DBorderColor, Tk_3DBorderGC, Tk_Free3DBorderFromObj, Tk_Free3DBorder \- draw borders with three-dimensional appearance Index: doc/BindTable.3 ================================================================== --- doc/BindTable.3 +++ doc/BindTable.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateBindingTable 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateBindingTable, Tk_DeleteBindingTable, Tk_CreateBinding, Tk_DeleteBinding, Tk_GetBinding, Tk_GetAllBindings, Tk_DeleteAllBindings, Tk_BindEvent \- invoke scripts in response to X events Index: doc/CanvPsY.3 ================================================================== --- doc/CanvPsY.3 +++ doc/CanvPsY.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CanvasPs 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CanvasPsY, Tk_CanvasPsBitmap, Tk_CanvasPsColor, Tk_CanvasPsFont, Tk_CanvasPsPath, Tk_CanvasPsStipple \- utility procedures for generating Postscript for canvases Index: doc/CanvTkwin.3 ================================================================== --- doc/CanvTkwin.3 +++ doc/CanvTkwin.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CanvasTkwin 3 4.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CanvasTkwin, Tk_CanvasGetCoord, Tk_CanvasDrawableCoords, Tk_CanvasSetStippleOrigin, Tk_CanvasWindowCoords, Tk_CanvasEventuallyRedraw, Tk_CanvasTagsOption \- utility procedures for canvas type managers Index: doc/CanvTxtInfo.3 ================================================================== --- doc/CanvTxtInfo.3 +++ doc/CanvTxtInfo.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CanvasTextInfo 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CanvasTextInfo \- additional information for managing text items in canvases Index: doc/Clipboard.3 ================================================================== --- doc/Clipboard.3 +++ doc/Clipboard.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ClipboardClear 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_ClipboardClear, Tk_ClipboardAppend \- Manage the clipboard Index: doc/ClrSelect.3 ================================================================== --- doc/ClrSelect.3 +++ doc/ClrSelect.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1992-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ClearSelection 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_ClearSelection \- Deselect a selection Index: doc/ConfigWind.3 ================================================================== --- doc/ConfigWind.3 +++ doc/ConfigWind.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ConfigureWindow 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_ConfigureWindow, Tk_MoveWindow, Tk_ResizeWindow, Tk_MoveResizeWindow, Tk_SetWindowBorderWidth, Tk_ChangeWindowAttributes, Tk_SetWindowBackground, Tk_SetWindowBackgroundPixmap, Tk_SetWindowBorder, Tk_SetWindowBorderPixmap, Tk_SetWindowColormap, Tk_DefineCursor, Tk_UndefineCursor \- change window configuration or attributes Index: doc/CoordToWin.3 ================================================================== --- doc/CoordToWin.3 +++ doc/CoordToWin.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CoordsToWindow 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CoordsToWindow \- Find window containing a point Index: doc/CrtCmHdlr.3 ================================================================== --- doc/CrtCmHdlr.3 +++ doc/CrtCmHdlr.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2000 Ajuba Solutions. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateClientMessageHandler 3 "8.4" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateClientMessageHandler, Tk_DeleteClientMessageHandler \- associate procedure callback with ClientMessage type X events Index: doc/CrtConsoleChan.3 ================================================================== --- doc/CrtConsoleChan.3 +++ doc/CrtConsoleChan.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2007 ActiveState Software Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_InitConsoleChannels 3 8.5 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_InitConsoleChannels \- Install the console channels as standard channels Index: doc/CrtErrHdlr.3 ================================================================== --- doc/CrtErrHdlr.3 +++ doc/CrtErrHdlr.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateErrorHandler 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateErrorHandler, Tk_DeleteErrorHandler \- handle X protocol errors Index: doc/CrtGenHdlr.3 ================================================================== --- doc/CrtGenHdlr.3 +++ doc/CrtGenHdlr.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1992-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateGenericHandler 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateGenericHandler, Tk_DeleteGenericHandler \- associate procedure callback with all X events Index: doc/CrtImgType.3 ================================================================== --- doc/CrtImgType.3 +++ doc/CrtImgType.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateImageType 3 8.5 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateImageType, Tk_GetImageMasterData, Tk_InitImageArgs \- define new kind of image Index: doc/CrtItemType.3 ================================================================== --- doc/CrtItemType.3 +++ doc/CrtItemType.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1994-1995 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateItemType 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateItemType, Tk_GetItemTypes \- define new kind of canvas item Index: doc/CrtPhImgFmt.3 ================================================================== --- doc/CrtPhImgFmt.3 +++ doc/CrtPhImgFmt.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Australian National University '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" '\" Author: Paul Mackerras (paulus@cs.anu.edu.au), '\" Department of Computer Science, '\" Australian National University. '\" .TH Tk_CreatePhotoImageFormat 3 8.5 Tk "Tk Library Procedures" Index: doc/DeleteImg.3 ================================================================== --- doc/DeleteImg.3 +++ doc/DeleteImg.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_DeleteImage 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_DeleteImage \- Destroy an image. Index: doc/DrawFocHlt.3 ================================================================== --- doc/DrawFocHlt.3 +++ doc/DrawFocHlt.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_DrawFocusHighlight 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_DrawFocusHighlight \- draw the traversal highlight ring for a widget Index: doc/EventHndlr.3 ================================================================== --- doc/EventHndlr.3 +++ doc/EventHndlr.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_CreateEventHandler 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateEventHandler, Tk_DeleteEventHandler \- associate procedure callback with an X event Index: doc/FindPhoto.3 ================================================================== --- doc/FindPhoto.3 +++ doc/FindPhoto.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Australian National University '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" '\" Author: Paul Mackerras (paulus@cs.anu.edu.au), '\" Department of Computer Science, '\" Australian National University. '\" .TH Tk_FindPhoto 3 8.0 Tk "Tk Library Procedures" @@ -97,12 +97,12 @@ .PP \fBTk_FindPhoto\fR returns an opaque handle that is used to identify a particular photo image to the other procedures. The parameter is the name of the image, that is, the name specified to the \fBimage create photo\fR command, or assigned by that command if no name was specified. -If \fIimageName\fR does not exist or is not a photo image, -\fBTk_FindPhoto\fR returns NULL. +If \fIimageName\fR does not exist or is not a photo image, +\fBTk_FindPhoto\fR returns NULL. .PP \fBTk_PhotoPutBlock\fR is used to supply blocks of image data to be displayed. The call affects an area of the image of size \fIwidth\fR x \fIheight\fR pixels, with its top-left corner at coordinates (\fIx\fR,\fIy\fR). All of \fIwidth\fR, \fIheight\fR, @@ -128,18 +128,27 @@ .CE The \fIpixelPtr\fR field points to the first pixel, that is, the top-left pixel in the block. The \fIwidth\fR and \fIheight\fR fields specify the dimensions of the block of pixels. The \fIpixelSize\fR field specifies the address -difference between two horizontally adjacent pixels. Often it is 3 -or 4, but it can have any value. The \fIpitch\fR field specifies the +difference between two horizontally adjacent pixels. It should be 4 for +RGB and 2 for grayscale image data. Other values are possible, if the +offsets in the \fIoffset\fR array are adjusted accordingly (e.g. for +red, green and blue data stored in different planes). Using such a +layout is strongly discouraged, though. Due to a bug, it might not work +correctly if an alpha channel is provided. (see the \fBBUGS\fR section +below). The \fIpitch\fR field specifies the address difference between two vertically adjacent pixels. The \fIoffset\fR array contains the offsets from the address of a pixel to the addresses of the bytes containing the red, green, blue and alpha -(transparency) components. These are normally 0, 1, 2 and 3, but can -have other values, e.g., for images that are stored as separate red, -green and blue planes. +(transparency) components. If the offsets for red, green and blue are +equal, the image is interpreted as grayscale. If they differ, RGB data +is assumed. Normally the offsets will be 0, 1, 2, 3 for RGB data +and 0, 0, 0, 1 for grayscale. It is possible to provide image data +without an alpha channel by setting the offset for alpha to a negative +value and adjusting the \fIpixelSize\fR field accordingly. This use is +discouraged, though (see the \fBBUGS\fR section below). .PP The \fIcompRule\fR parameter to \fBTk_PhotoPutBlock\fR specifies a compositing rule that says what to do with transparent pixels. The value \fBTK_PHOTO_COMPOSITE_OVERLAY\fR says that the previous contents of the photo image should show through, and the value @@ -182,20 +191,20 @@ in the structure pointed to by the \fIblockPtr\fR parameter with values that describe the address and layout of the image data that the photo image has stored internally. The values are valid until the image is destroyed or its size is changed. .PP -It is possible to modify an image by writing directly to the data +It is possible to modify an image by writing directly to the data the \fIpixelPtr\fR field points to. The size of the image cannot be changed this way, though. -Also, changes made by writing directly to \fIpixelPtr\fR will not be -immediately visible, but only after a call to -\fBTk_ImageChanged\fR or after an event that causes the interested +Also, changes made by writing directly to \fIpixelPtr\fR will not be +immediately visible, but only after a call to +\fBTk_ImageChanged\fR or after an event that causes the interested widgets to redraw themselves. -For these reasons usually it is preferable to make changes to -a copy of the image data and write it back with -\fBTk_PhotoPutBlock\fR or \fBTk_PhotoPutZoomedBlock\fR. +For these reasons usually it is preferable to make changes to +a copy of the image data and write it back with +\fBTk_PhotoPutBlock\fR or \fBTk_PhotoPutZoomedBlock\fR. .PP \fBTk_PhotoGetImage\fR returns 1 for compatibility with the corresponding procedure in the old photo widget. .PP \fBTk_PhotoBlank\fR blanks the entire area of the @@ -246,11 +255,29 @@ \fIinterp\fR argument or return any result code. If insufficient memory was available for an image, Tk would panic. This behaviour is still supported if you compile your extension with the additional flag -DUSE_PANIC_ON_PHOTO_ALLOC_FAILURE. Code linked using Stubs against older versions of Tk will continue to work. +.SH BUGS +The \fBTk_PhotoImageBlock\fR structure used to provide image data to +\fBTk_PhotoPutBlock\fR promises great flexibility in the layout of the +data (e.g. separate planes for the red, green, blue and alpha +channels). Unfortunately, the implementation fails to hold this +promise. The problem is that the \fIpixelSize\fR field is +(incorrectly) used to determine whether the image has an alpha channel. +Currently, if the offset for the alpha channel is greater or equal than +\fIpixelSize\fR, \fBtk_PhotoPutblock\fR assumes no alpha data is +present and makes the image fully opaque. This means that for layouts +where the channels are separate (or any other exotic layout where +\fIpixelSize\fR has to be smaller than the alpha offset), the alpha +channel will not be read correctly. In order to be on the safe side +if this issue will be corrected in a future release, it is strongly +recommended you always provide alpha data - even if the image has no +transparency - and only use the "standard" layout with a +\fIpixelSize\fR of 2 for grayscale and 4 for RGB data with +\fIoffset\fRs of 0, 0, 0, 1 or 0, 1, 2, 3 respectively. .SH CREDITS .PP The code for the photo image type was developed by Paul Mackerras, based on his earlier photo widget code. .SH KEYWORDS photo, image Index: doc/FreeXId.3 ================================================================== --- doc/FreeXId.3 +++ doc/FreeXId.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_FreeXId 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_FreeXId \- make X resource identifier available for reuse @@ -23,26 +23,8 @@ Identifier of X resource (window, font, pixmap, cursor, graphics context, or colormap) that is no longer in use. .BE .SH DESCRIPTION .PP -The default allocator for resource identifiers provided by Xlib is very -simple-minded and does not allow resource identifiers to be re-used. -If a long-running application reaches the end of the resource id -space, it will generate an X protocol error and crash. -Tk replaces the default id allocator with its own allocator, which -allows identifiers to be reused. -In order for this to work, \fBTk_FreeXId\fR must be called to -tell the allocator about resources that have been freed. -Tk automatically calls \fBTk_FreeXId\fR whenever it frees a -resource, so if you use procedures like \fBTk_GetFont\fR, -\fBTk_GetGC\fR, and \fBTk_GetPixmap\fR then you need not call -\fBTk_FreeXId\fR. -However, if you allocate resources directly from Xlib, for example -by calling \fBXCreatePixmap\fR, then you should call \fBTk_FreeXId\fR -when you call the corresponding Xlib free procedure, such as -\fBXFreePixmap\fR. -If you do not call \fBTk_FreeXId\fR then the resource identifier will -be lost, which could cause problems if the application runs long enough -to lose all of the available identifiers. +This function is deprecated, it doesn't do anything since 2008-08-19. .SH KEYWORDS resource identifier Index: doc/GeomReq.3 ================================================================== --- doc/GeomReq.3 +++ doc/GeomReq.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GeometryRequest 3 "8.4" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GeometryRequest, Tk_SetMinimumRequestSize, Tk_SetInternalBorder, Tk_SetInternalBorderEx \- specify desired geometry or internal border for a window Index: doc/GetAnchor.3 ================================================================== --- doc/GetAnchor.3 +++ doc/GetAnchor.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1998 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetAnchorFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetAnchorFromObj, Tk_GetAnchor, Tk_NameOfAnchor \- translate between strings and anchor positions Index: doc/GetBitmap.3 ================================================================== --- doc/GetBitmap.3 +++ doc/GetBitmap.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1998 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_AllocBitmapFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_AllocBitmapFromObj, Tk_GetBitmap, Tk_GetBitmapFromObj, Tk_DefineBitmap, Tk_NameOfBitmap, Tk_SizeOfBitmap, Tk_FreeBitmapFromObj, Tk_FreeBitmap \- maintain database of single-plane pixmaps Index: doc/GetCapStyl.3 ================================================================== --- doc/GetCapStyl.3 +++ doc/GetCapStyl.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetCapStyle 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetCapStyle, Tk_NameOfCapStyle \- translate between strings and cap styles Index: doc/GetClrmap.3 ================================================================== --- doc/GetClrmap.3 +++ doc/GetClrmap.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetColormap 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetColormap, Tk_PreserveColormap, Tk_FreeColormap \- allocate and free colormaps Index: doc/GetDash.3 ================================================================== --- doc/GetDash.3 +++ doc/GetDash.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1989-1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetDash 3 8.3 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetDash \- convert from string to valid dash structure. Index: doc/GetGC.3 ================================================================== --- doc/GetGC.3 +++ doc/GetGC.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetGC 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetGC, Tk_FreeGC \- maintain database of read-only graphics contexts Index: doc/GetHINSTANCE.3 ================================================================== --- doc/GetHINSTANCE.3 +++ doc/GetHINSTANCE.3 @@ -1,9 +1,9 @@ '\" '\" Copyright (c) 1998-2000 by Scriptics Corporation. '\" All rights reserved. -'\" +'\" .TH Tk_GetHISTANCE 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetHINSTANCE \- retrieve the global application instance handle Index: doc/GetHWND.3 ================================================================== --- doc/GetHWND.3 +++ doc/GetHWND.3 @@ -1,9 +1,9 @@ '\" '\" Copyright (c) 1998-2000 by Scriptics Corporation. '\" All rights reserved. -'\" +'\" .TH HWND 3 8.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetHWND, Tk_AttachHWND \- manage interactions between the Windows handle and an X window Index: doc/GetImage.3 ================================================================== --- doc/GetImage.3 +++ doc/GetImage.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetImage 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetImage, Tk_RedrawImage, Tk_SizeOfImage, Tk_FreeImage \- use an image in a widget Index: doc/GetJoinStl.3 ================================================================== --- doc/GetJoinStl.3 +++ doc/GetJoinStl.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetJoinStyle 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetJoinStyle, Tk_NameOfJoinStyle \- translate between strings and join styles Index: doc/GetJustify.3 ================================================================== --- doc/GetJustify.3 +++ doc/GetJustify.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1998 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetJustifyFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetJustifyFromObj, Tk_GetJustify, Tk_NameOfJustify \- translate between strings and justification styles Index: doc/GetOption.3 ================================================================== --- doc/GetOption.3 +++ doc/GetOption.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetOption 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetOption \- retrieve an option from the option database Index: doc/GetPixels.3 ================================================================== --- doc/GetPixels.3 +++ doc/GetPixels.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1998 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetPixelsFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetPixelsFromObj, Tk_GetPixels, Tk_GetMMFromObj, Tk_GetScreenMM \- translate between strings and screen units Index: doc/GetPixmap.3 ================================================================== --- doc/GetPixmap.3 +++ doc/GetPixmap.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetPixmap 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetPixmap, Tk_FreePixmap \- allocate and free pixmaps Index: doc/GetRelief.3 ================================================================== --- doc/GetRelief.3 +++ doc/GetRelief.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1998 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetReliefFromObj 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetReliefFromObj, Tk_GetRelief, Tk_NameOfRelief \- translate between strings and relief values Index: doc/GetRootCrd.3 ================================================================== --- doc/GetRootCrd.3 +++ doc/GetRootCrd.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetRootCoords 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetRootCoords \- Compute root-window coordinates of window Index: doc/GetScroll.3 ================================================================== --- doc/GetScroll.3 +++ doc/GetScroll.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetScrollInfo 3 8.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetScrollInfoObj, Tk_GetScrollInfo \- parse arguments for scrolling commands Index: doc/GetSelect.3 ================================================================== --- doc/GetSelect.3 +++ doc/GetSelect.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetSelection 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetSelection \- retrieve the contents of a selection Index: doc/GetUid.3 ================================================================== --- doc/GetUid.3 +++ doc/GetUid.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetUid 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetUid, Tk_Uid \- convert from string to unique identifier Index: doc/GetVRoot.3 ================================================================== --- doc/GetVRoot.3 +++ doc/GetVRoot.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetVRootGeometry 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetVRootGeometry \- Get location and size of virtual root for window Index: doc/GetVisual.3 ================================================================== --- doc/GetVisual.3 +++ doc/GetVisual.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_GetVisual 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetVisual \- translate from string to visual Index: doc/Grab.3 ================================================================== --- doc/Grab.3 +++ doc/Grab.3 @@ -1,9 +1,9 @@ '\" '\" Copyright (c) 1998-2000 by Scriptics Corporation. '\" All rights reserved. -'\" +'\" .TH Tk_Grab 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_Grab, Tk_Ungrab \- manipulate grab state in an application Index: doc/HWNDToWindow.3 ================================================================== --- doc/HWNDToWindow.3 +++ doc/HWNDToWindow.3 @@ -1,9 +1,9 @@ '\" '\" Copyright (c) 1998-2000 by Scriptics Corporation. '\" All rights reserved. -'\" +'\" .TH Tk_HWNDToWindow 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_HWNDToWindow \- Find Tk's window information for a Windows window Index: doc/HandleEvent.3 ================================================================== --- doc/HandleEvent.3 +++ doc/HandleEvent.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_HandleEvent 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_HandleEvent \- invoke event handlers for window system events Index: doc/IdToWindow.3 ================================================================== --- doc/IdToWindow.3 +++ doc/IdToWindow.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_IdToWindow 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_IdToWindow \- Find Tk's window information for an X window Index: doc/ImgChanged.3 ================================================================== --- doc/ImgChanged.3 +++ doc/ImgChanged.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ImageChanged 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_ImageChanged \- notify widgets that image needs to be redrawn Index: doc/Inactive.3 ================================================================== --- doc/Inactive.3 +++ doc/Inactive.3 @@ -1,9 +1,9 @@ '\" '\" Copyright (c) 1998-2000 by Scriptics Corporation. '\" All rights reserved. -'\" +'\" .TH Tk_GetUserInactiveTime 3 8.5 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_GetUserInactiveTime, Tk_ResetUserInactiveTime \- discover user inactivity time @@ -12,11 +12,11 @@ \fB#include \fR .sp long \fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR .sp -\fBTk_GetUserInactiveTime(\fIdisplay\fB)\fR +\fBTk_ResetUserInactiveTime(\fIdisplay\fB)\fR .SH ARGUMENTS .AS Display *display .AP Display *display in The display on which the user inactivity timer is to be queried or reset. @@ -24,11 +24,11 @@ .SH DESCRIPTION .PP \fBTk_GetUserInactiveTime\fR returns the number of milliseconds that have passed since the last user interaction (usually via keyboard or mouse) with the respective display. On systems and displays that do not -support querying the user inactiviy time, \fB\-1\fR is returned. -\fBTk_GetUserInactiveTime\fR resets the user inactivity timer of the +support querying the user inactivity time, \fB\-1\fR is returned. +\fBTk_ResetUserInactiveTime\fR resets the user inactivity timer of the given display to zero. On windowing systems that do not support multiple displays \fIdisplay\fR can be passed as \fBNULL\fR. .SH KEYWORDS idle, inactive Index: doc/InternAtom.3 ================================================================== --- doc/InternAtom.3 +++ doc/InternAtom.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_InternAtom 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_InternAtom, Tk_GetAtomName \- manage cache of X atoms Index: doc/MainLoop.3 ================================================================== --- doc/MainLoop.3 +++ doc/MainLoop.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_MainLoop 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_MainLoop \- loop for events until all windows are deleted Index: doc/MainWin.3 ================================================================== --- doc/MainWin.3 +++ doc/MainWin.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_MainWindow 3 7.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_MainWindow, Tk_GetNumMainWindows \- functions for querying main window information Index: doc/MaintGeom.3 ================================================================== --- doc/MaintGeom.3 +++ doc/MaintGeom.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_MaintainGeometry 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_MaintainGeometry, Tk_UnmaintainGeometry \- maintain geometry of one window relative to another Index: doc/ManageGeom.3 ================================================================== --- doc/ManageGeom.3 +++ doc/ManageGeom.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ManageGeometry 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_ManageGeometry \- arrange to handle geometry requests for a window Index: doc/MoveToplev.3 ================================================================== --- doc/MoveToplev.3 +++ doc/MoveToplev.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1993 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_MoveToplevelWindow 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_MoveToplevelWindow \- Adjust the position of a top-level window Index: doc/Name.3 ================================================================== --- doc/Name.3 +++ doc/Name.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_Name 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_Name, Tk_PathName, Tk_NameToWindow \- convert between names and window tokens Index: doc/NameOfImg.3 ================================================================== --- doc/NameOfImg.3 +++ doc/NameOfImg.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_NameOfImage 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_NameOfImage \- Return name of image. Index: doc/OwnSelect.3 ================================================================== --- doc/OwnSelect.3 +++ doc/OwnSelect.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_OwnSelection 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_OwnSelection \- make a window the owner of the primary selection Index: doc/ParseArgv.3 ================================================================== --- doc/ParseArgv.3 +++ doc/ParseArgv.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_ParseArgv 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_ParseArgv \- process command-line options Index: doc/QWinEvent.3 ================================================================== --- doc/QWinEvent.3 +++ doc/QWinEvent.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_QueueWindowEvent 3 7.5 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CollapseMotionEvents, Tk_QueueWindowEvent \- Add a window event to the Tcl event queue Index: doc/Restack.3 ================================================================== --- doc/Restack.3 +++ doc/Restack.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_RestackWindow 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_RestackWindow \- Change a window's position in the stacking order Index: doc/RestrictEv.3 ================================================================== --- doc/RestrictEv.3 +++ doc/RestrictEv.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_RestrictEvents 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_RestrictEvents \- filter and selectively delay X events Index: doc/SetAppName.3 ================================================================== --- doc/SetAppName.3 +++ doc/SetAppName.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_SetAppName 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_SetAppName \- Set the name of an application for 'send' commands Index: doc/SetCaret.3 ================================================================== --- doc/SetCaret.3 +++ doc/SetCaret.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2002 ActiveState Corporation. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_SetCaretPos 3 8.4 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_SetCaretPos \- set the display caret location Index: doc/SetClass.3 ================================================================== --- doc/SetClass.3 +++ doc/SetClass.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_SetClass 3 "" Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_SetClass, Tk_Class \- set or retrieve a window's class Index: doc/SetClassProcs.3 ================================================================== --- doc/SetClassProcs.3 +++ doc/SetClassProcs.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2000 Ajuba Solutions. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_SetClassProcs 3 8.4 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_SetClassProcs \- register widget specific procedures Index: doc/SetGrid.3 ================================================================== --- doc/SetGrid.3 +++ doc/SetGrid.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_SetGrid 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_SetGrid, Tk_UnsetGrid \- control the grid for interactive resizing Index: doc/SetOptions.3 ================================================================== --- doc/SetOptions.3 +++ doc/SetOptions.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1998 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_SetOptions 3 8.1 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_CreateOptionTable, Tk_DeleteOptionTable, Tk_InitOptions, Tk_SetOptions, Tk_FreeSavedOptions, Tk_RestoreSavedOptions, Tk_GetOptionValue, Tk_GetOptionInfo, Tk_FreeConfigOptions, Tk_Offset \- process configuration options @@ -50,11 +50,11 @@ options that are supported. Used to build a Tk_OptionTable. The information pointed to by this argument must exist for the lifetime of the Tk_OptionTable. .AP Tk_OptionTable optionTable in Token for an option table. Must have been returned by a previous call to \fBTk_CreateOptionTable\fR. -.AP char *recordPtr in/out +.AP void *recordPtr in/out Points to structure in which values of configuration options are stored; fields of this record are modified by procedures such as \fBTk_SetOptions\fR and read by procedures such as \fBTk_GetOptionValue\fR. .AP Tk_Window tkwin in For options such as \fBTK_OPTION_COLOR\fR, this argument indicates Index: doc/SetVisual.3 ================================================================== --- doc/SetVisual.3 +++ doc/SetVisual.3 @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_SetWindowVisual 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_SetWindowVisual \- change visual characteristics of window Index: doc/StrictMotif.3 ================================================================== --- doc/StrictMotif.3 +++ doc/StrictMotif.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_StrictMotif 3 4.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_StrictMotif \- Return value of tk_strictMotif variable Index: doc/TkInitStubs.3 ================================================================== --- doc/TkInitStubs.3 +++ doc/TkInitStubs.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1999 Scriptics Corporation '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_InitStubs 3 8.4 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_InitStubs \- initialize the Tk stubs mechanism Index: doc/Tk_Init.3 ================================================================== --- doc/Tk_Init.3 +++ doc/Tk_Init.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Tk_Init 3 8.0 Tk "Tk Library Procedures" .so man.macros .BS .SH NAME Tk_Init, Tk_SafeInit \- add Tk to an interpreter and make a new Tk application. Index: doc/bell.n ================================================================== --- doc/bell.n +++ doc/bell.n @@ -3,11 +3,11 @@ '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" Copyright (c) 2000 Ajuba Solutions. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH bell n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/bind.n ================================================================== --- doc/bind.n +++ doc/bind.n @@ -3,11 +3,11 @@ '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" Copyright (c) 1998 by Scriptics Corporation. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH bind n 8.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -17,13 +17,14 @@ .BE .SH "INTRODUCTION" .PP The \fBbind\fR command associates Tcl scripts with X events. If all three arguments are specified, \fBbind\fR will -arrange for \fIscript\fR (a Tcl script) to be evaluated whenever -the event(s) given by \fIsequence\fR occur in the window(s) -identified by \fItag\fR. +arrange for \fIscript\fR (a Tcl script called the +.QW "binding script") +to be evaluated whenever the event(s) given by \fIsequence\fR +occur in the window(s) identified by \fItag\fR. If \fIscript\fR is prefixed with a .QW + , then it is appended to any existing binding for \fIsequence\fR; otherwise \fIscript\fR replaces any existing binding. @@ -349,11 +350,11 @@ .RE .SS "EVENT DETAILS" .PP The last part of a long event specification is \fIdetail\fR. In the case of a \fBButtonPress\fR or \fBButtonRelease\fR event, it is the -number of a button (1\-5). If a button number is given, then only an +number of a button (1\-9). If a button number is given, then only an event on that particular button will match; if no button number is given, then an event on any button will match. Note: giving a specific button number is different than specifying a button modifier; in the first case, it refers to a button being pressed or released, while in the second it refers to some other button that is already @@ -385,11 +386,12 @@ \fItype\fR field may be omitted; it will default to \fBKeyPress\fR. For example, \fB\fR is equivalent to \fB\fR. .SH "BINDING SCRIPTS AND SUBSTITUTIONS" .PP -The \fIscript\fR argument to \fBbind\fR is a Tcl script, +The \fIscript\fR argument to \fBbind\fR is a Tcl script, called the +.QW "binding script", which will be executed whenever the given event sequence occurs. \fICommand\fR will be executed in the same interpreter that the \fBbind\fR command was executed in, and it will run at global level (only global variables will be accessible). If \fIscript\fR contains @@ -604,16 +606,24 @@ a particular window or to associate additional binding tags with the window. .PP The \fBcontinue\fR and \fBbreak\fR commands may be used inside a binding script to control the processing of matching scripts. -If \fBcontinue\fR is invoked, then the current binding script -is terminated but Tk will continue processing binding scripts -associated with other \fItag\fR's. +If \fBcontinue\fR is invoked within a binding script, then this +binding script, including all other +.QW + +appended scripts, is terminated but Tk will continue processing +binding scripts associated with other \fItag\fR's. If the \fBbreak\fR command is invoked within a binding script, then that script terminates and no other scripts will be invoked for the event. +.PP +Within a script called from the binding script, \fBreturn\fR +\fB-code ok\fR may be used to continue processing (including +.QW + +appended scripts), or \fBreturn\fR \fB-code break\fR may be used to +stop processing all other binding scripts. .PP If more than one binding matches a particular event and they have the same \fItag\fR, then the most specific binding is chosen and its script is evaluated. The following tests are applied, in order, to determine which of Index: doc/bindtags.n ================================================================== --- doc/bindtags.n +++ doc/bindtags.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH bindtags n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/bitmap.n ================================================================== --- doc/bitmap.n +++ doc/bitmap.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH bitmap n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/busy.n ================================================================== --- doc/busy.n +++ doc/busy.n @@ -26,13 +26,15 @@ .TH busy n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME -busy \- confine pointer and keyboard events to a window sub-tree +busy \- Make Tk widgets busy, temporarily blocking user interactions .SH SYNOPSIS \fBtk busy\fR \fIwindow \fR?\fIoptions\fR? +.sp +\fBtk busy busywindow \fIwindow\fR .sp \fBtk busy hold\fR \fIwindow \fR?\fIoptions\fR? .sp \fBtk busy configure \fIwindow\fR ?\fIoption value\fR?... .sp @@ -42,13 +44,14 @@ .sp \fBtk busy status \fIwindow\fR .BE .SH DESCRIPTION .PP -The \fBtk busy\fR command provides a simple means to block keyboard, button, -and pointer events from Tk widgets, while overriding the widget's cursor with -a configurable busy cursor. +The \fBtk busy\fR command provides a simple means to block mouse pointer events +from Tk widgets, while overriding the widget's cursor with a configurable busy +cursor. Note this command does not prevent keyboard events from being sent to +the widgets made busy. .SH INTRODUCTION .PP There are many times in applications where you want to temporarily restrict what actions the user can take. For example, an application could have a .QW Run @@ -66,12 +69,12 @@ etc.\0are ignored by the widget. You can set a special cursor (like a watch) that overrides the widget's normal cursor, providing feedback that the application (widget) is temporarily busy. .PP When a widget is made busy, the widget and all of its descendants will ignore -events. It's easy to make an entire panel of widgets busy. You can simply make -the toplevel widget (such as +pointer events. It's easy to make an entire panel of widgets busy. You can +simply make the toplevel widget (such as .QW . ) busy. This is easier and far much more efficient than recursively traversing the widget hierarchy, disabling each widget and re-configuring its cursor. .PP Often, the \fBtk busy\fR command can be used instead of Tk's \fBgrab\fR @@ -125,28 +128,15 @@ .TP \fBtk busy \fIwindow\fR ?\fIoption value\fR?... . Shortcut for \fBtk busy hold\fR command. .TP -\fBtk busy hold \fIwindow\fR ?\fIoption value\fR?... -. -Makes the specified \fIwindow\fR (and its descendants in the Tk window -hierarchy) appear busy. \fIWindow\fR must be a valid path name of a Tk widget. -A transparent window is put in front of the specified window. This transparent -window is mapped the next time idle tasks are processed, and the specified -window and its descendants will be blocked from user interactions. Normally -\fBupdate\fR should be called immediately afterward to insure that the hold -operation is in effect before the application starts its processing. The -following configuration options are valid: -.RS -.TP -\fB\-cursor \fIcursorName\fR -. -Specifies the cursor to be displayed when the widget is made busy. -\fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The -default cursor is \fBwait\fR on Windows and \fBwatch\fR on other platforms. -.RE +\fBtk busy busywindow \fIwindow\fR +. +Returns the pathname of the busy window (i.e. the transparent window +shielding the window appearing busy) created by the \fBtk busy hold\fR +command for \fIwindow\fR, or the empty string if \fIwindow\fR is not busy. .TP \fBtk busy cget \fIwindow\fR \fIoption\fR . Queries the \fBtk busy\fR command configuration options for \fIwindow\fR. \fIWindow\fR must be the path name of a widget previously made busy by the @@ -177,24 +167,45 @@ .CS option add *frame.busyCursor gumby option add *Frame.BusyCursor gumby .CE .RE +.TP +\fBtk busy current \fR?\fIpattern\fR? +. +Returns the pathnames of all widgets that are currently busy. If a +\fIpattern\fR is given, only the path names of busy widgets matching +\fIpattern\fR are returned. .TP \fBtk busy forget \fIwindow\fR ?\fIwindow\fR?... . Releases resources allocated by the \fBtk busy\fR command for \fIwindow\fR, including the transparent window. User events will again be received by \fIwindow\fR. Resources are also released when \fIwindow\fR is destroyed. \fIWindow\fR must be the name of a widget specified in the \fBhold\fR operation, otherwise an error is reported. .TP -\fBtk busy current \fR?\fIpattern\fR? +\fBtk busy hold \fIwindow\fR ?\fIoption value\fR?... +. +Makes the specified \fIwindow\fR (and its descendants in the Tk window +hierarchy) appear busy. \fIWindow\fR must be a valid path name of a Tk widget. +A transparent window is put in front of the specified window. This transparent +window is mapped the next time idle tasks are processed, and the specified +window and its descendants will be blocked from user interactions. Normally +\fBupdate\fR should be called immediately afterward to insure that the hold +operation is in effect before the application starts its processing. The +command returns the pathname of the busy window that was created (i.e. the +transparent window shielding the window appearing busy). The following +configuration options are valid: +.RS +.TP +\fB\-cursor \fIcursorName\fR . -Returns the pathnames of all widgets that are currently busy. If a -\fIpattern\fR is given, only the path names of busy widgets matching -\fIpattern\fR are returned. +Specifies the cursor to be displayed when the widget is made busy. +\fICursorName\fR can be in any form accepted by \fBTk_GetCursor\fR. The +default cursor is \fBwait\fR on Windows and \fBwatch\fR on other platforms. +.RE .TP \fBtk busy status \fIwindow\fR . Returns the status of a widget \fIwindow\fR. If \fIwindow\fR presently can not receive user interactions, \fB1\fR is returned, otherwise \fB0\fR. @@ -203,59 +214,52 @@ .PP The event blocking feature is implemented by creating and mapping a transparent window that completely covers the widget. When the busy window is mapped, it invisibly shields the widget and its hierarchy from all events that may be sent. Like Tk widgets, busy windows have widget names in the Tk window -hierarchy. This means that you can use the \fBbind\fR command, to handle -events in the busy window. +hierarchy. This means that you can use the \fBbind\fR command to handle +events in the busy window: .PP .CS \fBtk busy\fR hold .frame.canvas -bind .frame.canvas_Busy { ... } +bind [\fBtk busy\fR busywindow .frame.canvas] { ... } .CE .PP -Normally the busy window is a sibling of the widget. The name of the busy -window is -.QW \fIwidget\fB_Busy\fR -where \fIwidget\fR is the name of the widget to be made busy. In the previous -example, the pathname of the busy window is -.QW \fB.frame.canvas_Busy\fR . -The exception is when the widget is a toplevel widget (such as -.QW . ) -where the busy window can't be made a sibling. The busy window is then a child -of the widget named -.QW \fIwidget\fB._Busy\fR -where \fIwidget\fR is the name of the toplevel widget. In the following -example, the pathname of the busy window is -.QW \fB._Busy\fR . -.PP +or .CS -\fBtk busy\fR hold . -bind ._Busy { ... } +set busyWin [\fBtk busy\fR hold .frame.canvas] +bind $busyWin { ... } .CE .SS "ENTER/LEAVE EVENTS" .PP Mapping and unmapping busy windows generates Enter/Leave events for all widgets they cover. Please note this if you are tracking Enter/Leave events in widgets. .SS "KEYBOARD EVENTS" .PP When a widget is made busy, the widget is prevented from gaining the keyboard -focus by the busy window. But if the widget already had focus, it still may -received keyboard events. To prevent this, you must move focus to another -window. +focus by a user clicking on it by the busy window. But if the widget already had +focus, it still may receive keyboard events. The widget can also still receive +focus through keyboard traversal. To prevent this, you must move +focus to another window and make sure the focus can not go back to the widgets +made busy (e.g. but restricting focus to a cancel button). .PP .CS +pack [frame .frame] +pack [text .frame.text] \fBtk busy\fR hold .frame -label .dummy -focus .dummy +pack [button .cancel -text "Cancel" -command exit] +focus .cancel +bind .cancel {break} +bind .cancel {break} update .CE .PP The above example moves the focus from .frame immediately after invoking the \fBhold\fR so that no keyboard events will be sent to \fB.frame\fR or any of -its descendants. +its descendants. It also makes sure it's not possible to leave button +\fB.cancel\fR using the keyboard. .SH PORTABILITY .PP Note that the \fBtk busy\fR command does not currently have any effect on OSX when Tk is built using Aqua support. .SH "SEE ALSO" Index: doc/canvas.n ================================================================== --- doc/canvas.n +++ doc/canvas.n @@ -545,10 +545,19 @@ \fItagOrId\fR. If coordinates are specified, then they replace the current coordinates for the named item. If \fItagOrId\fR refers to multiple items, then the first one in the display list is used. +.RS +.PP +Note that for rectangles, ovals and arcs the returned list of coordinates +has a fixed order, namely the left, top, right and bottom coordinates, +which may not be the order originally given. Also the coordinates are always +returned in screen units with no units (that is, in pixels). So if the +original coordinates were specified for instance in centimeters or inches, +the returned values will nevertheless be in pixels. +.RE .TP \fIpathName \fBcreate \fItype x y \fR?\fIx y ...\fR? ?\fIoption value ...\fR? .TP \fIpathName \fBcreate \fItype coordList \fR?\fIoption value ...\fR? . @@ -646,10 +655,24 @@ Note: the insertion cursor is only displayed in an item if that item currently has the keyboard focus (see the \fBfocus\fR widget command, above), but the cursor position may be set even when the item does not have the focus. This command returns an empty string. +.TP +\fIpathName \fBimage \fIimagename\fR ?\fIsubsample\fR? ?\fIzoom\fR? +. +Draw the canvas into the Tk photo image named \fIimagename\fR. If a \fB-scrollregion\fR +has been defined then this will be the boundaries of the canvas region drawn and the +final size of the photo image. Otherwise the widget width and height with an origin +of 0,0 will be the size of the canvas region drawn and the final size of the photo +image. Optionally an integer \fIsubsample\fR factor may be given and the photo image +will be reduced in size. In addition to the \fIsubsample\fR an integer \fIzoom\fR +factor can also be given and the photo image will be enlarged. The image background +will be filled with the canvas background colour. The canvas widget does not need to +be mapped for this widget command to work, but at least one of it's ancestors must be +mapped. +This command returns an empty string. .TP \fIpathName \fBimove \fItagOrId index x y\fR .VS 8.6 This command causes the \fIindex\fR'th coordinate of each of the items indicated by \fItagOrId\fR to be relocated to the location (\fIx\fR,\fIy\fR). Index: doc/chooseColor.n ================================================================== --- doc/chooseColor.n +++ doc/chooseColor.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_chooseColor n 4.2 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/chooseDirectory.n ================================================================== --- doc/chooseDirectory.n +++ doc/chooseDirectory.n @@ -15,10 +15,17 @@ .PP The procedure \fBtk_chooseDirectory\fR pops up a dialog box for the user to select a directory. The following \fIoption\-value\fR pairs are possible as command line arguments: .TP +\fB\-command\fR \fIstring\fR +Specifies the prefix of a Tcl command to invoke when the user closes the +dialog after having selected an item. This callback is not called if the +user cancelled the dialog. The actual command consists of \fIstring\fR +followed by a space and the value selected by the user in the dialog. This +is only available on Mac OS X. +.TP \fB\-initialdir\fR \fIdirname\fR Specifies that the directories in \fIdirectory\fR should be displayed when the dialog pops up. If this parameter is not specified, the initial directory defaults to the current working directory on non-Windows systems and on Windows systems prior to Vista. @@ -25,10 +32,14 @@ On Vista and later systems, the initial directory defaults to the last user-selected directory for the application. If the parameter specifies a relative path, the return value will convert the relative path to an absolute path. .TP +\fB\-message\fR \fIstring\fR +Specifies a message to include in the client area of the dialog. +This is only available on Mac OS X. +.TP \fB\-mustexist\fR \fIboolean\fR Specifies whether the user may specify non-existent directories. If this parameter is true, then the user may only select directories that already exist. The default value is \fIfalse\fR. .TP Index: doc/console.n ================================================================== --- doc/console.n +++ doc/console.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2001 Donal K. Fellows '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH console n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/cursors.n ================================================================== --- doc/cursors.n +++ doc/cursors.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1998-2000 by Scriptics Corporation. '\" All rights reserved. -'\" +'\" '\" Copyright (c) 2006-2007 Daniel A. Steffen -'\" +'\" .TH cursors n 8.3 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/destroy.n ================================================================== --- doc/destroy.n +++ doc/destroy.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH destroy n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/dialog.n ================================================================== --- doc/dialog.n +++ doc/dialog.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_dialog n 4.1 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/entry.n ================================================================== --- doc/entry.n +++ doc/entry.n @@ -3,11 +3,11 @@ '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" Copyright (c) 1998-2000 Scriptics Corporation. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH entry n 8.3 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -21,10 +21,11 @@ \-exportselection \-insertofftime \-takefocus \-font \-insertontime \-textvariable \-foreground \-insertwidth \-xscrollcommand \-highlightbackground \-justify \-highlightcolor \-relief +\-placeholder \-placeholderforeground .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-disabledbackground disabledBackground DisabledBackground Specifies the background color to use when the entry is disabled. If this option is the empty string, the normal background color is used. Index: doc/event.n ================================================================== --- doc/event.n +++ doc/event.n @@ -336,11 +336,13 @@ \fB<>\fR This is sent to a text widget when the selection in the widget is changed. .TP \fB<>\fR -This is sent to a text widget when the ttk (Tile) theme changed. +This is sent to all widgets when the ttk theme changed. The ttk +widgets listen to this event and redisplay themselves when it fires. +The legacy widgets ignore this event. .TP \fB<>\fR This is sent to a widget when the focus enters the widget because of a user-driven .QW "tab to widget" Index: doc/focus.n ================================================================== --- doc/focus.n +++ doc/focus.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH focus n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/focusNext.n ================================================================== --- doc/focusNext.n +++ doc/focusNext.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_focusNext n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/fontchooser.n ================================================================== --- doc/fontchooser.n +++ doc/fontchooser.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2008 Daniel A. Steffen '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH fontchooser n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/frame.n ================================================================== --- doc/frame.n +++ doc/frame.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH frame n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/getOpenFile.n ================================================================== --- doc/getOpenFile.n +++ doc/getOpenFile.n @@ -33,10 +33,17 @@ whether the existing file should be overwritten or not. .PP The following \fIoption\-value\fR pairs are possible as command line arguments to these two commands: .TP +\fB\-command\fR \fIstring\fR +Specifies the prefix of a Tcl command to invoke when the user closes the +dialog after having selected an item. This callback is not called if the +user cancelled the dialog. The actual command consists of \fIstring\fR +followed by a space and the value selected by the user in the dialog. This +is only available on Mac OS X. +.TP \fB\-confirmoverwrite\fR \fIboolean\fR Configures how the Save dialog reacts when the selected file already exists, and saving would overwrite it. A true value requests a confirmation dialog be presented to the user. A false value requests that the overwrite take place without confirmation. Default value is true. Index: doc/grab.n ================================================================== --- doc/grab.n +++ doc/grab.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH grab n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/grid.n ================================================================== --- doc/grid.n +++ doc/grid.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH grid n 8.5 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -158,11 +158,12 @@ \fB\-row \fIn\fR . Insert the slave so that it occupies the \fIn\fRth row in the grid. Row numbers start with 0. If this option is not supplied, then the slave is arranged on the same row as the previous slave specified on this -call to \fBgrid\fR, or the first unoccupied row if this is the first slave. +call to \fBgrid\fR, or the next row after the highest occupied row +if this is the first slave. .TP \fB\-rowspan \fIn\fR . Insert the slave so that it occupies \fIn\fR rows in the grid. The default is one row. If the next \fBgrid\fR command contains @@ -199,10 +200,18 @@ master and unmaps their windows. The slaves will no longer be managed by the grid geometry manager. The configuration options for that window are forgotten, so that if the slave is managed once more by the grid geometry manager, the initial default settings are used. +.RS +.PP +.VS TIP518 +If the last slave of the master becomes unmanaged, this will also send +the virtual event \fB<>\fR to the master; the master +may choose to resize itself (or otherwise respond) to such a change. +.VE TIP518 +.RE .TP \fBgrid info \fIslave\fR . Returns a list whose elements are the current configuration state of the slave given by \fIslave\fR in the same option-value form that @@ -275,10 +284,18 @@ The slaves will no longer be managed by the grid geometry manager. However, the configuration options for that window are remembered, so that if the slave is managed once more by the grid geometry manager, the previous values are retained. +.RS +.PP +.VS TIP518 +If the last slave of the master becomes unmanaged, this will also send +the virtual event \fB<>\fR to the master; the master +may choose to resize itself (or otherwise respond) to such a change. +.VE TIP518 +.RE .TP \fBgrid size \fImaster\fR . Returns the size of the grid (in columns then rows) for \fImaster\fR. The size is determined either by the \fIslave\fR occupying the largest Index: doc/image.n ================================================================== --- doc/image.n +++ doc/image.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH image n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/keysyms.n ================================================================== --- doc/keysyms.n +++ doc/keysyms.n @@ -13,11 +13,13 @@ .PP Tk recognizes many keysyms when specifying key bindings (e.g., .QW "\fBbind\fR \fB. \fR" ). The following list enumerates the keysyms that will be recognized by Tk. Note that not all keysyms will -be valid on all platforms. For example, on Unix systems, the presence +be valid on all platforms, and some keysyms are also available on +platforms that have a different native name for that key. +For example, on Unix systems, the presence of a particular keysym is dependant on the configuration of the keyboard modifier map. This list shows keysyms along with their decimal and hexadecimal values. .PP .CS @@ -916,13 +918,20 @@ Super_L 65515 0xffeb Super_R 65516 0xffec Hyper_L 65517 0xffed Hyper_R 65518 0xffee Delete 65535 0xffff +XF86AudioLowerVolume 269025041 0x1008FF11 +XF86AudioMute 269025042 0x1008FF12 +XF86AudioRaiseVolume 269025043 0x1008FF13 +XF86AudioPlay 269025044 0x1008FF14 +XF86AudioStop 269025045 0x1008FF15 +XF86AudioPrev 269025046 0x1008FF16 +XF86AudioNext 269025047 0x1008FF17 .CE .SH "SEE ALSO" bind(n), event(n) .SH KEYWORDS bind, binding, event, keysym '\" Local Variables: '\" mode: nroff '\" End: Index: doc/label.n ================================================================== --- doc/label.n +++ doc/label.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH label n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/lower.n ================================================================== --- doc/lower.n +++ doc/lower.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH lower n 3.3 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/menu.n ================================================================== --- doc/menu.n +++ doc/menu.n @@ -17,11 +17,11 @@ \fBtk_menuSetFocus\fR \fIpathName\fR .SO \-activebackground \-borderwidth \-foreground \-activeborderwidth \-cursor \-relief \-activeforeground \-disabledforeground \-takefocus -\-background \-font +\-background \-font \-activerelief .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-postcommand postCommand Command If this option is specified then it provides a Tcl command to execute each time the menu is posted. The command is invoked by the \fBpost\fR @@ -32,16 +32,16 @@ .OP \-selectcolor selectColor Background For menu entries that are check buttons or radio buttons, this option specifies the color to display in the indicator when the check button or radio button is selected. .OP \-tearoff tearOff TearOff -This option must have a proper boolean value, which specifies -whether or not the menu should include a tear-off entry at the -top. If so, it will exist as entry 0 of the menu and the other -entries will number starting at 1. The default -menu bindings arrange for the menu to be torn off when the tear-off -entry is invoked. +This option must have a proper boolean value (default is false), +which specifies whether or not the menu should include a tear-off +entry at the top. If so, it will exist as entry 0 of the menu and +the other entries will number starting at 1. The default menu +bindings arrange for the menu to be torn off when the tear-off entry +is invoked. This option is ignored under Aqua/Mac OS X, where menus cannot be torn off. .OP \-tearoffcommand tearOffCommand TearOffCommand If this option has a non-empty value, then it specifies a Tcl command to invoke whenever the menu is torn off. The actual command will @@ -99,11 +99,11 @@ If the \fB\-accelerator\fR option is specified for an entry then a second textual field is displayed to the right of the label. The accelerator typically describes a keystroke sequence that may be used in the application to cause the same result as invoking the menu entry. This is a display option, it does not actually set the corresponding -binding (which can be achieved using the \fBbind\fR command). +binding (which can be achieved using the \fBbind\fR command). The third field is an \fIindicator\fR. The indicator is present only for checkbutton or radiobutton entries. It indicates whether the entry is selected or not, and is displayed to the left of the entry's string. .PP Index: doc/menubar.n ================================================================== --- doc/menubar.n +++ doc/menubar.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_menuBar n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/menubutton.n ================================================================== --- doc/menubutton.n +++ doc/menubutton.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH menubutton n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/message.n ================================================================== --- doc/message.n +++ doc/message.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH message n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/messageBox.n ================================================================== --- doc/messageBox.n +++ doc/messageBox.n @@ -22,10 +22,16 @@ popped up, \fBtk_messageBox\fR waits for the user to select one of the buttons. Then it returns the symbolic name of the selected button. .PP The following option-value pairs are supported: .TP +\fB\-command\fR \fIstring\fR +Specifies the prefix of a Tcl command to invoke when the user closes the +dialog. The actual command consists of \fIstring\fR followed by a space +and the name of the button clicked by the user to close the dialog. This +is only available on Mac OS X. +.TP \fB\-default\fR \fIname\fR . \fIName\fR gives the symbolic name of the default button for this message window ( .QW ok , Index: doc/option.n ================================================================== --- doc/option.n +++ doc/option.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH option n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/optionMenu.n ================================================================== --- doc/optionMenu.n +++ doc/optionMenu.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_optionMenu n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/options.n ================================================================== --- doc/options.n +++ doc/options.n @@ -56,10 +56,13 @@ This option is typically only available in widgets displaying more than one element at a time (e.g. menus but not buttons). .OP \-activeforeground activeForeground Background Specifies foreground color to use when drawing active elements. See above for definition of active elements. +.OP \-activerelief activeRelief Relief +Specifies the 3-D effect desired for the active item of the widget. +See the \fB-relief\fR option for details. .OP \-anchor anchor Anchor Specifies how the information in a widget (e.g. text or a bitmap) is to be displayed in the widget. Must be one of the values \fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR, \fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, or \fBcenter\fR. @@ -219,10 +222,18 @@ manager can satisfy this request, the widget will end up with extra internal space above and/or below what it displays inside. Most widgets only use this option for padding text: if they are displaying a bitmap or image, then they usually ignore padding options. +.OP \-placeholder placeHolder PlaceHolder +Specifies a help text string to display if no text is otherwise displayed, +that is when the widget is empty. The placeholder text is displayed using +the values of the \fB\-font\fR and \fB\-justify\fR options. +.OP \-placeholderforeground placeholderForeground PlaceholderForeground +Specifies the foreground color to use when the placeholder text is +displayed. If this option is the empty string, the default color gray70 +is used. .OP \-relief relief Relief Specifies the 3-D effect desired for the widget. Acceptable values are \fBraised\fR, \fBsunken\fR, \fBflat\fR, \fBridge\fR, \fBsolid\fR, and \fBgroove\fR. The value Index: doc/pack-old.n ================================================================== --- doc/pack-old.n +++ doc/pack-old.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH pack-old n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/pack.n ================================================================== --- doc/pack.n +++ doc/pack.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH pack n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -127,10 +127,18 @@ .TP \fBpack forget \fIslave \fR?\fIslave ...\fR? Removes each of the \fIslave\fRs from the packing order for its master and unmaps their windows. The slaves will no longer be managed by the packer. +.RS +.PP +.VS TIP518 +If the last slave of the master becomes unmanaged, this will also send +the virtual event \fB<>\fR to the master; the master +may choose to resize itself (or otherwise respond) to such a change. +.VE TIP518 +.RE .TP \fBpack info \fIslave\fR Returns a list whose elements are the current configuration state of the slave given by \fIslave\fR in the same option-value form that might be specified to \fBpack configure\fR. Index: doc/palette.n ================================================================== --- doc/palette.n +++ doc/palette.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1995-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_setPalette n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/panedwindow.n ================================================================== --- doc/panedwindow.n +++ doc/panedwindow.n @@ -27,10 +27,21 @@ drawn as squares. May be any value accepted by \fBTk_GetPixels\fR. .OP \-height height Height Specifies a desired height for the overall panedwindow widget. May be any value accepted by \fBTk_GetPixels\fR. If an empty string, the widget will be made high enough to allow all contained widgets to have their natural height. +.OP \-opaqueresize opaqueResize OpaqueResize +Specifies whether panes should be resized as a sash is moved (true), +or if resizing should be deferred until the sash is placed (false). +In the latter case, a +.QW ghost +version of the sash is displayed during the resizing to show where the +panes will be resized to when releasing the mouse button. This +.QW ghost +version of the sash is the proxy. It's rendering can be configured +using the \fB-proxybackground\fR, \fB-proxyborderwidth\fR and +\fB-proxyrelief\fR options. .OP \-proxybackground proxyBackground ProxyBackground Background color to use when drawing the proxy. If an empty string, the value of the \fB-background\fR option will be used. .OP \-proxyborderwidth proxyBorderWidth ProxyBorderWidth Specifies the borderwidth of the proxy. May be any value accepted by @@ -37,13 +48,10 @@ \fBTk_GetPixels\fR. .OP \-proxyrelief proxyRelief ProxyRelief Relief to use when drawing the proxy. May be any of the standard Tk relief values. If an empty string, the value of the \fB-sashrelief\fR option will be used. -.OP \-opaqueresize opaqueResize OpaqueResize -Specifies whether panes should be resized as a sash is moved (true), -or if resizing should be deferred until the sash is placed (false). .OP \-sashcursor sashCursor SashCursor Mouse cursor to use when over a sash. If null, \fBsb_h_double_arrow\fR will be used for horizontal panedwindows, and \fBsb_v_double_arrow\fR will be used for vertical panedwindows. .OP \-sashpad sashPad SashPad @@ -130,60 +138,10 @@ \fIx\fR and \fIy\fR, in window coordinates. If the point is over a sash or a sash handle, the result is a two element list containing the index of the sash or handle, and a word indicating whether it is over a sash or a handle, such as {0 sash} or {2 handle}. If the point is over any other part of the panedwindow, the result is an empty list. -.TP -\fIpathName \fBproxy \fR?\fIargs\fR? -. -This command is used to query and change the position of the sash -proxy, used for rubberband-style pane resizing. It can take any of -the following forms: -.RS -.TP -\fIpathName \fBproxy coord\fR -. -Return a list containing the x and y coordinates of the most recent -proxy location. -.TP -\fIpathName \fBproxy forget\fR -. -Remove the proxy from the display. -.TP -\fIpathName \fBproxy place \fIx y\fR -. -Place the proxy at the given \fIx\fR and \fIy\fR coordinates. -.RE -.TP -\fIpathName \fBsash \fR?\fIargs\fR? -This command is used to query and change the position of sashes in the -panedwindow. It can take any of the following forms: -.RS -.TP -\fIpathName \fBsash coord \fIindex\fR -. -Return the current x and y coordinate pair for the sash given by -\fIindex\fR. \fIIndex\fR must be an integer between 0 and 1 less than -the number of panes in the panedwindow. The coordinates given are -those of the top left corner of the region containing the sash. -.TP -\fIpathName \fBsash dragto \fIindex x y\fR -. -This command computes the difference between the given coordinates and the -coordinates given to the last \fBsash mark\fR command for the given -sash. It then moves that sash the computed difference. The return -value is the empty string. -.TP -\fIpathName \fBsash mark \fIindex x y\fR -. -Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in -conjunction with later \fBsash dragto\fR commands to move the sash. -.TP -\fIpathName \fBsash place \fIindex x y\fR -. -Place the sash given by \fIindex\fR at the given coordinates. -.RE .TP \fIpathName \fBpanecget \fIwindow option\fR . Query a management option for \fIwindow\fR. \fIOption\fR may be any value allowed by the \fBpaneconfigure\fR subcommand. @@ -308,10 +266,60 @@ .RE .TP \fIpathName \fBpanes\fR . Returns an ordered list of the widgets managed by \fIpathName\fR. +.TP +\fIpathName \fBproxy \fR?\fIargs\fR? +. +This command is used to query and change the position of the sash +proxy, used for rubberband-style pane resizing. It can take any of +the following forms: +.RS +.TP +\fIpathName \fBproxy coord\fR +. +Return a list containing the x and y coordinates of the most recent +proxy location. +.TP +\fIpathName \fBproxy forget\fR +. +Remove the proxy from the display. +.TP +\fIpathName \fBproxy place \fIx y\fR +. +Place the proxy at the given \fIx\fR and \fIy\fR coordinates. +.RE +.TP +\fIpathName \fBsash \fR?\fIargs\fR? +This command is used to query and change the position of sashes in the +panedwindow. It can take any of the following forms: +.RS +.TP +\fIpathName \fBsash coord \fIindex\fR +. +Return the current x and y coordinate pair for the sash given by +\fIindex\fR. \fIIndex\fR must be an integer between 0 and 1 less than +the number of panes in the panedwindow. The coordinates given are +those of the top left corner of the region containing the sash. +.TP +\fIpathName \fBsash dragto \fIindex x y\fR +. +This command computes the difference between the given coordinates and the +coordinates given to the last \fBsash mark\fR command for the given +sash. It then moves that sash the computed difference. The return +value is the empty string. +.TP +\fIpathName \fBsash mark \fIindex x y\fR +. +Records \fIx\fR and \fIy\fR for the sash given by \fIindex\fR; used in +conjunction with later \fBsash dragto\fR commands to move the sash. +.TP +\fIpathName \fBsash place \fIindex x y\fR +. +Place the sash given by \fIindex\fR at the given coordinates. +.RE .SH "RESIZING PANES" .PP A pane is resized by grabbing the sash (or sash handle if present) and dragging with the mouse. This is accomplished via mouse motion bindings on the widget. When a sash is moved, the sizes of the panes Index: doc/photo.n ================================================================== --- doc/photo.n +++ doc/photo.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1994 The Australian National University '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" '\" Author: Paul Mackerras (paulus@cs.anu.edu.au), '\" Department of Computer Science, '\" Australian National University. '\" .TH photo n 4.0 Tk "Tk Built-In Commands" @@ -22,56 +22,62 @@ \fIimageName \fBblank\fR \fIimageName \fBcget \fIoption\fR \fIimageName \fBconfigure\fR ?\fIoption\fR? ?\fIvalue option value ...\fR? \fIimageName \fBcopy \fIsourceImage\fR ?\fIoption value(s) ...\fR? \fIimageName \fBdata\fR ?\fIoption value(s) ...\fR? -\fIimageName \fBget \fIx y\fR +\fIimageName \fBget \fIx y\fR ?\fIoption\fR? \fIimageName \fBput \fIdata\fR ?\fIoption value(s) ...\fR? \fIimageName \fBread \fIfilename\fR ?\fIoption value(s) ...\fR? \fIimageName \fBredither\fR \fIimageName \fBtransparency \fIsubcommand \fR?\fIarg arg ...\fR? \fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR? .fi .BE .SH DESCRIPTION .PP -A photo is an image whose pixels can display any color or be -transparent. A photo image is stored internally in full color (32 -bits per pixel), and is displayed using dithering if necessary. Image -data for a photo image can be obtained from a file or a string, or it -can be supplied from -C code through a procedural interface. At present, only +A photo is an image whose pixels can display any color with a varying +degree of transparency (the alpha channel). A photo image is stored +internally in full color (32 bits per pixel), and is displayed using +dithering if necessary. Image data for a photo image can be obtained +from a file or a string, or it can be supplied from C code through a +procedural interface. At present, only .VS 8.6 PNG, .VE 8.6 -GIF and PPM/PGM -formats are supported, but an interface exists to allow additional -image file formats to be added easily. A photo image is transparent -in regions where no image data has been supplied -or where it has been set transparent by the \fBtransparency set\fR -subcommand. +GIF and PPM/PGM formats are supported, but an interface exists to +allow additional image file formats to be added easily. A photo image +is (semi)transparent if the image data it was obtained from had +transparency informaton. In regions where no image data has been +supplied, it is fully transparent. Transparency may also be modified +with the \fBtransparency set\fR subcommand. .SH "CREATING PHOTOS" .PP Like all images, photos are created using the \fBimage create\fR command. Photos support the following \fIoptions\fR: .TP \fB\-data \fIstring\fR . -Specifies the contents of the image as a string. The string should -contain binary data or, for some formats, base64-encoded data (this is +Specifies the contents of the image as a string. +.VS 8.7 +The string should +contain data in the default list-of-lists form, +.VE 8.7 +binary data or, for some formats, base64-encoded data (this is currently guaranteed to be supported for PNG and GIF images). The -format of the -string must be one of those for which there is an image file format -handler that will accept string data. If both the \fB\-data\fR -and \fB\-file\fR options are specified, the \fB\-file\fR option takes -precedence. +format of the string must be one of those for which there is an image +file format handler that will accept string data. If both the +\fB\-data\fR and \fB\-file\fR options are specified, the \fB\-file\fR +option takes precedence. .TP -\fB\-format \fIformat-name\fR +\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?} . Specifies the name of the file format for the data specified with the -\fB\-data\fR or \fB\-file\fR option. +\fB\-data\fR or \fB\-file\fR option and optional arguments passed to +the format handler. Note: the value of this option must be a Tcl list. +This means that the braces may be omitted if the argument has only one +word. Also, instead of braces, double quotes may be used for quoting. .TP \fB\-file \fIname\fR . \fIname\fR gives the name of a file that is to be read to supply data for the photo image. The file format must be one of those for which @@ -231,33 +237,43 @@ \fIoverlay\fR. .RE .TP \fIimageName \fBdata\fR ?\fIoption value(s) ...\fR? . -Returns image data in the form of a string. The following options -may be specified: +Returns image data in the form of a string. +.VS 8.7 +The format of the string depends on the format handler. By default, a +human readable format as a list of lists of pixel data is used, other +formats can be chosen with the \fB-format\fR option. +See \fBIMAGE FORMATS\fR below for details. +.VE 8.7 +The following options may be specified: .RS .TP \fB\-background\fI color\fR . If the color is specified, the data will not contain any transparency information. In all transparent pixels the color will be replaced by the specified color. .TP -\fB\-format\fI format-name\fR -. -Specifies the name of the image file format handler to be used. -Specifically, this subcommand searches -for the first handler whose name matches an initial substring of -\fIformat-name\fR and which has the capability to write a string -containing this image data. -If this option is not given, this subcommand uses a format that -consists of a list (one element per row) of lists (one element per -pixel/column) of colors in +\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?} +. +Specifies the name of the image file format handler to use and, +optionally, arguments to the format handler. Specifically, this +subcommand searches for the first handler whose name matches an +initial substring of \fIformat-name\fR and which has the capability to +write a string containing this image data. +.VS 8.7 +If this option is not given, this subcommand uses the default format +that consists of a list (one element per row) of lists (one element +per pixel/column) of colors in .QW \fB#\fIrrggbb\fR -format (where \fIrr\fR is a pair of hexadecimal digits for the red -channel, \fIgg\fR for green, and \fIbb\fR for blue). +format (see \fBIMAGE FORMATS\fR below). +.VE 8.7 +Note: the value of this option must be a Tcl list. +This means that the braces may be omitted if the argument has only one +word. Also, instead of braces, double quotes may be used for quoting. .TP \fB\-from \fIx1 y1 x2 y2\fR . Specifies a rectangular region of \fIimageName\fR to be returned. If only \fIx1\fR and \fIy1\fR are specified, the region @@ -270,47 +286,55 @@ \fB\-grayscale\fR . If this options is specified, the data will not contain color information. All pixel data will be transformed into grayscale. .RE +.VS 8.7 .TP -\fIimageName \fBget\fR \fIx y\fR +\fIimageName \fBget\fR \fIx y\fR ?\fB-withalpha\fR? . Returns the color of the pixel at coordinates (\fIx\fR,\fIy\fR) in the image as a list of three integers between 0 and 255, representing the -red, green and blue components respectively. +red, green and blue components respectively. If the \fB-withalpha\fR +option is specified, the returned list will have a fourth element +representing the alpha value of the pixel as an integer between 0 and +255. +.VE 8.7 .TP \fIimageName \fBput\fR \fIdata\fR ?\fIoption value(s) ...\fR? . Sets pixels in \fI imageName\fR to the data specified in \fIdata\fR. -This command first searches the list of image file format handlers for +.VS 8.7 +This command searches the list of image file format handlers for a handler that can interpret the data in \fIdata\fR, and then reads the image encoded within into \fIimageName\fR (the destination image). -If \fIdata\fR does not match any known format, an attempt to interpret -it as a (top-to-bottom) list of scan-lines is made, with each -scan-line being a (left-to-right) list of pixel colors (see -\fBTk_GetColor\fR for a description of valid colors.) Every scan-line -must be of the same length. Note that when \fIdata\fR is a single -color name, you are instructing Tk to fill a rectangular region with -that color. The following options may be specified: +See \fBIMAGE FORMATS\fR below for details on formats for image data. +.VE 8.7 +The following options may be specified: .RS .TP -\fB\-format \fIformat-name\fR +\fB\-format\fR {\fIformat-name\fR ?\fIoption value ..\fR?} . -Specifies the format of the image data in \fIdata\fR. +Specifies the format of the image data in \fIdata\fR and, optionally, +arguments to be passed to the format handler. Specifically, only image file format handlers whose names begin with \fIformat-name\fR will be used while searching for an image data format handler to read the data. +Note: the value of this option must be a Tcl list. +This means that the braces may be omitted if the argument has only one +word. Also, instead of braces, double quotes may be used for quoting. .TP \fB\-to \fIx1 y1\fR ?\fIx2 y2\fR? . Specifies the coordinates of the top-left corner (\fIx1\fR,\fIy1\fR) of the region of \fIimageName\fR into which the image data will be copied. The default position is (0,0). If \fIx2\fR,\fIy2\fR is given and \fIdata\fR is not large enough to cover the rectangle specified by this option, the image data extracted will be tiled so it covers the -entire destination rectangle. Note that if \fIdata\fR specifies a +entire destination rectangle. If the region specified with this opion +is smaller than the supplied \fIdata\fR, the exceeding data is silently +discarded. Note that if \fIdata\fR specifies a single color value, then a region extending to the bottom-right corner represented by (\fIx2\fR,\fIy2\fR) will be filled with that color. .RE .TP \fIimageName \fBread\fR \fIfilename\fR ?\fIoption value(s) ...\fR? @@ -321,16 +345,20 @@ in \fIfilename\fR, and then reads the image in \fIfilename\fR into \fIimageName\fR (the destination image). The following options may be specified: .RS .TP -\fB\-format \fIformat-name\fR +\fB\-format {\fIformat-name\fR ?\fIoption value ..\fR?} . -Specifies the format of the image data in \fIfilename\fR. +Specifies the format of the image data in \fIfilename\fR and, +optionally, additional options to the format handler. Specifically, only image file format handlers whose names begin with \fIformat-name\fR will be used while searching for an image data format handler to read the data. +Note: the value of this option must be a Tcl list. +This means that the braces may be omitted if the argument has only one +word. Also, instead of braces, double quotes may be used for quoting. .TP \fB\-from \fIx1 y1 x2 y2\fR . Specifies a rectangular sub-region of the image file data to be copied to the destination image. If only \fIx1\fR and \fIy1\fR are @@ -369,20 +397,30 @@ \fIimageName \fBtransparency \fIsubcommand \fR?\fIarg arg ...\fR? . Allows examination and manipulation of the transparency information in the photo image. Several subcommands are available: .RS -.TP -\fIimageName \fBtransparency get \fIx y\fR -. -Returns a boolean indicating if the pixel at (\fIx\fR,\fIy\fR) is -transparent. -.TP -\fIimageName \fBtransparency set \fIx y boolean\fR -. -Makes the pixel at (\fIx\fR,\fIy\fR) transparent if \fIboolean\fR is -true, and makes that pixel opaque otherwise. +.VS 8.7 +.TP +\fIimageName \fBtransparency get \fIx y\fR ?\fB-alpha\fR? +. +Returns true if the pixel at (\fIx\fR,\fIy\fR) is fully transparent, +false otherwise. If the option \fB-alpha\fR is passed, returns the +alpha value of the pixel instead, as an integer in the range 0 to 255. +.VE 8.7 + +.VS 8.7 +.TP +\fIimageName \fBtransparency set \fIx y\fR \fInewVal\fR ?\fB-alpha\fR? +. +Change the transparency of the pixel at (\fIx\fR,\fIy\fR) to +\fInewVal.\fR If no additional option is passed, \fInewVal\fR is +interpreted as a boolean and the pixel is made fully transparent if +that value is true, fully opaque otherwise. If the \fB-alpha\fR +option is passed, \fInewVal\fR is interpreted as an integral alpha +value for the pixel, which must be in the range 0 to 255. +.VE 8.7 .RE .TP \fIimageName \fBwrite \fIfilename\fR ?\fIoption value(s) ...\fR? . Writes image data from \fIimageName\fR to a file named \fIfilename\fR. @@ -393,19 +431,23 @@ . If the color is specified, the data will not contain any transparency information. In all transparent pixels the color will be replaced by the specified color. .TP -\fB\-format\fI format-name\fR +\fB\-format\fR {\fIformat-name\fR ?\fIoption value ...\fR?} . Specifies the name of the image file format handler to be used to -write the data to the file. Specifically, this subcommand searches -for the first handler whose name matches an initial substring of -\fIformat-name\fR and which has the capability to write an image -file. If this option is not given, the format is guessed from -the file extension. If that cannot be determined, this subcommand -uses the first handler that has the capability to write an image file. +write the data to the file and, optionally, options to pass to the +format handler. Specifically, this subcommand searches for the first +handler whose name matches an initial substring of \fIformat-name\fR +and which has the capability to write an image file. If this option +is not given, the format is guessed from the file extension. If that +cannot be determined, this subcommand uses the first handler that has +the capability to write an image file. +Note: the value of this option must be a Tcl list. +This means that the braces may be omitted if the argument has only one +word. Also, instead of braces, double quotes may be used for quoting. .TP \fB\-from \fIx1 y1 x2 y2\fR . Specifies a rectangular region of \fIimageName\fR to be written to the image file. If only \fIx1\fR and \fIy1\fR are specified, the region @@ -424,24 +466,28 @@ The photo image code is structured to allow handlers for additional image file formats to be added easily. The photo image code maintains a list of these handlers. Handlers are added to the list by registering them with a call to \fBTk_CreatePhotoImageFormat\fR. The standard Tk distribution comes with handlers for PPM/PGM, PNG and GIF -formats, which are automatically registered on initialization. +formats, +.VS 8.7 +as well as the \fBdefault\fR handler to encode/decode image +data in a human readable form. +.VE 8.7 +These handlers are automatically registered on initialization. .PP -When reading an image file or processing -string data specified with the \fB\-data\fR configuration option, the -photo image code invokes each handler in turn until one is -found that claims to be able to read the data in the file or string. -Usually this will find the correct handler, but if it does not, the -user may give a format name with the \fB\-format\fR option to specify -which handler to use. In fact the photo image code will try those -handlers whose names begin with the string specified for the -\fB\-format\fR option (the comparison is case-insensitive). For -example, if the user specifies \fB\-format gif\fR, then a handler -named GIF87 or GIF89 may be invoked, but a handler -named JPEG may not (assuming that such handlers had been +When reading an image file or processing string data specified with +the \fB\-data\fR configuration option, the photo image code invokes +each handler in turn until one is found that claims to be able to read +the data in the file or string. Usually this will find the correct +handler, but if it does not, the user may give a format name with the +\fB\-format\fR option to specify which handler to use. In this case, +the photo image code will try those handlers whose names begin with +the string specified for the \fB\-format\fR option (the comparison is +case-insensitive). For example, if the user specifies \fB\-format +gif\fR, then a handler named GIF87 or GIF89 may be invoked, but a +handler named JPEG may not (assuming that such handlers had been registered). .PP When writing image data to a file, the processing of the \fB\-format\fR option is slightly different: the string value given for the \fB\-format\fR option must begin with the complete name of the @@ -448,31 +494,113 @@ requested handler, and may contain additional information following that, which the handler can use, for example, to specify which variant to use of the formats supported by the handler. Note that not all image handlers may support writing transparency data to a file, even where the target image format does. +.VS 8.7 +.SS "THE DEFAULT IMAGE HANDLER" +.PP +The \fBdefault\fR image handler cannot be used to read or write data +from/to a file. Its sole purpose is to encode and decode image data in +string form in a clear text, human readable, form. The \fIimageName\fR +\fBdata\fR subcommand uses this handler when no other format is +specified. When reading image data from a string with \fIimageName\fR +\fBput\fR or the \fB-data\fR option, the default handler is treated +as the other handlers. +.PP +Image data in the \fBdefault\fR string format is a (top-to-bottom) +list of scan-lines, with each scan-line being a (left-to-right) list +of pixel data. Every scan-line has the same length. The color +and, optionally, alpha value of each pixel is specified in any of +the forms described in the \fBCOLOR FORMATS\fR section below. +.VE 8.7 + .SS "FORMAT SUBOPTIONS" .PP .VS 8.6 -Some image formats support sub-options, which are specified at the time that -the image is loaded using additional words in the \fB\-format\fR option. At -the time of writing, the following are supported: +Image formats may support sub-options, wich ahre specified using +additional words in the value to the \fB\-format\fR option. These +suboptions can affect how image data is read or written to file or +string. The nature and values of these options is up to the format +handler. +The built-in handlers support these suboptions: +.VS 8.7 +.TP +\fBdefault \-colorformat\fI formatType\fR +. +The option is allowed when writing image data to a string with +\fIimageName\fR \fBdata\fR. Specifies the format to use for the color +string of each pixel. \fIformatType\fR may be one of: \fBrgb\fR to +encode pixel data in the form \fB#\fIRRGGBB\fR, \fBrgba\fR to encode +pixel data in the form \fB#\fIRRGGBBAA\fR or \fBlist\fR to encode +pixel data as a list with four elements. See \fBCOLOR FORMATS\fR +below for details. The default is \fBrgb\fR. +.VE 8.7 .TP \fBgif \-index\fI indexValue\fR . -When parsing a multi-part GIF image, Tk normally only accesses the first -image. By giving the \fB\-index\fR sub-option, the \fIindexValue\fR'th value -may be used instead. The \fIindexValue\fR must be an integer from 0 up to the -number of image parts in the GIF data. +The option has effect when reading image data from a file. When +parsing a multi-part GIF image, Tk normally only accesses the first +image. By giving the \fB\-index\fR sub-option, the \fIindexValue\fR'th +value may be used instead. The \fIindexValue\fR must be an integer +from 0 up to the number of image parts in the GIF data. .TP \fBpng \-alpha\fI alphaValue\fR . -An additional alpha filtering for the overall image, which allows the -background on which the image is displayed to show through. This usually also -has the effect of desaturating the image. The \fIalphaValue\fR must be between -0.0 and 1.0. +The option has effect when reading image data from a file. Specifies +an additional alpha filtering for the overall image, which allows the +background on which the image is displayed to show through. This +usually also has the effect of desaturating the image. The +\fIalphaValue\fR must be between 0.0 and 1.0. .VE 8.6 +.VS 8.7 +.SH "COLOR FORMATS" +.PP +The default image handler can represent/parse color and alpha values +of a pixel in one of the formats listed below. If a color format does +not contain transparency information, full opacity is assumed. The +available color formats are: +.IP \(bu 3 +The empty string - interpreted as full transparency, the color value +is undefined. +.IP \(bu 3 +Any value accepted by \fBTk_GetColor\fR, optionally followed by an +alpha suffix. The alpha suffix may be one of: +.RS +.TP +\fB@\fR\fIA\fR +. +The alpha value \fIA\fR must be a fractional value in the range 0.0 +(fully transparent) to 1.0 (fully opaque). +.TP +\fB#\fR\fIX\fR +. +The alpha value \fIX\fR is a hexadecimal digit that specifies an integer +alpha value in the range 0 (fully transparent) to 255 (fully opaque). +This is expanded in range from 4 bits wide to 8 bits wide by +multiplication by 0x11. +.TP +\fB#\fR\fIXX\fR +. +The alpha value \fIXX\fR is passed as two hexadecimal digits that +specify an integer alpha value in the range 0 (fully transparent) to 255 +(fully opaque). +.RE +.IP \(bu 3 +A Tcl list with three or four integers in the range 0 to 255, +specifying the values for the red, green, blue and (optionally) +alpha channels respectively. +.IP \(bu 3 +\fB#\fR\fIRGBA\fR format: a \fB#\fR followed by four hexadecimal digits, +where each digit is the value for the red, green, blue and alpha +channels respectively. Each digit will be expanded internally to +8 bits by multiplication by 0x11. +.IP \(bu 3 +\fB#\fR\fIRRGGBBAA\fR format: \fB#\fR followed by eight hexadecimal digits, +where each pair of subsequent digits represents the value for the red, +green, blue and alpha channels respectively. +.VE 8.7 .SH "COLOR ALLOCATION" .PP When a photo image is displayed in a window, the photo image code allocates colors to use to display the image and dithers the image, if necessary, to display a reasonable approximation to the image using @@ -532,12 +660,29 @@ \fBimage create photo\fR iconDisabled \-file "icon.png" \e \-format "png \-alpha 0.5" button .b \-image icon \-disabledimage iconDisabled .CE .VE 8.6 +.PP +.VS 8.7 +Create a green box with a simple shadow effect +.PP +.CS +\fBimage create photo\fR foo + +# Make a simple graduated fill varying in alpha for the shadow +for {set i 14} {$i > 0} {incr i -1} { + set i2 [expr {$i + 30}] + foo \fBput\fR [format black#%x [expr {15-$i}]] -to $i $i $i2 $i2 +} + +# Put a solid green rectangle on top +foo \fBput\fR #F080 -to 0 0 30 30 +.VE 8.7 +.CE .SH "SEE ALSO" image(n) .SH KEYWORDS photo, image, color '\" Local Variables: '\" mode: nroff '\" End: Index: doc/place.n ================================================================== --- doc/place.n +++ doc/place.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH place n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/popup.n ================================================================== --- doc/popup.n +++ doc/popup.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk_popup n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/radiobutton.n ================================================================== --- doc/radiobutton.n +++ doc/radiobutton.n @@ -39,20 +39,10 @@ .OP \-indicatoron indicatorOn IndicatorOn Specifies whether or not the indicator should be drawn. Must be a proper boolean value. If false, the \fB\-relief\fR option is ignored and the widget's relief is always sunken if the widget is selected and raised otherwise. -.OP \-selectcolor selectColor Background -Specifies a background color to use when the button is selected. -If \fB\-indicatoron\fR is true then the color applies to the indicator. -Under Windows, this color is used as the background for the indicator -regardless of the select state. -If \fB\-indicatoron\fR is false, this color is used as the background -for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR, -whenever the widget is selected. -If specified as an empty string then no special color is used for -displaying when the widget is selected. .OP \-offrelief offRelief OffRelief Specifies the relief for the checkbutton when the indicator is not drawn and the checkbutton is off. The default value is .QW raised . By setting this option to @@ -69,10 +59,19 @@ mouse cursor is over the widget. This option can be used to make toolbar buttons, by configuring \fB\-relief flat \-overrelief raised\fR. If the value of this option is the empty string, then no alternative relief is used when the mouse cursor is over the radiobutton. The empty string is the default value. +.OP \-selectcolor selectColor Background +Specifies a background color to use when the button is selected. +If \fBindicatorOn\fR is true then the color is used as the background for +the indicator regardless of the select state. +If \fB\-indicatoron\fR is false, this color is used as the background +for the entire widget, in place of \fB\-background\fR or \fB\-activeBackground\fR, +whenever the widget is selected. +If specified as an empty string then no special color is used for +displaying when the widget is selected. .OP \-selectimage selectImage SelectImage Specifies an image to display (in place of the \fB\-image\fR option) when the radiobutton is selected. This option is ignored unless the \fB\-image\fR option has been specified. Index: doc/raise.n ================================================================== --- doc/raise.n +++ doc/raise.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH raise n 3.3 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -29,10 +29,13 @@ this could end up either raising or lowering \fIwindow\fR. .PP All \fBtoplevel\fR windows may be restacked with respect to each other, whatever their relative path names, but the window manager is not obligated to strictly honor requests to restack. +.PP +On macOS raising an iconified \fBtoplevel\fR window causes it to be +deiconified. .SH EXAMPLE .PP Make a button appear to be in a sibling frame that was created after it. This is is often necessary when building GUIs in the style where you create your activity widgets first before laying them out on the Index: doc/scale.n ================================================================== --- doc/scale.n +++ doc/scale.n @@ -89,14 +89,14 @@ value of the variable changes, the scale will update to reflect this value. Whenever the scale is manipulated interactively, the variable will be modified to reflect the scale's new value. .OP \-width width Width -Specifies the desired narrow dimension of the trough in screen units +Specifies the desired narrow dimension of the scale in screen units (i.e. any of the forms acceptable to \fBTk_GetPixels\fR). -For vertical scales this is the trough's width; for horizontal scales -this is the trough's height. +For vertical scales this is the scale's width; for horizontal scales +this is the scale's height. .BE .SH DESCRIPTION .PP The \fBscale\fR command creates a new window (given by the \fIpathName\fR argument) and makes it into a scale widget. Index: doc/scrollbar.n ================================================================== --- doc/scrollbar.n +++ doc/scrollbar.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH scrollbar n 4.1 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/selection.n ================================================================== --- doc/selection.n +++ doc/selection.n @@ -138,10 +138,30 @@ that it has lost the selection. If \fIcommand\fR is specified, it is a Tcl script to execute when some other window claims ownership of the selection away from \fIwindow\fR. \fISelection\fR defaults to PRIMARY. .RE +.SH WIDGET FACILITIES +.PP +The \fBtext\fR, \fBentry\fR, \fBttk::entry\fR, \fBlistbox\fR, \fBspinbox\fR and \fBttk::spinbox\fR widgets have the option \fB\-exportselection\fR. If a widget has this option set to boolean \fBtrue\fR, then (in an unsafe interpreter) a selection made in the widget is automatically written to the \fBPRIMARY\fR selection. +.PP +A GUI event, for example \fB<>\fR, can copy the \fBPRIMARY\fR selection to certain widgets. This copy is implemented by a widget binding to the event. The binding script makes appropriate calls to the \fBselection\fR command. +.PP +.SH PORTABILITY ISSUES +.PP +On X11, the \fBPRIMARY\fR selection is a system-wide feature of the X server, allowing communication between different processes that are X11 clients. +.PP +On Windows, the \fBPRIMARY\fR selection is not provided by the system, but only by Tk, and so it is shared only between windows of a 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. +.PP +.SH SECURITY +.PP +A safe interpreter cannot read from the \fBPRIMARY\fR selection because its \fBselection\fR command is hidden. For this reason the \fBPRIMARY\fR selection cannot be written to the Tk widgets of a safe interpreter. +.PP +A Tk widget can have its option \fB\-exportselection\fR set to boolean \fBtrue\fR, but in a safe interpreter this option has no effect: writing from the widget to the \fBPRIMARY\fR selection is disabled. +.PP +These are security features. A safe interpreter may run untrusted code, and it is a security risk if this untrusted code can read or write the \fBPRIMARY\fR selection used by other interpreters. +.PP .SH EXAMPLES .PP On X11 platforms, one of the standard selections available is the \fBSECONDARY\fR selection. Hardly anything uses it, but here is how to read it using Tk: Index: doc/send.n ================================================================== --- doc/send.n +++ doc/send.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH send n 4.0 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/spinbox.n ================================================================== --- doc/spinbox.n +++ doc/spinbox.n @@ -2,11 +2,11 @@ '\" Copyright (c) 2000 Jeffrey Hobbs. '\" Copyright (c) 2000 Ajuba Solutions. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH spinbox n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -21,10 +21,11 @@ \-exportselection \-insertwidth \-takefocus \-font \-insertofftime \-textvariable \-foreground \-justify \-xscrollcommand \-highlightbackground \-relief \-highlightcolor \-repeatdelay +\-placeholder \-placeholderforeground .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-buttonbackground buttonBackground Background The background color to be used for the spin buttons. .OP \-buttoncursor buttonCursor Cursor @@ -52,11 +53,12 @@ as it will format a floating-point number. .OP \-from from From A floating-point value corresponding to the lowest value for a spinbox, to be used in conjunction with \fB\-to\fR and \fB\-increment\fR. When all are specified correctly, the spinbox will use these values to control its -contents. This value must be less than the \fB\-to\fR option. +contents. If this value is greater than the \fB\-to\fR option, then +\fB\-from\fR and \fB\-to\fR values are automatically swapped. If \fB\-values\fR is specified, it supersedes this option. .OP "\-invalidcommand or \-invcmd" invalidCommand InvalidCommand Specifies a script to eval when \fB\-validatecommand\fR returns 0. Setting it to an empty string disables this feature (the default). The best use of this option is to set it to \fIbell\fR. See \fBVALIDATION\fR below for @@ -81,11 +83,12 @@ \fB\-disabledforeground\fR and \fB\-disabledbackground\fR options. .OP \-to to To A floating-point value corresponding to the highest value for the spinbox, to be used in conjunction with \fB\-from\fR and \fB\-increment\fR. When all are specified correctly, the spinbox will use these values to control -its contents. This value must be greater than the \fB\-from\fR option. +its contents. If this value is less than the \fB\-from\fR option, then +\fB\-from\fR and \fB\-to\fR values are automatically swapped. If \fB\-values\fR is specified, it supersedes this option. .OP \-validate validate Validate Specifies the mode in which validation should operate: \fBnone\fR, \fBfocus\fR, \fBfocusin\fR, \fBfocusout\fR, \fBkey\fR, or \fBall\fR. It defaults to \fBnone\fR. When you want validation, you must explicitly @@ -215,19 +218,23 @@ in the \fB\-validatecommand\fR or \fB\-invalidcommand\fR (whichever one you were editing the spinbox widget from). It is also recommended to not set an associated \fB\-textvariable\fR during validation, as that can cause the spinbox widget to become out of sync with the \fB\-textvariable\fR. .PP -Also, the \fBvalidate\fR option will set itself to \fBnone\fR when the -spinbox value gets changed because of adjustment of \fBfrom\fR or \fBto\fR -and the \fBvalidateCommand\fR returns false. For instance +Also, the \fB-validate\fR option will set itself to \fBnone\fR when the +spinbox value gets changed because of adjustment of \fB-from\fR or \fB-to\fR +and the \fB-validatecommand\fR returns false. For instance .CS \fIspinbox pathName \-from 1 \-to 10 \-validate all \-vcmd {return 0}\fR .CE -will in fact set the \fBvalidate\fR option to \fBnone\fR because the default -value for the spinbox gets changed (due to the \fBfrom\fR and \fBto\fR +will in fact set the \fB-validate\fR option to \fBnone\fR because the default +value for the spinbox gets changed (due to the \fB-from\fR and \fB-to\fR options) to a value not accepted by the validation script. +.PP +Moreover, forced validation is performed when invoking any spinbutton of +the spinbox. If the validation script returns false in this situation, +then the \fB-validate\fR option will be automatically set to \fBnone\fR. .SH "WIDGET COMMAND" .PP The \fBspinbox\fR command creates a new Tcl command whose name is \fIpathName\fR. This command may be used to invoke various operations on the widget. It has the following general form: Index: doc/text.n ================================================================== --- doc/text.n +++ doc/text.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH text n 8.5 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -535,11 +535,11 @@ character of that display line. .TP \fB\-rmargincolor \fIcolor\fR . \fIColor\fR specifies the background color to use in regions that do not -contain characters because they are indented by \fB\-rmargin1\fR. It may +contain characters because they are indented by \fB\-rmargin\fR. It may have any of the forms accepted by \fBTk_GetColor\fR. If \fIcolor\fR has not been specified, or if it is specified as an empty string, then the color used is specified by the \fB-background\fR tag option (or, if this is also unspecified, by the \fB-background\fR widget option). .TP @@ -607,13 +607,15 @@ specified by the \fB\-foreground\fR tag option is used. .TP \fB\-wrap \fImode\fR . \fIMode\fR specifies how to handle lines that are wider than the text's -window. It has the same legal values as the \fB\-wrap\fR option for the text -widget: \fBnone\fR, \fBchar\fR, or \fBword\fR. If this tag option is -specified, it overrides the \fB\-wrap\fR option for the text widget. +window. This option only applies to a display line if it applies to the +first non-elided character on that display line. It has the same legal +values as the \fB\-wrap\fR option for the text widget: \fBnone\fR, +\fBchar\fR, or \fBword\fR. If this tag option is specified, it +overrides the \fB\-wrap\fR option for the text widget. .PP If a character has several tags associated with it, and if their display options conflict, then the options of the highest priority tag are used. If a particular display option has not been specified for a particular tag, or if it is specified as an empty string, then that option will never be used; the @@ -1305,12 +1307,13 @@ of the widget to \fIboolean\fR. .TP \fIpathName \fBedit redo\fR . When the \fB\-undo\fR option is true, reapplies the last undone edits provided -no other edits were done since then. Generates an error when the redo stack is -empty. Does nothing when the \fB\-undo\fR option is false. +no other edits were done since then, and returns a list of indices indicating +what ranges were changed by the redo operation. Generates an error when the +redo stack is empty. Does nothing when the \fB\-undo\fR option is false. .TP \fIpathName \fBedit reset\fR . Clears the undo and redo stacks. .TP @@ -1319,13 +1322,14 @@ Inserts a separator (boundary) on the undo stack. Does nothing when the \fB\-undo\fR option is false. .TP \fIpathName \fBedit undo\fR . -Undoes the last edit action when the \fB\-undo\fR option is true. An edit -action is defined as all the insert and delete commands that are recorded on -the undo stack in between two separators. Generates an error when the undo +Undoes the last edit action when the \fB\-undo\fR option is true, and returns a +list of indices indicating what ranges were changed by the undo operation. An +edit action is defined as all the insert and delete commands that are recorded +on the undo stack in between two separators. Generates an error when the undo stack is empty. Does nothing when the \fB\-undo\fR option is false. .RE .TP \fIpathName \fBget\fR ?\fB\-displaychars\fR? ?\fB\-\-\fR? \fIindex1\fR ?\fIindex2 ...\fR? . @@ -2151,15 +2155,15 @@ insertion cursor without moving the insertion cursor. .IP [29] Meta-backspace and Meta-Delete delete the word to the left of the insertion cursor. .IP [30] +Control-t reverses the order of the two characters to the right of the +insertion cursor. +.IP [31] Control-x deletes whatever is selected in the text widget after copying it to the clipboard. -.IP [31] -Control-t reverses the order of the two characters to the right of the -insertion cursor. .IP [32] Control-z undoes the last edit action if the \fB\-undo\fR option is true. Does nothing otherwise. .IP [33] Control-Z (or Control-y on Windows) reapplies the last undone edit action if Index: doc/tk.n ================================================================== --- doc/tk.n +++ doc/tk.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/tk4.0.ps ================================================================== --- doc/tk4.0.ps +++ doc/tk4.0.ps @@ -14,11 +14,11 @@ % This file fixes the problem with NeWS printers dithering color output. % Any questions should be sent to mickey@magickingdom.eng.sun.com % % Known Problems: % Due to bugs in Transcript, the 'PS-Adobe-' is omitted from line 1 -/FMversion (3.0) def +/FMversion (3.0) def % Set up Color vs. Black-and-White /FMPrintInColor { % once-thru loop gimmick % See if we're a NeWSprint printer /currentcanvas where { @@ -36,38 +36,38 @@ systemdict /currentcolortransfer known and exit } loop def % Uncomment the following line to force b&w on color printer % /FMPrintInColor false def -/FrameDict 195 dict def +/FrameDict 195 dict def systemdict /errordict known not {/errordict 10 dict def errordict /rangecheck {stop} put} if % The readline in 23.0 doesn't recognize cr's as nl's on AppleTalk -FrameDict /tmprangecheck errordict /rangecheck get put -errordict /rangecheck {FrameDict /bug true put} put -FrameDict /bug false put -mark +FrameDict /tmprangecheck errordict /rangecheck get put +errordict /rangecheck {FrameDict /bug true put} put +FrameDict /bug false put +mark % Some PS machines read past the CR, so keep the following 3 lines together! currentfile 5 string readline 00 0000000000 -cleartomark -errordict /rangecheck FrameDict /tmprangecheck get put -FrameDict /bug get { +cleartomark +errordict /rangecheck FrameDict /tmprangecheck get put +FrameDict /bug get { /readline { /gstring exch def /gfile exch def /gindex 0 def { - gfile read pop - dup 10 eq {exit} if - dup 13 eq {exit} if - gstring exch gindex exch put - /gindex gindex 1 add def + gfile read pop + dup 10 eq {exit} if + dup 13 eq {exit} if + gstring exch gindex exch put + /gindex gindex 1 add def } loop - pop - gstring 0 gindex getinterval true + pop + gstring 0 gindex getinterval true } def } if /FMVERSION { FMversion ne { /Times-Roman findfont 18 scalefont setfont @@ -74,16 +74,16 @@ 100 100 moveto (FrameMaker version does not match postscript_prolog!) dup = show showpage } if - } def + } def /FMLOCAL { FrameDict begin - 0 def - end - } def + 0 def + end + } def /gstring FMLOCAL /gfile FMLOCAL /gindex FMLOCAL /orgxfer FMLOCAL /orgproc FMLOCAL @@ -92,12 +92,12 @@ /yscale FMLOCAL /xscale FMLOCAL /manualfeed FMLOCAL /paperheight FMLOCAL /paperwidth FMLOCAL -/FMDOCUMENT { - array /FMfonts exch def +/FMDOCUMENT { + array /FMfonts exch def /#copies exch def FrameDict begin 0 ne dup {setmanualfeed} if /manualfeed exch def /paperheight exch def @@ -105,109 +105,109 @@ /yscale exch def /xscale exch def currenttransfer cvlit /orgxfer exch def currentscreen cvlit /orgproc exch def /organgle exch def /orgfreq exch def - setpapername - manualfeed {true} {papersize} ifelse - {manualpapersize} {false} ifelse + setpapername + manualfeed {true} {papersize} ifelse + {manualpapersize} {false} ifelse {desperatepapersize} if - end - } def + end + } def /pagesave FMLOCAL /orgmatrix FMLOCAL /landscape FMLOCAL -/FMBEGINPAGE { - FrameDict begin +/FMBEGINPAGE { + FrameDict begin /pagesave save def 3.86 setmiterlimit /landscape exch 0 ne def - landscape { - 90 rotate 0 exch neg translate pop + landscape { + 90 rotate 0 exch neg translate pop } {pop pop} ifelse xscale yscale scale /orgmatrix matrix def - gsave - } def + gsave + } def /FMENDPAGE { - grestore + grestore pagesave restore - end + end showpage - } def -/FMFONTDEFINE { + } def +/FMFONTDEFINE { FrameDict begin - findfont - ReEncode - 1 index exch - definefont - FMfonts 3 1 roll + findfont + ReEncode + 1 index exch + definefont + FMfonts 3 1 roll put - end - } def + end + } def /FMFILLS { FrameDict begin array /fillvals exch def - end - } def + end + } def /FMFILL { FrameDict begin fillvals 3 1 roll put - end - } def -/FMNORMALIZEGRAPHICS { + end + } def +/FMNORMALIZEGRAPHICS { newpath 0.0 0.0 moveto 1 setlinewidth 0 setlinecap 0 0 0 sethsbcolor - 0 setgray + 0 setgray } bind def /fx FMLOCAL /fy FMLOCAL /fh FMLOCAL /fw FMLOCAL /llx FMLOCAL /lly FMLOCAL /urx FMLOCAL /ury FMLOCAL -/FMBEGINEPSF { - end - /FMEPSF save def - /showpage {} def - FMNORMALIZEGRAPHICS - [/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall - fx fy translate +/FMBEGINEPSF { + end + /FMEPSF save def + /showpage {} def + FMNORMALIZEGRAPHICS + [/fy /fx /fh /fw /ury /urx /lly /llx] {exch def} forall + fx fy translate rotate - fw urx llx sub div fh ury lly sub div scale - llx neg lly neg translate + fw urx llx sub div fh ury lly sub div scale + llx neg lly neg translate } bind def /FMENDEPSF { FMEPSF restore - FrameDict begin + FrameDict begin } bind def -FrameDict begin +FrameDict begin /setmanualfeed { %%BeginFeature *ManualFeed True statusdict /manualfeed true put %%EndFeature } def /max {2 copy lt {exch} if pop} bind def /min {2 copy gt {exch} if pop} bind def /inch {72 mul} def -/pagedimen { - paperheight sub abs 16 lt exch +/pagedimen { + paperheight sub abs 16 lt exch paperwidth sub abs 16 lt and {/papername exch def} {pop} ifelse } def /papersizedict FMLOCAL -/setpapername { - /papersizedict 14 dict def +/setpapername { + /papersizedict 14 dict def papersizedict begin - /papername /unknown def + /papername /unknown def /Letter 8.5 inch 11.0 inch pagedimen /LetterSmall 7.68 inch 10.16 inch pagedimen /Tabloid 11.0 inch 17.0 inch pagedimen /Ledger 17.0 inch 11.0 inch pagedimen /Legal 8.5 inch 14.0 inch pagedimen @@ -235,13 +235,13 @@ /B4 {b4tray b4} def /B5 {b5tray b5} def /unknown {unknown} def papersizedict dup papername known {papername} {/unknown} ifelse get end - /FMdicttop countdictstack 1 add def - statusdict begin stopped end - countdictstack -1 FMdicttop {pop end} for + /FMdicttop countdictstack 1 add def + statusdict begin stopped end + countdictstack -1 FMdicttop {pop end} for } def /manualpapersize { papersizedict begin /Letter {letter} def /LetterSmall {lettersmall} def @@ -256,18 +256,18 @@ /B4 {b4} def /B5 {b5} def /unknown {unknown} def papersizedict dup papername known {papername} {/unknown} ifelse get end - stopped + stopped } def /desperatepapersize { statusdict /setpageparams known { - paperwidth paperheight 0 1 + paperwidth paperheight 0 1 statusdict begin - {setpageparams} stopped pop + {setpageparams} stopped pop end } if } def /savematrix { orgmatrix currentmatrix pop @@ -312,22 +312,22 @@ /Acircumflex /Ecircumflex /Aacute /Edieresis /Egrave /Iacute /Icircumflex /Idieresis /Igrave /Oacute /Ocircumflex /.notdef /Ograve /Uacute /Ucircumflex /Ugrave /dotlessi /circumflex /tilde /macron /breve /dotaccent /ring /cedilla /hungarumlaut /ogonek /caron ] def -/ReEncode { - dup - length - dict begin - { - 1 index /FID ne - {def} - {pop pop} ifelse - } forall - 0 eq {/Encoding DiacriticEncoding def} if - currentdict - end +/ReEncode { + dup + length + dict begin + { + 1 index /FID ne + {def} + {pop pop} ifelse + } forall + 0 eq {/Encoding DiacriticEncoding def} if + currentdict + end } bind def /graymode true def /bwidth FMLOCAL /bpside FMLOCAL /bstring FMLOCAL @@ -340,11 +340,11 @@ /setpattern { /bwidth exch def /bpside exch def /bstring exch def /onbits 0 def /offbits 0 def - freq sangle landscape {90 add} if + freq sangle landscape {90 add} if {/y exch def /x exch def /xindex x 1 add 2 div bpside mul cvi def /yindex y 1 add 2 div bpside mul cvi def bstring yindex bwidth mul xindex 8 idiv add get @@ -368,65 +368,65 @@ } bind def /HUE FMLOCAL /SAT FMLOCAL /BRIGHT FMLOCAL /Colors FMLOCAL -FMPrintInColor - +FMPrintInColor + { /HUE 0 def /SAT 0 def /BRIGHT 0 def % array of arrays Hue and Sat values for the separations [HUE BRIGHT] - /Colors + /Colors [[0 0 ] % black [0 0 ] % white [0.00 1.0] % red [0.37 1.0] % green [0.60 1.0] % blue [0.50 1.0] % cyan [0.83 1.0] % magenta [0.16 1.0] % comment / yellow ] def - - /BEGINBITMAPCOLOR { + + /BEGINBITMAPCOLOR { BITMAPCOLOR} def - /BEGINBITMAPCOLORc { + /BEGINBITMAPCOLORc { BITMAPCOLORc} def - /BEGINBITMAPTRUECOLOR { + /BEGINBITMAPTRUECOLOR { BITMAPTRUECOLOR } def - /BEGINBITMAPTRUECOLORc { + /BEGINBITMAPTRUECOLORc { BITMAPTRUECOLORc } def - /K { + /K { Colors exch get dup - 0 get /HUE exch store + 0 get /HUE exch store 1 get /BRIGHT exch store HUE 0 eq BRIGHT 0 eq and {1.0 SAT sub setgray} - {HUE SAT BRIGHT sethsbcolor} + {HUE SAT BRIGHT sethsbcolor} ifelse } def - /FMsetgray { - /SAT exch 1.0 exch sub store + /FMsetgray { + /SAT exch 1.0 exch sub store HUE 0 eq BRIGHT 0 eq and {1.0 SAT sub setgray} - {HUE SAT BRIGHT sethsbcolor} + {HUE SAT BRIGHT sethsbcolor} ifelse } bind def } - + { - /BEGINBITMAPCOLOR { + /BEGINBITMAPCOLOR { BITMAPGRAY} def - /BEGINBITMAPCOLORc { + /BEGINBITMAPCOLORc { BITMAPGRAYc} def - /BEGINBITMAPTRUECOLOR { + /BEGINBITMAPTRUECOLOR { BITMAPTRUEGRAY } def - /BEGINBITMAPTRUECOLORc { + /BEGINBITMAPTRUECOLORc { BITMAPTRUEGRAYc } def /FMsetgray {setgray} bind def - /K { + /K { pop } def } ifelse /normalize { @@ -433,66 +433,66 @@ transform round exch round exch itransform } bind def /dnormalize { dtransform round exch round exch idtransform } bind def -/lnormalize { +/lnormalize { 0 dtransform exch cvi 2 idiv 2 mul 1 add exch idtransform pop } bind def -/H { +/H { lnormalize setlinewidth } bind def /Z { setlinecap } bind def /fillvals FMLOCAL -/X { +/X { fillvals exch get dup type /stringtype eq - {8 1 setpattern} + {8 1 setpattern} {grayness} ifelse } bind def -/V { +/V { gsave eofill grestore } bind def -/N { +/N { stroke } bind def /M {newpath moveto} bind def /E {lineto} bind def /D {curveto} bind def /O {closepath} bind def /n FMLOCAL -/L { +/L { /n exch def newpath normalize - moveto + moveto 2 1 n {pop normalize lineto} for } bind def -/Y { - L +/Y { + L closepath } bind def /x1 FMLOCAL /x2 FMLOCAL /y1 FMLOCAL /y2 FMLOCAL /rad FMLOCAL -/R { +/R { /y2 exch def /x2 exch def /y1 exch def /x1 exch def x1 y1 x2 y1 x2 y2 x1 y2 - 4 Y + 4 Y } bind def -/RR { +/RR { /rad exch def normalize /y2 exch def /x2 exch def normalize @@ -505,91 +505,91 @@ x2 y1 x1 y1 rad arcto x1 y1 x1 y2 rad arcto closepath 16 {pop} repeat } bind def -/C { +/C { grestore gsave - R + R clip } bind def /FMpointsize FMLOCAL -/F { +/F { FMfonts exch get FMpointsize scalefont setfont } bind def -/Q { +/Q { /FMpointsize exch def - F + F } bind def -/T { +/T { moveto show } bind def -/RF { +/RF { rotate 0 ne {-1 1 scale} if } bind def -/TF { +/TF { gsave - moveto + moveto RF show grestore } bind def -/P { +/P { moveto 0 32 3 2 roll widthshow } bind def -/PF { +/PF { gsave - moveto + moveto RF 0 32 3 2 roll widthshow grestore } bind def -/S { +/S { moveto 0 exch ashow } bind def -/SF { +/SF { gsave moveto RF 0 exch ashow grestore } bind def -/B { +/B { moveto 0 32 4 2 roll 0 exch awidthshow } bind def -/BF { +/BF { gsave moveto RF 0 32 4 2 roll 0 exch awidthshow grestore } bind def -/G { +/G { gsave newpath - normalize translate 0.0 0.0 moveto - dnormalize scale - 0.0 0.0 1.0 5 3 roll arc + normalize translate 0.0 0.0 moveto + dnormalize scale + 0.0 0.0 1.0 5 3 roll arc closepath fill grestore } bind def -/A { +/A { gsave savematrix newpath - 2 index 2 div add exch 3 index 2 div sub exch - normalize 2 index 2 div sub exch 3 index 2 div add exch - translate - scale - 0.0 0.0 1.0 5 3 roll arc + 2 index 2 div add exch 3 index 2 div sub exch + normalize 2 index 2 div sub exch 3 index 2 div add exch + translate + scale + 0.0 0.0 1.0 5 3 roll arc restorematrix stroke grestore } bind def /x FMLOCAL @@ -601,41 +601,41 @@ /ww FMLOCAL /hh FMLOCAL /FMsaveobject FMLOCAL /FMoptop FMLOCAL /FMdicttop FMLOCAL -/BEGINPRINTCODE { - /FMdicttop countdictstack 1 add def - /FMoptop count 4 sub def +/BEGINPRINTCODE { + /FMdicttop countdictstack 1 add def + /FMoptop count 4 sub def /FMsaveobject save def - userdict begin - /showpage {} def - FMNORMALIZEGRAPHICS + userdict begin + /showpage {} def + FMNORMALIZEGRAPHICS 3 index neg 3 index neg translate } bind def /ENDPRINTCODE { - count -1 FMoptop {pop pop} for - countdictstack -1 FMdicttop {pop end} for - FMsaveobject restore + count -1 FMoptop {pop pop} for + countdictstack -1 FMdicttop {pop end} for + FMsaveobject restore } bind def -/gn { - 0 - { 46 mul - cf read pop - 32 sub - dup 46 lt {exit} if - 46 sub add +/gn { + 0 + { 46 mul + cf read pop + 32 sub + dup 46 lt {exit} if + 46 sub add } loop - add + add } bind def /str FMLOCAL -/cfs { - /str sl string def - 0 1 sl 1 sub {str exch val put} for - str def +/cfs { + /str sl string def + 0 1 sl 1 sub {str exch val put} for + str def } bind def -/ic [ +/ic [ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0223 0 {0 hx} {1 hx} {2 hx} {3 hx} {4 hx} {5 hx} {6 hx} {7 hx} {8 hx} {9 hx} {10 hx} {11 hx} {12 hx} {13 hx} {14 hx} {15 hx} {16 hx} {17 hx} {18 hx} @@ -653,112 +653,112 @@ /im FMLOCAL /bs FMLOCAL /cs FMLOCAL /len FMLOCAL /pos FMLOCAL -/ms { - /sl exch def - /val 255 def - /ws cfs - /im cfs - /val 0 def - /bs cfs - /cs cfs - } bind def -400 ms -/ip { - is - 0 - cf cs readline pop - { ic exch get exec - add - } forall - pop - - } bind def -/wh { - /len exch def - /pos exch def +/ms { + /sl exch def + /val 255 def + /ws cfs + /im cfs + /val 0 def + /bs cfs + /cs cfs + } bind def +400 ms +/ip { + is + 0 + cf cs readline pop + { ic exch get exec + add + } forall + pop + + } bind def +/wh { + /len exch def + /pos exch def ws 0 len getinterval im pos len getinterval copy pop - pos len + pos len } bind def -/bl { - /len exch def - /pos exch def +/bl { + /len exch def + /pos exch def bs 0 len getinterval im pos len getinterval copy pop - pos len + pos len } bind def /s1 1 string def -/fl { - /len exch def - /pos exch def +/fl { + /len exch def + /pos exch def /val cf s1 readhexstring pop 0 get def pos 1 pos len add 1 sub {im exch val put} for - pos len + pos len } bind def -/hx { - 3 copy getinterval - cf exch readhexstring pop pop +/hx { + 3 copy getinterval + cf exch readhexstring pop pop } bind def /h FMLOCAL /w FMLOCAL /d FMLOCAL /lb FMLOCAL /bitmapsave FMLOCAL /is FMLOCAL /cf FMLOCAL -/wbytes { - dup - 8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse - } bind def -/BEGINBITMAPBWc { - 1 {} COMMONBITMAPc - } bind def -/BEGINBITMAPGRAYc { - 8 {} COMMONBITMAPc - } bind def -/BEGINBITMAP2BITc { - 2 {} COMMONBITMAPc - } bind def -/COMMONBITMAPc { - /r exch def - /d exch def - gsave - translate rotate scale /h exch def /w exch def - /lb w d wbytes def - sl lb lt {lb ms} if - /bitmapsave save def - r - /is im 0 lb getinterval def - ws 0 lb getinterval is copy pop - /cf currentfile def - w h d [w 0 0 h neg 0 h] - {ip} image - bitmapsave restore - grestore - } bind def -/BEGINBITMAPBW { - 1 {} COMMONBITMAP - } bind def -/BEGINBITMAPGRAY { - 8 {} COMMONBITMAP - } bind def -/BEGINBITMAP2BIT { - 2 {} COMMONBITMAP - } bind def -/COMMONBITMAP { - /r exch def - /d exch def - gsave - translate rotate scale /h exch def /w exch def - /bitmapsave save def - r - /is w d wbytes string def - /cf currentfile def - w h d [w 0 0 h neg 0 h] - {cf is readhexstring pop} image - bitmapsave restore +/wbytes { + dup + 8 eq {pop} {1 eq {7 add 8 idiv} {3 add 4 idiv} ifelse} ifelse + } bind def +/BEGINBITMAPBWc { + 1 {} COMMONBITMAPc + } bind def +/BEGINBITMAPGRAYc { + 8 {} COMMONBITMAPc + } bind def +/BEGINBITMAP2BITc { + 2 {} COMMONBITMAPc + } bind def +/COMMONBITMAPc { + /r exch def + /d exch def + gsave + translate rotate scale /h exch def /w exch def + /lb w d wbytes def + sl lb lt {lb ms} if + /bitmapsave save def + r + /is im 0 lb getinterval def + ws 0 lb getinterval is copy pop + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {ip} image + bitmapsave restore + grestore + } bind def +/BEGINBITMAPBW { + 1 {} COMMONBITMAP + } bind def +/BEGINBITMAPGRAY { + 8 {} COMMONBITMAP + } bind def +/BEGINBITMAP2BIT { + 2 {} COMMONBITMAP + } bind def +/COMMONBITMAP { + /r exch def + /d exch def + gsave + translate rotate scale /h exch def /w exch def + /bitmapsave save def + r + /is w d wbytes string def + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {cf is readhexstring pop} image + bitmapsave restore grestore } bind def /proc1 FMLOCAL /proc2 FMLOCAL /newproc FMLOCAL @@ -811,131 +811,131 @@ {} setblackgeneration } bind def /tran FMLOCAL /fakecolorsetup { /tran 256 string def - 0 1 255 {/indx exch def + 0 1 255 {/indx exch def tran indx red indx get 77 mul green indx get 151 mul blue indx get 28 mul add add 256 idiv put} for currenttransfer {255 mul cvi tran exch get 255.0 div} exch Fmcc settransfer } bind def -/BITMAPCOLOR { - /d 8 def - gsave - translate rotate scale /h exch def /w exch def - /bitmapsave save def - colorsetup - /is w d wbytes string def - /cf currentfile def - w h d [w 0 0 h neg 0 h] - {cf is readhexstring pop} {is} {is} true 3 colorimage - bitmapsave restore - grestore - } bind def -/BITMAPCOLORc { - /d 8 def - gsave - translate rotate scale /h exch def /w exch def - /lb w d wbytes def - sl lb lt {lb ms} if - /bitmapsave save def - colorsetup - /is im 0 lb getinterval def - ws 0 lb getinterval is copy pop - /cf currentfile def - w h d [w 0 0 h neg 0 h] - {ip} {is} {is} true 3 colorimage - bitmapsave restore - grestore - } bind def -/BITMAPTRUECOLORc { - gsave - translate rotate scale /h exch def /w exch def - /bitmapsave save def - - /is w string def - - ws 0 w getinterval is copy pop - /cf currentfile def - w h 8 [w 0 0 h neg 0 h] - {ip} {gip} {bip} true 3 colorimage - bitmapsave restore - grestore - } bind def -/BITMAPTRUECOLOR { - gsave - translate rotate scale /h exch def /w exch def - /bitmapsave save def +/BITMAPCOLOR { + /d 8 def + gsave + translate rotate scale /h exch def /w exch def + /bitmapsave save def + colorsetup + /is w d wbytes string def + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {cf is readhexstring pop} {is} {is} true 3 colorimage + bitmapsave restore + grestore + } bind def +/BITMAPCOLORc { + /d 8 def + gsave + translate rotate scale /h exch def /w exch def + /lb w d wbytes def + sl lb lt {lb ms} if + /bitmapsave save def + colorsetup + /is im 0 lb getinterval def + ws 0 lb getinterval is copy pop + /cf currentfile def + w h d [w 0 0 h neg 0 h] + {ip} {is} {is} true 3 colorimage + bitmapsave restore + grestore + } bind def +/BITMAPTRUECOLORc { + gsave + translate rotate scale /h exch def /w exch def + /bitmapsave save def + + /is w string def + + ws 0 w getinterval is copy pop + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] + {ip} {gip} {bip} true 3 colorimage + bitmapsave restore + grestore + } bind def +/BITMAPTRUECOLOR { + gsave + translate rotate scale /h exch def /w exch def + /bitmapsave save def /is w string def /gis w string def /bis w string def - /cf currentfile def - w h 8 [w 0 0 h neg 0 h] - { cf is readhexstring pop } - { cf gis readhexstring pop } - { cf bis readhexstring pop } - true 3 colorimage - bitmapsave restore + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] + { cf is readhexstring pop } + { cf gis readhexstring pop } + { cf bis readhexstring pop } + true 3 colorimage + bitmapsave restore grestore } bind def -/BITMAPTRUEGRAYc { +/BITMAPTRUEGRAYc { gsave translate rotate scale /h exch def /w exch def - /bitmapsave save def - + /bitmapsave save def + /is w string def - - ws 0 w getinterval is copy pop - /cf currentfile def - w h 8 [w 0 0 h neg 0 h] + + ws 0 w getinterval is copy pop + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] {ip gip bip w gray} image - bitmapsave restore + bitmapsave restore grestore } bind def /ww FMLOCAL /r FMLOCAL /g FMLOCAL /b FMLOCAL /i FMLOCAL -/gray { +/gray { /ww exch def /b exch def /g exch def /r exch def 0 1 ww 1 sub { /i exch def r i get .299 mul g i get .587 mul b i get .114 mul add add r i 3 -1 roll floor cvi put } for r } bind def -/BITMAPTRUEGRAY { +/BITMAPTRUEGRAY { gsave translate rotate scale /h exch def /w exch def - /bitmapsave save def + /bitmapsave save def /is w string def /gis w string def /bis w string def - /cf currentfile def - w h 8 [w 0 0 h neg 0 h] - { cf is readhexstring pop - cf gis readhexstring pop + /cf currentfile def + w h 8 [w 0 0 h neg 0 h] + { cf is readhexstring pop + cf gis readhexstring pop cf bis readhexstring pop w gray} image - bitmapsave restore + bitmapsave restore grestore } bind def -/BITMAPGRAY { +/BITMAPGRAY { 8 {fakecolorsetup} COMMONBITMAP } bind def -/BITMAPGRAYc { +/BITMAPGRAYc { 8 {fakecolorsetup} COMMONBITMAPc } bind def /ENDBITMAP { } bind def -end +end /ALDsave FMLOCAL /ALDmatrix matrix def ALDmatrix currentmatrix pop /StartALD { /ALDsave save def savematrix Index: doc/tk_mac.n ================================================================== --- doc/tk_mac.n +++ doc/tk_mac.n @@ -2,11 +2,11 @@ '\" Copyright (c) 2011 Kevin Walzer. '\" Copyright (c) 2011 Donal K. Fellows. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tk::mac n 8.6 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/tkvars.n ================================================================== --- doc/tkvars.n +++ doc/tkvars.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tkvars n 4.1 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/tkwait.n ================================================================== --- doc/tkwait.n +++ doc/tkwait.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1992 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH tkwait n "" Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/toplevel.n ================================================================== --- doc/toplevel.n +++ doc/toplevel.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH toplevel n 8.4 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/ttk_Theme.3 ================================================================== --- doc/ttk_Theme.3 +++ doc/ttk_Theme.3 @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2003 Joe English '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH Ttk_CreateTheme 3 8.5 Tk "Tk Themed Widget" .so man.macros .BS .SH NAME Ttk_CreateTheme, Ttk_GetTheme, Ttk_GetDefaultTheme, Ttk_GetCurrentTheme \- create and use Tk themes. Index: doc/ttk_button.n ================================================================== --- doc/ttk_button.n +++ doc/ttk_button.n @@ -15,11 +15,11 @@ .SH DESCRIPTION A \fBttk::button\fR widget displays a textual label and/or image, and evaluates a command when pressed. .SO ttk_widget \-class \-compound \-cursor -\-image \-state \-style +\-image \-justify \-state \-style \-takefocus \-text \-textvariable \-underline \-width .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-command command Command @@ -37,23 +37,15 @@ .RS .PP Depending on the theme, the default button may be displayed with an extra highlight ring, or with a different border color. .RE -.OP \-width width Width -If greater than zero, specifies how much space, in character widths, -to allocate for the text label. -If less than zero, specifies a minimum width. -If zero or unspecified, the natural width of the text label is used. -Note that some themes may specify a non-zero \fB\-width\fR -in the style. .\" Not documented -- may go away .\" .OP \-padding padding Padding .\" .OP \-foreground foreground Foreground .\" .OP \-font font Font .\" .OP \-anchor anchor Anchor -.\" .OP \-padding padding Padding .\" .OP \-relief relief Relief .SH "WIDGET COMMAND" .PP In addition to the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR @@ -63,19 +55,55 @@ Invokes the command associated with the button. .SH "STANDARD STYLES" .PP \fBTtk::button\fR widgets support the \fBToolbutton\fR style in all standard themes, which is useful for creating widgets for toolbars. -.SH "COMPATIBILITY OPTIONS" -.OP \-state state State -May be set to \fBnormal\fR or \fBdisabled\fR to control the -\fBdisabled\fR state bit. This is a -.QW write-only -option: setting it changes the widget state, but the \fBstate\fR -widget command does not affect the state option. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::button\fP is \fBTButton\fP. +.PP +Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBpressed\fP, \fBreadonly\fP. +.PP +\fBTButton\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-anchor\fP \fIanchor\fP +.br +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-font\fP \fIfont\fP +.br +\fB\-highlightcolor\fP \fIcolor\fP +.br +\fB\-highlightthickness\fP \fIamount\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-padding\fP \fIpadding\fP +.br +\fB\-relief\fP \fIrelief\fP +.br +\fB\-shiftrelief\fP \fIamount\fP +.RS +\fB\-shiftrelief\fP specifies how far the button contents are +shifted down and right in the \fIpressed\fP state. +This action provides additional skeumorphic feedback. +.RE +\fB\-width\fP \fIamount\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), button(n) .SH "KEYWORDS" widget, button, default, command '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_checkbutton.n ================================================================== --- doc/ttk_checkbutton.n +++ doc/ttk_checkbutton.n @@ -66,10 +66,38 @@ selection.) .SH "STANDARD STYLES" .PP \fBTtk::checkbutton\fR widgets support the \fBToolbutton\fR style in all standard themes, which is useful for creating widgets for toolbars. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::checkbutton\fP is \fBTCheckbutton\fP. +.PP +Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP, +\fBpressed\fP, \fBselected\fP, \fBreadonly\fP. +.PP +\fBTCheckbutton\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-indicatorbackground\fP \fIcolor\fP +.br +\fB\-indicatorcolor\fP \fIcolor\fP +.br +\fB\-indicatormargin\fP \fIpadding\fP +.br +\fB\-indicatorrelief\fP \fIrelief\fP +.br +\fB\-padding\fP \fIpadding\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), ttk::radiobutton(n), checkbutton(n) .SH "KEYWORDS" widget, button, toggle, check, option '\" Local Variables: Index: doc/ttk_combobox.n ================================================================== --- doc/ttk_combobox.n +++ doc/ttk_combobox.n @@ -17,11 +17,11 @@ A \fBttk::combobox\fR combines a text field with a pop-down list of values; the user may select the value of the text field from among the values in the list. .SO ttk_widget \-class \-cursor \-takefocus -\-style +\-style \-placeholder .SE .\" ALSO: Other entry widget options .SH "WIDGET-SPECIFIC OPTIONS" .OP \-exportselection exportSelection ExportSelection Boolean value. @@ -108,12 +108,89 @@ .PP The combobox widget generates a \fB<>\fR virtual event when the user selects an element from the list of values. If the selection action unposts the listbox, this event is delivered after the listbox is unposted. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::combobox\fP is \fBTCombobox\fP. +The \fBttk::combobox\fP uses the \fBentry\fP and +\fBlistbox\fP widgets internally. +The listbox frame has a class name of \fBComboboxPopdownFrame\fP. +.PP +Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBpressed\fP, \fBreadonly\fP. +.PP +\fBTCombobox\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-arrowcolor\fP \fIcolor\fP +.br +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-focusfill\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-fieldbackground\fP \fIcolor\fP +.RS +Can only be changed when using non-native and non-graphical themes. +.RE +\fB\-insertwidth\fP \fIamount\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-padding\fP \fIpadding\fP +.br +\fB\-postoffset\fP \fIpadding\fP +.br +\fB\-selectbackground\fP \fIcolor\fP +.RS +Text entry select background. +.RE +\fB\-selectforeground\fP \fIcolor\fP +.RS +Text entry select foreground. +.RE +.PP +The \fBttk::combobox\fP popdown listbox cannot be configured using +\fBttk::style\fP nor via the widget \fBconfigure\fP command. The listbox +can be configured using the option database. +.PP +option add *TCombobox*Listbox.background \fIcolor\fP +.br +option add *TCombobox*Listbox.font \fIfont\fP +.br +option add *TCombobox*Listbox.foreground \fIcolor\fP +.br +option add *TCombobox*Listbox.selectBackground \fIcolor\fP +.br +option add *TCombobox*Listbox.selectForeground \fIcolor\fP +.PP +To configure a specific listbox (subject to future change): +.CS +set popdown [ttk::combobox::PopdownWindow .mycombobox] +$popdown.f.l configure \-font \fIfont\fP +.CE +.PP +\fBComboboxPopdownFrame\fP +styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-borderwidth\fP \fIamount\fP +.br +\fB\-relief\fP \fIrelief\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), ttk::entry(n) .SH KEYWORDS choice, entry, list box, text box, widget '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_entry.n ================================================================== --- doc/ttk_entry.n +++ doc/ttk_entry.n @@ -21,23 +21,23 @@ The value of the string may be linked to a Tcl variable with the \fB\-textvariable\fR option. Entry widgets support horizontal scrolling with the standard \fB\-xscrollcommand\fR option and \fBxview\fR widget command. .SO ttk_widget -\-class \-cursor \-style -\-takefocus \-xscrollcommand +\-class \-cursor +\-font \-foreground +\-style +\-takefocus \-xscrollcommand \-placeholder .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-exportselection exportSelection ExportSelection A boolean value specifying whether or not a selection in the widget should be linked to the X selection. If the selection is exported, then selecting in the widget deselects the current X selection, selecting outside the widget deselects any widget selection, and the widget will respond to selection retrieval requests when it has a selection. -.\" MAYBE: .OP \-font font Font -.\" MAYBE: .OP \-foreground foreground Foreground .\" MAYBE: .OP \-insertbackground insertBackground Foreground .\" MAYBE: .OP \-insertwidth insertWidth InsertWidth .OP \-invalidcommand invalidCommand InvalidCommand A script template to evaluate whenever the \fB\-validatecommand\fR returns 0. See \fBVALIDATION\fR below for more information. @@ -459,12 +459,53 @@ in the \fBdisabled\fR state, and a different background is used in the \fBreadonly\fR state. .PP The entry widget sets the \fBinvalid\fR state if revalidation fails, and clears it whenever validation succeeds. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::entry\fP is \fBTEntry\fP. +.PP +Dynamic states: \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP. +.PP +\fBTEntry\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.RS +When using the aqua theme (Mac OS X), changes the \fB\-fieldbackground\fP. +.RE +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-fieldbackground\fP \fIcolor\fP +.RS +Does not work with the aqua theme (Mac OS X). +.br +Some themes use a graphical background and their field background colors cannot be changed. +.RE +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-insertwidth\fP \fIamount\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-padding\fP \fIpadding\fP +.br +\fB\-relief\fP \fIrelief\fP +.br +\fB\-selectbackground\fP \fIcolor\fP +.br +\fB\-selectborderwidth\fP \fIamount\fP +.br +\fB\-selectforeground\fP \fIcolor\fP +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), entry(n) .SH KEYWORDS entry, widget, text field '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_frame.n ================================================================== --- doc/ttk_frame.n +++ doc/ttk_frame.n @@ -15,23 +15,21 @@ .SH DESCRIPTION .PP A \fBttk::frame\fR widget is a container, used to group other widgets together. .SO ttk_widget -\-class \-cursor \-takefocus -\-style +\-class \-cursor \-padding \-style +\-takefocus .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-borderwidth borderWidth BorderWidth The desired width of the widget border. Defaults to 0. .OP \-relief relief Relief One of the standard Tk border styles: \fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR, or \fBsunken\fR. Defaults to \fBflat\fR. -.OP \-padding padding Padding -Additional padding to include inside the border. .OP \-width width Width If specified, the widget's requested width in pixels. .OP \-height height Height If specified, the widget's requested height in pixels. .SH "WIDGET COMMAND" @@ -45,12 +43,25 @@ are used to manage the children of the \fBframe\fR, by the GM's requested size will normally take precedence over the \fBframe\fR widget's \fB\-width\fR and \fB\-height\fR options. \fBpack propagate\fR and \fBgrid propagate\fR can be used to change this. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::frame\fP is \fBTFrame\fP. +.PP +\fBTFrame\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), ttk::labelframe(n), frame(n) .SH "KEYWORDS" widget, frame, container '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_image.n ================================================================== --- doc/ttk_image.n +++ doc/ttk_image.n @@ -27,19 +27,35 @@ Valid \fIoptions\fR are: .TP \fB\-border\fR \fIpadding\fR \fIpadding\fR is a list of up to four integers, specifying the left, top, right, and bottom borders, respectively. +If fewer than four elements are specified, +\fIbottom\fR defaults to \fItop\fR, +\fIright\fR defaults to \fIleft\fR, and +\fItop\fR defaults to \fIleft\fR. +In other words, a list of three numbers specify the left, vertical, and right border; +a list of two numbers specify the horizontal and the vertical border; +a single number specifies the same border all the way around the element. See \fBIMAGE STRETCHING\fR, below. .TP \fB\-height \fIheight\fR Specifies a minimum height for the element. If less than zero, the base image's height is used as a default. .TP \fB\-padding\fR \fIpadding\fR -Specifies the element's interior padding. Defaults to -\fB\-border\fR if not specified. +Specifies the element's interior padding. +The padding is a list of up to four length specifications +\fIleft top right bottom\fR. +If fewer than four elements are specified, +\fIbottom\fR defaults to \fItop\fR, +\fIright\fR defaults to \fIleft\fR, and +\fItop\fR defaults to \fIleft\fR. +In other words, a list of three numbers specify the left, vertical, and right padding; +a list of two numbers specify the horizontal and the vertical padding; +a single number specifies the same padding all the way around the widget. +Defaults to \fB\-border\fR if not specified. .TP \fB\-sticky\fR \fIspec\fR Specifies how the image is placed within the final parcel. \fIspec\fR contains zero or more characters .QW n , Index: doc/ttk_label.n ================================================================== --- doc/ttk_label.n +++ doc/ttk_label.n @@ -16,63 +16,50 @@ .PP A \fBttk::label\fR widget displays a textual label and/or image. The label may be linked to a Tcl variable to automatically change the displayed text. .SO ttk_widget -\-class \-compound \-cursor -\-image \-style \-takefocus +\-anchor \-class \-compound \-cursor +\-font \-foreground +\-image \-justify \-padding \-state \-style \-takefocus \-text \-textvariable \-underline -\-width +\-width \-wraplength .SE .SH "WIDGET-SPECIFIC OPTIONS" -.OP \-anchor anchor Anchor -Specifies how the information in the widget is positioned -relative to the inner margins. Legal values are -\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR, -\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, and \fBcenter\fR. -See also \fB\-justify\fR. .OP \-background frameColor FrameColor The widget's background color. If unspecified, the theme default is used. -.OP \-font font Font -Font to use for label text. -.OP \-foreground textColor TextColor -The widget's foreground color. -If unspecified, the theme default is used. -.OP \-justify justify Justify -If there are multiple lines of text, specifies how -the lines are laid out relative to one another. -One of \fBleft\fR, \fBcenter\fR, or \fBright\fR. -See also \fB\-anchor\fR. -.OP \-padding padding Padding -Specifies the amount of extra space to allocate for the widget. -The padding is a list of up to four length specifications -\fIleft top right bottom\fR. -If fewer than four elements are specified, -\fIbottom\fR defaults to \fItop\fR, -\fIright\fR defaults to \fIleft\fR, and -\fItop\fR defaults to \fIleft\fR. .OP \-relief relief Relief .\" Rewrite this: Specifies the 3-D effect desired for the widget border. Valid values are \fBflat\fR, \fBgroove\fR, \fBraised\fR, \fBridge\fR, \fBsolid\fR, and \fBsunken\fR. -.OP \-text text Text -Specifies a text string to be displayed inside the widget -(unless overridden by \fB\-textvariable\fR). -.OP \-wraplength wrapLength WrapLength -Specifies the maximum line length (in pixels). -If this option is less than or equal to zero, -then automatic wrapping is not performed; otherwise -the text is split into lines such that no line is longer -than the specified value. .SH "WIDGET COMMAND" .PP Supports the standard widget commands \fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR; see \fIttk::widget(n)\fR. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::label\fP is \fBTLabel\fP. +.PP +Dynamic states: \fBdisabled\fP, \fBreadonly\fP. +.PP +\fBTLabel\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-font\fP \fIfont\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), label(n) '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_labelframe.n ================================================================== --- doc/ttk_labelframe.n +++ doc/ttk_labelframe.n @@ -16,12 +16,12 @@ .PP A \fBttk::labelframe\fR widget is a container used to group other widgets together. It has an optional label, which may be a plain text string or another widget. .SO ttk_widget -\-class \-cursor \-takefocus -\-style +\-class \-cursor \-padding \-style +\-takefocus .SE .SH "WIDGET-SPECIFIC OPTIONS" .\" XXX: Currently included, but may go away: .\" XXX: .OP -borderwidth borderWidth BorderWidth .\" XXX: The desired width of the widget border. Default is theme-dependent. @@ -46,12 +46,10 @@ If set, specifies the integer index (0-based) of a character to underline in the text string. The underlined character is used for mnemonic activation. Mnemonic activation for a \fBttk::labelframe\fR sets the keyboard focus to the first child of the \fBttk::labelframe\fR widget. -.OP \-padding padding Padding -Additional padding to include inside the border. .OP \-labelwidget labelWidget LabelWidget The name of a widget to use for the label. If set, overrides the \fB\-text\fR option. The \fB\-labelwidget\fR must be a child of the \fBlabelframe\fR widget or one of the \fBlabelframe\fR's ancestors, and must belong to the @@ -65,12 +63,52 @@ .SH "WIDGET COMMAND" .PP Supports the standard widget commands \fBconfigure\fR, \fBcget\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR; see \fIttk::widget(n)\fR. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::labelframe\fP is \fBTLabelframe\fP. +The text label +has a class of \fBTLabelframe.Label\fP. +.PP +Dynamic states: \fBdisabled\fP, \fBreadonly\fP. +.PP +\fBTLabelframe\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-borderwidth\fP \fIamount\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-labelmargins\fP \fIamount\fP +.br +\fB\-labeloutside\fP \fIboolean\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-relief\fP \fIrelief\fP +.PP +\fBTLabelframe.Label\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-font\fP \fIfont\fP +.br +\fB\-foreground\fP \fIcolor\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), ttk::frame(n), labelframe(n) .SH "KEYWORDS" widget, frame, container, label, groupbox '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_menubutton.n ================================================================== --- doc/ttk_menubutton.n +++ doc/ttk_menubutton.n @@ -43,10 +43,37 @@ methods. No other widget methods are used. .SH "STANDARD STYLES" .PP \fBTtk::menubutton\fR widgets support the \fBToolbutton\fR style in all standard themes, which is useful for creating widgets for toolbars. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::menubutton\fP is \fBTMenubutton\fP. +.PP +Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBreadonly\fP. +.PP +\fBTMenubutton\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-arrowsize\fP \fIamount\fP +.br +\fB\-background\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-font\fP \fIfont\fP +.br +\fB\-padding\fP \fIpadding\fP +.br +\fB\-relief\fP \fIrelief\fP +.br +\fB\-width\fP \fIamount\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), menu(n), menubutton(n) .SH "KEYWORDS" widget, button, menu '\" Local Variables: Index: doc/ttk_notebook.n ================================================================== --- doc/ttk_notebook.n +++ doc/ttk_notebook.n @@ -39,10 +39,13 @@ \fIleft top right bottom\fR. If fewer than four elements are specified, \fIbottom\fR defaults to \fItop\fR, \fIright\fR defaults to \fIleft\fR, and \fItop\fR defaults to \fIleft\fR. +In other words, a list of three numbers specify the left, vertical, and right padding; +a list of two numbers specify the horizontal and the vertical padding; +a single number specifies the same padding all the way around the widget. .OP \-width width Width If present and greater than zero, specifies the desired width of the pane area (not including internal padding). Otherwise, the maximum width of all panes is used. @@ -169,11 +172,12 @@ returns the value of that \fIoption\fR. Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs. See \fBTAB OPTIONS\fR for the available options. .TP \fIpathname \fBtabs\fR -Returns the list of windows managed by the notebook. +Returns the list of windows managed by the notebook, in the index order of +their associated tabs. .SH "KEYBOARD TRAVERSAL" To enable keyboard traversal for a toplevel window containing a notebook widget \fI$nb\fR, call: .CS ttk::notebook::enableTraversal $nb @@ -202,12 +206,62 @@ \&.nb add [frame .nb.f1] \-text "First tab" \&.nb add [frame .nb.f2] \-text "Second tab" \&.nb select .nb.f2 ttk::notebook::enableTraversal .nb .CE +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::notebook\fP is \fBTNotebook\fP. The tab has +a class name of \fBTNotebook.Tab\fP +.PP +Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBselected\fP. +.PP +\fBTNotebook\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-padding\fP \fIpadding\fP +.br +\fB\-tabmargins\fP \fIpadding\fP +.br +\fB\-tabposition\fP \fIside\fP +.br +.PP +\fBTNotebook.Tab\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-expand\fP \fIpadding\fP +.RS +Defines how much the tab grows in size. Usually used with the +\fBselected\fP dynamic state. \fB\-tabmargins\fP should be +set appropriately so that there is room for the tab growth. +.RE +\fB\-font\fP \fIfont\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-padding\fP \fIpadding\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), grid(n) .SH "KEYWORDS" pane, tab '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_panedwindow.n ================================================================== --- doc/ttk_panedwindow.n +++ doc/ttk_panedwindow.n @@ -89,11 +89,12 @@ option values. If one \fI\-option\fR is specified, returns the value of that \fIoption\fR. Otherwise, sets the \fI\-option\fRs to the corresponding \fIvalue\fRs. .TP \fIpathname \fBpanes\fR -Returns the list of all windows managed by the widget. +Returns the list of all windows managed by the widget, in the index order of +their associated panes. .TP \fIpathname \fBsashpos \fIindex\fR ?\fInewpos\fR? If \fInewpos\fR is specified, sets the position of sash number \fIindex\fR. May adjust the positions of adjacent sashes @@ -103,16 +104,59 @@ .\" Full story: "total size" is either the -height (resp -width), .\" or the actual window height (resp actual window width), .\" depending on which changed most recently. Returns the new position of sash number \fIindex\fR. .\" Full story: new position may be different than the requested position. +.PP +The panedwindow widget also supports the following generic \fBttk::widget\fR +widget subcommands (see \fIttk::widget(n)\fR for details): +.DS +.ta 5.5c 11c +\fBcget\fR \fBconfigure\fR +\fBinstate\fR \fBstate\fR +.DE .SH "VIRTUAL EVENTS" .PP The panedwindow widget generates an \fB<>\fR virtual event on LeaveNotify/NotifyInferior events, because Tk does not execute binding scripts for events when the pointer crosses from a parent to a child. The panedwindow widget needs to know when that happens. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::panedwindow\fP is \fBTPanedwindow\fP. The +sash has a class name of \fBSash\fP. +.PP +\fBTPanedwindow\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.PP +\fBSash\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-gripcount\fP \fIcount\fP +.br +\fB\-handlepad\fP \fIamount\fP +.br +\fB\-handlesize\fP \fIamount\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-sashpad\fP \fIamount\fP +.br +\fB\-sashrelief\fP \fIrelief\fP +.br +\fB\-sashthickness\fP \fIamount\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), ttk::notebook(n), panedwindow(n) '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_progressbar.n ================================================================== --- doc/ttk_progressbar.n +++ doc/ttk_progressbar.n @@ -17,26 +17,41 @@ A \fBttk::progressbar\fR widget shows the status of a long-running operation. They can operate in two modes: \fIdeterminate\fR mode shows the amount completed relative to the total amount of work to be done, and \fIindeterminate\fR mode provides an animated display to let the user know that something is happening. +.PP +If the value of \fB-orient\fR is \fBhorizontal\fR a text string can be +displayed inside the progressbar. This string can be configured using +the \fB-anchor\fR, \fB-font\fR, \fB-foreground\fR, \fB-justify\fR, +\fB-text\fR and \fB-wraplength\fR options. If the value of \fB-orient\fR +is \fBvertical\fR then these options are ignored. .SO ttk_widget -\-class \-cursor \-takefocus -\-style +\-anchor \-class \-cursor +\-font \-foreground \-justify \-style +\-takefocus \-text \-wraplength .SE .SH "WIDGET-SPECIFIC OPTIONS" -.OP \-orient orient Orient -One of \fBhorizontal\fR or \fBvertical\fR. -Specifies the orientation of the progress bar. .OP \-length length Length Specifies the length of the long axis of the progress bar -(width if horizontal, height if vertical). -.OP \-mode mode Mode -One of \fBdeterminate\fR or \fBindeterminate\fR. +(width if horizontal, height if vertical). The value may have any of the forms +acceptable to \fBTk_GetPixels\fR. .OP \-maximum maximum Maximum A floating point number specifying the maximum \fB\-value\fR. Defaults to 100. +.OP \-mode mode Mode +One of \fBdeterminate\fR or \fBindeterminate\fR. +.OP \-orient orient Orient +One of \fBhorizontal\fR or \fBvertical\fR. +Specifies the orientation of the progress bar. +.OP \-phase phase Phase +Read-only option. +The widget periodically increments the value of this option +whenever the \fB\-value\fR is greater than 0 and, +in \fIdeterminate\fR mode, less than \fB\-maximum\fR. +This option may be used by the current theme +to provide additional animation effects. .OP \-value value Value The current value of the progress bar. In \fIdeterminate\fR mode, this represents the amount of work completed. In \fIindeterminate\fR mode, it is interpreted modulo \fB\-maximum\fR; that is, the progress bar completes one @@ -45,17 +60,10 @@ .OP \-variable variable Variable The name of a global Tcl variable which is linked to the \fB\-value\fR. If specified, the \fB\-value\fR of the progress bar is automatically set to the value of the variable whenever the latter is modified. -.OP \-phase phase Phase -Read-only option. -The widget periodically increments the value of this option -whenever the \fB\-value\fR is greater than 0 and, -in \fIdeterminate\fR mode, less than \fB\-maximum\fR. -This option may be used by the current theme -to provide additional animation effects. .SH "WIDGET COMMAND" .PP .TP \fIpathName \fBcget \fIoption\fR Returns the current value of the specified \fIoption\fR; see \fIttk::widget(n)\fR. @@ -84,10 +92,39 @@ \fIamount\fR defaults to 1.0 if omitted. .TP \fIpathName \fBstop\fR Stop autoincrement mode: cancels any recurring timer event initiated by \fIpathName \fBstart\fR. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::progressbar\fP is \fBTProgressbar\fP. +.PP +\fBTProgressbar\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-maxphase\fP +.RS +For the aqua theme. +.RE +\fB\-period\fP +.RS +For the aqua theme. +.RE +\fB\-troughcolor\fP \fIcolor\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n) '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_radiobutton.n ================================================================== --- doc/ttk_radiobutton.n +++ doc/ttk_radiobutton.n @@ -63,10 +63,38 @@ selection.) .SH "STANDARD STYLES" .PP \fBTtk::radiobutton\fR widgets support the \fBToolbutton\fR style in all standard themes, which is useful for creating widgets for toolbars. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::radiobutton\fP is \fBTRadiobutton\fP. +.PP +Dynamic states: \fBactive\fP, \fBalternate\fP, \fBdisabled\fP, +\fBpressed\fP, \fBreadonly\fP, \fBselected\fP. +.PP +\fBTRadiobutton\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-indicatorbackground\fP \fIcolor\fP +.br +\fB\-indicatorcolor\fP \fIcolor\fP +.br +\fB\-indicatormargin\fP \fIpadding\fP +.br +\fB\-indicatorrelief\fP \fIrelief\fP +.br +\fB\-padding\fP \fIpadding\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), ttk::checkbutton(n), radiobutton(n) .SH "KEYWORDS" widget, button, option '\" Local Variables: Index: doc/ttk_scale.n ================================================================== --- doc/ttk_scale.n +++ doc/ttk_scale.n @@ -89,10 +89,39 @@ \fIpathName \fBcoords \fR?\fIvalue\fR? . Get the coordinates corresponding to \fIvalue\fR, or the coordinates corresponding to the current value of the \fB\-value\fR option if \fIvalue\fR is omitted. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::scale\fP is \fBTProgressbar\fP. +.PP +Dynamic states: \fBactive\fP. +.PP +\fBTProgressbar\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-borderwidth\fP \fIamount\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-groovewidth\fP \fIamount\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-sliderwidth\fP \fIamount\fP +.br +\fB\-troughcolor\fP \fIcolor\fP +.br +\fB\-troughrelief\fP \fIrelief\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), scale(n) .SH KEYWORDS scale, slider, trough, widget .\" Local Variables: Index: doc/ttk_scrollbar.n ================================================================== --- doc/ttk_scrollbar.n +++ doc/ttk_scrollbar.n @@ -152,10 +152,37 @@ grid $f.vsb \-row 0 \-column 1 \-sticky nsew grid $f.hsb \-row 1 \-column 0 \-sticky nsew grid columnconfigure $f 0 \-weight 1 grid rowconfigure $f 0 \-weight 1 .CE +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::scrollbar\fP is \fBTScrollbar\fP. +.PP +Dynamic states: \fBactive\fP, \fBdisabled\fP. +.PP +\fBTScrollbar\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-arrowcolor\fP \fIcolor\fP +.br +\fB\-background\fP \fIcolor\fP +.br +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-troughcolor\fP \fIcolor\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), scrollbar(n) .SH KEYWORDS scrollbar, widget '\" Local Variables: Index: doc/ttk_separator.n ================================================================== --- doc/ttk_separator.n +++ doc/ttk_separator.n @@ -15,11 +15,11 @@ .SH DESCRIPTION .PP A \fBttk::separator\fR widget displays a horizontal or vertical separator bar. .SO ttk_widget -\-class \-cursor \-state +\-class \-cursor \-style \-takefocus .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-orient orient Orient One of \fBhorizontal\fR or \fBvertical\fR. @@ -27,12 +27,26 @@ .SH "WIDGET COMMAND" .PP Separator widgets support the standard \fBcget\fR, \fBconfigure\fR, \fBidentify\fR, \fBinstate\fR, and \fBstate\fR methods. No other widget methods are used. +.PP +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::separator\fP is \fBTSeparator\fP. +.PP +\fBTSeparator\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n) .SH "KEYWORDS" widget, separator '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_sizegrip.n ================================================================== --- doc/ttk_sizegrip.n +++ doc/ttk_sizegrip.n @@ -1,11 +1,11 @@ '\" '\" Copyright (c) 2006 Joe English '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH ttk::sizegrip n 8.5 Tk "Tk Themed Widget" .so man.macros .BS .SH NAME ttk::sizegrip \- Bottom-right corner resize widget @@ -16,11 +16,11 @@ .PP A \fBttk::sizegrip\fR widget (also known as a \fIgrow box\fR) allows the user to resize the containing toplevel window by pressing and dragging the grip. .SO ttk_widget -\-class \-cursor \-state +\-class \-cursor \-style \-takefocus .SE .SH "WIDGET COMMAND" .PP Sizegrip widgets support the standard @@ -58,12 +58,25 @@ the sizegrip widget will not resize the window. .PP \fBttk::sizegrip\fR widgets only support .QW southeast resizing. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::sizegrip\fP is \fBTSizegrip\fP. +.PP +\fBTSizegrip\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n) .SH "KEYWORDS" widget, sizegrip, grow box '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_spinbox.n ================================================================== --- doc/ttk_spinbox.n +++ doc/ttk_spinbox.n @@ -19,44 +19,44 @@ to select among a set of values. The widget implements all the features of the \fBttk::entry\fR widget including support of the \fB\-textvariable\fR option to link the value displayed by the widget to a Tcl variable. .SO ttk_widget -\-class \-cursor \-style -\-takefocus \-xscrollcommand +\-class \-cursor \-state \-style +\-takefocus \-xscrollcommand \-placeholder .SE .SO ttk_entry \-validate \-validatecommand .SE .SH "WIDGET-SPECIFIC OPTIONS" +.OP \-command command Command +Specifies a Tcl command to be invoked whenever a spinbutton is invoked. +.OP \-format format Format +Specifies an alternate format to use when setting the string value +when using the \fB\-from\fR and \fB\-to\fR range. +This must be a format specifier of the form \fB%.f\fR, +as it will format a floating-point number. .OP \-from from From A floating\-point value specifying the lowest value for the spinbox. This is used in conjunction with \fB\-to\fR and \fB\-increment\fR to set a numerical range. -.OP \-to to To -A floating\-point value specifying the highest permissible value for the -widget. See also \fB\-from\fR and \fB\-increment\fR. -range. .OP \-increment increment Increment A floating\-point value specifying the change in value to be applied each time one of the widget spin buttons is pressed. The up button applies a positive increment, the down button applies a negative increment. +.OP \-to to To +A floating\-point value specifying the highest permissible value for the +widget. See also \fB\-from\fR and \fB\-increment\fR. +range. .OP \-values values Values This must be a Tcl list of values. If this option is set then this will override any range set using the \fB\-from\fR, \fB\-to\fR and \fB\-increment\fR options. The widget will instead use the values specified beginning with the first value. .OP \-wrap wrap Wrap Must be a proper boolean value. If on, the spinbox will wrap around the values of data in the widget. -.OP \-format format Format -Specifies an alternate format to use when setting the string value -when using the \fB\-from\fR and \fB\-to\fR range. -This must be a format specifier of the form \fB%.f\fR, -as it will format a floating-point number. -.OP \-command command Command -Specifies a Tcl command to be invoked whenever a spinbutton is invoked. .SH "INDICES" .PP See the \fBttk::entry\fR manual for information about indexing characters. .SH "VALIDATION" .PP @@ -65,12 +65,10 @@ .SH "WIDGET COMMAND" .PP The following subcommands are possible for spinbox widgets in addition to the commands described for the \fBttk::entry\fR widget: .TP -\fIpathName \fBcurrent \fIindex\fR -.TP \fIpathName \fBget\fR Returns the spinbox's current value. .TP \fIpathName \fBset \fIvalue\fR Set the spinbox string to \fIvalue\fR. If a \fB\-format\fR option has @@ -80,12 +78,51 @@ .SH "VIRTUAL EVENTS" .PP The spinbox widget generates a \fB<>\fR virtual event when the user presses , and a \fB<>\fR virtual event when the user presses . +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::spinbox\fP is \fBTSpinbox\fP. +.PP +Dynamic states: \fBactive\fP, \fBdisabled\fP, \fBfocus\fP, \fBreadonly\fP. +.PP +\fBTSpinbox\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-arrowcolor\fP \fIcolor\fP +.br +\fB\-arrowsize\fP \fIamount\fP +.br +\fB\-background\fP \fIcolor\fP +.RS +When using the aqua theme (Mac OS X), changes the \fB\-fieldbackground\fP. +.RE +\fB\-bordercolor\fP \fIcolor\fP +.br +\fB\-darkcolor\fP \fIcolor\fP +.br +\fB\-fieldbackground\fP \fIcolor\fP +.RS +Does not work with the aqua theme (Mac OS X). +.RE +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-lightcolor\fP \fIcolor\fP +.br +\fB\-padding\fP \fIpadding\fP +.br +\fB\-selectbackground\fP \fIcolor\fP +.br +\fB\-selectforeground\fP \fIcolor\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), ttk::entry(n), spinbox(n) .SH KEYWORDS entry, spinbox, widget, text field '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_treeview.n ================================================================== --- doc/ttk_treeview.n +++ doc/ttk_treeview.n @@ -43,10 +43,11 @@ standard \fB\-\fR[\fBxy\fR]\fBscrollcommand\fR options and [\fBxy\fR]\fBview\fR widget commands. .SO ttk_widget \-class \-cursor \-takefocus \-style \-xscrollcommand \-yscrollcommand +\-padding .SE .SH "WIDGET-SPECIFIC OPTIONS" .OP \-columns columns Columns A list of column identifiers, specifying the number of columns and their names. @@ -61,14 +62,10 @@ all columns are shown in the order given. .OP \-height height Height Specifies the number of rows which should be visible. Note: the requested width is determined from the sum of the column widths. -.OP \-padding padding Padding -Specifies the internal padding for the widget. -The padding is a list of up to four length specifications; -see \fBTtk_GetPaddingFromObj()\fR for details. .OP \-selectmode selectMode SelectMode Controls how the built-in class bindings manage the selection. One of \fBextended\fR, \fBbrowse\fR, or \fBnone\fR. .RS .PP @@ -475,10 +472,76 @@ The \fBfocus\fR and \fBselection\fR widget commands can be used to determine the affected item or items. '\" Not yet: '\" In Tk 8.5, the affected item is also passed as the \fB\-detail\fR field '\" of the virtual event. +.SH "STYLING OPTIONS" +.PP +The class name for a \fBttk::treeview\fP is \fBTreeview\fP. +The treeview header class name is \fBHeading\fP. +The treeview item class name is \fBItem\fP. +The treeview cell class name is \fBCell\fP. +.PP +Dynamic states: \fBdisabled\fP, \fBselected\fP. +.PP +\fBTreeview\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-fieldbackground\fP \fIcolor\fP +.br +\fB\-font\fP \fIfont\fP +.br +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-rowheight\fP \fIamount\fP +.RS +The \fB\-rowheight\fP value is not corrected by the \fBtk scaling\fP +value or by the configured font size and must always be set. Also make +sure that the \fB\-rowheight\fP is large enough to contain any images. +.PP +To adjust the \fB\-rowheight\fP for the Treeview style, use the following code +after \fBtk scaling\fP has been applied. +Note that even if you do not support or change \fBtk scaling\fP +in your program, your users may have it set in their .wishrc. +.RE +.PP +.CS +ttk::style configure Treeview \\ + \-rowheight [expr {[font metrics \fIfont\fP \-linespace] + 2}] +.CE +.PP +\fBHeading\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-background\fP \fIcolor\fP +.br +\fB\-font\fP \fIfont\fP +.br +\fB\-relief\fP \fIrelief\fP +.PP +\fBItem\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-foreground\fP \fIcolor\fP +.br +\fB\-indicatormargins\fP \fIpadding\fP +.br +\fB\-indicatorsize\fP \fIamount\fP +.br +\fB\-padding\fP \fIpadding\fP +.PP +\fBCell\fP styling options configurable with \fBttk::style\fP +are: +.PP +\fB\-padding\fP \fIpadding\fP +.PP +Some options are only available for specific themes. +.PP +See the \fBttk::style\fP manual page for information on how to configure +ttk styles. .SH "SEE ALSO" ttk::widget(n), listbox(n), image(n), bind(n) '\" Local Variables: '\" mode: nroff '\" End: Index: doc/ttk_vsapi.n ================================================================== --- doc/ttk_vsapi.n +++ doc/ttk_vsapi.n @@ -32,10 +32,17 @@ \fB\-padding \fIpadding\fR . Specify the element's interior padding. \fIpadding\fR is a list of up to four integers specifying the left, top, right and bottom padding quantities respectively. +If fewer than four elements are specified, +\fIbottom\fR defaults to \fItop\fR, +\fIright\fR defaults to \fIleft\fR, and +\fItop\fR defaults to \fIleft\fR. +In other words, a list of three numbers specify the left, vertical, and right padding; +a list of two numbers specify the horizontal and the vertical padding; +a single number specifies the same padding all the way around the widget. This option may not be mixed with any other options. .TP \fB\-margins \fIpadding\fR . Specifies the elements exterior padding. @@ -59,11 +66,11 @@ The \fIstateMap\fR parameter is a list of ttk states and the corresponding Visual Styles API state value. This permits the element appearance to respond to changes in the widget state such as becoming active or being pressed. The list should be as described for the \fBttk::style map\fR command but note that the -last pair in the list should be the default state and is typically and +last pair in the list should be the default state and is typically an empty list and 1. Unfortunately all the Visual Styles parts have different state values and these must be looked up either in the Microsoft documentation or more likely in the header files. The original header to use was \fItmschema.h\fR, but in more recent versions of the Windows Development Kit this is \fIvssym32.h\fR. Index: doc/ttk_widget.n ================================================================== --- doc/ttk_widget.n +++ doc/ttk_widget.n @@ -69,28 +69,16 @@ A command prefix, used to communicate with vertical scrollbars. See the description of \fB\-xscrollcommand\fR above for details. .SH "LABEL OPTIONS" The following options are supported by labels, buttons, and other button-like widgets: -.OP \-text text Text -Specifies a text string to be displayed inside the widget -(unless overridden by \fB\-textvariable\fR). -.OP \-textvariable textVariable Variable -Specifies the name of a global variable whose value will be used -in place of the \fB\-text\fR resource. -.OP \-underline underline Underline -If set, specifies the integer index (0-based) of a character to underline -in the text string. -The underlined character is used for mnemonic activation. -.OP \-image image Image -Specifies an image to display. -This is a list of 1 or more elements. -The first element is the default image name. -The rest of the list is a sequence of \fIstatespec / value\fR pairs -as per \fBstyle map\fR, specifying different images to use when -the widget is in a particular state or combination of states. -All images in the list should have the same size. +.OP \-anchor anchor Anchor +Specifies how the information in the widget is positioned +relative to the inner margins. Legal values are +\fBn\fR, \fBne\fR, \fBe\fR, \fBse\fR, +\fBs\fR, \fBsw\fR, \fBw\fR, \fBnw\fR, and \fBcenter\fR. +See also \fB\-justify\fR (for widgets supporting this option). .OP \-compound compound Compound Specifies how to display the image relative to the text, in the case both \fB\-text\fR and \fB\-image\fR are present. Valid values are: .RS @@ -106,16 +94,74 @@ .IP right Display image above, below, left of, or right of the text, respectively. .IP none The default; display the image if present, otherwise the text. .RE +.OP \-font font Font +Font to use for the text displayed by the widget. +.OP \-foreground textColor TextColor +The widget's foreground color. +If unspecified, the theme default is used. +.OP \-image image Image +Specifies an image to display. +This is a list of 1 or more elements. +The first element is the default image name. +The rest of the list is a sequence of \fIstatespec / value\fR pairs +as per \fBstyle map\fR, specifying different images to use when +the widget is in a particular state or combination of states. +All images in the list should have the same size. +.OP \-justify justify Justify +If there are multiple lines of text, specifies how +the lines are laid out relative to one another. +One of \fBleft\fR, \fBcenter\fR, or \fBright\fR. +See also \fB\-anchor\fR (for widgets supporting this option). +.OP \-padding padding Padding +Specifies the internal padding for the widget. +The padding is a list of up to four length specifications +\fIleft top right bottom\fR. +If fewer than four elements are specified, +\fIbottom\fR defaults to \fItop\fR, +\fIright\fR defaults to \fIleft\fR, and +\fItop\fR defaults to \fIleft\fR. +In other words, a list of three numbers specify the left, vertical, and right padding; +a list of two numbers specify the horizontal and the vertical padding; +a single number specifies the same padding all the way around the widget. +.OP \-text text Text +Specifies a text string to be displayed inside the widget +(unless overridden by \fB\-textvariable\fR for the widgets supporting this option). +.OP \-textvariable textVariable Variable +Specifies the name of a global variable whose value will be used +in place of the \fB\-text\fR resource. +.OP \-underline underline Underline +If set, specifies the integer index (0-based) of a character to underline +in the text string. +The underlined character is used for mnemonic activation. .OP \-width width Width If greater than zero, specifies how much space, in character widths, to allocate for the text label. If less than zero, specifies a minimum width. If zero or unspecified, the natural width of the text label is used. +Note that some themes may specify a non-zero \fB\-width\fR +in the style. +.OP \-wraplength wrapLength WrapLength +Specifies the maximum line length. The value may have any of the forms +acceptable to \fBTk_GetPixels\fR. If this option is less than or equal +to zero, then automatic wrapping is not performed; otherwise +the text is split into lines such that no line is longer +than the specified value. +.SH "ENTRY OPTIONS" +The following option is supported by entry, spinbox and combobox: +.OP \-placeholder placeHolder PlaceHolder +Specifies a help text string to display if no text is otherwise displayed, +that is when the widget is empty. The placeholder text is displayed using +the values of the \fB\-font\fR and \fB\-justify\fR options. The foreground +color of the placeholder text can be changed using the +\fB\-placeholderforeground\fR style option. .SH "COMPATIBILITY OPTIONS" +This option is only available for themed widgets that have +.QW corresponding +traditional Tk widgets. .OP \-state state State May be set to \fBnormal\fR or \fBdisabled\fR to control the \fBdisabled\fR state bit. This is a write-only option: setting it changes the widget state, Index: doc/winfo.n ================================================================== --- doc/winfo.n +++ doc/winfo.n @@ -2,11 +2,11 @@ '\" Copyright (c) 1990-1994 The Regents of the University of California. '\" Copyright (c) 1994-1997 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH winfo n 4.3 Tk "Tk Built-In Commands" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME Index: doc/wish.1 ================================================================== --- doc/wish.1 +++ doc/wish.1 @@ -2,11 +2,11 @@ '\" Copyright (c) 1991-1994 The Regents of the University of California. '\" Copyright (c) 1994-1996 Sun Microsystems, Inc. '\" '\" See the file "license.terms" for information on usage and redistribution '\" of this file, and for a DISCLAIMER OF ALL WARRANTIES. -'\" +'\" .TH wish 1 8.0 Tk "Tk Applications" .so man.macros .BS '\" Note: do not modify the .SH NAME line immediately below! .SH NAME @@ -75,11 +75,11 @@ If there exists a file .QW \fB.wishrc\fR in the home directory of the user, \fBwish\fR evaluates the file as a Tcl script just before reading the first command from standard input. .PP -If arguments to \fBwish\fR do specify a \fIfileName\fR, then +If arguments to \fBwish\fR do specify a \fIfileName\fR, then \fIfileName\fR is treated as the name of a script file. \fBWish\fR will evaluate the script in \fIfileName\fR (which presumably creates a user interface), then it will respond to events until all windows have been deleted. Commands will not be read from standard input. Index: doc/wm.n ================================================================== --- doc/wm.n +++ doc/wm.n @@ -486,11 +486,17 @@ On X, the images are arranged into the _NET_WM_ICON X property, which most modern window managers support. A \fBwm iconbitmap\fR may exist simultaneously. It is recommended to use not more than 2 icons, placing the larger icon first. .PP -On Macintosh, this currently does nothing. +On Macintosh, the first image called is loaded into an OSX-native icon +format, and becomes the application icon in dialogs, the Dock, and +other contexts. At the +script level the command will accept only the first image passed in the +parameters as support for multiple sizes/resolutions on macOS is outside Tk's +scope. Developers should use the largest icon they can support +(preferably 512 pixels) to ensure smooth rendering on the Mac. .RE .TP \fBwm iconposition \fIwindow\fR ?\fIx y\fR? . If \fIx\fR and \fIy\fR are specified, they are passed to the window Index: generic/ks_names.h ================================================================== --- generic/ks_names.h +++ generic/ks_names.h @@ -1,7 +1,17 @@ /* - * This file is generated from $(INCLUDESRC)/keysymdef.h. Do not edit. + * This file should be maintained in sync with xlib/X11/keysymdefs.h + * + * Note that this should be done manually only, because in some cases + * keysymdefs.h defines the same integer for multiple keysyms, e.g.: + * + * #define XK_Greek_LAMDA 0x7cb + * #define XK_Greek_LAMBDA 0x7cb + * + * #define XK_Cyrillic_DZHE 0x6bf + * #define XK_Serbian_DZE 0x6bf (deprecated) + * */ { "BackSpace", 0xFF08 }, { "Tab", 0xFF09 }, { "Linefeed", 0xFF0A }, { "Clear", 0xFF0B }, @@ -918,5 +928,12 @@ { "hebrew_kuf", 0xcf7 }, { "hebrew_resh", 0xcf8 }, { "hebrew_shin", 0xcf9 }, { "hebrew_taf", 0xcfa }, { "Hebrew_switch", 0xFF7E }, +{ "XF86AudioLowerVolume", 0x1008FF11 }, +{ "XF86AudioMute", 0x1008FF12 }, +{ "XF86AudioRaiseVolume", 0x1008FF13 }, +{ "XF86AudioPlay", 0x1008FF14 }, +{ "XF86AudioStop", 0x1008FF15 }, +{ "XF86AudioPrev", 0x1008FF16 }, +{ "XF86AudioNext", 0x1008FF17 }, Index: generic/tk.decls ================================================================== --- generic/tk.decls +++ generic/tk.decls @@ -103,11 +103,11 @@ declare 18 { int Tk_CanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 19 { - CONST86 char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin, + const char *Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 20 { Tk_Window Tk_CanvasTkwin(Tk_Canvas canvas) } @@ -144,11 +144,11 @@ char *widgRec, const char *argvName, int flags) } declare 29 { int Tk_ConfigureWidget(Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, - int argc, CONST84 char **argv, char *widgRec, + int argc, const char **argv, char *widgRec, int flags) } declare 30 { void Tk_ConfigureWindow(Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr) @@ -243,11 +243,11 @@ } declare 54 { void Tk_DestroyWindow(Tk_Window tkwin) } declare 55 { - CONST84_RETURN char *Tk_DisplayName(Tk_Window tkwin) + const char *Tk_DisplayName(Tk_Window tkwin) } declare 56 { int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y) } declare 57 { @@ -324,11 +324,11 @@ void Tk_FreePixmap(Display *display, Pixmap pixmap) } declare 76 { void Tk_FreeTextLayout(Tk_TextLayout textLayout) } -declare 77 { +declare 77 {deprecated {function does nothing, call can be removed}} { void Tk_FreeXId(Display *display, XID xid) } declare 78 { GC Tk_GCForColor(XColor *colorPtr, Drawable drawable) } @@ -346,14 +346,14 @@ declare 82 { int Tk_GetAnchor(Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr) } declare 83 { - CONST84_RETURN char *Tk_GetAtomName(Tk_Window tkwin, Atom atom) + const char *Tk_GetAtomName(Tk_Window tkwin, Atom atom) } declare 84 { - CONST84_RETURN char *Tk_GetBinding(Tcl_Interp *interp, + const char *Tk_GetBinding(Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr) } declare 85 { Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *str) @@ -402,11 +402,11 @@ Tk_Image Tk_GetImage(Tcl_Interp *interp, Tk_Window tkwin, const char *name, Tk_ImageChangedProc *changeProc, ClientData clientData) } declare 98 { ClientData Tk_GetImageMasterData(Tcl_Interp *interp, - const char *name, CONST86 Tk_ImageType **typePtrPtr) + const char *name, const Tk_ImageType **typePtrPtr) } declare 99 { Tk_ItemType *Tk_GetItemTypes(void) } declare 100 { @@ -437,11 +437,11 @@ declare 107 { void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr) } declare 108 { int Tk_GetScrollInfo(Tcl_Interp *interp, - int argc, CONST84 char **argv, double *dblPtr, int *intPtr) + int argc, const char **argv, double *dblPtr, int *intPtr) } declare 109 { int Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr) } @@ -516,41 +516,41 @@ } declare 129 { void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y) } declare 130 { - CONST84_RETURN char *Tk_NameOf3DBorder(Tk_3DBorder border) + const char *Tk_NameOf3DBorder(Tk_3DBorder border) } declare 131 { - CONST84_RETURN char *Tk_NameOfAnchor(Tk_Anchor anchor) + const char *Tk_NameOfAnchor(Tk_Anchor anchor) } declare 132 { - CONST84_RETURN char *Tk_NameOfBitmap(Display *display, Pixmap bitmap) + const char *Tk_NameOfBitmap(Display *display, Pixmap bitmap) } declare 133 { - CONST84_RETURN char *Tk_NameOfCapStyle(int cap) + const char *Tk_NameOfCapStyle(int cap) } declare 134 { - CONST84_RETURN char *Tk_NameOfColor(XColor *colorPtr) + const char *Tk_NameOfColor(XColor *colorPtr) } declare 135 { - CONST84_RETURN char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor) + const char *Tk_NameOfCursor(Display *display, Tk_Cursor cursor) } declare 136 { - CONST84_RETURN char *Tk_NameOfFont(Tk_Font font) + const char *Tk_NameOfFont(Tk_Font font) } declare 137 { - CONST84_RETURN char *Tk_NameOfImage(Tk_ImageMaster imageMaster) + const char *Tk_NameOfImage(Tk_ImageMaster imageMaster) } declare 138 { - CONST84_RETURN char *Tk_NameOfJoinStyle(int join) + const char *Tk_NameOfJoinStyle(int join) } declare 139 { - CONST84_RETURN char *Tk_NameOfJustify(Tk_Justify justify) + const char *Tk_NameOfJustify(Tk_Justify justify) } declare 140 { - CONST84_RETURN char *Tk_NameOfRelief(int relief) + const char *Tk_NameOfRelief(int relief) } declare 141 { Tk_Window Tk_NameToWindow(Tcl_Interp *interp, const char *pathName, Tk_Window tkwin) } @@ -559,19 +559,19 @@ Atom selection, Tk_LostSelProc *proc, ClientData clientData) } declare 143 { int Tk_ParseArgv(Tcl_Interp *interp, - Tk_Window tkwin, int *argcPtr, CONST84 char **argv, + Tk_Window tkwin, int *argcPtr, const char **argv, const Tk_ArgvInfo *argTable, int flags) } -declare 144 { +declare 144 {deprecated {function signature changed}} { void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height) } -declare 145 { +declare 145 {deprecated {function signature changed}} { void Tk_PhotoPutZoomedBlock_NoComposite(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY) } @@ -579,17 +579,17 @@ int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr) } declare 147 { void Tk_PhotoBlank(Tk_PhotoHandle handle) } -declare 148 { +declare 148 {deprecated {function signature changed}} { void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height ) } declare 149 { void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr) } -declare 150 { +declare 150 {deprecated {function signature changed}} { void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height) } declare 151 { int Tk_PointToChar(Tk_TextLayout layout, int x, int y) } @@ -742,11 +742,11 @@ } declare 194 { void Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr) } declare 195 { - void Tk_FreeConfigOptions(char *recordPtr, Tk_OptionTable optionToken, + void Tk_FreeConfigOptions(void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin) } declare 196 { void Tk_FreeSavedOptions(Tk_SavedOptions *savePtr) } @@ -772,15 +772,15 @@ declare 203 { Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr) } declare 204 { Tcl_Obj *Tk_GetOptionInfo(Tcl_Interp *interp, - char *recordPtr, Tk_OptionTable optionTable, + void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin) } declare 205 { - Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, char *recordPtr, + Tcl_Obj *Tk_GetOptionValue(Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin) } declare 206 { int Tk_GetJustifyFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr) @@ -800,11 +800,11 @@ declare 210 { int Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr) } declare 211 { - int Tk_InitOptions(Tcl_Interp *interp, char *recordPtr, + int Tk_InitOptions(Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin) } declare 212 { void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp) @@ -811,11 +811,11 @@ } declare 213 { void Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr) } declare 214 { - int Tk_SetOptions(Tcl_Interp *interp, char *recordPtr, + int Tk_SetOptions(Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr) } declare 215 { @@ -941,16 +941,16 @@ # New in 8.4a5 # declare 245 { void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height) } -declare 246 { +declare 246 {deprecated {function signature changed}} { void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule) } -declare 247 { +declare 247 {deprecated {function signature changed}} { void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule) } @@ -999,26 +999,26 @@ Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId, Tk_OptionTable optionTable) } declare 261 { void Tk_GetElementSize(Tk_Style style, Tk_StyledElement element, - char *recordPtr, Tk_Window tkwin, int width, int height, + void *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr) } declare 262 { void Tk_GetElementBox(Tk_Style style, Tk_StyledElement element, - char *recordPtr, Tk_Window tkwin, int x, int y, int width, + void *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr) } declare 263 { int Tk_GetElementBorderWidth(Tk_Style style, Tk_StyledElement element, - char *recordPtr, Tk_Window tkwin) + void *recordPtr, Tk_Window tkwin) } declare 264 { void Tk_DrawElement(Tk_Style style, Tk_StyledElement element, - char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, + void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state) } # TIP#116 declare 265 { @@ -1146,9 +1146,17 @@ export { const char *Tk_PkgInitStubsCheck(Tcl_Interp *interp, const char *version, int exact) } +export { + void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc, + Tcl_Interp *interp) +} +export { + void Tk_MainExW(int argc, wchar_t **argv, + Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); +} # Local Variables: # mode: tcl # End: Index: generic/tk.h ================================================================== --- generic/tk.h +++ generic/tk.h @@ -15,21 +15,14 @@ #ifndef _TK #define _TK #include -#if (TCL_MAJOR_VERSION != 8) || (TCL_MINOR_VERSION < 6) -# error Tk 8.6 must be compiled with tcl.h from Tcl 8.6 or better +#if (TCL_MAJOR_VERSION < 8) || (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION < 6) +# error Tk 8.7 must be compiled with tcl.h from Tcl 8.6 or better #endif -#ifndef CONST84 -# define CONST84 const -# define CONST84_RETURN const -#endif -#ifndef CONST86 -# define CONST86 CONST84 -#endif #ifndef EXTERN # define EXTERN extern TCL_STORAGE_CLASS #endif /* @@ -57,12 +50,12 @@ /* * When version numbers change here, you must also go into the following files * and update the version numbers: * * library/tk.tcl (1 LOC patch) - * unix/configure.in (2 LOC Major, 2 LOC minor, 1 LOC patch) - * win/configure.in (as above) + * unix/configure.ac (2 LOC Major, 2 LOC minor, 1 LOC patch) + * win/configure.ac (as above) * README (sections 0 and 1) * macosx/Tk-Common.xcconfig (not patchlevel) 1 LOC * win/README (not patchlevel) * unix/README (not patchlevel) * unix/tk.spec (1 LOC patch) @@ -71,16 +64,16 @@ * You may also need to update some of these files when the numbers change for * the version of Tcl that this release of Tk is compiled against. */ #define TK_MAJOR_VERSION 8 -#define TK_MINOR_VERSION 6 -#define TK_RELEASE_LEVEL TCL_FINAL_RELEASE -#define TK_RELEASE_SERIAL 6 +#define TK_MINOR_VERSION 7 +#define TK_RELEASE_LEVEL TCL_ALPHA_RELEASE +#define TK_RELEASE_SERIAL 2 -#define TK_VERSION "8.6" -#define TK_PATCH_LEVEL "8.6.6" +#define TK_VERSION "8.7" +#define TK_PATCH_LEVEL "8.7a2" /* * A special definition used to allow this header file to be included from * windows or mac resource files so that they can obtain version information. * RC_INVOKED is defined by default by the windows RC tool and manually set @@ -103,10 +96,14 @@ #endif #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT +#else +# ifndef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLIMPORT +# endif #endif /* *---------------------------------------------------------------------- * @@ -188,24 +185,29 @@ const char *dbName; /* Name for option in option database. */ const char *dbClass; /* Class for option in database. */ const char *defValue; /* Default value for option if not specified * in command line, the option database, or * the system. */ - int objOffset; /* Where in record to store a Tcl_Obj * that +#if TCL_MAJOR_VERSION > 8 + size_t objOffset; /* Where in record to store a Tcl_Obj * that * holds the value of this option, specified * as an offset in bytes from the start of the * record. Use the Tk_Offset macro to generate * values for this. -1 means don't store the * Tcl_Obj in the record. */ - int internalOffset; /* Where in record to store the internal + size_t internalOffset; /* Where in record to store the internal * representation of the value of this option, * such as an int or XColor *. This field is * specified as an offset in bytes from the * start of the record. Use the Tk_Offset * macro to generate values for it. -1 means * don't store the internal representation in * the record. */ +#else + int objOffset; + int internalOffset; +#endif int flags; /* Any combination of the values defined * below. */ const void *clientData; /* An alternate place to put option-specific * data. Used for the monochrome default value * for colors, etc. */ @@ -288,11 +290,11 @@ * a Tcl object; may be NULL if the value was * not saved as an object. */ double internalForm; /* The old value of the option, in some * internal representation such as an int or * (XColor *). Valid only if the field - * optionPtr->specPtr->objOffset is < 0. The + * optionPtr->specPtr->objOffset is -1. The * space must be large enough to accommodate a * double, a long, or a pointer; right now it * looks like a double (i.e., 8 bytes) is big * enough. Also, using a double guarantees * that the field is properly aligned for @@ -304,15 +306,19 @@ #else # define TK_NUM_SAVED_OPTIONS 20 #endif typedef struct Tk_SavedOptions { - char *recordPtr; /* The data structure in which to restore + void *recordPtr; /* The data structure in which to restore * configuration options. */ Tk_Window tkwin; /* Window associated with recordPtr; needed to * restore certain options. */ - int numItems; /* The number of valid items in items field. */ +#if TCL_MAJOR_VERSION > 8 + size_t numItems; /* The number of valid items in items field. */ +#else + int numItems; +#endif Tk_SavedOption items[TK_NUM_SAVED_OPTIONS]; /* Items used to hold old values. */ struct Tk_SavedOptions *nextPtr; /* Points to next structure in list; needed if * too many options changed to hold all the @@ -333,12 +339,12 @@ */ #ifndef __NO_OLD_CONFIG typedef int (Tk_OptionParseProc) (ClientData clientData, Tcl_Interp *interp, - Tk_Window tkwin, CONST84 char *value, char *widgRec, int offset); -typedef CONST86 char *(Tk_OptionPrintProc) (ClientData clientData, + Tk_Window tkwin, const char *value, char *widgRec, int offset); +typedef const char *(Tk_OptionPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); typedef struct Tk_CustomOption { Tk_OptionParseProc *parseProc; /* Procedure to call to parse an option and @@ -360,23 +366,27 @@ typedef struct Tk_ConfigSpec { int type; /* Type of option, such as TK_CONFIG_COLOR; * see definitions below. Last option in table * must have type TK_CONFIG_END. */ - CONST86 char *argvName; /* Switch used to specify option in argv. NULL + const char *argvName; /* Switch used to specify option in argv. NULL * means this spec is part of a group. */ Tk_Uid dbName; /* Name for option in option database. */ Tk_Uid dbClass; /* Class for option in database. */ Tk_Uid defValue; /* Default value for option if not specified * in command line or database. */ - int offset; /* Where in widget record to store value; use +#if TCL_MAJOR_VERSION > 8 + size_t offset; /* Where in widget record to store value; use * Tk_Offset macro to generate values for * this. */ +#else + int offset; +#endif int specFlags; /* Any combination of the values defined * below; other bits are used internally by * tkConfig.c. */ - CONST86 Tk_CustomOption *customPtr; + const Tk_CustomOption *customPtr; /* If type is TK_CONFIG_CUSTOM then this is a * pointer to info about how to parse and * print the option. Otherwise it is * irrelevant. */ } Tk_ConfigSpec; @@ -412,27 +422,29 @@ #define TK_CONFIG_NULL_OK (1 << 0) #define TK_CONFIG_COLOR_ONLY (1 << 1) #define TK_CONFIG_MONO_ONLY (1 << 2) #define TK_CONFIG_DONT_SET_DEFAULT (1 << 3) -#define TK_CONFIG_OPTION_SPECIFIED (1 << 4) +#ifndef TK_NO_DEPRECATED +# define TK_CONFIG_OPTION_SPECIFIED (1 << 4) +#endif /* !TK_NO_DEPRECATED */ #define TK_CONFIG_USER_BIT 0x100 #endif /* __NO_OLD_CONFIG */ /* * Structure used to specify how to handle argv options. */ typedef struct { - CONST86 char *key; /* The key string that flags the option in the + const char *key; /* The key string that flags the option in the * argv array. */ int type; /* Indicates option type; see below. */ char *src; /* Value to be used in setting dst; usage * depends on type. */ char *dst; /* Address of value to be modified; usage * depends on type. */ - CONST86 char *help; /* Documentation message describing this + const char *help; /* Documentation message describing this * option. */ } Tk_ArgvInfo; /* * Legal values for the type field of a Tk_ArgvInfo: see the user @@ -674,11 +686,11 @@ unsigned long serial; /* # of last request processed by server. */ Bool send_event; /* True if this came from a SendEvent * request. */ Display *display; /* Display the event was read from. */ Window event; /* Window on which event was requested. */ - Window root; /* Root window that the event occured on. */ + Window root; /* Root window that the event occurred on. */ Window subwindow; /* Child window. */ Time time; /* Milliseconds. */ int x, y; /* Pointer x, y coordinates in event * window. */ int x_root, y_root; /* Coordinates relative to root. */ @@ -744,13 +756,14 @@ (((Tk_FakeWin *) (tkwin))->flags & TK_TOP_HIERARCHY) #define Tk_IsManageable(tkwin) \ (((Tk_FakeWin *) (tkwin))->flags & TK_WM_MANAGEABLE) #define Tk_ReqWidth(tkwin) (((Tk_FakeWin *) (tkwin))->reqWidth) #define Tk_ReqHeight(tkwin) (((Tk_FakeWin *) (tkwin))->reqHeight) -/* Tk_InternalBorderWidth is deprecated */ +#ifndef TK_NO_DEPRECATED #define Tk_InternalBorderWidth(tkwin) \ (((Tk_FakeWin *) (tkwin))->internalBorderLeft) +#endif /* !TK_NO_DEPRECATED */ #define Tk_InternalBorderLeft(tkwin) \ (((Tk_FakeWin *) (tkwin))->internalBorderLeft) #define Tk_InternalBorderRight(tkwin) \ (((Tk_FakeWin *) (tkwin))->internalBorderRight) #define Tk_InternalBorderTop(tkwin) \ @@ -812,10 +825,13 @@ int internalBorderTop; int internalBorderBottom; int minReqWidth; int minReqHeight; char *dummy20; /* geometryMaster */ +#ifdef TK_USE_INPUT_METHODS + int dummy21; +#endif /* TK_USE_INPUT_METHODS */ } Tk_FakeWin; /* * Flag values for TkWindow (and Tk_FakeWin) structures are: * @@ -913,11 +929,11 @@ TK_STATE_NULL = -1, TK_STATE_ACTIVE, TK_STATE_DISABLED, TK_STATE_NORMAL, TK_STATE_HIDDEN } Tk_State; typedef struct Tk_SmoothMethod { - CONST86 char *name; + const char *name; int (*coordProc) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); void (*postscriptProc) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints, int numSteps); } Tk_SmoothMethod; @@ -1041,18 +1057,22 @@ int first, int last); #ifndef __NO_OLD_CONFIG typedef struct Tk_ItemType { - CONST86 char *name; /* The name of this type of item, such as + const char *name; /* The name of this type of item, such as * "line". */ - int itemSize; /* Total amount of space needed for item's +#if TCL_MAJOR_VERSION > 8 + size_t itemSize; /* Total amount of space needed for item's * record. */ +#else + int itemSize; +#endif Tk_ItemCreateProc *createProc; /* Procedure to create a new item of this * type. */ - CONST86 Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for + const Tk_ConfigSpec *configSpecs; /* Pointer to array of configuration specs for * this type. Used for returning configuration * info. */ Tk_ItemConfigureProc *configProc; /* Procedure to call to change configuration * options. */ @@ -1169,11 +1189,11 @@ int xoffset; /* x offset */ int yoffset; /* y offset */ } Tk_TSOffset; /* - * Bit fields in Tk_Offset->flags: + * Bit fields in Tk_TSOffset->flags: */ #define TK_OFFSET_INDEX 1 #define TK_OFFSET_RELATIVE 2 #define TK_OFFSET_LEFT 4 @@ -1218,12 +1238,12 @@ #ifdef USE_OLD_IMAGE typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, char *name, int argc, char **argv, Tk_ImageType *typePtr, Tk_ImageMaster master, ClientData *masterDataPtr); #else -typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, CONST86 char *name, int objc, - Tcl_Obj *const objv[], CONST86 Tk_ImageType *typePtr, Tk_ImageMaster master, +typedef int (Tk_ImageCreateProc) (Tcl_Interp *interp, const char *name, int objc, + Tcl_Obj *const objv[], const Tk_ImageType *typePtr, Tk_ImageMaster master, ClientData *masterDataPtr); #endif /* USE_OLD_IMAGE */ typedef ClientData (Tk_ImageGetProc) (Tk_Window tkwin, ClientData masterData); typedef void (Tk_ImageDisplayProc) (ClientData instanceData, Display *display, Drawable drawable, int imageX, int imageY, int width, int height, @@ -1243,11 +1263,11 @@ * that respond to various events. Each image manager is represented by one of * these structures. */ struct Tk_ImageType { - CONST86 char *name; /* Name of image type. */ + const char *name; /* Name of image type. */ Tk_ImageCreateProc *createProc; /* Procedure to call to create a new image of * this type. */ Tk_ImageGetProc *getProc; /* Procedure to call the first time * Tk_GetImage is called in a new way (new @@ -1355,11 +1375,11 @@ * images (e.g., PPM, GIF, JPEG, etc.). It provides information to allow image * files of that format to be recognized and read into a photo image. */ struct Tk_PhotoImageFormat { - CONST86 char *name; /* Name of image file format */ + const char *name; /* Name of image file format */ Tk_ImageFileMatchProc *fileMatchProc; /* Procedure to call to determine whether an * image file matches this format. */ Tk_ImageStringMatchProc *stringMatchProc; /* Procedure to call to determine whether the @@ -1526,11 +1546,11 @@ typedef int (Tk_ErrorProc) (ClientData clientData, XErrorEvent *errEventPtr); typedef void (Tk_EventProc) (ClientData clientData, XEvent *eventPtr); typedef int (Tk_GenericProc) (ClientData clientData, XEvent *eventPtr); typedef int (Tk_ClientMessageProc) (Tk_Window tkwin, XEvent *eventPtr); typedef int (Tk_GetSelProc) (ClientData clientData, Tcl_Interp *interp, - CONST86 char *portion); + const char *portion); typedef void (Tk_LostSelProc) (ClientData clientData); typedef Tk_RestrictAction (Tk_RestrictProc) (ClientData clientData, XEvent *eventPtr); typedef int (Tk_SelectionProc) (ClientData clientData, int offset, char *buffer, int maxBytes); @@ -1554,16 +1574,17 @@ /* *---------------------------------------------------------------------- * * Allow users to say that they don't want to alter their source to add extra - * arguments to Tk_PhotoPutBlock() et al; DO NOT DEFINE THIS WHEN BUILDING TK. + * arguments to Tk_PhotoPutBlock() et al. * * This goes after the inclusion of the stubbed-decls so that the declarations * of what is actually there can be correct. */ +#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 #ifdef USE_COMPOSITELESS_PHOTO_PUT_BLOCK # ifdef Tk_PhotoPutBlock # undef Tk_PhotoPutBlock # endif # define Tk_PhotoPutBlock Tk_PhotoPutBlock_NoComposite @@ -1592,10 +1613,11 @@ # ifdef Tk_PhotoSetSize # undef Tk_PhotoSetSize # endif # define Tk_PhotoSetSize Tk_PhotoSetSize_Panic #endif /* USE_PANIC_ON_PHOTO_ALLOC_FAILURE */ +#endif /* !TK_NO_DEPRECATED */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* RC_INVOKED */ Index: generic/tk3d.h ================================================================== --- generic/tk3d.h +++ generic/tk3d.h @@ -26,20 +26,20 @@ * the border. */ int depth; /* Number of bits per pixel of drawables where * the border will be used. */ Colormap colormap; /* Colormap out of which pixels are * allocated. */ - int resourceRefCount; /* Number of active uses of this color (each + TkSizeT resourceRefCount; /* Number of active uses of this color (each * active use corresponds to a call to * Tk_Alloc3DBorderFromObj or Tk_Get3DBorder). * If this count is 0, then this structure is * no longer valid and it isn't present in * borderTable: it is being kept around only * because there are objects referring to it. * The structure is freed when objRefCount and * resourceRefCount are both 0. */ - int objRefCount; /* The number of Tcl objects that reference + TkSizeT objRefCount; /* The number of Tcl objects that reference * this structure. */ XColor *bgColorPtr; /* Background color (intensity between * lightColorPtr and darkColorPtr). */ XColor *darkColorPtr; /* Color for darker areas (must free when * deleting structure). NULL means shadows Index: generic/tkAtom.c ================================================================== --- generic/tkAtom.c +++ generic/tkAtom.c @@ -154,11 +154,11 @@ if (mustFree) { XFree(mustFree); } name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr); hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew); - Tcl_SetHashValue(hPtr, name); + Tcl_SetHashValue(hPtr, (char *)name); } return Tcl_GetHashValue(hPtr); } /* @@ -200,11 +200,11 @@ name = atomNameArray[atom - 1]; hPtr = Tcl_CreateHashEntry(&dispPtr->nameTable, name, &isNew); Tcl_SetHashValue(hPtr, INT2PTR(atom)); name = Tcl_GetHashKey(&dispPtr->nameTable, hPtr); hPtr = Tcl_CreateHashEntry(&dispPtr->atomTable, INT2PTR(atom), &isNew); - Tcl_SetHashValue(hPtr, name); + Tcl_SetHashValue(hPtr, (char *)name); } } /* * Local Variables: Index: generic/tkBind.c ================================================================== --- generic/tkBind.c +++ generic/tkBind.c @@ -685,29 +685,29 @@ Tcl_InitHashTable(&keySymTable, TCL_STRING_KEYS); Tcl_InitHashTable(&nameTable, TCL_ONE_WORD_KEYS); for (kPtr = keyArray; kPtr->name != NULL; kPtr++) { hPtr = Tcl_CreateHashEntry(&keySymTable, kPtr->name, &newEntry); - Tcl_SetHashValue(hPtr, kPtr->value); - hPtr = Tcl_CreateHashEntry(&nameTable, (char *) kPtr->value, + Tcl_SetHashValue(hPtr, INT2PTR(kPtr->value)); + hPtr = Tcl_CreateHashEntry(&nameTable, INT2PTR(kPtr->value), &newEntry); if (newEntry) { - Tcl_SetHashValue(hPtr, kPtr->name); + Tcl_SetHashValue(hPtr, (char *) kPtr->name); } } #endif /* REDO_KEYSYM_LOOKUP */ Tcl_InitHashTable(&modTable, TCL_STRING_KEYS); for (modPtr = modArray; modPtr->name != NULL; modPtr++) { hPtr = Tcl_CreateHashEntry(&modTable, modPtr->name, &newEntry); - Tcl_SetHashValue(hPtr, modPtr); + Tcl_SetHashValue(hPtr, (ModInfo *) modPtr); } Tcl_InitHashTable(&eventTable, TCL_STRING_KEYS); for (eiPtr = eventArray; eiPtr->name != NULL; eiPtr++) { hPtr = Tcl_CreateHashEntry(&eventTable, eiPtr->name, &newEntry); - Tcl_SetHashValue(hPtr, eiPtr); + Tcl_SetHashValue(hPtr, (EventInfo *) eiPtr); } initialized = 1; } Tcl_MutexUnlock(&bindMutex); } @@ -1257,10 +1257,20 @@ if ((eventPtr->type == FocusIn) || (eventPtr->type == FocusOut)) { if (eventPtr->xfocus.detail == NotifyInferior) { return; } } + + /* + * Ignore event types which are not in flagArray and all zeroes there. + * Most notably, NoExpose events can fill the ring buffer and disturb + * (thus masking out) event sequences of interest. + */ + + if ((eventPtr->type >= TK_LASTEVENT) || !flagArray[eventPtr->type]) { + return; + } dispPtr = ((TkWindow *) tkwin)->dispPtr; bindInfoPtr = winPtr->mainPtr->bindInfo; /* @@ -1726,13 +1736,14 @@ goto nextSequence; } } if (psPtr->flags & PAT_NEARBY) { XEvent *firstPtr = &bindPtr->eventRing[bindPtr->curEvent]; - int timeDiff; + long timeDiff; - timeDiff = (Time) firstPtr->xkey.time - eventPtr->xkey.time; + timeDiff = ((long)firstPtr->xkey.time - + (long)eventPtr->xkey.time); if ((firstPtr->xkey.x_root < (eventPtr->xkey.x_root - NEARBY_PIXELS)) || (firstPtr->xkey.x_root > (eventPtr->xkey.x_root + NEARBY_PIXELS)) || (firstPtr->xkey.y_root @@ -1909,11 +1920,12 @@ unsigned int scriptCount, /* The number of script-based binding patterns * matched so far for this event. */ Tcl_DString *dsPtr) /* Dynamic string in which to append new * command. */ { - int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl + size_t spaceNeeded; + int cvtFlags; /* Used to substitute string as proper Tcl * list element. */ int number, flags, length; #define NUM_SIZE 40 const char *string; Tcl_DString buf; @@ -2491,11 +2503,11 @@ * * Add a new definition for a virtual event. If the virtual event is * already defined, the new definition augments those that already exist. * * Results: - * The return value is TCL_ERROR if an error occured while creating the + * The return value is TCL_ERROR if an error occurred while creating the * virtual binding. In this case, an error message will be left in the * interp's result. If all went well then the return value is TCL_OK. * * Side effects: * The virtual event may cause future calls to Tk_BindEvent to behave @@ -2866,11 +2878,11 @@ * event.xany.window is filled with the target window. * event.xany.display is filled with the target window's display. * Any other fields in eventPtr which are not specified by the pattern * string or the optional arguments, are set to 0. * - * The event may be handled sychronously or asynchronously, depending on + * The event may be handled synchronously or asynchronously, depending on * the value specified by the optional "-when" option. The default * setting is synchronous. * *--------------------------------------------------------------------------- */ @@ -3321,13 +3333,13 @@ case EVENT_TIME: if (Tcl_GetIntFromObj(interp, valuePtr, &number) != TCL_OK) { return TCL_ERROR; } if (flags & KEY_BUTTON_MOTION_CROSSING) { - event.general.xkey.time = (Time) number; + event.general.xkey.time = number; } else if (flags & PROP) { - event.general.xproperty.time = (Time) number; + event.general.xproperty.time = number; } else { goto badopt; } break; case EVENT_WIDTH: @@ -3453,17 +3465,28 @@ * We only allow warping if the window is mapped. */ if ((warp != 0) && Tk_IsMapped(tkwin)) { TkDisplay *dispPtr = TkGetDisplay(event.general.xmotion.display); + + Tk_Window warpWindow = Tk_IdToWindow(dispPtr->display, + event.general.xmotion.window); if (!(dispPtr->flags & TK_DISPLAY_IN_WARP)) { Tcl_DoWhenIdle(DoWarp, dispPtr); dispPtr->flags |= TK_DISPLAY_IN_WARP; } - dispPtr->warpWindow = Tk_IdToWindow(dispPtr->display, - event.general.xmotion.window); + + if (warpWindow != dispPtr->warpWindow) { + if (warpWindow) { + Tcl_Preserve(warpWindow); + } + if (dispPtr->warpWindow) { + Tcl_Release(dispPtr->warpWindow); + } + dispPtr->warpWindow = warpWindow; + } dispPtr->warpMainwin = mainWin; dispPtr->warpX = event.general.xmotion.x; dispPtr->warpY = event.general.xmotion.y; } @@ -3547,10 +3570,15 @@ (Tk_IsMapped(dispPtr->warpWindow) && (Tk_WindowId(dispPtr->warpWindow) != None))) { TkpWarpPointer(dispPtr); XForceScreenSaver(dispPtr->display, ScreenSaverReset); } + + if (dispPtr->warpWindow) { + Tcl_Release(dispPtr->warpWindow); + dispPtr->warpWindow = None; + } dispPtr->flags &= ~TK_DISPLAY_IN_WARP; } /* *------------------------------------------------------------------------- @@ -3947,11 +3975,11 @@ p++; } p = GetField(p, field, FIELD_SIZE); } if (*field != '\0') { - if ((*field >= '1') && (*field <= '5') && (field[1] == '\0')) { + if ((*field >= '1') && (*field <= '9') && (field[1] == '\0')) { if (eventFlags == 0) { patPtr->eventType = ButtonPress; eventMask = ButtonPressMask; } else if (eventFlags & KEY) { goto getKeysym; @@ -4286,13 +4314,40 @@ TkWindow *winPtr = (TkWindow *) Tk_MainWindow(interp); BindingTable *bindPtr = winPtr->mainPtr->bindingTable; return &(bindPtr->eventRing[bindPtr->curEvent]); } + +/* + *---------------------------------------------------------------------- + * + * TkpCancelWarp -- + * + * This function cancels an outstanding pointer warp and + * is called during tear down of the display. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +void +TkpCancelWarp( + TkDisplay *dispPtr) +{ + if (dispPtr->flags & TK_DISPLAY_IN_WARP) { + Tcl_CancelIdleCall(DoWarp, dispPtr); + dispPtr->flags &= ~TK_DISPLAY_IN_WARP; + } +} /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ Index: generic/tkBusy.c ================================================================== --- generic/tkBusy.c +++ generic/tkBusy.c @@ -15,20 +15,18 @@ #include "tkInt.h" #include "tkBusy.h" #include "default.h" /* - * Things about the busy system that may be configured. Note that currently on - * OSX/Aqua, that's nothing at all. + * Things about the busy system that may be configured. Note that on some + * platforms this may or may not have an effect. */ static const Tk_OptionSpec busyOptionSpecs[] = { -#ifndef MAC_OSX_TK {TK_OPTION_CURSOR, "-cursor", "cursor", "Cursor", DEF_BUSY_CURSOR, -1, Tk_Offset(Busy, cursor), TK_OPTION_NULL_OK, 0, 0}, -#endif {TK_OPTION_END, NULL, NULL, NULL, NULL, 0, 0, 0, 0, 0} }; /* * Forward declarations of functions defined in this file. @@ -571,11 +569,11 @@ busyPtr->x = Tk_X(tkRef); busyPtr->y = Tk_Y(tkRef); busyPtr->cursor = None; Tk_SetClass(tkBusy, "Busy"); busyPtr->optionTable = Tk_CreateOptionTable(interp, busyOptionSpecs); - if (Tk_InitOptions(interp, (char *) busyPtr, busyPtr->optionTable, + if (Tk_InitOptions(interp, busyPtr, busyPtr->optionTable, tkBusy) != TCL_OK) { Tk_DestroyWindow(tkBusy); return NULL; } SetWindowInstanceData(tkBusy, busyPtr); @@ -638,11 +636,11 @@ int objc, Tcl_Obj *const objv[]) { Tk_Cursor oldCursor = busyPtr->cursor; - if (Tk_SetOptions(interp, (char *) busyPtr, busyPtr->optionTable, objc, + if (Tk_SetOptions(interp, busyPtr, busyPtr->optionTable, objc, objv, busyPtr->tkBusy, NULL, NULL) != TCL_OK) { return TCL_ERROR; } if (busyPtr->cursor != oldCursor) { if (busyPtr->cursor == None) { @@ -761,10 +759,13 @@ if (Tk_IsMapped(busyPtr->tkRef)) { TkpShowBusyWindow(busyPtr); } else { TkpHideBusyWindow(busyPtr); } + if (result == TCL_OK) { + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1)); + } return result; } /* *---------------------------------------------------------------------- @@ -794,15 +795,16 @@ Tcl_HashTable *busyTablePtr = &((TkWindow *) tkwin)->mainPtr->busyTable; Busy *busyPtr; Tcl_Obj *objPtr; int index, result = TCL_OK; static const char *const optionStrings[] = { - "cget", "configure", "current", "forget", "hold", "status", NULL + "busywindow", "cget", "configure", "current", "forget", "hold", + "status", NULL }; enum options { - BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, BUSY_HOLD, - BUSY_STATUS + BUSY_BUSYWINDOW, BUSY_CGET, BUSY_CONFIGURE, BUSY_CURRENT, BUSY_FORGET, + BUSY_HOLD, BUSY_STATUS }; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "options ?arg arg ...?"); return TCL_ERROR; @@ -823,10 +825,23 @@ if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, sizeof(char *), "option", 0, &index) != TCL_OK) { return TCL_ERROR; } switch ((enum options) index) { + case BUSY_BUSYWINDOW: + if (objc != 3) { + Tcl_WrongNumArgs(interp, 2, objv, "window"); + return TCL_ERROR; + } + busyPtr = GetBusy(interp, busyTablePtr, objv[2]); + if (busyPtr == NULL) { + Tcl_ResetResult(interp); + return TCL_OK; + } + Tcl_SetObjResult(interp, Tcl_NewStringObj(Tk_PathName(busyPtr->tkBusy), -1)); + return TCL_OK; + case BUSY_CGET: if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "window option"); return TCL_ERROR; } @@ -833,11 +848,11 @@ busyPtr = GetBusy(interp, busyTablePtr, objv[2]); if (busyPtr == NULL) { return TCL_ERROR; } Tcl_Preserve(busyPtr); - objPtr = Tk_GetOptionValue(interp, (char *) busyPtr, + objPtr = Tk_GetOptionValue(interp, busyPtr, busyPtr->optionTable, objv[3], busyPtr->tkBusy); if (objPtr == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, objPtr); @@ -854,11 +869,11 @@ if (busyPtr == NULL) { return TCL_ERROR; } Tcl_Preserve(busyPtr); if (objc <= 4) { - objPtr = Tk_GetOptionInfo(interp, (char *) busyPtr, + objPtr = Tk_GetOptionInfo(interp, busyPtr, busyPtr->optionTable, (objc == 4) ? objv[3] : NULL, busyPtr->tkBusy); if (objPtr == NULL) { result = TCL_ERROR; } else { Index: generic/tkButton.c ================================================================== --- generic/tkButton.c +++ generic/tkButton.c @@ -747,11 +747,11 @@ Tk_CreateEventHandler(butPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, ButtonEventProc, butPtr); - if (Tk_InitOptions(interp, (char *) butPtr, optionTable, tkwin) + if (Tk_InitOptions(interp, butPtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(butPtr->tkwin); return TCL_ERROR; } if (ConfigureButton(interp, butPtr, objc - 2, objv + 2) != TCL_OK) { @@ -808,21 +808,21 @@ case COMMAND_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "cget option"); goto error; } - objPtr = Tk_GetOptionValue(interp, (char *) butPtr, + objPtr = Tk_GetOptionValue(interp, butPtr, butPtr->optionTable, objv[2], butPtr->tkwin); if (objPtr == NULL) { goto error; } Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) butPtr, + objPtr = Tk_GetOptionInfo(interp, butPtr, butPtr->optionTable, (objc == 3) ? objv[2] : NULL, butPtr->tkwin); if (objPtr == NULL) { goto error; } @@ -1066,11 +1066,11 @@ if (!error) { /* * First pass: set options to new values. */ - if (Tk_SetOptions(interp, (char *) butPtr, + if (Tk_SetOptions(interp, butPtr, butPtr->optionTable, objc, objv, butPtr->tkwin, &savedOptions, NULL) != TCL_OK) { continue; } } else { @@ -1607,10 +1607,23 @@ int flags) /* Information about what happened. */ { register TkButton *butPtr = clientData; const char *value; Tcl_Obj *valuePtr; + + /* + * See ticket [5d991b82]. + */ + + if (butPtr->selVarNamePtr == NULL) { + if (!(flags & TCL_INTERP_DESTROYED)) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonVarProc, clientData); + } + return NULL; + } /* * If the variable is being unset, then just re-establish the trace unless * the whole interpreter is going away. */ @@ -1690,20 +1703,33 @@ /* ARGSUSED */ static char * ButtonTextVarProc( ClientData clientData, /* Information about button. */ Tcl_Interp *interp, /* Interpreter containing variable. */ - const char *name1, /* Not used. */ - const char *name2, /* Not used. */ + const char *name1, /* Name of variable. */ + const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { TkButton *butPtr = clientData; Tcl_Obj *valuePtr; if (butPtr->flags & BUTTON_DELETED) { return NULL; } + + /* + * See ticket [5d991b82]. + */ + + if (butPtr->textVarNamePtr == NULL) { + if (!(flags & TCL_INTERP_DESTROYED)) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ButtonTextVarProc, clientData); + } + return NULL; + } /* * If the variable is unset, then immediately recreate it unless the whole * interpreter is going away. */ Index: generic/tkCanvPs.c ================================================================== --- generic/tkCanvPs.c +++ generic/tkCanvPs.c @@ -489,11 +489,11 @@ */ Tcl_AppendObjToObj(psObj, preambleObj); if (psInfo.chan != NULL) { - if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) { channelWriteFailed: Tcl_SetObjResult(interp, Tcl_ObjPrintf( "problem writing postscript data to channel: %s", Tcl_PosixError(interp))); result = TCL_ERROR; @@ -543,11 +543,11 @@ psInfo.x2, Tk_PostscriptY((double)psInfo.y2, (Tk_PostscriptInfo)psInfoPtr), psInfo.x, Tk_PostscriptY((double)psInfo.y2, (Tk_PostscriptInfo)psInfoPtr)); if (psInfo.chan != NULL) { - if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) { goto channelWriteFailed; } Tcl_DecrRefCount(psObj); psObj = Tcl_NewObj(); } @@ -585,11 +585,11 @@ Tcl_AppendToObj(psObj, "gsave\n", -1); Tcl_AppendObjToObj(psObj, Tcl_GetObjResult(interp)); Tcl_AppendToObj(psObj, "grestore\n", -1); if (psInfo.chan != NULL) { - if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) { goto channelWriteFailed; } Tcl_DecrRefCount(psObj); psObj = Tcl_NewObj(); } @@ -606,11 +606,11 @@ "%%Trailer\n" "end\n" "%%EOF\n", -1); if (psInfo.chan != NULL) { - if (Tcl_WriteObj(psInfo.chan, psObj) == -1) { + if (Tcl_WriteObj(psInfo.chan, psObj) == TCL_IO_FAILURE) { goto channelWriteFailed; } } } @@ -823,11 +823,11 @@ Tcl_DStringInit(&ds); points = Tk_PostscriptFontName(tkfont, &ds); fontname = Tcl_DStringValue(&ds); Tcl_AppendPrintfToObj(GetPostscriptBuffer(interp), "/%s findfont %d scalefont%s setfont\n", - fontname, TkFontGetPoints(psInfoPtr->tkwin, points), + fontname, (int)(TkFontGetPoints(psInfoPtr->tkwin, points) + 0.5), strncasecmp(fontname, "Symbol", 7) ? " ISOEncode" : ""); Tcl_CreateHashEntry(&psInfoPtr->fontTable, Tcl_DStringValue(&ds), &i); Tcl_DStringFree(&ds); return TCL_OK; Index: generic/tkCanvText.c ================================================================== --- generic/tkCanvText.c +++ generic/tkCanvText.c @@ -1004,16 +1004,17 @@ int index, /* Character index before which string is to * be inserted. */ Tcl_Obj *obj) /* New characters to be inserted. */ { TextItem *textPtr = (TextItem *) itemPtr; - int byteIndex, byteCount, charsAdded; + int byteIndex, charsAdded; + size_t byteCount; char *newStr, *text; const char *string; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; - string = Tcl_GetStringFromObj(obj, &byteCount); + string = TkGetStringFromObj(obj, &byteCount); text = textPtr->text; if (index < 0) { index = 0; @@ -1341,15 +1342,15 @@ * itemPtr's text. */ int *indexPtr) /* Where to store converted character * index. */ { TextItem *textPtr = (TextItem *) itemPtr; - int length; + size_t length; int c; TkCanvas *canvasPtr = (TkCanvas *) canvas; Tk_CanvasTextInfo *textInfoPtr = textPtr->textInfoPtr; - const char *string = Tcl_GetStringFromObj(obj, &length); + const char *string = TkGetStringFromObj(obj, &length); c = string[0]; if ((c == 'e') && (strncmp(string, "end", (unsigned) length) == 0)) { *indexPtr = textPtr->numChars; Index: generic/tkCanvUtil.c ================================================================== --- generic/tkCanvUtil.c +++ generic/tkCanvUtil.c @@ -1134,11 +1134,13 @@ } } if (mask && (dash->number != 0)) { gcValues->line_style = LineOnOffDash; gcValues->dash_offset = outline->offset; - if (dash->number > 0) { + if ((unsigned int)ABS(dash->number) > sizeof(char *)) { + gcValues->dashes = dash->pattern.pt[0]; + } else if (dash->number != 0) { gcValues->dashes = dash->pattern.array[0]; } else { gcValues->dashes = (char) (4 * width + 0.5); } mask |= GCLineStyle|GCDashList|GCDashOffset; @@ -1338,11 +1340,13 @@ } if ((dash->number > 2) || (dash->number < -1) || (dash->number==2 && (dash->pattern.array[0] != dash->pattern.array[1])) || ((dash->number == -1) && (dash->pattern.array[0] != ','))) { - if (dash->number > 0) { + if ((unsigned int)ABS(dash->number) > sizeof(char *)) { + dashList = dash->pattern.pt[0]; + } else if (dash->number != 0) { dashList = dash->pattern.array[0]; } else { dashList = (char) (4 * width + 0.5); } XSetDashes(Canvas(canvas)->display, outline->gc, outline->offset, Index: generic/tkCanvas.c ================================================================== --- generic/tkCanvas.c +++ generic/tkCanvas.c @@ -13,13 +13,13 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ /* #define USE_OLD_TAG_SEARCH 1 */ -#include "default.h" #include "tkInt.h" #include "tkCanvas.h" +#include "default.h" #ifdef TK_NO_DOUBLE_BUFFERING #ifdef MAC_OSX_TK #include "tkMacOSXInt.h" #endif #endif /* TK_NO_DOUBLE_BUFFERING */ @@ -266,10 +266,11 @@ static void CanvasWorldChanged(ClientData instanceData); static int ConfigureCanvas(Tcl_Interp *interp, TkCanvas *canvasPtr, int argc, Tcl_Obj *const *argv, int flags); static void DestroyCanvas(char *memPtr); +static int DrawCanvas(Tcl_Interp *interp, ClientData clientData, Tk_PhotoHandle photohandle, int subsample, int zoom); static void DisplayCanvas(ClientData clientData); static void DoItem(Tcl_Obj *accumObj, Tk_Item *itemPtr, Tk_Uid tag); static void EventuallyRedrawItem(TkCanvas *canvasPtr, Tk_Item *itemPtr); @@ -803,10 +804,11 @@ static const char *const optionStrings[] = { "addtag", "bbox", "bind", "canvasx", "canvasy", "cget", "configure", "coords", "create", "dchars", "delete", "dtag", "find", "focus", "gettags", "icursor", + "image", "imove", "index", "insert", "itemcget", "itemconfigure", "lower", "move", "moveto", "postscript", "raise", "rchars", "scale", "scan", "select", "type", "xview", "yview", @@ -815,10 +817,11 @@ enum options { CANV_ADDTAG, CANV_BBOX, CANV_BIND, CANV_CANVASX, CANV_CANVASY, CANV_CGET, CANV_CONFIGURE, CANV_COORDS, CANV_CREATE, CANV_DCHARS, CANV_DELETE, CANV_DTAG, CANV_FIND, CANV_FOCUS, CANV_GETTAGS, CANV_ICURSOR, + CANV_IMAGE, CANV_IMOVE, CANV_INDEX, CANV_INSERT, CANV_ITEMCGET, CANV_ITEMCONFIGURE, CANV_LOWER, CANV_MOVE, CANV_MOVETO, CANV_POSTSCRIPT, CANV_RAISE, CANV_RCHARS, CANV_SCALE, CANV_SCAN, CANV_SELECT, CANV_TYPE, CANV_XVIEW, CANV_YVIEW @@ -1184,12 +1187,12 @@ tmpObj = Tcl_NewListObj(2, objv+4); FOR_EVERY_CANVAS_ITEM_MATCHING(objv[2], &searchPtr, goto doneImove) { int index; - int x1,x2,y1,y2; - int dontRedraw1,dontRedraw2; + int x1, x2, y1, y2; + int dontRedraw1, dontRedraw2; /* * The TK_MOVABLE_POINTS flag should only be set for types that * support the same semantics of index, dChars and insert methods * as lines and canvases. @@ -1215,15 +1218,15 @@ x1 = itemPtr->x1; y1 = itemPtr->y1; x2 = itemPtr->x2; y2 = itemPtr->y2; itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; ItemDelChars(canvasPtr, itemPtr, index, index); - dontRedraw1=itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; + dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; ItemInsert(canvasPtr, itemPtr, index, tmpObj); - dontRedraw2=itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; + dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; if (!(dontRedraw1 && dontRedraw2)) { Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, x1, y1, x2, y2); EventuallyRedrawItem(canvasPtr, itemPtr); @@ -1247,12 +1250,11 @@ if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "type coords ?arg ...?"); result = TCL_ERROR; goto done; } - arg = Tcl_GetString(objv[2]); - length = objv[2]->length; + arg = TkGetStringFromObj(objv[2], &length); c = arg[0]; /* * Lock because the list of types is a global resource that could be * updated by another thread. That's fairly unlikely, but not @@ -1332,11 +1334,11 @@ Tcl_SetObjResult(interp, Tcl_NewIntObj(itemPtr->id)); break; } case CANV_DCHARS: { int first, last; - int x1,x2,y1,y2; + int x1, x2, y1, y2; if ((objc != 4) && (objc != 5)) { Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first ?last?"); result = TCL_ERROR; goto done; @@ -1360,11 +1362,11 @@ } /* * Redraw both item's old and new areas: it's possible that a * delete could result in a new area larger than the old area. - * Except if the insertProc sets the TK_ITEM_DONT_REDRAW flag, + * Except if the dCharsProc sets the TK_ITEM_DONT_REDRAW flag, * nothing more needs to be done. */ x1 = itemPtr->x1; y1 = itemPtr->y1; x2 = itemPtr->x2; y2 = itemPtr->y2; @@ -1570,11 +1572,11 @@ Tcl_SetObjResult(interp, Tcl_NewIntObj(index)); break; } case CANV_INSERT: { int beforeThis; - int x1,x2,y1,y2; + int x1, x2, y1, y2; if (objc != 5) { Tcl_WrongNumArgs(interp, 2, objv, "tagOrId beforeThis string"); result = TCL_ERROR; goto done; @@ -1798,11 +1800,12 @@ RELINK_ITEMS(objv[2], prevPtr); break; } case CANV_RCHARS: { int first, last; - int x1,x2,y1,y2; + int x1, x2, y1, y2; + int dontRedraw1, dontRedraw2; if (objc != 6) { Tcl_WrongNumArgs(interp, 2, objv, "tagOrId first last string"); result = TCL_ERROR; goto done; @@ -1829,16 +1832,20 @@ * TK_ITEM_DONT_REDRAW flag, nothing more needs to be done. */ x1 = itemPtr->x1; y1 = itemPtr->y1; x2 = itemPtr->x2; y2 = itemPtr->y2; - itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; ItemDelChars(canvasPtr, itemPtr, first, last); + dontRedraw1 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; + + itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; ItemInsert(canvasPtr, itemPtr, first, objv[5]); + dontRedraw2 = itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW; - if (!(itemPtr->redraw_flags & TK_ITEM_DONT_REDRAW)) { + if (!(dontRedraw1 && dontRedraw2)) { Tk_CanvasEventuallyRedraw((Tk_Canvas) canvasPtr, x1, y1, x2, y2); EventuallyRedrawItem(canvasPtr, itemPtr); } itemPtr->redraw_flags &= ~TK_ITEM_DONT_REDRAW; @@ -2124,10 +2131,50 @@ break; } CanvasSetOrigin(canvasPtr, canvasPtr->xOrigin, newY); break; } + case CANV_IMAGE: { + Tk_PhotoHandle photohandle; + int subsample = 1, zoom = 1; + + if (objc < 3 || objc > 5) { + Tcl_WrongNumArgs(interp, 2, objv, "imagename ?subsample? ?zoom?"); + result = TCL_ERROR; + goto done; + } + + if ((photohandle = Tk_FindPhoto(interp, Tcl_GetString(objv[2]) )) == 0) { + result = TCL_ERROR; + goto done; + } + + /* + * If we are given a subsample or a zoom then grab them. + */ + + if (objc >= 4 && Tcl_GetIntFromObj(interp, objv[3], &subsample) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + if (objc >= 5 && Tcl_GetIntFromObj(interp, objv[4], &zoom) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + + /* + * Set the image size to zero, which allows the DrawCanvas() function + * to expand the image automatically when it copies the pixmap into it. + */ + + if (Tk_PhotoSetSize(interp, photohandle, 0, 0) != TCL_OK) { + result = TCL_ERROR; + goto done; + } + + result = DrawCanvas(interp, clientData, photohandle, subsample, zoom); + } } done: #ifndef USE_OLD_TAG_SEARCH TagSearchDestroy(searchPtr); @@ -2409,10 +2456,504 @@ canvasPtr->xOrigin, canvasPtr->yOrigin, canvasPtr->xOrigin + Tk_Width(canvasPtr->tkwin), canvasPtr->yOrigin + Tk_Height(canvasPtr->tkwin)); } +/* + *---------------------------------------------------------------------- + * + * DecomposeMaskToShiftAndBits -- + * + * Given a 32 bit pixel mask, we find the position of the lowest bit and the + * width of the mask bits. + * + * Results: + * None. + * + * Side effects: +* None. + * + *---------------------------------------------------------------------- + */ +static void +DecomposeMaskToShiftAndBits( + unsigned long mask, /* The pixel mask to examine */ + int *shift, /* Where to put the shift count (position of lowest bit) */ + int *bits) /* Where to put the bit count (width of the pixel mask) */ +{ + int i; + + *shift = 0; + *bits = 0; + + /* + * Find the lowest '1' bit in the mask. + */ + + for (i = 0; i < 32; ++i) { + if (mask & 1 << i) + break; + } + if (i < 32) { + *shift = i; + + /* + * Now find the next '0' bit and the width of the mask. + */ + + for ( ; i < 32; ++i) { + if ((mask & 1 << i) == 0) + break; + else + ++*bits; + } + + /* + * Limit to the top 8 bits if the mask was wider than 8. + */ + + if (*bits > 8) { + *shift += *bits - 8; + *bits = 8; + } + } +} + +/* + *---------------------------------------------------------------------- + * + * DrawCanvas -- + * + * This function draws the contents of a canvas into the given Photo image. + * This function is called from the widget "image" subcommand. + * The canvas does not need to be mapped (one of it's ancestors must be) + * in order for this function to work. + * + * Results: + * None. + * + * Side effects: + * Canvas contents from within the -scrollregion or widget size are rendered + * into the Photo. Any errors are left in the result. + * + *---------------------------------------------------------------------- + */ + +#define OVERDRAW_PIXELS 32 /* How much larger we make the pixmap + * that the canvas objects are drawn into */ + +/* From stackoverflow.com/questions/2100331/c-macro-definition-to-determine-big-endian-or-little-endian-machine */ +#define IS_BIG_ENDIAN (*(unsigned short *)"\0\xff" < 0x100) + +#define BYTE_SWAP16(n) ((((unsigned short)n)>>8) | (((unsigned short)n)<<8)) +#define BYTE_SWAP32(n) (((n>>24)&0x000000FF) | ((n<<8)&0x00FF0000) | ((n>>8)&0x0000FF00) | ((n<<24)&0xFF000000)) + +static int +DrawCanvas( + Tcl_Interp *interp, /* As passed to the widget command, and we will leave errors here */ + ClientData clientData, + Tk_PhotoHandle photohandle, /* The photo we are rendering into */ + int subsample, /* If either subsample or zoom are not 1 then we call Tk_PhotoPutZoomedBlock() */ + int zoom) +{ + TkCanvas * canvasPtr = clientData; + Tk_Window tkwin; + Display *displayPtr; + Tk_PhotoImageBlock blockPtr = {0}; + Window wid; + Tk_Item * itemPtr; + Pixmap pixmap = 0; + XImage *ximagePtr = NULL; + Visual *visualPtr; + GC xgc = 0; + XGCValues xgcValues; + int canvasX1, canvasY1, canvasX2, canvasY2, cWidth, cHeight, + pixmapX1, pixmapY1, pixmapX2, pixmapY2, pmWidth, pmHeight, + bitsPerPixel, bytesPerPixel, x, y, result = TCL_OK, + rshift, gshift, bshift, rbits, gbits, bbits; + +#ifdef DEBUG_DRAWCANVAS + char buffer[128]; +#endif + + if ((tkwin = canvasPtr->tkwin) == NULL) { + Tcl_AppendResult(interp, "canvas tkwin is NULL!", NULL); + result = TCL_ERROR; + goto done; + } + + /* + * If this canvas is unmapped, then we won't have a window id, so we will + * try the ancestors of the canvas until we find a window that has a + * valid window id. The Tk_GetPixmap() call requires a valid window id. + */ + + do { + + if ((displayPtr = Tk_Display(tkwin)) == NULL) { + Tcl_AppendResult(interp, "canvas (or parent) display is NULL!", NULL); + result = TCL_ERROR; + goto done; + } + + if ((wid = Tk_WindowId(tkwin)) != 0) { + continue; + } + + if ((tkwin = Tk_Parent(tkwin)) == NULL) { + Tcl_AppendResult(interp, "canvas has no parent with a valid window id! Is the toplevel window mapped?", NULL); + result = TCL_ERROR; + goto done; + } + + } while (wid == 0); + + bitsPerPixel = Tk_Depth(tkwin); + visualPtr = Tk_Visual(tkwin); + + if (subsample == 0) { + Tcl_AppendResult(interp, "subsample cannot be zero", NULL); + result = TCL_ERROR; + goto done; + } + + /* + * Scan through the item list, registering the bounding box for all items + * that didn't do that for the final coordinates yet. This can be + * determined by the FORCE_REDRAW flag. + */ + + for (itemPtr = canvasPtr -> firstItemPtr; itemPtr != NULL; + itemPtr = itemPtr -> nextPtr) { + if (itemPtr -> redraw_flags & FORCE_REDRAW) { + itemPtr -> redraw_flags &= ~FORCE_REDRAW; + EventuallyRedrawItem(canvasPtr, itemPtr); + itemPtr -> redraw_flags &= ~FORCE_REDRAW; + } + } + + /* + * The DisplayCanvas() function works out the region that needs redrawing, + * but we don't do this. We grab the whole scrollregion or canvas window + * area. If we have a defined -scrollregion we use that as the drawing + * region, otherwise use the canvas window height and width with an origin + * of 0,0. + */ + if (canvasPtr->scrollX1 != 0 || canvasPtr->scrollY1 != 0 || + canvasPtr->scrollX2 != 0 || canvasPtr->scrollY2 != 0) { + + canvasX1 = canvasPtr->scrollX1; + canvasY1 = canvasPtr->scrollY1; + canvasX2 = canvasPtr->scrollX2; + canvasY2 = canvasPtr->scrollY2; + cWidth = canvasX2 - canvasX1 + 1; + cHeight = canvasY2 - canvasY1 + 1; + + } else { + + cWidth = Tk_Width(tkwin); + cHeight = Tk_Height(tkwin); + canvasX1 = 0; + canvasY1 = 0; + canvasX2 = canvasX1 + cWidth - 1; + canvasY2 = canvasY1 + cHeight - 1; + } + + /* + * Allocate a pixmap to draw into. We add OVERDRAW_PIXELS in the same way + * that DisplayCanvas() does to avoid problems on some systems when objects + * are being drawn too close to the edge. + */ + + pixmapX1 = canvasX1 - OVERDRAW_PIXELS; + pixmapY1 = canvasY1 - OVERDRAW_PIXELS; + pixmapX2 = canvasX2 + OVERDRAW_PIXELS; + pixmapY2 = canvasY2 + OVERDRAW_PIXELS; + pmWidth = pixmapX2 - pixmapX1 + 1; + pmHeight = pixmapY2 - pixmapY1 + 1; + if ((pixmap = Tk_GetPixmap(displayPtr, Tk_WindowId(tkwin), pmWidth, pmHeight, + bitsPerPixel)) == 0) { + Tcl_AppendResult(interp, "failed to create drawing Pixmap", NULL); + result = TCL_ERROR; + goto done; + } + + /* + * Before we can draw the canvas objects into the pixmap it's background + * should be filled with canvas background colour. + */ + + xgcValues.function = GXcopy; + xgcValues.foreground = Tk_3DBorderColor(canvasPtr->bgBorder)->pixel; + xgc = XCreateGC(displayPtr, pixmap, GCFunction|GCForeground, &xgcValues); + XFillRectangle(displayPtr,pixmap,xgc,0,0,pmWidth,pmHeight); + + /* + * Draw all the cavas items into the pixmap + */ + + canvasPtr->drawableXOrigin = pixmapX1; + canvasPtr->drawableYOrigin = pixmapY1; + for (itemPtr = canvasPtr->firstItemPtr; itemPtr != NULL; + itemPtr = itemPtr->nextPtr) { + if ((itemPtr->x1 >= pixmapX2) || (itemPtr->y1 >= pixmapY2) || + (itemPtr->x2 < pixmapX1) || (itemPtr->y2 < pixmapY1)) { + if (!AlwaysRedraw(itemPtr)) { + continue; + } + } + if (itemPtr->state == TK_STATE_HIDDEN || + (itemPtr->state == TK_STATE_NULL && canvasPtr->canvas_state + == TK_STATE_HIDDEN)) { + continue; + } + ItemDisplay(canvasPtr, itemPtr, pixmap, pixmapX1, pixmapY1, pmWidth, + pmHeight); + } + + /* + * Copy the Pixmap into an ZPixmap format XImage so we can copy it across + * to the photo image. This seems to be the only way to get Pixmap image + * data out of an image. Note we have to account for the OVERDRAW_PIXELS + * border width. + */ + + if ((ximagePtr = XGetImage(displayPtr, pixmap, -pixmapX1, -pixmapY1, cWidth, + cHeight, AllPlanes, ZPixmap)) == NULL) { + Tcl_AppendResult(interp, "failed to copy Pixmap to XImage", NULL); + result = TCL_ERROR; + goto done; + } + +#ifdef DEBUG_DRAWCANVAS + Tcl_AppendResult(interp, "ximagePtr {", NULL); + sprintf(buffer,"%d",ximagePtr->width); Tcl_AppendResult(interp, " width ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->height); Tcl_AppendResult(interp, " height ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->xoffset); Tcl_AppendResult(interp, " xoffset ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->format); Tcl_AppendResult(interp, " format ", buffer, NULL); + Tcl_AppendResult(interp, " ximagePtr->data", NULL); + if (ximagePtr->data != NULL) { + int ix, iy; + + Tcl_AppendResult(interp, " {", NULL); + for (iy = 0; iy < ximagePtr->height; ++ iy) { + Tcl_AppendResult(interp, " {", NULL); + for (ix = 0; ix < ximagePtr->bytes_per_line; ++ ix) { + if (ix > 0) { + if (ix % 4 == 0) + Tcl_AppendResult(interp, "-", NULL); + else + Tcl_AppendResult(interp, " ", NULL); + } + sprintf(buffer,"%2.2x",ximagePtr->data[ximagePtr->bytes_per_line * iy + ix]&0xFF); + Tcl_AppendResult(interp, buffer, NULL); + } + Tcl_AppendResult(interp, " }", NULL); + } + Tcl_AppendResult(interp, " }", NULL); + } else + sprintf(buffer," NULL"); + sprintf(buffer,"%d",ximagePtr->byte_order); Tcl_AppendResult(interp, " byte_order ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->bitmap_unit); Tcl_AppendResult(interp, " bitmap_unit ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->bitmap_bit_order); Tcl_AppendResult(interp, " bitmap_bit_order ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->bitmap_pad); Tcl_AppendResult(interp, " bitmap_pad ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->depth); Tcl_AppendResult(interp, " depth ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->bytes_per_line); Tcl_AppendResult(interp, " bytes_per_line ", buffer, NULL); + sprintf(buffer,"%d",ximagePtr->bits_per_pixel); Tcl_AppendResult(interp, " bits_per_pixel ", buffer, NULL); + sprintf(buffer,"0x%8.8lx",ximagePtr->red_mask); Tcl_AppendResult(interp, " red_mask ", buffer, NULL); + sprintf(buffer,"0x%8.8lx",ximagePtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL); + sprintf(buffer,"0x%8.8lx",ximagePtr->blue_mask); Tcl_AppendResult(interp, " blue_mask ", buffer, NULL); + Tcl_AppendResult(interp, " }", NULL); + + Tcl_AppendResult(interp, "\nvisualPtr {", NULL); + sprintf(buffer,"0x%8.8lx",visualPtr->red_mask); Tcl_AppendResult(interp, " red_mask ", buffer, NULL); + sprintf(buffer,"0x%8.8lx",visualPtr->green_mask); Tcl_AppendResult(interp, " green_mask ", buffer, NULL); + sprintf(buffer,"0x%8.8lx",visualPtr->blue_mask); Tcl_AppendResult(interp, " blue_mask ", buffer, NULL); + Tcl_AppendResult(interp, " }", NULL); + +#endif + + /* + * Fill in the PhotoImageBlock structure abd allocate a block of memory + * for the converted image data. Note we allocate an alpha channel even + * though we don't use one, because this layout helps Tk_PhotoPutBlock() + * use memcpy() instead of the slow pixel or line copy. + */ + + blockPtr.width = cWidth; + blockPtr.height = cHeight; + blockPtr.pixelSize = 4; + blockPtr.pitch = blockPtr.pixelSize * blockPtr.width; + blockPtr.offset[0] = 0; + blockPtr.offset[1] = 1; + blockPtr.offset[2] = 2; + blockPtr.offset[3] = 3; + blockPtr.pixelPtr = ckalloc(blockPtr.pixelSize * blockPtr.height * blockPtr.width); + + /* + * Now convert the image data pixel by pixel from XImage to 32bit RGBA + * format suitable for Tk_PhotoPutBlock(). + */ + + DecomposeMaskToShiftAndBits(visualPtr->red_mask,&rshift,&rbits); + DecomposeMaskToShiftAndBits(visualPtr->green_mask,&gshift,&gbits); + DecomposeMaskToShiftAndBits(visualPtr->blue_mask,&bshift,&bbits); + +#ifdef DEBUG_DRAWCANVAS + sprintf(buffer,"%d",rshift); Tcl_AppendResult(interp, "\nbits { rshift ", buffer, NULL); + sprintf(buffer,"%d",gshift); Tcl_AppendResult(interp, " gshift ", buffer, NULL); + sprintf(buffer,"%d",bshift); Tcl_AppendResult(interp, " bshift ", buffer, NULL); + sprintf(buffer,"%d",rbits); Tcl_AppendResult(interp, " rbits ", buffer, NULL); + sprintf(buffer,"%d",gbits); Tcl_AppendResult(interp, " gbits ", buffer, NULL); + sprintf(buffer,"%d",bbits); Tcl_AppendResult(interp, " bbits ", buffer, " }", NULL); + Tcl_AppendResult(interp, "\nConverted_image {", NULL); +#endif + + /* Ok, had to use ximagePtr->bits_per_pixel here and in the switch (...) + * below to get this to work on Windows. X11 correctly sets the bitmap + *_pad and bitmap_unit fields to 32, but on Windows they are 0 and 8 + * respectively! + */ + + bytesPerPixel = ximagePtr->bits_per_pixel/8; + for (y = 0; y < blockPtr.height; ++y) { + +#ifdef DEBUG_DRAWCANVAS + Tcl_AppendResult(interp, " {", NULL); +#endif + + for(x = 0; x < blockPtr.width; ++x) { + unsigned long pixel = 0; + + switch (ximagePtr->bits_per_pixel) { + + /* + * Get an 8 bit pixel from the XImage. + */ + + case 8 : + pixel = *((unsigned char *)(ximagePtr->data + bytesPerPixel * x + + ximagePtr->bytes_per_line * y)); + break; + + /* + * Get a 16 bit pixel from the XImage, and correct the + * byte order as necessary. + */ + + case 16 : + pixel = *((unsigned short *)(ximagePtr->data + bytesPerPixel * x + + ximagePtr->bytes_per_line * y)); + if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst) + || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst)) + pixel = BYTE_SWAP16(pixel); + break; + + /* + * Grab a 32 bit pixel from the XImage, and correct the + * byte order as necessary. + */ + + case 32 : + pixel = *((unsigned long *)(ximagePtr->data + bytesPerPixel * x + + ximagePtr->bytes_per_line * y)); + if ((IS_BIG_ENDIAN && ximagePtr->byte_order == LSBFirst) + || (!IS_BIG_ENDIAN && ximagePtr->byte_order == MSBFirst)) + pixel = BYTE_SWAP32(pixel); + break; + } + + /* + * We have a pixel with the correct byte order, so pull out the + * colours and place them in the photo block. Perhaps we could + * just not bother with the alpha byte because we are using + * TK_PHOTO_COMPOSITE_SET later? + * ***Windows: We have to swap the red and blue values. The + * XImage storage is B - G - R - A which becomes a 32bit ARGB + * quad. However the visual mask is a 32bit ABGR quad. And + * Tk_PhotoPutBlock() wants R-G-B-A which is a 32bit ABGR quad. + * If the visual mask was correct there would be no need to + * swap anything here. + */ + +#ifdef _WIN32 +#define R_OFFSET 2 +#define B_OFFSET 0 +#else +#define R_OFFSET 0 +#define B_OFFSET 2 +#endif + blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + R_OFFSET] = + (unsigned char)((pixel & visualPtr->red_mask) >> rshift); + blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +1] = + (unsigned char)((pixel & visualPtr->green_mask) >> gshift); + blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x + B_OFFSET] = + (unsigned char)((pixel & visualPtr->blue_mask) >> bshift); + blockPtr.pixelPtr[blockPtr.pitch * y + blockPtr.pixelSize * x +3] = 0xFF; + +#ifdef DEBUG_DRAWCANVAS + { + int ix; + if (x > 0) + Tcl_AppendResult(interp, "-", NULL); + for (ix = 0; ix < 4; ++ix) { + if (ix > 0) + Tcl_AppendResult(interp, " ", NULL); + sprintf(buffer,"%2.2x",blockPtr.pixelPtr[blockPtr.pitch * y + + blockPtr.pixelSize * x + ix]&0xFF); + Tcl_AppendResult(interp, buffer, NULL); + } + } +#endif + + } + +#ifdef DEBUG_DRAWCANVAS + Tcl_AppendResult(interp, " }", NULL); +#endif + + } + +#ifdef DEBUG_DRAWCANVAS + Tcl_AppendResult(interp, " }", NULL); +#endif + + /* + * Now put the copied pixmap into the photo. + * If either zoom or subsample are not 1, we use the zoom function. + */ + + if (subsample != 1 || zoom != 1) { + if ((result = Tk_PhotoPutZoomedBlock(interp, photohandle, &blockPtr, + 0, 0, cWidth * zoom / subsample, cHeight * zoom / subsample, + zoom, zoom, subsample, subsample, TK_PHOTO_COMPOSITE_SET)) + != TCL_OK) { + goto done; + } + } else { + if ((result = Tk_PhotoPutBlock(interp, photohandle, &blockPtr, 0, 0, + cWidth, cHeight, TK_PHOTO_COMPOSITE_SET)) != TCL_OK) { + goto done; + } + } + + /* + * Clean up anything we have allocated and exit. + */ + +done: + if (blockPtr.pixelPtr) + ckfree(blockPtr.pixelPtr); + if (pixmap) + Tk_FreePixmap(Tk_Display(tkwin), pixmap); + if (ximagePtr) + XDestroyImage(ximagePtr); + if (xgc) + XFreeGC(displayPtr,xgc); + return result; +} + /* *---------------------------------------------------------------------- * * DisplayCanvas -- * Index: generic/tkClipboard.c ================================================================== --- generic/tkClipboard.c +++ generic/tkClipboard.c @@ -447,14 +447,15 @@ const char *string; static const char *const appendOptionStrings[] = { "-displayof", "-format", "-type", NULL }; enum appendOptions { APPEND_DISPLAYOF, APPEND_FORMAT, APPEND_TYPE }; - int subIndex, length; + int subIndex; + size_t length; for (i = 2; i < objc - 1; i++) { - string = Tcl_GetStringFromObj(objv[i], &length); + string = TkGetStringFromObj(objv[i], &length); if (string[0] != '-') { break; } /* Index: generic/tkCmds.c ================================================================== --- generic/tkCmds.c +++ generic/tkCmds.c @@ -99,10 +99,11 @@ "-displayof", "-nice", NULL }; enum options { TK_BELL_DISPLAYOF, TK_BELL_NICE }; Tk_Window tkwin = clientData; int i, index, nice = 0; + Tk_ErrorHandler handler; if (objc > 4) { wrongArgs: Tcl_WrongNumArgs(interp, 1, objv, "?-displayof window? ?-nice?"); return TCL_ERROR; @@ -126,15 +127,17 @@ case TK_BELL_NICE: nice = 1; break; } } + handler = Tk_CreateErrorHandler(Tk_Display(tkwin), -1, -1, -1, NULL, NULL); XBell(Tk_Display(tkwin), 0); if (!nice) { XForceScreenSaver(Tk_Display(tkwin), ScreenSaverReset); } XFlush(Tk_Display(tkwin)); + Tk_DeleteErrorHandler(handler); return TCL_OK; } /* *---------------------------------------------------------------------- @@ -2066,18 +2069,18 @@ * option to "-displayof" argument, or * unmodified if "-displayof" argument was not * present. */ { const char *string; - int length; + size_t length; if (objc < 1) { return 0; } - string = Tcl_GetStringFromObj(objv[0], &length); + string = TkGetStringFromObj(objv[0], &length); if ((length >= 2) && - (strncmp(string, "-displayof", (unsigned) length) == 0)) { + (strncmp(string, "-displayof", length) == 0)) { if (objc < 2) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "value for \"-displayof\" missing", -1)); Tcl_SetErrorCode(interp, "TK", "NO_VALUE", "DISPLAYOF", NULL); return -1; Index: generic/tkColor.c ================================================================== --- generic/tkColor.c +++ generic/tkColor.c @@ -478,12 +478,11 @@ if (tkColPtr->magic != COLOR_MAGIC) { Tcl_Panic("Tk_FreeColor called with bogus color"); } - tkColPtr->resourceRefCount--; - if (tkColPtr->resourceRefCount > 0) { + if (tkColPtr->resourceRefCount-- > 1) { return; } /* * This color is no longer being actively used, so free the color @@ -585,12 +584,11 @@ Tcl_Obj *objPtr) /* The object we are releasing. */ { TkColor *tkColPtr = objPtr->internalRep.twoPtrValue.ptr1; if (tkColPtr != NULL) { - tkColPtr->objRefCount--; - if ((tkColPtr->objRefCount == 0) + if ((tkColPtr->objRefCount-- <= 1) && (tkColPtr->resourceRefCount == 0)) { ckfree(tkColPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -818,13 +816,13 @@ } for ( ; (tkColPtr != NULL); tkColPtr = tkColPtr->nextPtr) { Tcl_Obj *objPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(tkColPtr->resourceRefCount)); + Tcl_NewWideIntObj(tkColPtr->resourceRefCount)); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(tkColPtr->objRefCount)); + Tcl_NewWideIntObj(tkColPtr->objRefCount)); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return resultPtr; } Index: generic/tkColor.h ================================================================== --- generic/tkColor.h +++ generic/tkColor.h @@ -36,21 +36,21 @@ Screen *screen; /* Screen where this color is valid. Used to * delete it, and to find its display. */ Colormap colormap; /* Colormap from which this entry was * allocated. */ Visual *visual; /* Visual associated with colormap. */ - int resourceRefCount; /* Number of active uses of this color (each + TkSizeT resourceRefCount; /* Number of active uses of this color (each * active use corresponds to a call to * Tk_AllocColorFromObj or Tk_GetColor). If * this count is 0, then this TkColor * structure is no longer valid and it isn't * present in a hash table: it is being kept * around only because there are objects * referring to it. The structure is freed * when resourceRefCount and objRefCount are * both 0. */ - int objRefCount; /* The number of Tcl objects that reference + TkSizeT objRefCount; /* The number of Tcl objects that reference * this structure. */ int type; /* TK_COLOR_BY_NAME or TK_COLOR_BY_VALUE. */ Tcl_HashEntry *hashPtr; /* Pointer to hash table entry for this * structure. (for use in deleting entry). */ struct TkColor *nextPtr; /* Points to the next TkColor structure with Index: generic/tkConfig.c ================================================================== --- generic/tkConfig.c +++ generic/tkConfig.c @@ -89,11 +89,11 @@ * One of the following exists for each Tk_OptionSpec array that has been * passed to Tk_CreateOptionTable. */ typedef struct OptionTable { - int refCount; /* Counts the number of uses of this table + size_t refCount; /* Counts the number of uses of this table * (the number of times Tk_CreateOptionTable * has returned it). This can be greater than * 1 if it is shared along several option * table chains, or if the same table is used * for multiple purposes. */ @@ -101,11 +101,11 @@ * used to delete the entry. */ struct OptionTable *nextPtr;/* If templatePtr was part of a chain of * templates, this points to the table * corresponding to the next template in the * chain. */ - int numOptions; /* The number of items in the options array + size_t numOptions; /* The number of items in the options array * below. */ Option options[1]; /* Information about the individual options in * the table. This must be the last field in * the structure: the actual size of the array * will be numOptions, not 1. */ @@ -113,18 +113,18 @@ /* * Forward declarations for functions defined later in this file: */ -static int DoObjConfig(Tcl_Interp *interp, char *recordPtr, +static int DoObjConfig(Tcl_Interp *interp, void *recordPtr, Option *optionPtr, Tcl_Obj *valuePtr, Tk_Window tkwin, Tk_SavedOption *savePtr); static void FreeResources(Option *optionPtr, Tcl_Obj *objPtr, - char *internalPtr, Tk_Window tkwin); -static Tcl_Obj * GetConfigList(char *recordPtr, + void *internalPtr, Tk_Window tkwin); +static Tcl_Obj * GetConfigList(void *recordPtr, Option *optionPtr, Tk_Window tkwin); -static Tcl_Obj * GetObjectForOption(char *recordPtr, +static Tcl_Obj * GetObjectForOption(void *recordPtr, Option *optionPtr, Tk_Window tkwin); static Option * GetOption(const char *name, OptionTable *tablePtr); static Option * GetOptionFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, OptionTable *tablePtr); static int ObjectIsEmpty(Tcl_Obj *objPtr); @@ -175,11 +175,11 @@ Tcl_HashEntry *hashEntryPtr; int newEntry; OptionTable *tablePtr; const Tk_OptionSpec *specPtr, *specPtr2; Option *optionPtr; - int numOptions, i; + size_t numOptions, i; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); /* * We use an TSD in the thread to keep a hash table of @@ -277,11 +277,11 @@ optionPtr->extra.custom = specPtr->clientData; } } if (((specPtr->type == TK_OPTION_STRING) - && (specPtr->internalOffset >= 0)) + && (specPtr->internalOffset != TCL_AUTO_LENGTH)) || (specPtr->type == TK_OPTION_COLOR) || (specPtr->type == TK_OPTION_FONT) || (specPtr->type == TK_OPTION_BITMAP) || (specPtr->type == TK_OPTION_BORDER) || (specPtr->type == TK_OPTION_CURSOR) @@ -328,14 +328,13 @@ Tk_DeleteOptionTable( Tk_OptionTable optionTable) /* The option table to delete. */ { OptionTable *tablePtr = (OptionTable *) optionTable; Option *optionPtr; - int count; + size_t count; - tablePtr->refCount--; - if (tablePtr->refCount > 0) { + if (tablePtr->refCount-- > 1) { return; } if (tablePtr->nextPtr != NULL) { Tk_DeleteOptionTable((Tk_OptionTable) tablePtr->nextPtr); @@ -380,11 +379,11 @@ int Tk_InitOptions( Tcl_Interp *interp, /* Interpreter for error reporting. NULL means * don't leave an error message. */ - char *recordPtr, /* Pointer to the record to configure. Note: + void *recordPtr, /* Pointer to the record to configure. Note: * the caller should have properly initialized * the record with NULL pointers for each * option value. */ Tk_OptionTable optionTable, /* The token which matches the config specs * for the widget in question. */ @@ -551,11 +550,11 @@ static int DoObjConfig( Tcl_Interp *interp, /* Interpreter for error reporting. If NULL, * then no message is left if an error * occurs. */ - char *recordPtr, /* The record to modify to hold the new option + void *recordPtr, /* The record to modify to hold the new option * value. */ Option *optionPtr, /* Pointer to information about the option. */ Tcl_Obj *valuePtr, /* New value for option. */ Tk_Window tkwin, /* Window in which option will be used (needed * to allocate resources for some options). @@ -567,14 +566,14 @@ * be stored here, and it becomes the property * of the caller (the caller must eventually * free the old value). */ { Tcl_Obj **slotPtrPtr, *oldPtr; - char *internalPtr; /* Points to location in record where internal + void *internalPtr; /* Points to location in record where internal * representation of value should be stored, * or NULL. */ - char *oldInternalPtr; /* Points to location in which to save old + void *oldInternalPtr; /* Points to location in which to save old * internal representation of value. */ Tk_SavedOption internal; /* Used to save the old internal * representation of the value if * savedOptionPtr is NULL. */ const Tk_OptionSpec *specPtr; @@ -583,12 +582,12 @@ /* * Save the old object form for the value, if there is one. */ specPtr = optionPtr->specPtr; - if (specPtr->objOffset >= 0) { - slotPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset); + if (specPtr->objOffset != TCL_AUTO_LENGTH) { + slotPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset); oldPtr = *slotPtrPtr; } else { slotPtrPtr = NULL; oldPtr = NULL; } @@ -596,12 +595,12 @@ /* * Apply the new value in a type-specific way. Also remember the old * object and internal forms, if they exist. */ - if (specPtr->internalOffset >= 0) { - internalPtr = recordPtr + specPtr->internalOffset; + if (specPtr->internalOffset != TCL_AUTO_LENGTH) { + internalPtr = (char *)recordPtr + specPtr->internalOffset; } else { internalPtr = NULL; } if (savedOptionPtr != NULL) { savedOptionPtr->optionPtr = optionPtr; @@ -655,18 +654,18 @@ break; } case TK_OPTION_STRING: { char *newStr; const char *value; - int length; + size_t length; if (nullOK && ObjectIsEmpty(valuePtr)) { valuePtr = NULL; } if (internalPtr != NULL) { if (valuePtr != NULL) { - value = Tcl_GetStringFromObj(valuePtr, &length); + value = TkGetStringFromObj(valuePtr, &length); newStr = ckalloc(length + 1); strcpy(newStr, value); } else { newStr = NULL; } @@ -935,20 +934,17 @@ static int ObjectIsEmpty( Tcl_Obj *objPtr) /* Object to test. May be NULL. */ { - int length; - if (objPtr == NULL) { return 1; } - if (objPtr->bytes != NULL) { - return (objPtr->length == 0); + if (objPtr->bytes == NULL) { + Tcl_GetString(objPtr); } - (void)Tcl_GetStringFromObj(objPtr, &length); - return (length == 0); + return (objPtr->length == 0); } /* *---------------------------------------------------------------------- * @@ -976,11 +972,11 @@ OptionTable *tablePtr) /* Table in which to look up name. */ { Option *bestPtr, *optionPtr; OptionTable *tablePtr2; const char *p1, *p2; - int count; + size_t count; /* * Search through all of the option tables in the chain to find the best * match. Some tricky aspects: * @@ -1224,11 +1220,11 @@ int Tk_SetOptions( Tcl_Interp *interp, /* Interpreter for error reporting. If NULL, * then no error message is returned.*/ - char *recordPtr, /* The record to configure. */ + void *recordPtr, /* The record to configure. */ Tk_OptionTable optionTable, /* Describes valid options. */ int objc, /* The number of elements in objv. */ Tcl_Obj *const objv[], /* Contains one or more name-value pairs. */ Tk_Window tkwin, /* Window associated with the thing being * configured; needed for some options (such @@ -1342,16 +1338,16 @@ void Tk_RestoreSavedOptions( Tk_SavedOptions *savePtr) /* Holds saved option information; must have * been passed to Tk_SetOptions. */ { - int i; + size_t i; Option *optionPtr; Tcl_Obj *newPtr; /* New object value of option, which we * replace with old value and free. Taken from * record. */ - char *internalPtr; /* Points to internal value of option in + void *internalPtr; /* Points to internal value of option in * record. */ const Tk_OptionSpec *specPtr; /* * Be sure to restore the options in the opposite order they were set. @@ -1362,26 +1358,26 @@ if (savePtr->nextPtr != NULL) { Tk_RestoreSavedOptions(savePtr->nextPtr); ckfree(savePtr->nextPtr); savePtr->nextPtr = NULL; } - for (i = savePtr->numItems - 1; i >= 0; i--) { + for (i = savePtr->numItems - 1; i != (size_t)-1; i--) { optionPtr = savePtr->items[i].optionPtr; specPtr = optionPtr->specPtr; /* * First free the new value of the option, which is currently in the * record. */ - if (specPtr->objOffset >= 0) { - newPtr = *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset)); + if (specPtr->objOffset != TCL_AUTO_LENGTH) { + newPtr = *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset)); } else { newPtr = NULL; } - if (specPtr->internalOffset >= 0) { - internalPtr = savePtr->recordPtr + specPtr->internalOffset; + if (specPtr->internalOffset != TCL_AUTO_LENGTH) { + internalPtr = (char *)savePtr->recordPtr + specPtr->internalOffset; } else { internalPtr = NULL; } if (optionPtr->flags & OPTION_NEEDS_FREEING) { FreeResources(optionPtr, newPtr, internalPtr, savePtr->tkwin); @@ -1392,15 +1388,15 @@ /* * Now restore the old value of the option. */ - if (specPtr->objOffset >= 0) { - *((Tcl_Obj **) (savePtr->recordPtr + specPtr->objOffset)) + if (specPtr->objOffset != TCL_AUTO_LENGTH) { + *((Tcl_Obj **) ((char *)savePtr->recordPtr + specPtr->objOffset)) = savePtr->items[i].valuePtr; } - if (specPtr->internalOffset >= 0) { + if (specPtr->internalOffset != TCL_AUTO_LENGTH) { register char *ptr = (char *) &savePtr->items[i].internalForm; CLANG_ASSERT(internalPtr); switch (specPtr->type) { case TK_OPTION_BOOLEAN: @@ -1489,11 +1485,11 @@ void Tk_FreeSavedOptions( Tk_SavedOptions *savePtr) /* Contains options saved in a previous call * to Tk_SetOptions. */ { - int count; + size_t count; Tk_SavedOption *savedOptionPtr; if (savePtr->nextPtr != NULL) { Tk_FreeSavedOptions(savePtr->nextPtr); ckfree(savePtr->nextPtr); @@ -1529,21 +1525,21 @@ */ /* ARGSUSED */ void Tk_FreeConfigOptions( - char *recordPtr, /* Record whose fields contain current values + void *recordPtr, /* Record whose fields contain current values * for options. */ Tk_OptionTable optionTable, /* Describes legal options. */ Tk_Window tkwin) /* Window associated with recordPtr; needed * for freeing some options. */ { OptionTable *tablePtr; Option *optionPtr; - int count; + size_t count; Tcl_Obj **oldPtrPtr, *oldPtr; - char *oldInternalPtr; + void *oldInternalPtr; const Tk_OptionSpec *specPtr; for (tablePtr = (OptionTable *) optionTable; tablePtr != NULL; tablePtr = tablePtr->nextPtr) { for (optionPtr = tablePtr->options, count = tablePtr->numOptions; @@ -1550,19 +1546,19 @@ count > 0; optionPtr++, count--) { specPtr = optionPtr->specPtr; if (specPtr->type == TK_OPTION_SYNONYM) { continue; } - if (specPtr->objOffset >= 0) { - oldPtrPtr = (Tcl_Obj **) (recordPtr + specPtr->objOffset); + if (specPtr->objOffset != TCL_AUTO_LENGTH) { + oldPtrPtr = (Tcl_Obj **) ((char *)recordPtr + specPtr->objOffset); oldPtr = *oldPtrPtr; *oldPtrPtr = NULL; } else { oldPtr = NULL; } - if (specPtr->internalOffset >= 0) { - oldInternalPtr = recordPtr + specPtr->internalOffset; + if (specPtr->internalOffset != TCL_AUTO_LENGTH) { + oldInternalPtr = (char *)recordPtr + specPtr->internalOffset; } else { oldInternalPtr = NULL; } if (optionPtr->flags & OPTION_NEEDS_FREEING) { FreeResources(optionPtr, oldPtr, oldInternalPtr, tkwin); @@ -1595,14 +1591,14 @@ static void FreeResources( Option *optionPtr, /* Description of the configuration option. */ Tcl_Obj *objPtr, /* The current value of the option, specified * as an object. */ - char *internalPtr, /* A pointer to an internal representation for + void *internalPtr, /* A pointer to an internal representation for * the option's value, such as an int or * (XColor *). Only valid if - * optionPtr->specPtr->internalOffset >= 0. */ + * optionPtr->specPtr->internalOffset != -1. */ Tk_Window tkwin) /* The window in which this option is used. */ { int internalFormExists; /* @@ -1609,11 +1605,11 @@ * If there exists an internal form for the value, use it to free * resources (also zero out the internal form). If there is no internal * form, then use the object form. */ - internalFormExists = optionPtr->specPtr->internalOffset >= 0; + internalFormExists = optionPtr->specPtr->internalOffset != TCL_AUTO_LENGTH; switch (optionPtr->specPtr->type) { case TK_OPTION_STRING: if (internalFormExists) { if (*((char **) internalPtr) != NULL) { ckfree(*((char **) internalPtr)); @@ -1641,12 +1637,10 @@ break; case TK_OPTION_STYLE: if (internalFormExists) { Tk_FreeStyle(*((Tk_Style *) internalPtr)); *((Tk_Style *) internalPtr) = NULL; - } else if (objPtr != NULL) { - Tk_FreeStyleFromObj(objPtr); } break; case TK_OPTION_BITMAP: if (internalFormExists) { if (*((Pixmap *) internalPtr) != None) { @@ -1717,11 +1711,11 @@ Tcl_Obj * Tk_GetOptionInfo( Tcl_Interp *interp, /* Interpreter for error reporting. If NULL, * then no error message is created. */ - char *recordPtr, /* Record whose fields contain current values + void *recordPtr, /* Record whose fields contain current values * for options. */ Tk_OptionTable optionTable, /* Describes all the legal options. */ Tcl_Obj *namePtr, /* If non-NULL, the string value selects a * single option whose info is to be returned. * Otherwise info is returned for all options @@ -1731,11 +1725,11 @@ * options. */ { Tcl_Obj *resultPtr; OptionTable *tablePtr = (OptionTable *) optionTable; Option *optionPtr; - int count; + size_t count; /* * If information is only wanted for a single configuration spec, then * handle that one spec specially. */ @@ -1785,11 +1779,11 @@ *-------------------------------------------------------------- */ static Tcl_Obj * GetConfigList( - char *recordPtr, /* Pointer to record holding current values of + void *recordPtr, /* Pointer to record holding current values of * configuration options. */ Option *optionPtr, /* Pointer to information describing a * particular option. */ Tk_Window tkwin) /* Window corresponding to recordPtr. */ { @@ -1828,12 +1822,12 @@ } else { elementPtr = Tcl_NewObj(); } Tcl_ListObjAppendElement(NULL, listPtr, elementPtr); - if (optionPtr->specPtr->objOffset >= 0) { - elementPtr = *((Tcl_Obj **) (recordPtr + if (optionPtr->specPtr->objOffset != TCL_AUTO_LENGTH) { + elementPtr = *((Tcl_Obj **) ((char *)recordPtr + optionPtr->specPtr->objOffset)); if (elementPtr == NULL) { elementPtr = Tcl_NewObj(); } } else { @@ -1863,22 +1857,22 @@ *---------------------------------------------------------------------- */ static Tcl_Obj * GetObjectForOption( - char *recordPtr, /* Pointer to record holding current values of + void *recordPtr, /* Pointer to record holding current values of * configuration options. */ Option *optionPtr, /* Pointer to information describing an option * whose internal value is stored in * *recordPtr. */ Tk_Window tkwin) /* Window corresponding to recordPtr. */ { Tcl_Obj *objPtr; - char *internalPtr; /* Points to internal value of option in + void *internalPtr; /* Points to internal value of option in * record. */ - internalPtr = recordPtr + optionPtr->specPtr->internalOffset; + internalPtr = (char *)recordPtr + optionPtr->specPtr->internalOffset; objPtr = NULL; switch (optionPtr->specPtr->type) { case TK_OPTION_BOOLEAN: objPtr = Tcl_NewIntObj(*((int *) internalPtr)); break; @@ -2005,11 +1999,11 @@ Tcl_Obj * Tk_GetOptionValue( Tcl_Interp *interp, /* Interpreter for error reporting. If NULL * then no messages are provided for * errors. */ - char *recordPtr, /* Record whose fields contain current values + void *recordPtr, /* Record whose fields contain current values * for options. */ Tk_OptionTable optionTable, /* Describes legal options. */ Tcl_Obj *namePtr, /* Gives the command-line name for the option * whose value is to be returned. */ Tk_Window tkwin) /* Window corresponding to recordPtr. */ @@ -2023,12 +2017,12 @@ return NULL; } if (optionPtr->specPtr->type == TK_OPTION_SYNONYM) { optionPtr = optionPtr->extra.synonymPtr; } - if (optionPtr->specPtr->objOffset >= 0) { - resultPtr = *((Tcl_Obj **) (recordPtr+optionPtr->specPtr->objOffset)); + if (optionPtr->specPtr->objOffset != TCL_AUTO_LENGTH) { + resultPtr = *((Tcl_Obj **) ((char *)recordPtr+optionPtr->specPtr->objOffset)); if (resultPtr == NULL) { /* * This option has a null value and is represented by a null * object pointer. We can't return the null pointer, since that * would indicate an error. Instead, return a new empty object. @@ -2094,13 +2088,13 @@ hashEntryPtr != NULL; hashEntryPtr = Tcl_NextHashEntry(&search)) { if (tablePtr == (OptionTable *) Tcl_GetHashValue(hashEntryPtr)) { for ( ; tablePtr != NULL; tablePtr = tablePtr->nextPtr) { Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(tablePtr->refCount)); + Tcl_NewWideIntObj(tablePtr->refCount)); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(tablePtr->numOptions)); + Tcl_NewWideIntObj(tablePtr->numOptions)); Tcl_ListObjAppendElement(NULL, objPtr, Tcl_NewStringObj( tablePtr->options[0].specPtr->optionName, -1)); } break; } Index: generic/tkConsole.c ================================================================== --- generic/tkConsole.c +++ generic/tkConsole.c @@ -22,11 +22,11 @@ */ typedef struct ConsoleInfo { Tcl_Interp *consoleInterp; /* Interpreter displaying the console. */ Tcl_Interp *interp; /* Interpreter controlled by console. */ - int refCount; + size_t refCount; } ConsoleInfo; /* * Each console channel holds an instance of the ChannelData struct as * its instance data. It contains ConsoleInfo, so the channel can work @@ -221,11 +221,11 @@ /* * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return; } consoleInitPtr = Tcl_GetThreadData(&consoleInitKey, (int) sizeof(int)); if (*consoleInitPtr) { @@ -316,11 +316,11 @@ *---------------------------------------------------------------------- * * Tk_CreateConsoleWindow -- * * Initialize the console. This code actually creates a new application - * and associated interpreter. This effectivly hides the implementation + * and associated interpreter. This effectively hides the implementation * from the main application. * * Results: * None. * @@ -342,13 +342,17 @@ int haveConsoleChannel = 1; /* Init an interp with Tcl and Tk */ Tcl_Interp *consoleInterp = Tcl_CreateInterp(); if (Tcl_Init(consoleInterp) != TCL_OK) { + Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp); + Tcl_SetObjResult(interp, result_obj); goto error; } if (Tk_Init(consoleInterp) != TCL_OK) { + Tcl_Obj *result_obj = Tcl_GetObjResult(consoleInterp); + Tcl_SetObjResult(interp, result_obj); goto error; } /* * Fetch the instance data from whatever std channel is a @@ -450,11 +454,11 @@ Tcl_DeleteCommandFromToken(interp, token); mainWindow = Tk_MainWindow(interp); if (mainWindow) { Tk_DeleteEventHandler(mainWindow, StructureNotifyMask, ConsoleEventProc, info); - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } goto error; } @@ -590,11 +594,11 @@ { ChannelData *data = instanceData; ConsoleInfo *info = data->info; if (info) { - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { /* * Assuming the Tcl_Interp * fields must already be NULL. */ ckfree(info); @@ -879,11 +883,11 @@ if (info->consoleInterp == interp) { Tcl_DeleteThreadExitHandler(DeleteConsoleInterp, info->consoleInterp); info->consoleInterp = NULL; } - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } /* @@ -910,11 +914,11 @@ ConsoleInfo *info = clientData; if (info->consoleInterp) { Tcl_DeleteInterp(info->consoleInterp); } - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } /* @@ -947,11 +951,11 @@ if (consoleInterp && !Tcl_InterpDeleted(consoleInterp)) { Tcl_EvalEx(consoleInterp, "tk::ConsoleExit", -1, TCL_EVAL_GLOBAL); } - if (--info->refCount <= 0) { + if (info->refCount-- <= 1) { ckfree(info); } } } Index: generic/tkCursor.c ================================================================== --- generic/tkCursor.c +++ generic/tkCursor.c @@ -461,12 +461,11 @@ FreeCursor( TkCursor *cursorPtr) /* Cursor to be released. */ { TkCursor *prevPtr; - cursorPtr->resourceRefCount--; - if (cursorPtr->resourceRefCount > 0) { + if (cursorPtr->resourceRefCount-- > 1) { return; } Tcl_DeleteHashEntry(cursorPtr->idHashPtr); prevPtr = Tcl_GetHashValue(cursorPtr->hashPtr); @@ -588,12 +587,11 @@ Tcl_Obj *objPtr) /* The object we are releasing. */ { TkCursor *cursorPtr = objPtr->internalRep.twoPtrValue.ptr1; if (cursorPtr != NULL) { - cursorPtr->objRefCount--; - if ((cursorPtr->objRefCount == 0) + if ((cursorPtr->objRefCount-- <= 1) && (cursorPtr->resourceRefCount == 0)) { ckfree(cursorPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; } @@ -862,13 +860,13 @@ Tcl_Panic("TkDebugCursor found empty hash table entry"); } for ( ; (cursorPtr != NULL); cursorPtr = cursorPtr->nextPtr) { objPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(cursorPtr->resourceRefCount)); + Tcl_NewWideIntObj(cursorPtr->resourceRefCount)); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(cursorPtr->objRefCount)); + Tcl_NewWideIntObj(cursorPtr->objRefCount)); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return resultPtr; } Index: generic/tkDecls.h ================================================================== --- generic/tkDecls.h +++ generic/tkDecls.h @@ -15,10 +15,18 @@ #ifdef BUILD_tk #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLEXPORT #endif +#if !defined(BUILD_tk) +# define TK_DEPRECATED(msg) EXTERN TCL_DEPRECATED_API(msg) +#elif defined(TK_NO_DEPRECATED) +# define TK_DEPRECATED(msg) MODULE_SCOPE +#else +# define TK_DEPRECATED(msg) EXTERN +#endif + /* * WARNING: This file is automatically generated by the tools/genStubs.tcl * script. Any modifications to the function declarations below should be made * in the generic/tk.decls script. */ @@ -93,11 +101,11 @@ /* 18 */ EXTERN int Tk_CanvasTagsParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 19 */ -EXTERN CONST86 char * Tk_CanvasTagsPrintProc(ClientData clientData, +EXTERN const char * Tk_CanvasTagsPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 20 */ EXTERN Tk_Window Tk_CanvasTkwin(Tk_Canvas canvas); /* 21 */ @@ -131,11 +139,11 @@ char *widgRec, const char *argvName, int flags); /* 29 */ EXTERN int Tk_ConfigureWidget(Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, - int argc, CONST84 char **argv, char *widgRec, + int argc, const char **argv, char *widgRec, int flags); /* 30 */ EXTERN void Tk_ConfigureWindow(Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); @@ -213,11 +221,11 @@ EXTERN void Tk_DeleteSelHandler(Tk_Window tkwin, Atom selection, Atom target); /* 54 */ EXTERN void Tk_DestroyWindow(Tk_Window tkwin); /* 55 */ -EXTERN CONST84_RETURN char * Tk_DisplayName(Tk_Window tkwin); +EXTERN const char * Tk_DisplayName(Tk_Window tkwin); /* 56 */ EXTERN int Tk_DistanceToTextLayout(Tk_TextLayout layout, int x, int y); /* 57 */ EXTERN void Tk_Draw3DPolygon(Tk_Window tkwin, Drawable drawable, @@ -279,11 +287,12 @@ /* 75 */ EXTERN void Tk_FreePixmap(Display *display, Pixmap pixmap); /* 76 */ EXTERN void Tk_FreeTextLayout(Tk_TextLayout textLayout); /* 77 */ -EXTERN void Tk_FreeXId(Display *display, XID xid); +TK_DEPRECATED("function does nothing, call can be removed") +void Tk_FreeXId(Display *display, XID xid); /* 78 */ EXTERN GC Tk_GCForColor(XColor *colorPtr, Drawable drawable); /* 79 */ EXTERN void Tk_GeometryRequest(Tk_Window tkwin, int reqWidth, int reqHeight); @@ -296,13 +305,13 @@ ClientData object); /* 82 */ EXTERN int Tk_GetAnchor(Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); /* 83 */ -EXTERN CONST84_RETURN char * Tk_GetAtomName(Tk_Window tkwin, Atom atom); +EXTERN const char * Tk_GetAtomName(Tk_Window tkwin, Atom atom); /* 84 */ -EXTERN CONST84_RETURN char * Tk_GetBinding(Tcl_Interp *interp, +EXTERN const char * Tk_GetBinding(Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 85 */ EXTERN Pixmap Tk_GetBitmap(Tcl_Interp *interp, Tk_Window tkwin, const char *str); @@ -346,11 +355,11 @@ Tk_ImageChangedProc *changeProc, ClientData clientData); /* 98 */ EXTERN ClientData Tk_GetImageMasterData(Tcl_Interp *interp, const char *name, - CONST86 Tk_ImageType **typePtrPtr); + const Tk_ImageType **typePtrPtr); /* 99 */ EXTERN Tk_ItemType * Tk_GetItemTypes(void); /* 100 */ EXTERN int Tk_GetJoinStyle(Tcl_Interp *interp, const char *str, int *joinPtr); @@ -374,11 +383,11 @@ /* 107 */ EXTERN void Tk_GetRootCoords(Tk_Window tkwin, int *xPtr, int *yPtr); /* 108 */ EXTERN int Tk_GetScrollInfo(Tcl_Interp *interp, int argc, - CONST84 char **argv, double *dblPtr, + const char **argv, double *dblPtr, int *intPtr); /* 109 */ EXTERN int Tk_GetScreenMM(Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr); /* 110 */ @@ -436,48 +445,49 @@ /* 128 */ EXTERN void Tk_MoveWindow(Tk_Window tkwin, int x, int y); /* 129 */ EXTERN void Tk_MoveToplevelWindow(Tk_Window tkwin, int x, int y); /* 130 */ -EXTERN CONST84_RETURN char * Tk_NameOf3DBorder(Tk_3DBorder border); +EXTERN const char * Tk_NameOf3DBorder(Tk_3DBorder border); /* 131 */ -EXTERN CONST84_RETURN char * Tk_NameOfAnchor(Tk_Anchor anchor); +EXTERN const char * Tk_NameOfAnchor(Tk_Anchor anchor); /* 132 */ -EXTERN CONST84_RETURN char * Tk_NameOfBitmap(Display *display, Pixmap bitmap); +EXTERN const char * Tk_NameOfBitmap(Display *display, Pixmap bitmap); /* 133 */ -EXTERN CONST84_RETURN char * Tk_NameOfCapStyle(int cap); +EXTERN const char * Tk_NameOfCapStyle(int cap); /* 134 */ -EXTERN CONST84_RETURN char * Tk_NameOfColor(XColor *colorPtr); +EXTERN const char * Tk_NameOfColor(XColor *colorPtr); /* 135 */ -EXTERN CONST84_RETURN char * Tk_NameOfCursor(Display *display, - Tk_Cursor cursor); +EXTERN const char * Tk_NameOfCursor(Display *display, Tk_Cursor cursor); /* 136 */ -EXTERN CONST84_RETURN char * Tk_NameOfFont(Tk_Font font); +EXTERN const char * Tk_NameOfFont(Tk_Font font); /* 137 */ -EXTERN CONST84_RETURN char * Tk_NameOfImage(Tk_ImageMaster imageMaster); +EXTERN const char * Tk_NameOfImage(Tk_ImageMaster imageMaster); /* 138 */ -EXTERN CONST84_RETURN char * Tk_NameOfJoinStyle(int join); +EXTERN const char * Tk_NameOfJoinStyle(int join); /* 139 */ -EXTERN CONST84_RETURN char * Tk_NameOfJustify(Tk_Justify justify); +EXTERN const char * Tk_NameOfJustify(Tk_Justify justify); /* 140 */ -EXTERN CONST84_RETURN char * Tk_NameOfRelief(int relief); +EXTERN const char * Tk_NameOfRelief(int relief); /* 141 */ EXTERN Tk_Window Tk_NameToWindow(Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 142 */ EXTERN void Tk_OwnSelection(Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 143 */ EXTERN int Tk_ParseArgv(Tcl_Interp *interp, Tk_Window tkwin, - int *argcPtr, CONST84 char **argv, + int *argcPtr, const char **argv, const Tk_ArgvInfo *argTable, int flags); /* 144 */ -EXTERN void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutBlock_NoComposite(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 145 */ -EXTERN void Tk_PhotoPutZoomedBlock_NoComposite( +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutZoomedBlock_NoComposite( Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 146 */ @@ -484,17 +494,19 @@ EXTERN int Tk_PhotoGetImage(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 147 */ EXTERN void Tk_PhotoBlank(Tk_PhotoHandle handle); /* 148 */ -EXTERN void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoExpand_Panic(Tk_PhotoHandle handle, int width, int height); /* 149 */ EXTERN void Tk_PhotoGetSize(Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 150 */ -EXTERN void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoSetSize_Panic(Tk_PhotoHandle handle, int width, int height); /* 151 */ EXTERN int Tk_PointToChar(Tk_TextLayout layout, int x, int y); /* 152 */ EXTERN int Tk_PostscriptFontName(Tk_Font tkfont, @@ -618,11 +630,11 @@ EXTERN void Tk_FreeBitmapFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); /* 194 */ EXTERN void Tk_FreeColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); /* 195 */ -EXTERN void Tk_FreeConfigOptions(char *recordPtr, +EXTERN void Tk_FreeConfigOptions(void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 196 */ EXTERN void Tk_FreeSavedOptions(Tk_SavedOptions *savePtr); /* 197 */ EXTERN void Tk_FreeCursorFromObj(Tk_Window tkwin, @@ -640,16 +652,16 @@ /* 202 */ EXTERN XColor * Tk_GetColorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */ EXTERN Tk_Cursor Tk_GetCursorFromObj(Tk_Window tkwin, Tcl_Obj *objPtr); /* 204 */ -EXTERN Tcl_Obj * Tk_GetOptionInfo(Tcl_Interp *interp, char *recordPtr, +EXTERN Tcl_Obj * Tk_GetOptionInfo(Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */ EXTERN Tcl_Obj * Tk_GetOptionValue(Tcl_Interp *interp, - char *recordPtr, Tk_OptionTable optionTable, + void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 206 */ EXTERN int Tk_GetJustifyFromObj(Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 207 */ @@ -665,20 +677,20 @@ /* 210 */ EXTERN int Tk_GetScrollInfoObj(Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 211 */ -EXTERN int Tk_InitOptions(Tcl_Interp *interp, char *recordPtr, +EXTERN int Tk_InitOptions(Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 212 */ EXTERN void Tk_MainEx(int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 213 */ EXTERN void Tk_RestoreSavedOptions(Tk_SavedOptions *savePtr); /* 214 */ -EXTERN int Tk_SetOptions(Tcl_Interp *interp, char *recordPtr, +EXTERN int Tk_SetOptions(Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 215 */ EXTERN void Tk_InitConsoleChannels(Tcl_Interp *interp); @@ -774,15 +786,17 @@ int minWidth, int minHeight); /* 245 */ EXTERN void Tk_SetCaretPos(Tk_Window tkwin, int x, int y, int height); /* 246 */ -EXTERN void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 247 */ -EXTERN void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle, +TK_DEPRECATED("function signature changed") +void Tk_PhotoPutZoomedBlock_Panic(Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 248 */ EXTERN int Tk_CollapseMotionEvents(Display *display, @@ -816,26 +830,26 @@ /* 260 */ EXTERN Tk_StyledElement Tk_GetStyledElement(Tk_Style style, int elementId, Tk_OptionTable optionTable); /* 261 */ EXTERN void Tk_GetElementSize(Tk_Style style, - Tk_StyledElement element, char *recordPtr, + Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 262 */ EXTERN void Tk_GetElementBox(Tk_Style style, - Tk_StyledElement element, char *recordPtr, + Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 263 */ EXTERN int Tk_GetElementBorderWidth(Tk_Style style, - Tk_StyledElement element, char *recordPtr, + Tk_StyledElement element, void *recordPtr, Tk_Window tkwin); /* 264 */ EXTERN void Tk_DrawElement(Tk_Style style, - Tk_StyledElement element, char *recordPtr, + Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 265 */ EXTERN int Tk_PhotoExpand(Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); @@ -893,21 +907,21 @@ void (*tk_CanvasPsPath) (Tcl_Interp *interp, Tk_Canvas canvas, double *coordPtr, int numPoints); /* 14 */ int (*tk_CanvasPsStipple) (Tcl_Interp *interp, Tk_Canvas canvas, Pixmap bitmap); /* 15 */ double (*tk_CanvasPsY) (Tk_Canvas canvas, double y); /* 16 */ void (*tk_CanvasSetStippleOrigin) (Tk_Canvas canvas, GC gc); /* 17 */ int (*tk_CanvasTagsParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 18 */ - CONST86 char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */ + const char * (*tk_CanvasTagsPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 19 */ Tk_Window (*tk_CanvasTkwin) (Tk_Canvas canvas); /* 20 */ void (*tk_CanvasWindowCoords) (Tk_Canvas canvas, double x, double y, short *screenXPtr, short *screenYPtr); /* 21 */ void (*tk_ChangeWindowAttributes) (Tk_Window tkwin, unsigned long valueMask, XSetWindowAttributes *attsPtr); /* 22 */ int (*tk_CharBbox) (Tk_TextLayout layout, int index, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 23 */ void (*tk_ClearSelection) (Tk_Window tkwin, Atom selection); /* 24 */ int (*tk_ClipboardAppend) (Tcl_Interp *interp, Tk_Window tkwin, Atom target, Atom format, const char *buffer); /* 25 */ int (*tk_ClipboardClear) (Tcl_Interp *interp, Tk_Window tkwin); /* 26 */ int (*tk_ConfigureInfo) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 27 */ int (*tk_ConfigureValue) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, char *widgRec, const char *argvName, int flags); /* 28 */ - int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, CONST84 char **argv, char *widgRec, int flags); /* 29 */ + int (*tk_ConfigureWidget) (Tcl_Interp *interp, Tk_Window tkwin, const Tk_ConfigSpec *specs, int argc, const char **argv, char *widgRec, int flags); /* 29 */ void (*tk_ConfigureWindow) (Tk_Window tkwin, unsigned int valueMask, XWindowChanges *valuePtr); /* 30 */ Tk_TextLayout (*tk_ComputeTextLayout) (Tk_Font font, const char *str, int numChars, int wrapLength, Tk_Justify justify, int flags, int *widthPtr, int *heightPtr); /* 31 */ Tk_Window (*tk_CoordsToWindow) (int rootX, int rootY, Tk_Window tkwin); /* 32 */ unsigned long (*tk_CreateBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr, const char *script, int append); /* 33 */ Tk_BindingTable (*tk_CreateBindingTable) (Tcl_Interp *interp); /* 34 */ @@ -929,11 +943,11 @@ void (*tk_DeleteEventHandler) (Tk_Window token, unsigned long mask, Tk_EventProc *proc, ClientData clientData); /* 50 */ void (*tk_DeleteGenericHandler) (Tk_GenericProc *proc, ClientData clientData); /* 51 */ void (*tk_DeleteImage) (Tcl_Interp *interp, const char *name); /* 52 */ void (*tk_DeleteSelHandler) (Tk_Window tkwin, Atom selection, Atom target); /* 53 */ void (*tk_DestroyWindow) (Tk_Window tkwin); /* 54 */ - CONST84_RETURN char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */ + const char * (*tk_DisplayName) (Tk_Window tkwin); /* 55 */ int (*tk_DistanceToTextLayout) (Tk_TextLayout layout, int x, int y); /* 56 */ void (*tk_Draw3DPolygon) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, XPoint *pointPtr, int numPoints, int borderWidth, int leftRelief); /* 57 */ void (*tk_Draw3DRectangle) (Tk_Window tkwin, Drawable drawable, Tk_3DBorder border, int x, int y, int width, int height, int borderWidth, int relief); /* 58 */ void (*tk_DrawChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, int x, int y); /* 59 */ void (*tk_DrawFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable); /* 60 */ @@ -951,18 +965,18 @@ void (*tk_FreeGC) (Display *display, GC gc); /* 72 */ void (*tk_FreeImage) (Tk_Image image); /* 73 */ void (*tk_FreeOptions) (const Tk_ConfigSpec *specs, char *widgRec, Display *display, int needFlags); /* 74 */ void (*tk_FreePixmap) (Display *display, Pixmap pixmap); /* 75 */ void (*tk_FreeTextLayout) (Tk_TextLayout textLayout); /* 76 */ - void (*tk_FreeXId) (Display *display, XID xid); /* 77 */ + TCL_DEPRECATED_API("function does nothing, call can be removed") void (*tk_FreeXId) (Display *display, XID xid); /* 77 */ GC (*tk_GCForColor) (XColor *colorPtr, Drawable drawable); /* 78 */ void (*tk_GeometryRequest) (Tk_Window tkwin, int reqWidth, int reqHeight); /* 79 */ Tk_3DBorder (*tk_Get3DBorder) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid colorName); /* 80 */ void (*tk_GetAllBindings) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object); /* 81 */ int (*tk_GetAnchor) (Tcl_Interp *interp, const char *str, Tk_Anchor *anchorPtr); /* 82 */ - CONST84_RETURN char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */ - CONST84_RETURN char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 84 */ + const char * (*tk_GetAtomName) (Tk_Window tkwin, Atom atom); /* 83 */ + const char * (*tk_GetBinding) (Tcl_Interp *interp, Tk_BindingTable bindingTable, ClientData object, const char *eventStr); /* 84 */ Pixmap (*tk_GetBitmap) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 85 */ Pixmap (*tk_GetBitmapFromData) (Tcl_Interp *interp, Tk_Window tkwin, const void *source, int width, int height); /* 86 */ int (*tk_GetCapStyle) (Tcl_Interp *interp, const char *str, int *capPtr); /* 87 */ XColor * (*tk_GetColor) (Tcl_Interp *interp, Tk_Window tkwin, Tk_Uid name); /* 88 */ XColor * (*tk_GetColorByValue) (Tk_Window tkwin, XColor *colorPtr); /* 89 */ @@ -972,21 +986,21 @@ Tk_Font (*tk_GetFont) (Tcl_Interp *interp, Tk_Window tkwin, const char *str); /* 93 */ Tk_Font (*tk_GetFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 94 */ void (*tk_GetFontMetrics) (Tk_Font font, Tk_FontMetrics *fmPtr); /* 95 */ GC (*tk_GetGC) (Tk_Window tkwin, unsigned long valueMask, XGCValues *valuePtr); /* 96 */ Tk_Image (*tk_GetImage) (Tcl_Interp *interp, Tk_Window tkwin, const char *name, Tk_ImageChangedProc *changeProc, ClientData clientData); /* 97 */ - ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, const char *name, CONST86 Tk_ImageType **typePtrPtr); /* 98 */ + ClientData (*tk_GetImageMasterData) (Tcl_Interp *interp, const char *name, const Tk_ImageType **typePtrPtr); /* 98 */ Tk_ItemType * (*tk_GetItemTypes) (void); /* 99 */ int (*tk_GetJoinStyle) (Tcl_Interp *interp, const char *str, int *joinPtr); /* 100 */ int (*tk_GetJustify) (Tcl_Interp *interp, const char *str, Tk_Justify *justifyPtr); /* 101 */ int (*tk_GetNumMainWindows) (void); /* 102 */ Tk_Uid (*tk_GetOption) (Tk_Window tkwin, const char *name, const char *className); /* 103 */ int (*tk_GetPixels) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *intPtr); /* 104 */ Pixmap (*tk_GetPixmap) (Display *display, Drawable d, int width, int height, int depth); /* 105 */ int (*tk_GetRelief) (Tcl_Interp *interp, const char *name, int *reliefPtr); /* 106 */ void (*tk_GetRootCoords) (Tk_Window tkwin, int *xPtr, int *yPtr); /* 107 */ - int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, CONST84 char **argv, double *dblPtr, int *intPtr); /* 108 */ + int (*tk_GetScrollInfo) (Tcl_Interp *interp, int argc, const char **argv, double *dblPtr, int *intPtr); /* 108 */ int (*tk_GetScreenMM) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, double *doublePtr); /* 109 */ int (*tk_GetSelection) (Tcl_Interp *interp, Tk_Window tkwin, Atom selection, Atom target, Tk_GetSelProc *proc, ClientData clientData); /* 110 */ Tk_Uid (*tk_GetUid) (const char *str); /* 111 */ Visual * (*tk_GetVisual) (Tcl_Interp *interp, Tk_Window tkwin, const char *str, int *depthPtr, Colormap *colormapPtr); /* 112 */ void (*tk_GetVRootGeometry) (Tk_Window tkwin, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 113 */ @@ -1004,31 +1018,31 @@ void (*tk_MapWindow) (Tk_Window tkwin); /* 125 */ int (*tk_MeasureChars) (Tk_Font tkfont, const char *source, int numBytes, int maxPixels, int flags, int *lengthPtr); /* 126 */ void (*tk_MoveResizeWindow) (Tk_Window tkwin, int x, int y, int width, int height); /* 127 */ void (*tk_MoveWindow) (Tk_Window tkwin, int x, int y); /* 128 */ void (*tk_MoveToplevelWindow) (Tk_Window tkwin, int x, int y); /* 129 */ - CONST84_RETURN char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */ - CONST84_RETURN char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */ - CONST84_RETURN char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */ - CONST84_RETURN char * (*tk_NameOfCapStyle) (int cap); /* 133 */ - CONST84_RETURN char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */ - CONST84_RETURN char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */ - CONST84_RETURN char * (*tk_NameOfFont) (Tk_Font font); /* 136 */ - CONST84_RETURN char * (*tk_NameOfImage) (Tk_ImageMaster imageMaster); /* 137 */ - CONST84_RETURN char * (*tk_NameOfJoinStyle) (int join); /* 138 */ - CONST84_RETURN char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */ - CONST84_RETURN char * (*tk_NameOfRelief) (int relief); /* 140 */ + const char * (*tk_NameOf3DBorder) (Tk_3DBorder border); /* 130 */ + const char * (*tk_NameOfAnchor) (Tk_Anchor anchor); /* 131 */ + const char * (*tk_NameOfBitmap) (Display *display, Pixmap bitmap); /* 132 */ + const char * (*tk_NameOfCapStyle) (int cap); /* 133 */ + const char * (*tk_NameOfColor) (XColor *colorPtr); /* 134 */ + const char * (*tk_NameOfCursor) (Display *display, Tk_Cursor cursor); /* 135 */ + const char * (*tk_NameOfFont) (Tk_Font font); /* 136 */ + const char * (*tk_NameOfImage) (Tk_ImageMaster imageMaster); /* 137 */ + const char * (*tk_NameOfJoinStyle) (int join); /* 138 */ + const char * (*tk_NameOfJustify) (Tk_Justify justify); /* 139 */ + const char * (*tk_NameOfRelief) (int relief); /* 140 */ Tk_Window (*tk_NameToWindow) (Tcl_Interp *interp, const char *pathName, Tk_Window tkwin); /* 141 */ void (*tk_OwnSelection) (Tk_Window tkwin, Atom selection, Tk_LostSelProc *proc, ClientData clientData); /* 142 */ - int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, CONST84 char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */ - void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */ - void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */ + int (*tk_ParseArgv) (Tcl_Interp *interp, Tk_Window tkwin, int *argcPtr, const char **argv, const Tk_ArgvInfo *argTable, int flags); /* 143 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height); /* 144 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_NoComposite) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY); /* 145 */ int (*tk_PhotoGetImage) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr); /* 146 */ void (*tk_PhotoBlank) (Tk_PhotoHandle handle); /* 147 */ - void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoExpand_Panic) (Tk_PhotoHandle handle, int width, int height); /* 148 */ void (*tk_PhotoGetSize) (Tk_PhotoHandle handle, int *widthPtr, int *heightPtr); /* 149 */ - void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoSetSize_Panic) (Tk_PhotoHandle handle, int width, int height); /* 150 */ int (*tk_PointToChar) (Tk_TextLayout layout, int x, int y); /* 151 */ int (*tk_PostscriptFontName) (Tk_Font tkfont, Tcl_DString *dsPtr); /* 152 */ void (*tk_PreserveColormap) (Display *display, Colormap colormap); /* 153 */ void (*tk_QueueWindowEvent) (XEvent *eventPtr, Tcl_QueuePosition position); /* 154 */ void (*tk_RedrawImage) (Tk_Image image, int imageX, int imageY, int width, int height, Drawable drawable, int drawableX, int drawableY); /* 155 */ @@ -1069,30 +1083,30 @@ Tk_OptionTable (*tk_CreateOptionTable) (Tcl_Interp *interp, const Tk_OptionSpec *templatePtr); /* 190 */ void (*tk_DeleteOptionTable) (Tk_OptionTable optionTable); /* 191 */ void (*tk_Free3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 192 */ void (*tk_FreeBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 193 */ void (*tk_FreeColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 194 */ - void (*tk_FreeConfigOptions) (char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 195 */ + void (*tk_FreeConfigOptions) (void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 195 */ void (*tk_FreeSavedOptions) (Tk_SavedOptions *savePtr); /* 196 */ void (*tk_FreeCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 197 */ void (*tk_FreeFontFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 198 */ Tk_3DBorder (*tk_Get3DBorderFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 199 */ int (*tk_GetAnchorFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Anchor *anchorPtr); /* 200 */ Pixmap (*tk_GetBitmapFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 201 */ XColor * (*tk_GetColorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 202 */ Tk_Cursor (*tk_GetCursorFromObj) (Tk_Window tkwin, Tcl_Obj *objPtr); /* 203 */ - Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */ - Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */ + Tcl_Obj * (*tk_GetOptionInfo) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 204 */ + Tcl_Obj * (*tk_GetOptionValue) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, Tcl_Obj *namePtr, Tk_Window tkwin); /* 205 */ int (*tk_GetJustifyFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, Tk_Justify *justifyPtr); /* 206 */ int (*tk_GetMMFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, double *doublePtr); /* 207 */ int (*tk_GetPixelsFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, int *intPtr); /* 208 */ int (*tk_GetReliefFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr, int *resultPtr); /* 209 */ int (*tk_GetScrollInfoObj) (Tcl_Interp *interp, int objc, Tcl_Obj *const objv[], double *dblPtr, int *intPtr); /* 210 */ - int (*tk_InitOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */ + int (*tk_InitOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionToken, Tk_Window tkwin); /* 211 */ void (*tk_MainEx) (int argc, char **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); /* 212 */ void (*tk_RestoreSavedOptions) (Tk_SavedOptions *savePtr); /* 213 */ - int (*tk_SetOptions) (Tcl_Interp *interp, char *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */ + int (*tk_SetOptions) (Tcl_Interp *interp, void *recordPtr, Tk_OptionTable optionTable, int objc, Tcl_Obj *const objv[], Tk_Window tkwin, Tk_SavedOptions *savePtr, int *maskPtr); /* 214 */ void (*tk_InitConsoleChannels) (Tcl_Interp *interp); /* 215 */ int (*tk_CreateConsoleWindow) (Tcl_Interp *interp); /* 216 */ void (*tk_CreateSmoothMethod) (Tcl_Interp *interp, const Tk_SmoothMethod *method); /* 217 */ void (*reserved218)(void); void (*reserved219)(void); @@ -1120,12 +1134,12 @@ Tk_Window (*tk_CreateAnonymousWindow) (Tcl_Interp *interp, Tk_Window parent, const char *screenName); /* 241 */ void (*tk_SetClassProcs) (Tk_Window tkwin, const Tk_ClassProcs *procs, ClientData instanceData); /* 242 */ void (*tk_SetInternalBorderEx) (Tk_Window tkwin, int left, int right, int top, int bottom); /* 243 */ void (*tk_SetMinimumRequestSize) (Tk_Window tkwin, int minWidth, int minHeight); /* 244 */ void (*tk_SetCaretPos) (Tk_Window tkwin, int x, int y, int height); /* 245 */ - void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */ - void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 246 */ + TCL_DEPRECATED_API("function signature changed") void (*tk_PhotoPutZoomedBlock_Panic) (Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 247 */ int (*tk_CollapseMotionEvents) (Display *display, int collapse); /* 248 */ Tk_StyleEngine (*tk_RegisterStyleEngine) (const char *name, Tk_StyleEngine parent); /* 249 */ Tk_StyleEngine (*tk_GetStyleEngine) (const char *name); /* 250 */ int (*tk_RegisterStyledElement) (Tk_StyleEngine engine, Tk_ElementSpec *templatePtr); /* 251 */ int (*tk_GetElementId) (const char *name); /* 252 */ @@ -1135,14 +1149,14 @@ const char * (*tk_NameOfStyle) (Tk_Style style); /* 256 */ Tk_Style (*tk_AllocStyleFromObj) (Tcl_Interp *interp, Tcl_Obj *objPtr); /* 257 */ Tk_Style (*tk_GetStyleFromObj) (Tcl_Obj *objPtr); /* 258 */ void (*tk_FreeStyleFromObj) (Tcl_Obj *objPtr); /* 259 */ Tk_StyledElement (*tk_GetStyledElement) (Tk_Style style, int elementId, Tk_OptionTable optionTable); /* 260 */ - void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */ - void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */ - int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin); /* 263 */ - void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, char *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */ + void (*tk_GetElementSize) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int width, int height, int inner, int *widthPtr, int *heightPtr); /* 261 */ + void (*tk_GetElementBox) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, int x, int y, int width, int height, int inner, int *xPtr, int *yPtr, int *widthPtr, int *heightPtr); /* 262 */ + int (*tk_GetElementBorderWidth) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin); /* 263 */ + void (*tk_DrawElement) (Tk_Style style, Tk_StyledElement element, void *recordPtr, Tk_Window tkwin, Drawable d, int x, int y, int width, int height, int state); /* 264 */ int (*tk_PhotoExpand) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 265 */ int (*tk_PhotoPutBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int compRule); /* 266 */ int (*tk_PhotoPutZoomedBlock) (Tcl_Interp *interp, Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height, int zoomX, int zoomY, int subsampleX, int subsampleY, int compRule); /* 267 */ int (*tk_PhotoSetSize) (Tcl_Interp *interp, Tk_PhotoHandle handle, int width, int height); /* 268 */ long (*tk_GetUserInactiveTime) (Display *dpy); /* 269 */ @@ -1718,16 +1732,34 @@ /* Functions that don't belong in the stub table */ #undef Tk_MainEx #undef Tk_Init #undef Tk_SafeInit #undef Tk_CreateConsoleWindow + +#undef Tk_FreeXId +#define Tk_FreeXId(display,xid) +#undef Tk_GetStyleFromObj +#undef Tk_FreeStyleFromObj +#define Tk_GetStyleFromObj(obj) Tk_AllocStyleFromObj(NULL, obj) +#define Tk_FreeStyleFromObj(obj) /* no-op */ + #if defined(_WIN32) && defined(UNICODE) # define Tk_MainEx Tk_MainExW EXTERN void Tk_MainExW(int argc, wchar_t **argv, Tcl_AppInitProc *appInitProc, Tcl_Interp *interp); #endif + +#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8 +#undef Tk_PhotoPutBlock_NoComposite +#undef Tk_PhotoPutZoomedBlock_NoComposite +#undef Tk_PhotoExpand_Panic +#undef Tk_PhotoPutBlock_Panic +#undef Tk_PhotoPutZoomedBlock_Panic +#undef Tk_PhotoSetSize_Panic +#endif /* TK_NO_DEPRECATED */ + #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT #endif /* _TKDECLS */ Index: generic/tkEntry.c ================================================================== --- generic/tkEntry.c +++ generic/tkEntry.c @@ -14,12 +14,12 @@ * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkInt.h" -#include "default.h" #include "tkEntry.h" +#include "default.h" /* * The following macro defines how many extra pixels to leave on each side of * the text in the entry. */ @@ -116,10 +116,16 @@ TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL, NULL, 0, -1, 0, "-invalidcommand", 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0}, + {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder", + DEF_ENTRY_PLACEHOLDER, -1, Tk_Offset(Entry, placeholderString), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground", + "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, -1, + Tk_Offset(Entry, placeholderColorPtr), 0, 0, 0}, {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground", "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1, Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK, (ClientData) DEF_ENTRY_READONLY_BG_MONO, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", @@ -256,10 +262,16 @@ TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_SYNONYM, "-invcmd", NULL, NULL, NULL, 0, -1, 0, "-invalidcommand", 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", DEF_ENTRY_JUSTIFY, -1, Tk_Offset(Entry, justify), 0, 0, 0}, + {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder", + DEF_ENTRY_PLACEHOLDER, -1, Tk_Offset(Entry, placeholderString), + TK_OPTION_NULL_OK, 0, 0}, + {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground", + "PlaceholderForeground", DEF_ENTRY_PLACEHOLDERFG, -1, + Tk_Offset(Entry, placeholderColorPtr), 0, 0, 0}, {TK_OPTION_RELIEF, "-relief", "relief", "Relief", DEF_ENTRY_RELIEF, -1, Tk_Offset(Entry, relief), 0, 0, 0}, {TK_OPTION_BORDER, "-readonlybackground", "readonlyBackground", "ReadonlyBackground", DEF_ENTRY_READONLY_BG_COLOR, -1, Tk_Offset(Entry, readonlyBorder), TK_OPTION_NULL_OK, @@ -535,10 +547,12 @@ entryPtr->selTextGC = None; entryPtr->highlightGC = None; entryPtr->avgWidth = 1; entryPtr->validate = VALIDATE_NONE; + entryPtr->placeholderGC = None; + /* * Keep a hold of the associated tkwin until we destroy the entry, * otherwise Tk might free it while we still need it. */ @@ -550,11 +564,11 @@ ExposureMask|StructureNotifyMask|FocusChangeMask, EntryEventProc, entryPtr); Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING, EntryFetchSelection, entryPtr, XA_STRING); - if ((Tk_InitOptions(interp, (char *) entryPtr, optionTable, tkwin) + if ((Tk_InitOptions(interp, entryPtr, optionTable, tkwin) != TCL_OK) || (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK)) { Tk_DestroyWindow(entryPtr->tkwin); return TCL_ERROR; } @@ -638,21 +652,21 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); goto error; } - objPtr = Tk_GetOptionValue(interp, (char *) entryPtr, + objPtr = Tk_GetOptionValue(interp, entryPtr, entryPtr->optionTable, objv[2], entryPtr->tkwin); if (objPtr == NULL) { goto error; } Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, + objPtr = Tk_GetOptionInfo(interp, entryPtr, entryPtr->optionTable, (objc == 3) ? objv[2] : NULL, entryPtr->tkwin); if (objPtr == NULL) { goto error; @@ -885,11 +899,12 @@ } else { entryPtr->selectFirst = index; entryPtr->selectLast = index2; } if (!(entryPtr->flags & GOT_SELECTION) - && (entryPtr->exportSelection)) { + && (entryPtr->exportSelection) + && (!Tcl_IsSafe(entryPtr->interp))) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, entryPtr); entryPtr->flags |= GOT_SELECTION; } EventuallyRedraw(entryPtr); @@ -1120,11 +1135,11 @@ /* * Store old values that we need to effect certain behavior if they change * value. */ - oldExport = entryPtr->exportSelection; + oldExport = (entryPtr->exportSelection) && (!Tcl_IsSafe(entryPtr->interp)); if (entryPtr->type == TK_SPINBOX) { oldValues = sbPtr->valueStr; oldFormat = sbPtr->reqFormat; oldFrom = sbPtr->fromValue; oldTo = sbPtr->toValue; @@ -1134,11 +1149,11 @@ if (!error) { /* * First pass: set options to new values. */ - if (Tk_SetOptions(interp, (char *) entryPtr, + if (Tk_SetOptions(interp, entryPtr, entryPtr->optionTable, objc, objv, entryPtr->tkwin, &savedOptions, NULL) != TCL_OK) { continue; } } else { @@ -1174,17 +1189,19 @@ entryPtr->insertBorderWidth = entryPtr->insertWidth/2; } if (entryPtr->type == TK_SPINBOX) { if (sbPtr->fromValue > sbPtr->toValue) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "-to value must be greater than -from value", - -1)); - Tcl_SetErrorCode(interp, "TK", "SPINBOX", "RANGE_SANITY", - NULL); - continue; - } + /* + * Swap -from and -to values. + */ + + double tmpFromTo = sbPtr->fromValue; + + sbPtr->fromValue = sbPtr->toValue; + sbPtr->toValue = tmpFromTo; + } if (sbPtr->reqFormat && (oldFormat != sbPtr->reqFormat)) { /* * Make sure that the given format is somewhat correct, and * calculate the minimum space we'll need for the values as @@ -1274,10 +1291,11 @@ /* * Claim the selection if we've suddenly started exporting it. */ if (entryPtr->exportSelection && (!oldExport) + && (!Tcl_IsSafe(entryPtr->interp)) && (entryPtr->selectFirst != -1) && !(entryPtr->flags & GOT_SELECTION)) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, entryPtr); entryPtr->flags |= GOT_SELECTION; @@ -1482,13 +1500,25 @@ gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues); if (entryPtr->textGC != None) { Tk_FreeGC(entryPtr->display, entryPtr->textGC); } entryPtr->textGC = gc; + + if (entryPtr->placeholderColorPtr != NULL) { + gcValues.foreground = entryPtr->placeholderColorPtr->pixel; + } + mask = GCForeground | GCFont | GCGraphicsExposures; + gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues); + if (entryPtr->placeholderGC != None) { + Tk_FreeGC(entryPtr->display, entryPtr->placeholderGC); + } + entryPtr->placeholderGC = gc; if (entryPtr->selFgColorPtr != NULL) { gcValues.foreground = entryPtr->selFgColorPtr->pixel; + } else { + gcValues.foreground = colorPtr->pixel; } gcValues.font = Tk_FontId(entryPtr->tkfont); mask = GCForeground | GCFont; gc = Tk_GetGC(entryPtr->tkwin, mask, &gcValues); if (entryPtr->selTextGC != None) { @@ -1732,13 +1762,19 @@ /* * Draw the text in two pieces: first the unselected portion, then the * selected portion on top of it. */ - Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC, + if ((entryPtr->numChars != 0) || (entryPtr->placeholderChars == 0)) { + Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->textGC, entryPtr->textLayout, entryPtr->layoutX, entryPtr->layoutY, entryPtr->leftIndex, entryPtr->numChars); + } else { + Tk_DrawTextLayout(entryPtr->display, pixmap, entryPtr->placeholderGC, + entryPtr->placeholderLayout, entryPtr->placeholderX, entryPtr->layoutY, + entryPtr->placeholderLeftIndex, entryPtr->placeholderChars); + } if (showSelection && (entryPtr->state != STATE_DISABLED) && (entryPtr->selTextGC != entryPtr->textGC) && (entryPtr->selectFirst < entryPtr->selectLast)) { int selFirst; @@ -1922,23 +1958,23 @@ * If we're displaying a special character instead of the value of the * entry, recompute the displayString. */ if (entryPtr->showChar != NULL) { - Tcl_UniChar ch; - char buf[TCL_UTF_MAX]; + int ch; + char buf[6]; int size; /* * Normalize the special character so we can safely duplicate it in * the display string. If we didn't do this, then two malformed * characters might end up looking like one valid UTF character in the * resulting string. */ - Tcl_UtfToUniChar(entryPtr->showChar, &ch); - size = Tcl_UniCharToUtf(ch, buf); + TkUtfToUniChar(entryPtr->showChar, &ch); + size = TkUniCharToUtf(ch, buf); entryPtr->numDisplayBytes = entryPtr->numChars * size; p = ckalloc(entryPtr->numDisplayBytes + 1); entryPtr->displayString = p; @@ -1946,10 +1982,62 @@ memcpy(p, buf, size); p += size; } *p = '\0'; } + + /* Recompute layout of placeholder text. + * Only the placeholderX and placeholderLeftIndex value is needed. + * We use the same font so we can use the layoutY value from below. + */ + + Tk_FreeTextLayout(entryPtr->placeholderLayout); + if (entryPtr->placeholderString) { + entryPtr->placeholderChars = strlen(entryPtr->placeholderString); + entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont, + entryPtr->placeholderString, entryPtr->placeholderChars, 0, + entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, NULL); + overflow = totalLength - + (Tk_Width(entryPtr->tkwin) - 2*entryPtr->inset - entryPtr->xWidth); + if (overflow <= 0) { + entryPtr->placeholderLeftIndex = 0; + if (entryPtr->justify == TK_JUSTIFY_LEFT) { + entryPtr->placeholderX = entryPtr->inset; + } else if (entryPtr->justify == TK_JUSTIFY_RIGHT) { + entryPtr->placeholderX = Tk_Width(entryPtr->tkwin) - entryPtr->inset + - entryPtr->xWidth - totalLength; + } else { + entryPtr->placeholderX = (Tk_Width(entryPtr->tkwin) + - entryPtr->xWidth - totalLength)/2; + } + } else { + + /* + * The whole string can't fit in the window. Compute the maximum + * number of characters that may be off-screen to the left without + * leaving empty space on the right of the window, then don't let + * placeholderLeftIndex be any greater than that. + */ + + maxOffScreen = Tk_PointToChar(entryPtr->placeholderLayout, overflow, 0); + Tk_CharBbox(entryPtr->placeholderLayout, maxOffScreen, + &rightX, NULL, NULL, NULL); + if (rightX < overflow) { + maxOffScreen++; + } + entryPtr->placeholderLeftIndex = maxOffScreen; + Tk_CharBbox(entryPtr->placeholderLayout, entryPtr->placeholderLeftIndex, &rightX, + NULL, NULL, NULL); + entryPtr->placeholderX = entryPtr->inset -rightX; + } + } else { + entryPtr->placeholderChars = 0; + entryPtr->placeholderLayout = Tk_ComputeTextLayout(entryPtr->tkfont, + entryPtr->placeholderString, 0, 0, + entryPtr->justify, TK_IGNORE_NEWLINES, NULL, NULL); + entryPtr->placeholderX = entryPtr->inset; + } Tk_FreeTextLayout(entryPtr->textLayout); entryPtr->textLayout = Tk_ComputeTextLayout(entryPtr->tkfont, entryPtr->displayString, entryPtr->numChars, 0, entryPtr->justify, TK_IGNORE_NEWLINES, &totalLength, &height); @@ -2042,13 +2130,11 @@ int index, /* Add the new elements before this character * index. */ const char *value) /* New characters to add (NULL-terminated * string). */ { - ptrdiff_t byteIndex; - size_t byteCount, newByteCount; - int oldChars, charsAdded; + size_t byteIndex, byteCount, newByteCount, oldChars, charsAdded; const char *string; char *newStr; string = entryPtr->string; byteIndex = Tcl_UtfAtIndex(string, index) - string; @@ -2743,11 +2829,12 @@ /* * Grab the selection if we don't own it already. */ - if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection)) { + if (!(entryPtr->flags & GOT_SELECTION) && (entryPtr->exportSelection) + && (!Tcl_IsSafe(entryPtr->interp))) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, entryPtr); entryPtr->flags |= GOT_SELECTION; } @@ -2810,11 +2897,12 @@ Entry *entryPtr = clientData; int byteCount; const char *string; const char *selStart, *selEnd; - if ((entryPtr->selectFirst < 0) || !(entryPtr->exportSelection)) { + if ((entryPtr->selectFirst < 0) || (!entryPtr->exportSelection) + || Tcl_IsSafe(entryPtr->interp)) { return -1; } string = entryPtr->displayString; selStart = Tcl_UtfAtIndex(string, entryPtr->selectFirst); selEnd = Tcl_UtfAtIndex(selStart, @@ -2863,11 +2951,12 @@ * selection since it is always visible. * This is controlled by ::tk::AlwaysShowSelection. */ if (TkpAlwaysShowSelection(entryPtr->tkwin) - && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection) { + && (entryPtr->selectFirst >= 0) && entryPtr->exportSelection + && (!Tcl_IsSafe(entryPtr->interp))) { entryPtr->selectFirst = -1; entryPtr->selectLast = -1; EventuallyRedraw(entryPtr); } } @@ -3128,12 +3217,12 @@ /* ARGSUSED */ static char * EntryTextVarProc( ClientData clientData, /* Information about button. */ Tcl_Interp *interp, /* Interpreter containing variable. */ - const char *name1, /* Not used. */ - const char *name2, /* Not used. */ + const char *name1, /* Name of variable. */ + const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { Entry *entryPtr = clientData; const char *value; @@ -3141,10 +3230,23 @@ /* * Just abort early if we entered here while being deleted. */ return NULL; } + + /* + * See ticket [5d991b82]. + */ + + if (entryPtr->textVarName == NULL) { + if (!(flags & TCL_INTERP_DESTROYED)) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + EntryTextVarProc, clientData); + } + return NULL; + } /* * If the variable is unset, then immediately recreate it unless the whole * interpreter is going away. */ @@ -3244,11 +3346,11 @@ * This function is invoked when any character is added or removed from * the entry widget, or a focus has trigerred validation. * * Results: * TCL_OK if the validatecommand accepts the new string, TCL_ERROR if any - * problems occured with validatecommand. + * problems occurred with validatecommand. * * Side effects: * The insertion/deletion may be aborted, and the validatecommand might * turn itself off (if an error or loop condition arises). * @@ -3301,11 +3403,11 @@ Tcl_DStringFree(&script); /* * If e->validate has become VALIDATE_NONE during the validation, or we * now have VALIDATE_VAR set (from EntrySetValue) and didn't before, it - * means that a loop condition almost occured. Do not allow this + * means that a loop condition almost occurred. Do not allow this * validation result to finish. */ if (entryPtr->validate == VALIDATE_NONE || (!varValidate && (entryPtr->flags & VALIDATE_VAR))) { @@ -3410,11 +3512,11 @@ { int spaceNeeded, cvtFlags; /* Used to substitute string as proper Tcl * list element. */ int number, length; register const char *string; - Tcl_UniChar ch; + int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (1) { if (*before == '\0') { break; @@ -3443,11 +3545,11 @@ * There's a percent sequence here. Process it. */ before++; /* skip over % */ if (*before != '\0') { - before += Tcl_UtfToUniChar(before, &ch); + before += TkUtfToUniChar(before, &ch); } else { ch = '%'; } if (type == VALIDATE_BUTTON) { /* @@ -3463,11 +3565,11 @@ break; case 'W': /* widget name */ string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; } } else { @@ -3523,11 +3625,11 @@ break; case 'W': /* widget name */ string = Tk_PathName(entryPtr->tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; } } @@ -3638,10 +3740,12 @@ sbPtr->increment = 1.0; sbPtr->formatBuf = ckalloc(TCL_DOUBLE_SPACE); sbPtr->bdRelief = TK_RELIEF_FLAT; sbPtr->buRelief = TK_RELIEF_FLAT; + entryPtr->placeholderGC = None; + /* * Keep a hold of the associated tkwin until we destroy the spinbox, * otherwise Tk might free it while we still need it. */ @@ -3653,11 +3757,11 @@ PointerMotionMask|ExposureMask|StructureNotifyMask|FocusChangeMask, EntryEventProc, entryPtr); Tk_CreateSelHandler(entryPtr->tkwin, XA_PRIMARY, XA_STRING, EntryFetchSelection, entryPtr, XA_STRING); - if (Tk_InitOptions(interp, (char *) sbPtr, optionTable, tkwin) + if (Tk_InitOptions(interp, sbPtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(entryPtr->tkwin); return TCL_ERROR; } if (ConfigureEntry(interp, entryPtr, objc-2, objv+2) != TCL_OK) { @@ -3748,21 +3852,21 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); goto error; } - objPtr = Tk_GetOptionValue(interp, (char *) entryPtr, + objPtr = Tk_GetOptionValue(interp, entryPtr, entryPtr->optionTable, objv[2], entryPtr->tkwin); if (objPtr == NULL) { goto error; } Tcl_SetObjResult(interp, objPtr); break; case SB_CMD_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) entryPtr, + objPtr = Tk_GetOptionInfo(interp, entryPtr, entryPtr->optionTable, (objc == 3) ? objv[2] : NULL, entryPtr->tkwin); if (objPtr == NULL) { goto error; } @@ -4032,11 +4136,12 @@ } else { entryPtr->selectFirst = index; entryPtr->selectLast = index2; } if (!(entryPtr->flags & GOT_SELECTION) - && entryPtr->exportSelection) { + && entryPtr->exportSelection + && (!Tcl_IsSafe(entryPtr->interp))) { Tk_OwnSelection(entryPtr->tkwin, XA_PRIMARY, EntryLostSelection, entryPtr); entryPtr->flags |= GOT_SELECTION; } EventuallyRedraw(entryPtr); @@ -4277,20 +4382,21 @@ * Somehow the string changed from what we expected, so let's * do a search on the list to see if the current value is * there. If not, move to the first element of the list. */ - int i, listc, elemLen, length = entryPtr->numChars; + int i, listc; + size_t elemLen, length = entryPtr->numChars; const char *bytes; Tcl_Obj **listv; Tcl_ListObjGetElements(interp, sbPtr->listObj, &listc, &listv); for (i = 0; i < listc; i++) { - bytes = Tcl_GetStringFromObj(listv[i], &elemLen); + bytes = TkGetStringFromObj(listv[i], &elemLen); if ((length == elemLen) && (memcmp(bytes, entryPtr->string, - (size_t) length) == 0)) { + length) == 0)) { sbPtr->eIndex = i; break; } } } Index: generic/tkEntry.h ================================================================== --- generic/tkEntry.h +++ generic/tkEntry.h @@ -126,10 +126,23 @@ char *showChar; /* Value of -show option. If non-NULL, first * character is used for displaying all * characters in entry. Malloc'ed. This is * only used by the Entry widget. */ + /* + * Fields used in displaying help text if entry value is empty + */ + + Tk_TextLayout placeholderLayout;/* Cached placeholder text layout information. */ + char *placeholderString; /* String value of placeholder. */ + int placeholderChars; /* Number of chars in placeholder. */ + XColor *placeholderColorPtr;/* Color value of placeholder foreground. */ + GC placeholderGC; /* For drawing placeholder text. */ + int placeholderX; /* Origin for layout. */ + int placeholderLeftIndex; /* Character index of left-most character + * visible in window. */ + /* * Fields whose values are derived from the current values of the * configuration settings above. */ @@ -219,11 +232,11 @@ * Malloc'ed. */ char *reqFormat; /* Sprintf conversion specifier used for the * value that the users requests. Malloc'ed */ char *valueFormat; /* Sprintf conversion specifier used for the * value. */ - char digitFormat[10]; /* Sprintf conversion specifier computed from + char digitFormat[16]; /* Sprintf conversion specifier computed from * digits and other information; used for the * value. */ char *valueStr; /* Values List. Malloc'ed. */ Tcl_Obj *listObj; /* Pointer to the list object being used */ Index: generic/tkError.c ================================================================== --- generic/tkError.c +++ generic/tkError.c @@ -80,12 +80,12 @@ Tk_ErrorProc *errorProc, /* Procedure to invoke when a matching error * occurs. NULL means just ignore matching * errors. */ ClientData clientData) /* Arbitrary value to pass to errorProc. */ { - register TkErrorHandler *errorPtr; - register TkDisplay *dispPtr; + TkErrorHandler *errorPtr; + TkDisplay *dispPtr; /* * Find the display. If Tk doesn't know about this display then it's an * error: panic. */ @@ -145,12 +145,12 @@ void Tk_DeleteErrorHandler( Tk_ErrorHandler handler) /* Token for handler to delete; was previous * return value from Tk_CreateErrorHandler. */ { - register TkErrorHandler *errorPtr = (TkErrorHandler *) handler; - register TkDisplay *dispPtr = errorPtr->dispPtr; + TkErrorHandler *errorPtr = (TkErrorHandler *) handler; + TkDisplay *dispPtr = errorPtr->dispPtr; errorPtr->lastRequest = NextRequest(dispPtr->display) - 1; /* * Every once-in-a-while, cleanup handlers that are no longer active. We @@ -162,23 +162,30 @@ * errors that might occur while the dead handlers are hanging around, but * reduces the overhead of scanning the list to clean up (particularly if * there are many handlers that stay around forever). */ - dispPtr->deleteCount += 1; - if (dispPtr->deleteCount >= 10) { - register TkErrorHandler *prevPtr; + if (dispPtr->deleteCount++ >= 9) { + TkErrorHandler *prevPtr; TkErrorHandler *nextPtr; - int lastSerial; + unsigned long lastSerial = LastKnownRequestProcessed(dispPtr->display); + + /* + * Last chance to catch errors for this handler: if no event/error + * processing took place to follow up the end of this error handler + * we need a round trip with the X server now. + */ + if (errorPtr->lastRequest > lastSerial) { + XSync(dispPtr->display, False); + } dispPtr->deleteCount = 0; - lastSerial = LastKnownRequestProcessed(dispPtr->display); errorPtr = dispPtr->errorPtr; for (prevPtr = NULL; errorPtr != NULL; errorPtr = nextPtr) { nextPtr = errorPtr->nextPtr; if ((errorPtr->lastRequest != (unsigned long) -1) - && (errorPtr->lastRequest <= (unsigned long) lastSerial)) { + && (errorPtr->lastRequest <= lastSerial)) { if (prevPtr == NULL) { dispPtr->errorPtr = nextPtr; } else { prevPtr->nextPtr = nextPtr; } @@ -211,15 +218,15 @@ */ static int ErrorProc( Display *display, /* Display for which error occurred. */ - register XErrorEvent *errEventPtr) + XErrorEvent *errEventPtr) /* Information about error. */ { - register TkDisplay *dispPtr; - register TkErrorHandler *errorPtr; + TkDisplay *dispPtr; + TkErrorHandler *errorPtr; /* * See if we know anything about the display. If not, then invoke the * default error handler. */ Index: generic/tkEvent.c ================================================================== --- generic/tkEvent.c +++ generic/tkEvent.c @@ -354,10 +354,11 @@ if (winPtr->inputContext == NULL) { /* XCreateIC failed. */ return; } + winPtr->ximGeneration = dispPtr->ximGeneration; /* * Adjust the window's event mask if the IM requires it. */ XGetICValues(winPtr->inputContext, XNFilterEvents, &im_event_mask, NULL); @@ -1286,18 +1287,28 @@ * set the input context focus to the receiving window. This code is only * ever active for X11. */ #ifdef TK_USE_INPUT_METHODS + /* + * If the XIC has been invalidated, it must be recreated. + */ + if (winPtr->dispPtr->ximGeneration != winPtr->ximGeneration) { + winPtr->flags &= ~TK_CHECKED_IC; + winPtr->inputContext = NULL; + } + if ((winPtr->dispPtr->flags & TK_DISPLAY_USE_IM)) { if (!(winPtr->flags & (TK_CHECKED_IC|TK_ALREADY_DEAD))) { winPtr->flags |= TK_CHECKED_IC; if (winPtr->dispPtr->inputMethod != NULL) { CreateXIC(winPtr); } } - if (eventPtr->type == FocusIn && winPtr->inputContext != NULL) { + if ((eventPtr->type == FocusIn) && + (winPtr->dispPtr->inputMethod != NULL) && + (winPtr->inputContext != NULL)) { XSetICFocus(winPtr->inputContext); } } #endif /*TK_USE_INPUT_METHODS*/ Index: generic/tkFont.c ================================================================== --- generic/tkFont.c +++ generic/tkFont.c @@ -39,11 +39,11 @@ * for each named font that has been defined. The named font is only deleted * when the last reference to it goes away. */ typedef struct NamedFont { - int refCount; /* Number of users of named font. */ + size_t refCount; /* Number of users of named font. */ int deletePending; /* Non-zero if font should be deleted when * last reference goes away. */ TkFontAttributes fa; /* Desired attributes for named font. */ } NamedFont; @@ -349,11 +349,11 @@ const Tcl_ObjType tkFontObjType = { "font", /* name */ FreeFontObjProc, /* freeIntRepProc */ DupFontObjProc, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetFontFromAny /* setFromAnyProc */ + NULL /* setFromAnyProc */ }; /* *--------------------------------------------------------------------------- * @@ -495,11 +495,11 @@ case FONT_ACTUAL: { int skip, result, n; const char *s; Tk_Font tkfont; Tcl_Obj *optPtr, *charPtr, *resultPtr; - Tcl_UniChar uniChar = 0; + int uniChar = 0; const TkFontAttributes *faPtr; TkFontAttributes fa; /* * Params 0 and 1 are 'font actual'. Param 2 is the font name. 3-4 may @@ -560,21 +560,23 @@ /* * The 'charPtr' arg must be a single Unicode. */ if (charPtr != NULL) { - if (Tcl_GetCharLength(charPtr) != 1) { + const char *string = Tcl_GetString(charPtr); + size_t len = TkUtfToUniChar(string, &uniChar); + + if (len != (size_t)charPtr->length) { resultPtr = Tcl_NewStringObj( "expected a single character but got \"", -1); - Tcl_AppendLimitedToObj(resultPtr, Tcl_GetString(charPtr), + Tcl_AppendLimitedToObj(resultPtr, string, -1, 40, "..."); Tcl_AppendToObj(resultPtr, "\"", -1); Tcl_SetObjResult(interp, resultPtr); Tcl_SetErrorCode(interp, "TK", "VALUE", "FONT_SAMPLE", NULL); return TCL_ERROR; } - uniChar = Tcl_GetUniChar(charPtr, 0); } /* * Find the font. */ @@ -708,11 +710,12 @@ break; } case FONT_MEASURE: { const char *string; Tk_Font tkfont; - int length = 0, skip = 0; + size_t length = 0; + int skip = 0; if (objc > 4) { skip = TkGetDisplayOf(interp, objc - 3, objv + 3, &tkwin); if (skip < 0) { return TCL_ERROR; @@ -725,11 +728,11 @@ } tkfont = Tk_AllocFontFromObj(interp, tkwin, objv[2]); if (tkfont == NULL) { return TCL_ERROR; } - string = Tcl_GetStringFromObj(objv[3 + skip], &length); + string = TkGetStringFromObj(objv[3 + skip], &length); Tcl_SetObjResult(interp, Tcl_NewIntObj( Tk_TextWidth(tkfont, string, length))); Tk_FreeFont(tkfont); break; } @@ -1224,11 +1227,11 @@ * non-underlined font. */ descent = fontPtr->fm.descent; fontPtr->underlinePos = descent / 2; - fontPtr->underlineHeight = TkFontGetPixels(tkwin, fontPtr->fa.size) / 10; + fontPtr->underlineHeight = (int) (TkFontGetPixels(tkwin, fontPtr->fa.size) / 10 + 0.5); if (fontPtr->underlineHeight == 0) { fontPtr->underlineHeight = 1; } if (fontPtr->underlinePos + fontPtr->underlineHeight > descent) { /* @@ -1419,23 +1422,21 @@ NamedFont *nfPtr; if (fontPtr == NULL) { return; } - fontPtr->resourceRefCount--; - if (fontPtr->resourceRefCount > 0) { + if (fontPtr->resourceRefCount-- > 1) { return; } if (fontPtr->namedHashPtr != NULL) { /* * This font derived from a named font. Reduce the reference count on * the named font and free it if no-one else is using it. */ nfPtr = Tcl_GetHashValue(fontPtr->namedHashPtr); - nfPtr->refCount--; - if ((nfPtr->refCount == 0) && nfPtr->deletePending) { + if ((nfPtr->refCount-- <= 1) && nfPtr->deletePending) { Tcl_DeleteHashEntry(fontPtr->namedHashPtr); ckfree(nfPtr); } } @@ -1518,12 +1519,11 @@ Tcl_Obj *objPtr) /* The object we are releasing. */ { TkFont *fontPtr = objPtr->internalRep.twoPtrValue.ptr1; if (fontPtr != NULL) { - fontPtr->objRefCount--; - if ((fontPtr->resourceRefCount == 0) && (fontPtr->objRefCount == 0)) { + if ((fontPtr->objRefCount-- <= 1) && (fontPtr->resourceRefCount == 0)) { ckfree(fontPtr); } objPtr->internalRep.twoPtrValue.ptr1 = NULL; objPtr->internalRep.twoPtrValue.ptr2 = NULL; } @@ -1692,11 +1692,11 @@ } else if (strcasecmp(family, "ZapfChancery") == 0) { family = "ZapfChancery"; } else if (strcasecmp(family, "ZapfDingbats") == 0) { family = "ZapfDingbats"; } else { - Tcl_UniChar ch; + int ch; /* * Inline, capitalize the first letter of each word, lowercase the * rest of the letters in each word, and then take out the spaces * between the words. This may make the DString shorter, which is safe @@ -1710,18 +1710,18 @@ for (; *src != '\0'; ) { while (isspace(UCHAR(*src))) { /* INTL: ISO space */ src++; upper = 1; } - src += Tcl_UtfToUniChar(src, &ch); + src += TkUtfToUniChar(src, &ch); if (upper) { ch = Tcl_UniCharToUpper(ch); upper = 0; } else { ch = Tcl_UniCharToLower(ch); } - dest += Tcl_UniCharToUtf(ch, dest); + dest += TkUniCharToUtf(ch, dest); } *dest = '\0'; Tcl_DStringSetLength(dsPtr, dest - Tcl_DStringValue(dsPtr)); family = Tcl_DStringValue(dsPtr) + len; } @@ -1792,11 +1792,11 @@ if (slantString != NULL) { Tcl_DStringAppend(dsPtr, slantString, -1); } } - return fontPtr->fa.size; + return (int)(fontPtr->fa.size + 0.5); } /* *--------------------------------------------------------------------------- * @@ -3143,26 +3143,24 @@ cx[0] = cx[3] = chunkPtr->x; cy[0] = cy[1] = chunkPtr->y - fontPtr->fm.ascent; cx[1] = cx[2] = chunkPtr->x + chunkPtr->displayWidth; cy[2] = cy[3] = chunkPtr->y + fontPtr->fm.descent; - if ( !PointInQuadrilateral(cx, cy, rx[0], ry[0]) || - !PointInQuadrilateral(cx, cy, rx[1], ry[1]) || - !PointInQuadrilateral(cx, cy, rx[2], ry[2]) || - !PointInQuadrilateral(cx, cy, rx[3], ry[3])) { - goto notReverseInside; - } - } - return 0; + if ( PointInQuadrilateral(cx, cy, rx[0], ry[0]) && + PointInQuadrilateral(cx, cy, rx[1], ry[1]) && + PointInQuadrilateral(cx, cy, rx[2], ry[2]) && + PointInQuadrilateral(cx, cy, rx[3], ry[3])) { + return 0; + } + } /* * If we're overlapping now, we must be partially in and out of at least * one chunk. If that is the case, there must be one line segment of the * rectangle that is touching or crossing a line segment of a chunk. */ - notReverseInside: chunkPtr = layoutPtr->chunks; for (i=0 ; inumChunks ; i++,chunkPtr++) { int j; @@ -3244,14 +3242,15 @@ { TextLayout *layoutPtr = (TextLayout *) layout; LayoutChunk *chunkPtr = layoutPtr->chunks; int baseline = chunkPtr->y; Tcl_Obj *psObj = Tcl_NewObj(); - int i, j, len; + int i, j; + size_t len; const char *p, *glyphname; char uindex[5], c, *ps; - Tcl_UniChar ch; + int ch; Tcl_AppendToObj(psObj, "[(", -1); for (i = 0; i < layoutPtr->numChunks; i++, chunkPtr++) { if (baseline != chunkPtr->y) { Tcl_AppendToObj(psObj, ")]\n[(", -1); @@ -3270,11 +3269,11 @@ * from the standard set defined by Adobe. The rest get punted. * Eventually this should be revised to handle more sophsticiated * international postscript fonts. */ - p += Tcl_UtfToUniChar(p, &ch); + p += TkUtfToUniChar(p, &ch); if ((ch == '(') || (ch == ')') || (ch == '\\') || (ch < 0x20)) { /* * Tricky point: the "03" is necessary in the sprintf below, * so that a full three digits of octal are always generated. * Without the "03", a number following this sequence could be @@ -3296,14 +3295,17 @@ /* * This character doesn't belong to the ASCII character set, so we * use the full glyph name. */ + if (ch > 0xffff) { + goto noMapping; + } sprintf(uindex, "%04X", ch); /* endianness? */ glyphname = Tcl_GetVar2(interp, "::tk::psglyphs", uindex, 0); if (glyphname) { - ps = Tcl_GetStringFromObj(psObj, &len); + ps = TkGetStringFromObj(psObj, &len); if (ps[len-1] == '(') { /* * In-place edit. Ewww! */ @@ -3316,10 +3318,11 @@ } else { /* * No known mapping for the character into the space of * PostScript glyphs. Ignore it. :-( */ +noMapping: ; #ifdef TK_DEBUG_POSTSCRIPT_OUTPUT fprintf(stderr, "Warning: no mapping to PostScript " "glyphs for \\u%04x\n", ch); #endif @@ -3397,11 +3400,11 @@ break; case FONT_SIZE: if (Tcl_GetIntFromObj(interp, valuePtr, &n) != TCL_OK) { return TCL_ERROR; } - faPtr->size = n; + faPtr->size = (double)n; break; case FONT_WEIGHT: n = TkFindStateNumObj(interp, optionPtr, weightMap, valuePtr); if (n == TK_FW_UNKNOWN) { return TCL_ERROR; @@ -3488,11 +3491,15 @@ str = faPtr->family; valuePtr = Tcl_NewStringObj(str, ((str == NULL) ? 0 : -1)); break; case FONT_SIZE: - valuePtr = Tcl_NewIntObj(faPtr->size); + if (faPtr->size >= 0.0) { + valuePtr = Tcl_NewIntObj((int)(faPtr->size + 0.5)); + } else { + valuePtr = Tcl_NewIntObj(-(int)(-faPtr->size + 0.5)); + } break; case FONT_WEIGHT: str = TkFindStateString(weightMap, faPtr->weight); valuePtr = Tcl_NewStringObj(str, -1); @@ -3637,11 +3644,11 @@ faPtr->family = Tk_GetUid(Tcl_GetString(objv[0])); if (objc > 1) { if (Tcl_GetIntFromObj(interp, objv[1], &n) != TCL_OK) { return TCL_ERROR; } - faPtr->size = n; + faPtr->size = (double)n; } i = 2; if (objc == 3) { if (Tcl_ListObjGetElements(interp, objv[2], &objc, &objv) != TCL_OK) { @@ -3881,11 +3888,11 @@ /* * Pointsize in tenths of a point, but treat it as tenths of a pixel for * historical compatibility. */ - faPtr->size = 12; + faPtr->size = 12.0; if (FieldSpecified(field[XLFD_POINT_SIZE])) { if (field[XLFD_POINT_SIZE][0] == '[') { /* * Some X fonts have the point size specified as follows: @@ -3895,14 +3902,14 @@ * where N1 is the point size (in points, not decipoints!), and * N2, N3, and N4 are some additional numbers that I don't know * the purpose of, so I ignore them. */ - faPtr->size = atoi(field[XLFD_POINT_SIZE] + 1); + faPtr->size = atof(field[XLFD_POINT_SIZE] + 1); } else if (Tcl_GetInt(NULL, field[XLFD_POINT_SIZE], - &faPtr->size) == TCL_OK) { - faPtr->size /= 10; + &i) == TCL_OK) { + faPtr->size = i/10.0; } else { return TCL_ERROR; } } @@ -3920,13 +3927,15 @@ * where N1 is the pixel size, and where N2, N3, and N4 are some * additional numbers that I don't know the purpose of, so I * ignore them. */ - faPtr->size = atoi(field[XLFD_PIXEL_SIZE] + 1); + faPtr->size = atof(field[XLFD_PIXEL_SIZE] + 1); } else if (Tcl_GetInt(NULL, field[XLFD_PIXEL_SIZE], - &faPtr->size) != TCL_OK) { + &i) == TCL_OK) { + faPtr->size = (double)i; + } else { return TCL_ERROR; } } faPtr->size = -faPtr->size; @@ -3998,25 +4007,25 @@ * None. * *--------------------------------------------------------------------------- */ -int +double TkFontGetPixels( Tk_Window tkwin, /* For point->pixel conversion factor. */ - int size) /* Font size. */ + double size) /* Font size. */ { double d; - if (size < 0) { + if (size <= 0.0) { return -size; } d = size * 25.4 / 72.0; d *= WidthOfScreen(Tk_Screen(tkwin)); d /= WidthMMOfScreen(Tk_Screen(tkwin)); - return (int) (d + 0.5); + return d; } /* *--------------------------------------------------------------------------- * @@ -4032,25 +4041,25 @@ * None. * *--------------------------------------------------------------------------- */ -int +double TkFontGetPoints( Tk_Window tkwin, /* For pixel->point conversion factor. */ - int size) /* Font size. */ + double size) /* Font size. */ { double d; - if (size >= 0) { + if (size >= 0.0) { return size; } d = -size * 72.0 / 25.4; d *= WidthMMOfScreen(Tk_Screen(tkwin)); d /= WidthOfScreen(Tk_Screen(tkwin)); - return (int) (d + 0.5); + return d; } /* *------------------------------------------------------------------------- * @@ -4193,13 +4202,13 @@ Tcl_Panic("TkDebugFont found empty hash table entry"); } for ( ; (fontPtr != NULL); fontPtr = fontPtr->nextPtr) { objPtr = Tcl_NewObj(); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(fontPtr->resourceRefCount)); + Tcl_NewWideIntObj(fontPtr->resourceRefCount)); Tcl_ListObjAppendElement(NULL, objPtr, - Tcl_NewIntObj(fontPtr->objRefCount)); + Tcl_NewWideIntObj(fontPtr->objRefCount)); Tcl_ListObjAppendElement(NULL, resultPtr, objPtr); } } return resultPtr; } Index: generic/tkFont.h ================================================================== --- generic/tkFont.h +++ generic/tkFont.h @@ -21,11 +21,11 @@ */ struct TkFontAttributes { Tk_Uid family; /* Font family, or NULL to represent plaform- * specific default system font. */ - int size; /* Pointsize of font, 0 for default size, or + double size; /* Pointsize of font, 0.0 for default size, or * negative number meaning pixel size. */ int weight; /* Weight flag; see below for def'n. */ int slant; /* Slant flag; see below for def'n. */ int underline; /* Non-zero for underline font. */ int overstrike; /* Non-zero for overstrike font. */ @@ -83,21 +83,21 @@ typedef struct TkFont { /* * Fields used and maintained exclusively by generic code. */ - int resourceRefCount; /* Number of active uses of this font (each + TkSizeT resourceRefCount; /* Number of active uses of this font (each * active use corresponds to a call to * Tk_AllocFontFromTable or Tk_GetFont). If * this count is 0, then this TkFont structure * is no longer valid and it isn't present in * a hash table: it is being kept around only * because there are objects referring to it. * The structure is freed when * resourceRefCount and objRefCount are both * 0. */ - int objRefCount; /* The number of Tcl objects that reference + TkSizeT objRefCount; /* The number of Tcl objects that reference * this structure. */ Tcl_HashEntry *cacheHashPtr;/* Entry in font cache for this structure, * used when deleting it. */ Tcl_HashEntry *namedHashPtr;/* Pointer to hash table entry that * corresponds to the named font that the @@ -196,12 +196,12 @@ MODULE_SCOPE int TkFontParseXLFD(const char *string, TkFontAttributes *faPtr, TkXLFDAttributes *xaPtr); MODULE_SCOPE const char *const * TkFontGetAliasList(const char *faceName); MODULE_SCOPE const char *const *const * TkFontGetFallbacks(void); -MODULE_SCOPE int TkFontGetPixels(Tk_Window tkwin, int size); -MODULE_SCOPE int TkFontGetPoints(Tk_Window tkwin, int size); +MODULE_SCOPE double TkFontGetPixels(Tk_Window tkwin, double size); +MODULE_SCOPE double TkFontGetPoints(Tk_Window tkwin, double size); MODULE_SCOPE const char *const * TkFontGetGlobalClass(void); MODULE_SCOPE const char *const * TkFontGetSymbolClass(void); MODULE_SCOPE int TkCreateNamedFont(Tcl_Interp *interp, Tk_Window tkwin, const char *name, TkFontAttributes *faPtr); MODULE_SCOPE int TkDeleteNamedFont(Tcl_Interp *interp, Index: generic/tkFrame.c ================================================================== --- generic/tkFrame.c +++ generic/tkFrame.c @@ -10,12 +10,12 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" +#include "default.h" /* * The following enum is used to define the type of the frame. */ @@ -456,11 +456,10 @@ * zero means create a frame. */ Tcl_Obj *nameObj) /* Should only be non-NULL if there is no main * window associated with the interpreter. * Gives the base name to use for the new * application. */ - { int objc; Tcl_Obj **objv; if (TCL_OK != Tcl_ListObjGetElements(interp, listObj, &objc, &objv)) { @@ -487,11 +486,12 @@ Frame *framePtr; Tk_OptionTable optionTable; Tk_Window newWin; const char *className, *screenName, *visualName, *colormapName; const char *arg, *useOption; - int i, length, depth; + int i, depth; + size_t length; unsigned int mask; Colormap colormap; Visual *visual; if (objc < 2) { @@ -514,28 +514,28 @@ */ className = colormapName = screenName = visualName = useOption = NULL; colormap = None; for (i = 2; i < objc; i += 2) { - arg = Tcl_GetStringFromObj(objv[i], &length); + arg = TkGetStringFromObj(objv[i], &length); if (length < 2) { continue; } if ((arg[1] == 'c') && (length >= 3) - && (strncmp(arg, "-class", (unsigned) length) == 0)) { + && (strncmp(arg, "-class", length) == 0)) { className = Tcl_GetString(objv[i+1]); } else if ((arg[1] == 'c') && (length >= 3) - && (strncmp(arg, "-colormap", (unsigned) length) == 0)) { + && (strncmp(arg, "-colormap", length) == 0)) { colormapName = Tcl_GetString(objv[i+1]); } else if ((arg[1] == 's') && (type == TYPE_TOPLEVEL) - && (strncmp(arg, "-screen", (unsigned) length) == 0)) { + && (strncmp(arg, "-screen", length) == 0)) { screenName = Tcl_GetString(objv[i+1]); } else if ((arg[1] == 'u') && (type == TYPE_TOPLEVEL) - && (strncmp(arg, "-use", (unsigned) length) == 0)) { + && (strncmp(arg, "-use", length) == 0)) { useOption = Tcl_GetString(objv[i+1]); } else if ((arg[1] == 'v') - && (strncmp(arg, "-visual", (unsigned) length) == 0)) { + && (strncmp(arg, "-visual", length) == 0)) { visualName = Tcl_GetString(objv[i+1]); } } /* @@ -681,11 +681,11 @@ mask = ExposureMask | StructureNotifyMask | FocusChangeMask; if (type == TYPE_TOPLEVEL) { mask |= ActivateMask; } Tk_CreateEventHandler(newWin, mask, FrameEventProc, framePtr); - if ((Tk_InitOptions(interp, (char *) framePtr, optionTable, newWin) + if ((Tk_InitOptions(interp, framePtr, optionTable, newWin) != TCL_OK) || (ConfigureFrame(interp, framePtr, objc-2, objv+2) != TCL_OK)) { goto error; } if (framePtr->isContainer) { @@ -742,11 +742,12 @@ enum options { FRAME_CGET, FRAME_CONFIGURE }; register Frame *framePtr = clientData; int result = TCL_OK, index; - int c, i, length; + int c, i; + size_t length; Tcl_Obj *objPtr; if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; @@ -761,21 +762,21 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; goto done; } - objPtr = Tk_GetOptionValue(interp, (char *) framePtr, + objPtr = Tk_GetOptionValue(interp, framePtr, framePtr->optionTable, objv[2], framePtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; goto done; } Tcl_SetObjResult(interp, objPtr); break; case FRAME_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) framePtr, + objPtr = Tk_GetOptionInfo(interp, framePtr, framePtr->optionTable, (objc == 3) ? objv[2] : NULL, framePtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; goto done; @@ -786,11 +787,11 @@ * Don't allow the options -class, -colormap, -container, -screen, * -use, or -visual to be changed. */ for (i = 2; i < objc; i++) { - const char *arg = Tcl_GetStringFromObj(objv[i], &length); + const char *arg = TkGetStringFromObj(objv[i], &length); if (length < 2) { continue; } c = arg[1]; @@ -959,11 +960,11 @@ } if (framePtr->type == TYPE_LABELFRAME) { oldWindow = labelframePtr->labelWin; } - if (Tk_SetOptions(interp, (char *) framePtr, + if (Tk_SetOptions(interp, framePtr, framePtr->optionTable, objc, objv, framePtr->tkwin, &savedOptions, NULL) != TCL_OK) { if (oldMenuName != NULL) { ckfree(oldMenuName); } Index: generic/tkGC.c ================================================================== --- generic/tkGC.c +++ generic/tkGC.c @@ -21,11 +21,11 @@ */ typedef struct { GC gc; /* Graphics context. */ Display *display; /* Display to which gc belongs. */ - int refCount; /* Number of active uses of gc. */ + size_t refCount; /* Number of active uses of gc. */ Tcl_HashEntry *valueHashPtr;/* Entry in valueTable (needed when deleting * this structure). */ } TkGC; typedef struct { @@ -310,13 +310,11 @@ idHashPtr = Tcl_FindHashEntry(&dispPtr->gcIdTable, (char *) gc); if (idHashPtr == NULL) { Tcl_Panic("Tk_FreeGC received unknown gc argument"); } gcPtr = Tcl_GetHashValue(idHashPtr); - gcPtr->refCount--; - if (gcPtr->refCount == 0) { - Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); + if (gcPtr->refCount-- <= 1) { XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(idHashPtr); ckfree(gcPtr); } @@ -349,16 +347,10 @@ for (entryPtr = Tcl_FirstHashEntry(&dispPtr->gcIdTable, &search); entryPtr != NULL; entryPtr = Tcl_NextHashEntry(&search)) { gcPtr = Tcl_GetHashValue(entryPtr); - /* - * This call is not needed, as it is only used on Unix to restore the - * Id to the stack pool, and we don't want to use them anymore. - * Tk_FreeXId(gcPtr->display, (XID) XGContextFromGC(gcPtr->gc)); - */ - XFreeGC(gcPtr->display, gcPtr->gc); Tcl_DeleteHashEntry(gcPtr->valueHashPtr); Tcl_DeleteHashEntry(entryPtr); ckfree(gcPtr); } Index: generic/tkGrab.c ================================================================== --- generic/tkGrab.c +++ generic/tkGrab.c @@ -188,11 +188,11 @@ int globalGrab; Tk_Window tkwin; TkDisplay *dispPtr; const char *arg; int index; - int len; + size_t len; static const char *const optionStrings[] = { "current", "release", "set", "status", NULL }; static const char *const flagStrings[] = { "-global", NULL @@ -225,11 +225,11 @@ /* * First check for a window name or "-global" as the first argument. */ - arg = Tcl_GetStringFromObj(objv[1], &len); + arg = TkGetStringFromObj(objv[1], &len); if (arg[0] == '.') { /* [grab window] */ if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "?-global? window"); return TCL_ERROR; Index: generic/tkGrid.c ================================================================== --- generic/tkGrid.c +++ generic/tkGrid.c @@ -1730,19 +1730,16 @@ int usedX, usedY; masterPtr->flags &= ~REQUESTED_RELAYOUT; /* - * If the master has no slaves anymore, then don't do anything at all: - * just leave the master's size as-is, but signal the master with the - * <> virtual event. + * If the master has no slaves anymore, then don't change the master size. * Otherwise there is no way to "relinquish" control over the master * so another geometry manager can take over. */ if (masterPtr->slavePtr == NULL) { - TkSendVirtualEvent(masterPtr->tkwin, "GeometryManager", NULL); return; } if (masterPtr->masterDataPtr == NULL) { return; @@ -2777,15 +2774,19 @@ slavePtr->masterPtr = NULL; /* * If we have emptied this master from slaves it means we are no longer * handling it and should mark it as free. + * + * Send the event "NoManagedChild" to the master to inform it about there + * being no managed children inside it. */ if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) { TkFreeGeometryMaster(masterPtr->tkwin, "grid"); masterPtr->flags &= ~ALLOCED_MASTER; + TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL); } } /* *---------------------------------------------------------------------- @@ -2868,21 +2869,22 @@ gridPtr->masterPtr->flags |= REQUESTED_RELAYOUT; Tcl_DoWhenIdle(ArrangeGrid, gridPtr->masterPtr); } } } else if (eventPtr->type == DestroyNotify) { - register Gridder *gridPtr2, *nextPtr; + register Gridder *slavePtr, *nextPtr; if (gridPtr->masterPtr != NULL) { Unlink(gridPtr); } - for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL; - gridPtr2 = nextPtr) { - Tk_UnmapWindow(gridPtr2->tkwin); - gridPtr2->masterPtr = NULL; - nextPtr = gridPtr2->nextPtr; - gridPtr2->nextPtr = NULL; + for (slavePtr = gridPtr->slavePtr; slavePtr != NULL; + slavePtr = nextPtr) { + Tk_ManageGeometry(slavePtr->tkwin, NULL, NULL); + Tk_UnmapWindow(slavePtr->tkwin); + slavePtr->masterPtr = NULL; + nextPtr = slavePtr->nextPtr; + slavePtr->nextPtr = NULL; } Tcl_DeleteHashEntry(Tcl_FindHashEntry(&dispPtr->gridHashTable, (char *) gridPtr->tkwin)); if (gridPtr->flags & REQUESTED_RELAYOUT) { Tcl_CancelIdleCall(ArrangeGrid, gridPtr); @@ -2894,15 +2896,15 @@ && !(gridPtr->flags & REQUESTED_RELAYOUT)) { gridPtr->flags |= REQUESTED_RELAYOUT; Tcl_DoWhenIdle(ArrangeGrid, gridPtr); } } else if (eventPtr->type == UnmapNotify) { - register Gridder *gridPtr2; + register Gridder *slavePtr; - for (gridPtr2 = gridPtr->slavePtr; gridPtr2 != NULL; - gridPtr2 = gridPtr2->nextPtr) { - Tk_UnmapWindow(gridPtr2->tkwin); + for (slavePtr = gridPtr->slavePtr; slavePtr != NULL; + slavePtr = slavePtr->nextPtr) { + Tk_UnmapWindow(slavePtr->tkwin); } } } /* @@ -2964,14 +2966,14 @@ * Count the number of windows, or window short-cuts. */ firstChar = 0; for (numWindows=0, i=0; i < objc; i++) { - int length; + size_t length; char prevChar = firstChar; - string = Tcl_GetStringFromObj(objv[i], &length); + string = TkGetStringFromObj(objv[i], &length); firstChar = string[0]; if (firstChar == '.') { /* * Check that windows are valid, and locate the first slave's @@ -3083,11 +3085,12 @@ defaultRow = tmp; } } /* - * If no -row is given, use the first unoccupied row of the master. + * If no -row is given, use the next row after the highest occupied row + * of the master. */ if (defaultRow < 0) { if (masterPtr != NULL && masterPtr->masterDataPtr != NULL) { SetGridSize(masterPtr); @@ -3314,10 +3317,13 @@ masterPtr = GetGrid(parent); InitMasterData(masterPtr); } if (slavePtr->masterPtr != NULL && slavePtr->masterPtr != masterPtr) { + if (slavePtr->masterPtr->tkwin != Tk_Parent(slavePtr->tkwin)) { + Tk_UnmaintainGeometry(slavePtr->tkwin, slavePtr->masterPtr->tkwin); + } Unlink(slavePtr); slavePtr->masterPtr = NULL; } if (slavePtr->masterPtr == NULL) { @@ -3504,15 +3510,19 @@ SetGridSize(masterPtr); /* * If we have emptied this master from slaves it means we are no longer * handling it and should mark it as free. + * + * Send the event "NoManagedChild" to the master to inform it about there + * being no managed children inside it. */ if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) { TkFreeGeometryMaster(masterPtr->tkwin, "grid"); masterPtr->flags &= ~ALLOCED_MASTER; + TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL); } return TCL_OK; } Index: generic/tkImgBmap.c ================================================================== --- generic/tkImgBmap.c +++ generic/tkImgBmap.c @@ -47,11 +47,11 @@ * The following data structure represents all of the instances of an image * that lie within a particular window: */ typedef struct BitmapInstance { - int refCount; /* Number of instances that share this data + size_t refCount; /* Number of instances that share this data * structure. */ BitmapMaster *masterPtr; /* Pointer to master for image. */ Tk_Window tkwin; /* Window in which the instances will be * displayed. */ XColor *fg; /* Foreground color for displaying image. */ @@ -949,12 +949,11 @@ Display *display) /* Display containing window that used image. */ { BitmapInstance *instancePtr = clientData; BitmapInstance *prevPtr; - instancePtr->refCount--; - if (instancePtr->refCount > 0) { + if (instancePtr->refCount-- > 1) { return; } /* * There are no more uses of the image within this widget. Free the @@ -1078,14 +1077,14 @@ static int GetByte( Tcl_Channel chan) /* The channel we read from. */ { char buffer; - int size; + size_t size; size = Tcl_Read(chan, &buffer, 1); - if (size <= 0) { + if ((size + 1) < 2) { return EOF; } else { return buffer; } } Index: generic/tkImgGIF.c ================================================================== --- generic/tkImgGIF.c +++ generic/tkImgGIF.c @@ -53,11 +53,11 @@ typedef struct mFile { unsigned char *data; /* mmencoded source string */ int c; /* bits left over from previous character */ int state; /* decoder state (0-4 or GIF_DONE) */ - int length; /* Total amount of bytes in data */ + size_t length; /* Total amount of bytes in data */ } MFile; /* * Non-ASCII encoding support: * Most data in a GIF image is binary and is treated as such. However, a few @@ -109,12 +109,12 @@ /* * Type of a function used to do the writing to a file or buffer when * serializing in the GIF format. */ -typedef int (WriteBytesFunc) (ClientData clientData, const char *bytes, - int byteCount); +typedef size_t (WriteBytesFunc) (ClientData clientData, const char *bytes, + size_t byteCount); /* * The format record for the GIF file format: */ @@ -185,18 +185,18 @@ /* * these are for the BASE64 image reader code only */ -static int Fread(GIFImageConfig *gifConfPtr, unsigned char *dst, +static size_t Fread(GIFImageConfig *gifConfPtr, unsigned char *dst, size_t size, size_t count, Tcl_Channel chan); -static int Mread(unsigned char *dst, size_t size, size_t count, +static size_t Mread(unsigned char *dst, size_t size, size_t count, MFile *handle); static int Mgetc(MFile *handle); static int char64(int c); static void mInit(unsigned char *string, MFile *handle, - int length); + size_t length); /* * Types, defines and variables needed to write and compress a GIF. */ @@ -755,14 +755,14 @@ int *widthPtr, /* where to put the string width */ int *heightPtr, /* where to put the string height */ Tcl_Interp *interp) /* not used */ { unsigned char *data, header[10]; - int got, length; + size_t got, length; MFile handle; - data = Tcl_GetByteArrayFromObj(dataObj, &length); + data = TkGetByteArrayFromObj(dataObj, &length); /* * Header is a minimum of 10 bytes. */ @@ -824,13 +824,13 @@ int destX, int destY, /* The rectangular region of the */ int width, int height, /* image to copy */ int srcX, int srcY) { MFile handle, *hdlPtr = &handle; - int length; + size_t length; const char *xferFormat; - unsigned char *data = Tcl_GetByteArrayFromObj(dataObj, &length); + unsigned char *data = TkGetByteArrayFromObj(dataObj, &length); mInit(data, hdlPtr, length); /* * Check whether the data is Base64 encoded by doing a character-by- @@ -915,11 +915,11 @@ { int i; unsigned char rgb[3]; for (i = 0; i < number; ++i) { - if (Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) <= 0) { + if (((size_t)Fread(gifConfPtr, rgb, sizeof(rgb), 1, chan) + 1) < 2) { return 0; } if (buffer) { buffer[i][CM_RED] = rgb[0]; @@ -981,15 +981,15 @@ Tcl_Channel chan, unsigned char *buf) { unsigned char count; - if (Fread(gifConfPtr, &count, 1, 1, chan) <= 0) { + if (((size_t)Fread(gifConfPtr, &count, 1, 1, chan) + 1) < 2) { return -1; } - if ((count != 0) && (Fread(gifConfPtr, buf, count, 1, chan) <= 0)) { + if ((count != 0) && (((size_t)Fread(gifConfPtr, buf, count, 1, chan) + 1) < 2)) { return -1; } return count; } @@ -1047,11 +1047,11 @@ /* * Initialize the decoder */ - if (Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) <= 0) { + if (((size_t)Fread(gifConfPtr, &initialCodeSize, 1, 1, chan) + 1) < 2) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading GIF image: %s", Tcl_PosixError(interp))); return TCL_ERROR; } @@ -1139,13 +1139,13 @@ if (oldCode == -1) { /* * Last pass reset the decoder, so the first code we see * must be a singleton. Seed the stack with it, and set up * the old/first code pointers for insertion into the - * string table. We can't just roll this into the - * clearCode test above, because at that point we have not - * yet read the next code. + * codes table. We can't just roll this into the clearCode + * test above, because at that point we have not yet read + * the next code. */ *top++ = append[code]; oldCode = code; firstCode = code; @@ -1152,54 +1152,50 @@ continue; } inCode = code; - if (code == maxCode) { + if ((code == maxCode) && (maxCode < (1 << MAX_LWZ_BITS))) { /* * maxCode is always one bigger than our highest assigned * code. If the code we see is equal to maxCode, then we - * are about to add a new string to the table. ??? + * are about to add a new entry to the codes table. */ *top++ = firstCode; code = oldCode; } while (code > clearCode) { /* - * Populate the stack by tracing the string in the string + * Populate the stack by tracing the code in the codes * table from its tail to its head */ *top++ = append[code]; code = prefix[code]; } firstCode = append[code]; - /* - * If there's no more room in our string table, quit. - * Otherwise, add a new string to the table - */ - - if (maxCode >= (1 << MAX_LWZ_BITS)) { - return TCL_OK; - } - - /* - * Push the head of the string onto the stack. - */ - - *top++ = firstCode; - - /* - * Add a new string to the string table - */ - - prefix[maxCode] = oldCode; - append[maxCode] = firstCode; - maxCode++; + /* + * Push the head of the code onto the stack. + */ + + *top++ = firstCode; + + if (maxCode < (1 << MAX_LWZ_BITS)) { + /* + * If there's still room in our codes table, add a new entry. + * Otherwise don't, and keep using the current table. + * See DEFERRED CLEAR CODE IN LZW COMPRESSION in the GIF89a + * specification. + */ + + prefix[maxCode] = oldCode; + append[maxCode] = firstCode; + maxCode++; + } /* * maxCode tells us the maximum code value we can accept. If * we see that we need more bits to represent it than we are * requesting from the unpacker, we need to increase the @@ -1375,11 +1371,11 @@ static void mInit( unsigned char *string, /* string containing initial mmencoded data */ MFile *handle, /* mmdecode "file" handle */ - int length) /* Number of bytes in string */ + size_t length) /* Number of bytes in string */ { handle->data = string; handle->state = 0; handle->c = 0; handle->length = length; @@ -1401,19 +1397,19 @@ * The base64 handle will change state. * *---------------------------------------------------------------------- */ -static int +static size_t Mread( unsigned char *dst, /* where to put the result */ size_t chunkSize, /* size of each transfer */ size_t numChunks, /* number of chunks */ MFile *handle) /* mmdecode "file" handle */ { - register int i, c; - int count = chunkSize * numChunks; + int c; + size_t i, count = chunkSize * numChunks; for (i=0; ifromData == INLINE_DATA_BINARY) { MFile *handle = (MFile *) chan; - if (handle->length <= 0 || (size_t) handle->length < hunk*count) { - return -1; + if ((handle->length + 1 < 2) || (handle->length < hunk*count)) { + return (size_t)-1; } - memcpy(dst, handle->data, (size_t) (hunk * count)); + memcpy(dst, handle->data, hunk * count); handle->data += hunk * count; - return (int)(hunk * count); + handle->length -= hunk * count; + return hunk * count; } /* * Otherwise we've got a real file to read. */ - return Tcl_Read(chan, (char *) dst, (int) (hunk * count)); + return Tcl_Read(chan, (char *) dst, hunk * count); } /* * ChanWriteGIF - writes a image in GIF format. *------------------------------------------------------------------------- @@ -1655,26 +1652,26 @@ } Tcl_DecrRefCount(objPtr); return result; } -static int +static size_t WriteToChannel( ClientData clientData, const char *bytes, - int byteCount) + size_t byteCount) { Tcl_Channel handle = clientData; return Tcl_Write(handle, bytes, byteCount); } -static int +static size_t WriteToByteArray( ClientData clientData, const char *bytes, - int byteCount) + size_t byteCount) { Tcl_Obj *objPtr = clientData; Tcl_Obj *tmpObj = Tcl_NewByteArrayObj((unsigned char *) bytes, byteCount); Tcl_IncrRefCount(tmpObj); ADDED generic/tkImgListFormat.c Index: generic/tkImgListFormat.c ================================================================== --- /dev/null +++ generic/tkImgListFormat.c @@ -0,0 +1,1141 @@ +/* + * tkImgListFormat.c -- + * + * Implements the default image data format. I.e. the format used for + * [imageName data] and [imageName put] if no other format is specified. + * + * The default format consits of a list of scan lines (rows) with each + * list element being itself a list of pixels (or columns). For details, + * see the manpage photo.n + * + * This image format cannot read/write files, it is meant for string + * data only. + * + * + * Copyright (c) 1994 The Australian National University. + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * Copyright (c) 2002-2003 Donal K. Fellows + * Copyright (c) 2003 ActiveState Corporation. + * + * See the file "license.terms" for information on usage and redistribution of + * this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * Authors: + * Paul Mackerras (paulus@cs.anu.edu.au), + * Department of Computer Science, + * Australian National University. + * + * Simon Bachmann (simonbachmann@bluewin.ch) + */ + + +#include "tkImgPhoto.h" + +/* + * Message to generate when an attempt to allocate memory for an image fails. + */ + +#define TK_PHOTO_ALLOC_FAILURE_MESSAGE \ + "not enough free memory for image buffer" + + +/* + * Color name length limit: do not attempt to parse as color strings that are + * longer than this limit + */ + +#define TK_PHOTO_MAX_COLOR_CHARS 99 + +/* + * Symbols for the different formats of a color string. + */ + +enum ColorFormatType { + COLORFORMAT_TKCOLOR, + COLORFORMAT_EMPTYSTRING, + COLORFORMAT_LIST, + COLORFORMAT_RGB1, + COLORFORMAT_RGB2, + COLORFORMAT_RGBA1, + COLORFORMAT_RGBA2 +}; + +/* + * Names for the color format types above. + * Order must match the one in enum ColorFormatType + */ + +static const char *const colorFormatNames[] = { + "tkcolor", + "emptystring", + "list", + "rgb-short", + "rgb", + "rgba-short", + "rgba", + NULL +}; + +/* + * The following data structure is used to return information from + * ParseFormatOptions: + */ + +struct FormatOptions { + int options; /* Individual bits indicate which options were + * specified - see below. */ + Tcl_Obj *formatName; /* Name specified without an option. */ + enum ColorFormatType colorFormat; + /* The color format type given with the + * -colorformat option */ +}; + +/* + * Bit definitions for use with ParseFormatOptions: each bit is set in the + * allowedOptions parameter on a call to ParseFormatOptions if that option + * is allowed for the current photo image subcommand. On return, the bit is + * set in the options field of the FormatOptions structure if that option + * was specified. + * + * OPT_COLORFORMAT: Set if -alpha option allowed/specified. + */ + +#define OPT_COLORFORMAT 1 + +/* + * List of format option names. The order here must match the order of + * declarations of the FMT_OPT_* constants above. + */ + +static const char *const formatOptionNames[] = { + "-colorformat", + NULL +}; + +/* + * Forward declarations + */ + +static int ParseFormatOptions(Tcl_Interp *interp, int allowedOptions, + int objc, Tcl_Obj *const objv[], int *indexPtr, + struct FormatOptions *optPtr); +static Tcl_Obj *GetBadOptMsg(const char *badValue, int allowedOpts); +static int StringMatchDef(Tcl_Obj *data, Tcl_Obj *formatString, + int *widthPtr, int *heightPtr, Tcl_Interp *interp); +static int StringReadDef(Tcl_Interp *interp, Tcl_Obj *data, + Tcl_Obj *formatString, Tk_PhotoHandle imageHandle, + int destX, int destY, int width, int height, + int srcX, int srcY); +static int StringWriteDef(Tcl_Interp *interp, + Tcl_Obj *formatString, + Tk_PhotoImageBlock *blockPtr); +static int ParseColor(Tcl_Interp *interp, Tcl_Obj *specObj, + Display *display, Colormap colormap, unsigned char *redPtr, + unsigned char *greenPtr, unsigned char *bluePtr, + unsigned char *alphaPtr); +static int ParseColorAsList(Tcl_Interp *interp, const char *colorString, + int colorStrLen, unsigned char *redPtr, + unsigned char *greenPtr, unsigned char *bluePtr, + unsigned char *alphaPtr); +static int ParseColorAsHex(Tcl_Interp *interp, const char *colorString, + int colorStrLen, Display *display, Colormap colormap, + unsigned char *redPtr, unsigned char *greenPtr, + unsigned char *bluePtr, unsigned char *alphaPtr); +static int ParseColorAsStandard(Tcl_Interp *interp, + const char *colorString, int colorStrLen, + Display *display, Colormap colormap, + unsigned char *redPtr, unsigned char *greenPtr, + unsigned char *bluePtr, unsigned char *alphaPtr); + +/* + * The format record for the default image handler + */ + +Tk_PhotoImageFormat tkImgFmtDefault = { + "default", /* name */ + NULL, /* fileMatchProc: format doesn't support file ops */ + StringMatchDef, /* stringMatchProc */ + NULL, /* fileReadProc: format doesn't support file read */ + StringReadDef, /* stringReadProc */ + NULL, /* fileWriteProc: format doesn't support file write */ + StringWriteDef /* stringWriteProc */ +}; + +/* + *---------------------------------------------------------------------- + * + * ParseFormatOptions -- + * + * Parse the options passed to the image format handler. + * + * Results: + * On success, the structure pointed to by optPtr is filled with the + * values passed or with the defaults and TCL_OK returned. + * If an error occurs, leaves an error message in interp and returns + * TCL_ERROR. + * + * Side effects: + * The value in *indexPtr is updated to the index of the fist + * element in argv[] that does not look like an option/value, or to + * argc if parsing reached the end of argv[]. + * + *---------------------------------------------------------------------- + */ +static int +ParseFormatOptions( + Tcl_Interp *interp, /* For error messages */ + int allowedOptions, /* Bitfield specifying which options are + * to be considered allowed */ + int objc, /* Number of elements in argv[] */ + Tcl_Obj *const objv[], /* The arguments to parse */ + int *indexPtr, /* Index giving the first element to + * parse. The value is updated to the + * index where parsing ended */ + struct FormatOptions *optPtr) /* Parsed option values are written to + * this struct */ + +{ + int index, optIndex, typeIndex, first; + const char *option; + + first = 1; + + /* + * Fill in default values + */ + optPtr->options = 0; + optPtr->formatName = NULL; + optPtr->colorFormat = COLORFORMAT_RGB2; + for (index = *indexPtr; index < objc; *indexPtr = ++index) { + int optionExists; + + /* + * The first value can be the format handler's name. It goes to + * optPtr->name. + */ + option = Tcl_GetString(objv[index]); + if (option[0] != '-') { + if (first) { + optPtr->formatName = objv[index]; + first = 0; + continue; + } else { + break; + } + } + first = 0; + + /* + * Check if option is known and allowed + */ + + optionExists = 1; + if (Tcl_GetIndexFromObj(NULL, objv[index], formatOptionNames, + "format option", 0, &optIndex) != TCL_OK) { + optionExists = 0; + } + if (!optionExists || !((1 << optIndex) & allowedOptions)) { + Tcl_SetObjResult(interp, GetBadOptMsg(Tcl_GetString(objv[index]), + allowedOptions)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL); + return TCL_ERROR; + } + + /* + * Option-specific checks + */ + + switch (1 << optIndex) { + case OPT_COLORFORMAT: + *indexPtr = ++index; + if (index >= objc) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("the \"%s\" option " + "requires a value", Tcl_GetString(objv[index - 1]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "MISSING_VALUE", NULL); + return TCL_ERROR; + } + if (Tcl_GetIndexFromObj(NULL, objv[index], colorFormatNames, "", + TCL_EXACT, &typeIndex) != TCL_OK + || (typeIndex != COLORFORMAT_LIST + && typeIndex != COLORFORMAT_RGB2 + && typeIndex != COLORFORMAT_RGBA2) ) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("bad color format " + "\"%s\": must be rgb, rgba, or list", + Tcl_GetString(objv[index]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "BAD_COLOR_FORMAT", NULL); + return TCL_ERROR; + } + optPtr->colorFormat = typeIndex; + break; + default: + Tcl_Panic("ParseFormatOptions: unexpected switch fallthrough"); + } + + /* + * Add option to bitfield in optPtr + */ + optPtr->options |= (1 << optIndex); + } + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * GetBadOptMsg -- + * + * Build a Tcl_Obj containing an error message in the form "bad option + * "xx": must be y, or z", based on the bits set in allowedOpts. + * + * Results: + * A Tcl Object containig the error message. + * + * Side effects: + * None + *---------------------------------------------------------------------- + */ +static Tcl_Obj * +GetBadOptMsg( + const char *badValue, /* the erroneous option */ + int allowedOpts) /* bitfield specifying the allowed options */ +{ + int i, bit; + Tcl_Obj *resObj = Tcl_ObjPrintf("bad format option \"%s\": ", badValue); + + if (allowedOpts == 0) { + Tcl_AppendToObj(resObj, "no options allowed", -1); + } else { + Tcl_AppendToObj(resObj, "must be ", -1); + bit = 1; + for (i = 0; formatOptionNames[i] != NULL; i++) { + if (allowedOpts & bit) { + if (allowedOpts & (bit -1)) { + /* + * not the first option + */ + if (allowedOpts & ~((bit << 1) - 1)) { + /* + * not the last option + */ + Tcl_AppendToObj(resObj, ", ", -1); + } else { + Tcl_AppendToObj(resObj, ", or ", -1); + } + } + Tcl_AppendToObj(resObj, formatOptionNames[i], -1); + } + bit <<=1; + } + } + return resObj; +} + +/* + *---------------------------------------------------------------------- + * + * StringMatchDef -- + * + * Default string match function. Test if image data in string form + * appears to be in the default list-of-list-of-pixel-data format + * accepted by the " put" command. + * + * Results: + * If thte data is in the default format, writes the size of the image + * to widthPtr and heightPtr and returns 1. Otherwise, leaves an error + * message in interp (if not NULL) and returns 0. + * Note that this function does not parse all data points. A return + * value of 1 does not guarantee that the data can be read without + * errors. + * + * Side effects: + * None + *---------------------------------------------------------------------- + */ +static int +StringMatchDef( + Tcl_Obj *data, /* The data to check */ + Tcl_Obj *formatString, /* Value of the -format option, not used here */ + int *widthPtr, /* Width of image is written to this location */ + int *heightPtr, /* Height of image is written to this location */ + Tcl_Interp *interp) /* Error messages are left in this interpreter */ +{ + int y, rowCount, colCount, curColCount; + unsigned char dummy; + Tcl_Obj **rowListPtr, *pixelData; + + /* + * See if data can be parsed as a list, if every element is itself a valid + * list and all sublists have the same length. + */ + + if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr) + != TCL_OK) { + return 0; + } + if (rowCount == 0) { + /* + * empty list is valid data + */ + + *widthPtr = 0; + *heightPtr = 0; + return 1; + } + colCount = -1; + for (y = 0; y < rowCount; y++) { + if (Tcl_ListObjLength(interp, rowListPtr[y], &curColCount) != TCL_OK) { + return 0; + } + if (colCount < 0) { + colCount = curColCount; + } else if (curColCount != colCount) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid row # %d: " + "all rows must have the same number of elements", y)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "INVALID_DATA", NULL); + } + return 0; + } + } + + /* + * Data in base64 encoding (or even binary data), might actually pass + * these tests. To avoid parsing it as list of lists format, check one + * pixel for validity. + */ + if (Tcl_ListObjIndex(interp, rowListPtr[0], 0, &pixelData) != TCL_OK) { + return 0; + } + if (Tcl_GetCharLength(pixelData) > TK_PHOTO_MAX_COLOR_CHARS) { + return 0; + } + if (ParseColor(interp, pixelData, Tk_Display(Tk_MainWindow(interp)), + Tk_Colormap(Tk_MainWindow(interp)), &dummy, &dummy, &dummy, &dummy) + != TCL_OK) { + return 0; + } + + /* + * Looks like we have valid data for this format. + * We do not check any pixel values - that's the job of ImgStringRead() + */ + + *widthPtr = colCount; + *heightPtr = rowCount; + + return 1; + +} + +/* + *---------------------------------------------------------------------- + * + * StringReadDef -- + * + * String read function for default format. (see manpage for details on + * the format). + * + * Results: + * A standard Tcl result. + * + * Side effects: + * If the data has valid format, write it to the image identified by + * imageHandle. + * If the image data cannot be parsed, an error message is left in + * interp. + * + *---------------------------------------------------------------------- +*/ + +static int +StringReadDef( + Tcl_Interp *interp, /* leave error messages here */ + Tcl_Obj *data, /* the data to parse */ + Tcl_Obj *formatString, /* value of the -format option */ + Tk_PhotoHandle imageHandle, /* write data to this image */ + int destX, int destY, /* start writing data at this point + * in destination image*/ + int width, int height, /* dimensions of area to write to */ + int srcX, int srcY) /* start reading source data at these + * coordinates */ +{ + Tcl_Obj **rowListPtr, **colListPtr; + Tcl_Obj **objv; + int objc; + unsigned char *curPixelPtr; + int x, y, rowCount, colCount, curColCount; + Tk_PhotoImageBlock srcBlock; + Display *display; + Colormap colormap; + struct FormatOptions opts; + int optIndex; + + /* + * Parse format suboptions + * We don't use any format suboptions, but we still need to provide useful + * error messages if suboptions were specified. + */ + + memset(&opts, 0, sizeof(opts)); + if (formatString != NULL) { + if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv) + != TCL_OK) { + return TCL_ERROR; + } + optIndex = 0; + if (ParseFormatOptions(interp, 0, objc, objv, &optIndex, &opts) + != TCL_OK) { + return TCL_ERROR; + } + if (optIndex < objc) { + Tcl_SetObjResult(interp, + GetBadOptMsg(Tcl_GetString(objv[optIndex]), 0)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL); + return TCL_ERROR; + } + } + + /* + * Check input data + */ + + if (Tcl_ListObjGetElements(interp, data, &rowCount, &rowListPtr) + != TCL_OK ) { + return TCL_ERROR; + } + if ( rowCount > 0 && Tcl_ListObjLength(interp, rowListPtr[0], &colCount) + != TCL_OK) { + return TCL_ERROR; + } + if (width <= 0 || height <= 0 || rowCount == 0 || colCount == 0) { + /* + * No changes with zero sized input or zero sized output region + */ + + return TCL_OK; + } + if (srcX < 0 || srcY < 0 || srcX >= rowCount || srcY >= colCount) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("source coordinates out of range")); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", NULL); + return TCL_ERROR; + } + + /* + * Memory allocation overflow protection. + * May not be able to trigger/ demo / test this. + */ + + if (colCount > (int)(UINT_MAX / 4 / rowCount)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "photo image dimensions exceed Tcl memory limits")); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "OVERFLOW", NULL); + return TCL_OK; + } + + /* + * Read data and put it to imageHandle + */ + + srcBlock.width = colCount - srcX; + srcBlock.height = rowCount - srcY; + srcBlock.pixelSize = 4; + srcBlock.pitch = srcBlock.width * 4; + srcBlock.offset[0] = 0; + srcBlock.offset[1] = 1; + srcBlock.offset[2] = 2; + srcBlock.offset[3] = 3; + srcBlock.pixelPtr = attemptckalloc(srcBlock.pitch * srcBlock.height); + if (srcBlock.pixelPtr == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf(TK_PHOTO_ALLOC_FAILURE_MESSAGE)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + return TCL_ERROR; + } + curPixelPtr = srcBlock.pixelPtr; + display = Tk_Display(Tk_MainWindow(interp)); + colormap = Tk_Colormap(Tk_MainWindow(interp)); + for (y = srcY; y < rowCount; y++) { + /* + * We don't test the length of row, as that's been done in + * ImgStringMatch() + */ + + if (Tcl_ListObjGetElements(interp, rowListPtr[y], &curColCount, + &colListPtr) != TCL_OK) { + goto errorExit; + } + for (x = srcX; x < colCount; x++) { + if (ParseColor(interp, colListPtr[x], display, colormap, + curPixelPtr, curPixelPtr + 1, curPixelPtr + 2, + curPixelPtr + 3) != TCL_OK) { + goto errorExit; + } + curPixelPtr += 4; + } + } + + /* + * Write image data to destHandle + */ + if (Tk_PhotoPutBlock(interp, imageHandle, &srcBlock, destX, destY, + width, height, TK_PHOTO_COMPOSITE_SET) != TCL_OK) { + goto errorExit; + } + + ckfree(srcBlock.pixelPtr); + + return TCL_OK; + + errorExit: + ckfree(srcBlock.pixelPtr); + + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * StringWriteDef -- + * + * String write function for default image data format. See the user + * documentation for details. + * + * Results: + * The converted data is set as the result of interp. Returns a standard + * Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +StringWriteDef( + Tcl_Interp *interp, /* For the result and errors */ + Tcl_Obj *formatString, /* The value of the -format option */ + Tk_PhotoImageBlock *blockPtr) /* The image data to convert */ +{ + int greenOffset, blueOffset, alphaOffset, hasAlpha; + Tcl_Obj *result, **objv = NULL; + int objc, allowedOpts, optIndex; + struct FormatOptions opts; + + /* + * Parse format suboptions + */ + if (Tcl_ListObjGetElements(interp, formatString, &objc, &objv) + != TCL_OK) { + return TCL_ERROR; + } + allowedOpts = OPT_COLORFORMAT; + optIndex = 0; + if (ParseFormatOptions(interp, allowedOpts, objc, objv, &optIndex, &opts) + != TCL_OK) { + return TCL_ERROR; + } + if (optIndex < objc) { + Tcl_SetObjResult(interp, + GetBadOptMsg(Tcl_GetString(objv[optIndex]), allowedOpts)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", NULL); + return TCL_ERROR; + } + + greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; + blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; + + /* + * A negative alpha offset signals that the image is fully opaque. + * That's not really documented anywhere, but it's the way it is! + */ + + if (blockPtr->offset[3] < 0) { + hasAlpha = 0; + alphaOffset = 0; + } else { + hasAlpha = 1; + alphaOffset = blockPtr->offset[3] - blockPtr->offset[0]; + } + + if ((blockPtr->width > 0) && (blockPtr->height > 0)) { + int row, col; + Tcl_DString data, line; + char colorBuf[11]; + unsigned char *pixelPtr; + unsigned char alphaVal = 255; + + Tcl_DStringInit(&data); + for (row=0; rowheight; row++) { + pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0] + + row * blockPtr->pitch; + Tcl_DStringInit(&line); + for (col=0; colwidth; col++) { + if (hasAlpha) { + alphaVal = pixelPtr[alphaOffset]; + } + + /* + * We don't build lines as a list for #RGBA and #RGB. Since + * these color formats look like comments, the first element + * of the list would get quoted with an additional {} . + * While this is not a problem if the data is used as + * a list, it would cause problems if someone decides to parse + * it as a string (and it looks kinda strange) + */ + + switch (opts.colorFormat) { + case COLORFORMAT_RGB2: + sprintf(colorBuf, "#%02x%02x%02x ", pixelPtr[0], + pixelPtr[greenOffset], pixelPtr[blueOffset]); + Tcl_DStringAppend(&line, colorBuf, -1); + break; + case COLORFORMAT_RGBA2: + sprintf(colorBuf, "#%02x%02x%02x%02x ", + pixelPtr[0], pixelPtr[greenOffset], + pixelPtr[blueOffset], alphaVal); + Tcl_DStringAppend(&line, colorBuf, -1); + break; + case COLORFORMAT_LIST: + Tcl_DStringStartSublist(&line); + sprintf(colorBuf, "%d", pixelPtr[0]); + Tcl_DStringAppendElement(&line, colorBuf); + sprintf(colorBuf, "%d", pixelPtr[greenOffset]); + Tcl_DStringAppendElement(&line, colorBuf); + sprintf(colorBuf, "%d", pixelPtr[blueOffset]); + Tcl_DStringAppendElement(&line, colorBuf); + sprintf(colorBuf, "%d", alphaVal); + Tcl_DStringAppendElement(&line, colorBuf); + Tcl_DStringEndSublist(&line); + break; + default: + Tcl_Panic("unexpected switch fallthrough"); + } + pixelPtr += blockPtr->pixelSize; + } + if (opts.colorFormat != COLORFORMAT_LIST) { + /* + * For the #XXX formats, we need to remove the last + * whitespace. + */ + + *(Tcl_DStringValue(&line) + Tcl_DStringLength(&line) - 1) + = '\0'; + } + Tcl_DStringAppendElement(&data, Tcl_DStringValue(&line)); + Tcl_DStringFree(&line); + } + result = Tcl_NewStringObj(Tcl_DStringValue(&data), -1); + Tcl_DStringFree(&data); + } else { + result = Tcl_NewObj(); + } + + Tcl_SetObjResult(interp, result); + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ParseColor -- + * + * This function extracts color and alpha values from a string. It + * understands standard Tk color formats, alpha suffixes and the color + * formats specific to photo images, which include alpha data. + * + * Results: + * On success, writes red, green, blue and alpha values to the + * corresponding pointers. If the color spec contains no alpha + * information, 255 is taken as transparency value. + * If the input cannot be parsed, leaves an error message in + * interp. Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static int +ParseColor( + Tcl_Interp *interp, /* error messages go there */ + Tcl_Obj *specObj, /* the color data to parse */ + Display *display, /* display of main window, needed to parse + * standard Tk colors */ + Colormap colormap, /* colormap of current display */ + unsigned char *redPtr, /* the result is written to these pointers */ + unsigned char *greenPtr, + unsigned char *bluePtr, + unsigned char *alphaPtr) +{ + const char *specString; + size_t charCount; + + /* + * Find out which color format we have + */ + + specString = TkGetStringFromObj(specObj, &charCount); + + if (charCount == 0) { + /* Empty string */ + *redPtr = *greenPtr = *bluePtr = *alphaPtr = 0; + return TCL_OK; + } + if (charCount > TK_PHOTO_MAX_COLOR_CHARS) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid color")); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "INVALID_COLOR", NULL); + return TCL_ERROR; + } + if (specString[0] == '#') { + return ParseColorAsHex(interp, specString, charCount, display, + colormap, redPtr, greenPtr, bluePtr, alphaPtr); + } + if (ParseColorAsList(interp, specString, charCount, + redPtr, greenPtr, bluePtr, alphaPtr) == TCL_OK) { + return TCL_OK; + } + + /* + * Parsing the color as standard Tk color always is the last option tried + * because TkParseColor() is very slow with values it cannot parse. + */ + + Tcl_ResetResult(interp); + return ParseColorAsStandard(interp, specString, charCount, display, + colormap, redPtr, greenPtr, bluePtr, alphaPtr); + +} + +/* + *---------------------------------------------------------------------- + * + * ParseColorAsList -- + * + * This function extracts color and alpha values from a list of 3 or 4 + * integers (the list color format). + * + * Results: + * On success, writes red, green, blue and alpha values to the + * corresponding pointers. If the color spec contains no alpha + * information, 255 is taken as transparency value. + * Returns a standard Tcl result. + * + * Side effects: + * Does *not* leave error messages in interp. The reason is that + * it is not always possible to tell if the list format was even + * intended and thus it is hard to return meaningful messages. + * A general error message from the caller is probably the best + * alternative. + * + *---------------------------------------------------------------------- + */ +static int +ParseColorAsList( + Tcl_Interp *interp, /* not used */ + const char *colorString, /* the color data to parse */ + int colorStrLen, /* length of the color string */ + unsigned char *redPtr, /* the result is written to these pointers */ + unsigned char *greenPtr, + unsigned char *bluePtr, + unsigned char *alphaPtr) +{ + + /* + * This is kinda ugly. The code would be certainly nicer if it + * used Tcl_ListObjGetElements() and Tcl_GetIntFromObj(). But with + * strtol() it's *much* faster. + */ + + const char *curPos; + int values[4]; + int i; + + curPos = colorString; + i = 0; + + /* + * strtol can give false positives with a sequence of space chars. + * To avoid that, avance the pointer to the next non-blank char. + */ + + while(isspace(*curPos)) { + ++curPos; + } + while (i < 4 && *curPos != '\0') { + values[i] = strtol(curPos, (char **)&curPos, 0); + if (values[i] < 0 || values[i] > 255) { + return TCL_ERROR; + } + while(isspace(*curPos)) { + ++curPos; + } + ++i; + } + + if (i < 3 || *curPos != '\0') { + return TCL_ERROR; + } + if (i < 4) { + values[3] = 255; + } + + *redPtr = (unsigned char) values[0]; + *greenPtr = (unsigned char) values[1]; + *bluePtr = (unsigned char) values[2]; + *alphaPtr = (unsigned char) values[3]; + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * ParseColorAsHex -- + * + * This function extracts color and alpha values from a string + * starting with '#', followed by hex digits. It undestands both + * the #RGBA form and the #RBG (with optional suffix) + * + * Results: + * On success, writes red, green, blue and alpha values to the + * corresponding pointers. If the color spec contains no alpha + * information, 255 is taken as transparency value. + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static int +ParseColorAsHex( + Tcl_Interp *interp, /* error messages are left here */ + const char *colorString, /* the color data to parse */ + int colorStrLen, /* length of the color string */ + Display *display, /* display of main window */ + Colormap colormap, /* colormap of current display */ + unsigned char *redPtr, /* the result is written to these pointers */ + unsigned char *greenPtr, + unsigned char *bluePtr, + unsigned char *alphaPtr) +{ + int i; + unsigned long int colorValue = 0; + + if (colorStrLen - 1 != 4 && colorStrLen - 1 != 8) { + return ParseColorAsStandard(interp, colorString, colorStrLen, + display, colormap, redPtr, greenPtr, bluePtr, alphaPtr); + } + for (i = 1; i < colorStrLen; i++) { + if (!isxdigit(UCHAR(colorString[i]))) { + /* + * There still is a chance that this is a Tk color with + * an alpha suffix + */ + + return ParseColorAsStandard(interp, colorString, colorStrLen, + display, colormap, redPtr, greenPtr, bluePtr, alphaPtr); + } + } + + colorValue = strtoul(colorString + 1, NULL, 16); + switch (colorStrLen - 1) { + case 4: + /* #RGBA format */ + *redPtr = (unsigned char) ((colorValue >> 12) * 0x11); + *greenPtr = (unsigned char) (((colorValue >> 8) & 0xf) * 0x11); + *bluePtr = (unsigned char) (((colorValue >> 4) & 0xf) * 0x11); + *alphaPtr = (unsigned char) ((colorValue & 0xf) * 0x11); + return TCL_OK; + case 8: + /* #RRGGBBAA format */ + *redPtr = (unsigned char) (colorValue >> 24); + *greenPtr = (unsigned char) ((colorValue >> 16) & 0xff); + *bluePtr = (unsigned char) ((colorValue >> 8) & 0xff); + *alphaPtr = (unsigned char) (colorValue & 0xff); + return TCL_OK; + default: + Tcl_Panic("unexpected switch fallthrough"); + } + + /* Shouldn't get here */ + return TCL_ERROR; +} + +/* + *---------------------------------------------------------------------- + * + * ParseColorAsStandard -- + * + * This function tries to split a color stirng in a color and a + * suffix part and to extract color and alpha values from them. The + * color part is treated as regular Tk color. + * + * Results: + * On success, writes red, green, blue and alpha values to the + * corresponding pointers. If the color spec contains no alpha + * information, 255 is taken as transparency value. + * Returns a standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +static int +ParseColorAsStandard( + Tcl_Interp *interp, /* error messages are left here */ + const char *specString, /* the color data to parse */ + int specStrLen, /* length of the color string */ + Display *display, /* display of main window */ + Colormap colormap, /* colormap of current display */ + unsigned char *redPtr, /* the result is written to these pointers */ + unsigned char *greenPtr, + unsigned char *bluePtr, + unsigned char *alphaPtr) +{ + XColor parsedColor; + const char *suffixString, *colorString; + char colorBuffer[TK_PHOTO_MAX_COLOR_CHARS + 1]; + char *tmpString; + double fracAlpha; + unsigned int suffixAlpha; + int i; + + /* + * Split color data string in color and suffix parts + */ + + if ((suffixString = strrchr(specString, '@')) == NULL + && ((suffixString = strrchr(specString, '#')) == NULL + || suffixString == specString)) { + suffixString = specString + specStrLen; + colorString = specString; + } else { + strncpy(colorBuffer, specString, suffixString - specString); + colorBuffer[suffixString - specString] = '\0'; + colorString = (const char*)colorBuffer; + } + + /* + * Try to parse as standard Tk color. + * + * We don't use Tk_GetColor() et al. here, as those functions + * migth return a color that does not exaxtly match the given name + * if the colormap is full. Also, we don't really want the color to be + * added to the colormap. + */ + + if ( ! TkParseColor(display, colormap, colorString, &parsedColor)) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid color name \"%s\"", specString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "INVALID_COLOR", NULL); + return TCL_ERROR; + } + + /* + * parse the Suffix + */ + + switch (suffixString[0]) { + case '\0': + suffixAlpha = 255; + break; + case '@': + fracAlpha = strtod(suffixString + 1, &tmpString); + if (*tmpString != '\0') { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha " + "suffix \"%s\": expected floating-point value", + suffixString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "INVALID COLOR", NULL); + return TCL_ERROR; + } + if (fracAlpha < 0 || fracAlpha > 1) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("invalid alpha suffix" + " \"%s\": value must be in the range from 0 to 1", + suffixString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "INVALID_COLOR", NULL); + return TCL_ERROR; + } + suffixAlpha = (unsigned int) floor(fracAlpha * 255 + 0.5); + break; + case '#': + if (strlen(suffixString + 1) < 1 || strlen(suffixString + 1)> 2) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid alpha suffix \"%s\"", suffixString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "INVALID_COLOR", NULL); + return TCL_ERROR; + } + for (i = 1; i <= (int)strlen(suffixString + 1); i++) { + if ( ! isxdigit(UCHAR(suffixString[i]))) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid alpha suffix \"%s\": expected hex digit", + suffixString)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "INVALID_COLOR", NULL); + return TCL_ERROR; + } + } + if (strlen(suffixString + 1) == 1) { + sscanf(suffixString, "#%1x", &suffixAlpha); + suffixAlpha *= 0x11; + } else { + sscanf(suffixString, "#%2x", &suffixAlpha); + } + break; + default: + Tcl_Panic("unexpected switch fallthrough"); + } + + *redPtr = (unsigned char) (parsedColor.red >> 8); + *greenPtr = (unsigned char) (parsedColor.green >> 8); + *bluePtr = (unsigned char) (parsedColor.blue >> 8); + *alphaPtr = (unsigned char) suffixAlpha; + + return TCL_OK; +} + +/* + *---------------------------------------------------------------------- + * + * TkDebugStringMatchDef -- + * + * Debugging function for StringMatchDef. Basically just an alias for + * that function, intended to expose it directly to tests, as + * StirngMatchDef cannot be sufficiently tested otherwise. + * + * Results: + * See StringMatchDef. + * + * Side effects: + * None + *---------------------------------------------------------------------- + */ +int +TkDebugPhotoStringMatchDef( + Tcl_Interp *interp, /* Error messages are left in this interpreter */ + Tcl_Obj *data, /* The data to check */ + Tcl_Obj *formatString, /* Value of the -format option, not used here */ + int *widthPtr, /* Width of image is written to this location */ + int *heightPtr) /* Height of image is written to this location */ +{ + return StringMatchDef(data, formatString, widthPtr, heightPtr, interp); +} + + +/* Local Variables: */ +/* mode: c */ +/* fill-column: 78 */ +/* c-basic-offset: 4 */ +/* tab-width: 8 */ +/* indent-tabs-mode: nil */ +/* End: */ Index: generic/tkImgPNG.c ================================================================== --- generic/tkImgPNG.c +++ generic/tkImgPNG.c @@ -33,11 +33,11 @@ /* * Chunk type flags. */ -#define PNG_CF_ANCILLARY 0x10000000L /* Non-critical chunk (can ignore). */ +#define PNG_CF_ANCILLARY 0x20000000L /* Non-critical chunk (can ignore). */ #define PNG_CF_PRIVATE 0x00100000L /* Application-specific chunk. */ #define PNG_CF_RESERVED 0x00001000L /* Not used. */ #define PNG_CF_COPYSAFE 0x00000010L /* Opaque data safe for copying. */ /* @@ -125,11 +125,11 @@ */ Tcl_Channel channel; /* Channel for from-file reads. */ Tcl_Obj *objDataPtr; unsigned char *strDataBuf; /* Raw source data for from-string reads. */ - int strDataLen; /* Length of source data. */ + size_t strDataLen; /* Length of source data. */ unsigned char *base64Data; /* base64 encoded string data. */ unsigned char base64Bits; /* Remaining bits from last base64 read. */ unsigned char base64State; /* Current state of base64 decoder. */ double alpha; /* Alpha from -format option. */ @@ -213,20 +213,20 @@ Tcl_Channel chan, Tcl_Obj *objPtr, int dir); static inline unsigned char Paeth(int a, int b, int c); static int ParseFormat(Tcl_Interp *interp, Tcl_Obj *fmtObj, PNGImage *pngPtr); static int ReadBase64(Tcl_Interp *interp, PNGImage *pngPtr, - unsigned char *destPtr, int destSz, + unsigned char *destPtr, size_t destSz, unsigned long *crcPtr); static int ReadByteArray(Tcl_Interp *interp, PNGImage *pngPtr, - unsigned char *destPtr, int destSz, + unsigned char *destPtr, size_t destSz, unsigned long *crcPtr); static int ReadData(Tcl_Interp *interp, PNGImage *pngPtr, - unsigned char *destPtr, int destSz, + unsigned char *destPtr, size_t destSz, unsigned long *crcPtr); static int ReadChunkHeader(Tcl_Interp *interp, PNGImage *pngPtr, - int *sizePtr, unsigned long *typePtr, + size_t *sizePtr, unsigned long *typePtr, unsigned long *crcPtr); static int ReadIDAT(Tcl_Interp *interp, PNGImage *pngPtr, int chunkSz, unsigned long crc); static int ReadIHDR(Tcl_Interp *interp, PNGImage *pngPtr); static inline int ReadInt32(Tcl_Interp *interp, PNGImage *pngPtr, @@ -249,13 +249,13 @@ static int UnfilterLine(Tcl_Interp *interp, PNGImage *pngPtr); static inline int WriteByte(Tcl_Interp *interp, PNGImage *pngPtr, unsigned char c, unsigned long *crcPtr); static inline int WriteChunk(Tcl_Interp *interp, PNGImage *pngPtr, unsigned long chunkType, - const unsigned char *dataPtr, int dataSize); + const unsigned char *dataPtr, size_t dataSize); static int WriteData(Tcl_Interp *interp, PNGImage *pngPtr, - const unsigned char *srcPtr, int srcSz, + const unsigned char *srcPtr, size_t srcSz, unsigned long *crcPtr); static int WriteExtraChunks(Tcl_Interp *interp, PNGImage *pngPtr); static int WriteIHDR(Tcl_Interp *interp, PNGImage *pngPtr, Tk_PhotoImageBlock *blockPtr); @@ -318,11 +318,11 @@ if (objPtr) { Tcl_IncrRefCount(objPtr); pngPtr->objDataPtr = objPtr; pngPtr->strDataBuf = - Tcl_GetByteArrayFromObj(objPtr, &pngPtr->strDataLen); + TkGetByteArrayFromObj(objPtr, &pngPtr->strDataLen); } /* * Initialize the palette transparency table to fully opaque. */ @@ -429,11 +429,11 @@ static int ReadBase64( Tcl_Interp *interp, PNGImage *pngPtr, unsigned char *destPtr, - int destSz, + size_t destSz, unsigned long *crcPtr) { static const unsigned char from64[] = { 0x82, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x80, 0x80, 0x83, 0x80, 0x80, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, 0x83, @@ -554,26 +554,26 @@ static int ReadByteArray( Tcl_Interp *interp, PNGImage *pngPtr, unsigned char *destPtr, - int destSz, + size_t destSz, unsigned long *crcPtr) { /* * Check to make sure the number of requested bytes are available. */ - if (pngPtr->strDataLen < destSz) { + if ((size_t)pngPtr->strDataLen < destSz) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "unexpected end of image data", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EARLY_END", NULL); return TCL_ERROR; } while (destSz) { - int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ); + size_t blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ); memcpy(destPtr, pngPtr->strDataBuf, blockSz); pngPtr->strDataBuf += blockSz; pngPtr->strDataLen -= blockSz; @@ -612,24 +612,24 @@ static int ReadData( Tcl_Interp *interp, PNGImage *pngPtr, unsigned char *destPtr, - int destSz, + size_t destSz, unsigned long *crcPtr) { if (pngPtr->base64Data) { return ReadBase64(interp, pngPtr, destPtr, destSz, crcPtr); } else if (pngPtr->strDataBuf) { return ReadByteArray(interp, pngPtr, destPtr, destSz, crcPtr); } while (destSz) { - int blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ); + size_t blockSz = PNG_MIN(destSz, PNG_BLOCK_SZ); - blockSz = Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz); - if (blockSz < 0) { + blockSz = (size_t)Tcl_Read(pngPtr->channel, (char *)destPtr, blockSz); + if (blockSz == (size_t)-1) { /* TODO: failure info... */ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "channel read failed: %s", Tcl_PosixError(interp))); return TCL_ERROR; } @@ -857,11 +857,11 @@ static int ReadChunkHeader( Tcl_Interp *interp, PNGImage *pngPtr, - int *sizePtr, + size_t *sizePtr, unsigned long *typePtr, unsigned long *crcPtr) { unsigned long chunkType = 0; int chunkSz = 0; @@ -982,11 +982,11 @@ * No nice ASCII conversion; shouldn't happen either, but * we'll be doubly careful. */ Tcl_SetObjResult(interp, Tcl_NewStringObj( - "encountered an unsupported criticial chunk type", + "encountered an unsupported critical chunk type", -1)); } else { char typeString[5]; typeString[0] = (char) ((chunkType >> 24) & 255); @@ -993,11 +993,11 @@ typeString[1] = (char) ((chunkType >> 16) & 255); typeString[2] = (char) ((chunkType >> 8) & 255); typeString[3] = (char) (chunkType & 255); typeString[4] = '\0'; Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "encountered an unsupported criticial chunk type" + "encountered an unsupported critical chunk type" " \"%s\"", typeString)); } Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "UNSUPPORTED_CRITICAL", NULL); return TCL_ERROR; @@ -1238,11 +1238,11 @@ Tcl_Interp *interp, PNGImage *pngPtr) { unsigned char sigBuf[PNG_SIG_SZ]; unsigned long chunkType; - int chunkSz; + size_t chunkSz; unsigned long crc; unsigned long width, height; int mismatch; /* @@ -1262,11 +1262,11 @@ /* * If reading from string, reset position and try base64 decode. */ if (mismatch && pngPtr->strDataBuf) { - pngPtr->strDataBuf = Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, + pngPtr->strDataBuf = TkGetByteArrayFromObj(pngPtr->objDataPtr, &pngPtr->strDataLen); pngPtr->base64Data = pngPtr->strDataBuf; if (ReadData(interp, pngPtr, sigBuf, PNG_SIG_SZ, NULL) == TCL_ERROR) { return TCL_ERROR; @@ -2096,11 +2096,11 @@ /* * Process IDAT contents until there is no more in this chunk. */ while (chunkSz && !Tcl_ZlibStreamEof(pngPtr->stream)) { - int len1, len2; + size_t len1, len2; /* * Read another block of input into the zlib stream if data remains. */ @@ -2145,18 +2145,18 @@ * Inflate, processing each output buffer's worth as a line of pixels, * until we cannot fill the buffer any more. */ getNextLine: - Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len1); + TkGetByteArrayFromObj(pngPtr->thisLineObj, &len1); if (Tcl_ZlibStreamGet(pngPtr->stream, pngPtr->thisLineObj, pngPtr->phaseSize - len1) == TCL_ERROR) { return TCL_ERROR; } - Tcl_GetByteArrayFromObj(pngPtr->thisLineObj, &len2); + TkGetByteArrayFromObj(pngPtr->thisLineObj, &len2); - if (len2 == pngPtr->phaseSize) { + if (len2 == (size_t)pngPtr->phaseSize) { if (pngPtr->phase > 7) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "extra data after final scan line of final phase", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "EXTRA_DATA", @@ -2243,14 +2243,14 @@ int offset = pngPtr->block.offset[3]; p += offset; if (16 == pngPtr->bitDepth) { - register int channel; + register unsigned int channel; while (p < endPtr) { - channel = (unsigned char) + channel = (unsigned int) (((p[0] << 8) | p[1]) * pngPtr->alpha); *p++ = (unsigned char) (channel >> 8); *p++ = (unsigned char) (channel & 0xff); @@ -2381,11 +2381,11 @@ Tk_PhotoHandle imageHandle, int destX, int destY) { unsigned long chunkType; - int chunkSz; + size_t chunkSz; unsigned long crc; /* * Parse the PNG signature and IHDR (header) chunk. */ @@ -2766,11 +2766,11 @@ PNGImage png; int match = 0; InitPNGImage(NULL, &png, NULL, pObjData, TCL_ZLIB_STREAM_INFLATE); - png.strDataBuf = Tcl_GetByteArrayFromObj(pObjData, &png.strDataLen); + png.strDataBuf = TkGetByteArrayFromObj(pObjData, &png.strDataLen); if (ReadIHDR(interp, &png) == TCL_OK) { *widthPtr = png.block.width; *heightPtr = png.block.height; match = 1; @@ -2844,11 +2844,11 @@ static int WriteData( Tcl_Interp *interp, PNGImage *pngPtr, const unsigned char *srcPtr, - int srcSz, + size_t srcSz, unsigned long *crcPtr) { if (!srcPtr || !srcSz) { return TCL_OK; } @@ -2861,16 +2861,16 @@ * TODO: is Tcl_AppendObjToObj faster here? i.e., does Tcl join the * objects immediately or store them in a multi-object rep? */ if (pngPtr->objDataPtr) { - int objSz; + size_t objSz; unsigned char *destPtr; - Tcl_GetByteArrayFromObj(pngPtr->objDataPtr, &objSz); + TkGetByteArrayFromObj(pngPtr->objDataPtr, &objSz); - if (objSz > INT_MAX - srcSz) { + if (objSz + srcSz > INT_MAX) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "image too large to store completely in byte array", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "PNG", "TOO_LARGE", NULL); return TCL_ERROR; } @@ -2883,11 +2883,11 @@ Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); return TCL_ERROR; } memcpy(destPtr+objSz, srcPtr, srcSz); - } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) < 0) { + } else if (Tcl_Write(pngPtr->channel, (const char *) srcPtr, srcSz) == TCL_IO_FAILURE) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "write to channel failed: %s", Tcl_PosixError(interp))); return TCL_ERROR; } @@ -2959,11 +2959,11 @@ WriteChunk( Tcl_Interp *interp, PNGImage *pngPtr, unsigned long chunkType, const unsigned char *dataPtr, - int dataSize) + size_t dataSize) { unsigned long crc = Tcl_ZlibCRC32(0, NULL, 0); int result = TCL_OK; /* @@ -3130,13 +3130,14 @@ WriteIDAT( Tcl_Interp *interp, PNGImage *pngPtr, Tk_PhotoImageBlock *blockPtr) { - int rowNum, flush = TCL_ZLIB_NO_FLUSH, outputSize, result; + int rowNum, flush = TCL_ZLIB_NO_FLUSH, result; Tcl_Obj *outputObj; unsigned char *outputBytes; + size_t outputSize; /* * Filter and compress each row one at a time. */ @@ -3224,11 +3225,11 @@ * Now get the compressed data and write it as one big IDAT chunk. */ outputObj = Tcl_NewObj(); (void) Tcl_ZlibStreamGet(pngPtr->stream, outputObj, -1); - outputBytes = Tcl_GetByteArrayFromObj(outputObj, &outputSize); + outputBytes = TkGetByteArrayFromObj(outputObj, &outputSize); result = WriteChunk(interp, pngPtr, CHUNK_IDAT, outputBytes, outputSize); Tcl_DecrRefCount(outputObj); return result; } Index: generic/tkImgPPM.c ================================================================== --- generic/tkImgPPM.c +++ generic/tkImgPPM.c @@ -139,11 +139,12 @@ * written to. */ int srcX, int srcY) /* Coordinates of top-left pixel to be used in * image being read. */ { int fileWidth, fileHeight, maxIntensity; - int nLines, nBytes, h, type, count, bytesPerChannel = 1; + int nLines, h, type, bytesPerChannel = 1; + size_t nBytes, count; unsigned char *pixelPtr; Tk_PhotoImageBlock block; type = ReadPPMFileHeader(chan, &fileWidth, &fileHeight, &maxIntensity); if (type == 0) { @@ -283,11 +284,12 @@ const char *fileName, Tcl_Obj *format, Tk_PhotoImageBlock *blockPtr) { Tcl_Channel chan; - int w, h, greenOffset, blueOffset, nBytes; + int w, h, greenOffset, blueOffset; + size_t nBytes; unsigned char *pixelPtr, *pixLinePtr; char header[16 + TCL_INTEGER_SPACE * 2]; chan = Tcl_OpenFileChannel(interp, fileName, "w", 0666); if (chan == NULL) { @@ -313,20 +315,20 @@ blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; if ((greenOffset == 1) && (blueOffset == 2) && (blockPtr->pixelSize == 3) && (blockPtr->pitch == (blockPtr->width * 3))) { nBytes = blockPtr->height * blockPtr->pitch; - if (Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) { + if ((size_t)Tcl_Write(chan, (char *) pixLinePtr, nBytes) != nBytes) { goto writeerror; } } else { for (h = blockPtr->height; h > 0; h--) { pixelPtr = pixLinePtr; for (w = blockPtr->width; w > 0; w--) { - if ( Tcl_Write(chan,(char *)&pixelPtr[0], 1) == -1 || - Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1)==-1 || - Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) ==-1) { + if (Tcl_Write(chan,(char *)&pixelPtr[0], 1) == TCL_IO_FAILURE || + Tcl_Write(chan,(char *)&pixelPtr[greenOffset],1) == TCL_IO_FAILURE || + Tcl_Write(chan,(char *)&pixelPtr[blueOffset],1) == TCL_IO_FAILURE) { goto writeerror; } pixelPtr += blockPtr->pixelSize; } pixLinePtr += blockPtr->pitch; @@ -760,14 +762,15 @@ unsigned char **dataBufferPtr, int *dataSizePtr) { #define BUFFER_SIZE 1000 char buffer[BUFFER_SIZE], c; - int i, numFields, dataSize, type = 0; + int i, numFields, type = 0; + size_t dataSize; unsigned char *dataBuffer; - dataBuffer = Tcl_GetByteArrayFromObj(dataPtr, &dataSize); + dataBuffer = TkGetByteArrayFromObj(dataPtr, &dataSize); /* * Read 4 space-separated fields from the string, ignoring comments (any * line that starts with "#"). */ Index: generic/tkImgPhInstance.c ================================================================== --- generic/tkImgPhInstance.c +++ generic/tkImgPhInstance.c @@ -108,11 +108,11 @@ /* * Free up our old color table, and get a new one. */ if (colorTablePtr != NULL) { - colorTablePtr->liveRefCount -= 1; + colorTablePtr->liveRefCount--; FreeColorTable(colorTablePtr, 0); } GetColorTable(instancePtr); /* @@ -416,10 +416,17 @@ #define GetBValue(rgb) (UCHAR(((rgb) & blue_mask) >> blue_shift)) #define RGB(r, g, b) ((unsigned)( \ (UCHAR(r) << red_shift) | \ (UCHAR(g) << green_shift) | \ (UCHAR(b) << blue_shift) )) +#ifdef MAC_OSX_TK +#define RGBA(r, g, b, a) ((unsigned)( \ + (UCHAR(r) << red_shift) | \ + (UCHAR(g) << green_shift) | \ + (UCHAR(b) << blue_shift) | \ + (UCHAR(a) << alpha_shift) )) +#endif #define RGB15(r, g, b) ((unsigned)( \ (((r) * red_mask / 255) & red_mask) | \ (((g) * green_mask / 255) & green_mask) | \ (((b) * blue_mask / 255) & blue_mask) )) #endif /* !_WIN32 */ @@ -483,10 +490,17 @@ green_shift++; } while ((0x0001 & (blue_mask >> blue_shift)) == 0) { blue_shift++; } +#ifdef MAC_OSX_TK + unsigned long alpha_mask = visual->alpha_mask; + unsigned long alpha_shift = 0; + while ((0x0001 & (alpha_mask >> alpha_shift)) == 0) { + alpha_shift++; + } +#endif #endif /* !_WIN32 */ /* * Only UNIX requires the special case for <24bpp. It varies with 3 extra * shifts and uses RGB15. The 24+bpp version could also then be further @@ -583,11 +597,15 @@ unalpha = 255 - alpha; /* Calculate once. */ r = ALPHA_BLEND(ra, r, alpha, unalpha); g = ALPHA_BLEND(ga, g, alpha, unalpha); b = ALPHA_BLEND(ba, b, alpha, unalpha); } +#ifndef MAC_OSX_TK XPutPixel(bgImg, x, y, RGB(r, g, b)); +#else + XPutPixel(bgImg, x, y, RGBA(r, g, b, alpha)); +#endif } } } #undef ALPHA_BLEND } @@ -719,12 +737,11 @@ * image. */ { PhotoInstance *instancePtr = clientData; ColorTable *colorPtr; - instancePtr->refCount -= 1; - if (instancePtr->refCount > 0) { + if (instancePtr->refCount-- > 1) { return; } /* * There are no more uses of the image within this widget. Decrement the @@ -733,11 +750,11 @@ * structure. */ colorPtr = instancePtr->colorTablePtr; if (colorPtr != NULL) { - colorPtr->liveRefCount -= 1; + colorPtr->liveRefCount--; } Tcl_DoWhenIdle(TkImgDisposeInstance, instancePtr); } @@ -1116,12 +1133,11 @@ FreeColorTable( ColorTable *colorPtr, /* Pointer to the color table which is no * longer required by an instance. */ int force) /* Force free to happen immediately. */ { - colorPtr->refCount--; - if (colorPtr->refCount > 0) { + if (colorPtr->refCount-- > 1) { return; } if (force) { if (colorPtr->flags & DISPOSE_PENDING) { @@ -1260,11 +1276,11 @@ } } } } else { /* - * Monochrome display - allocate the shades of grey we want. + * Monochrome display - allocate the shades of gray we want. */ for (i = 0; i < numColors; ++i) { if (igam == 1.0) { r = CFRAC(i, numColors - 1); Index: generic/tkImgPhoto.c ================================================================== --- generic/tkImgPhoto.c +++ generic/tkImgPhoto.c @@ -46,45 +46,51 @@ * allowedOptions parameter on a call to ParseSubcommandOptions if that option * is allowed for the current photo image subcommand. On return, the bit is * set in the options field of the SubcommandOptions structure if that option * was specified. * + * OPT_ALPHA: Set if -alpha option allowed/specified. * OPT_BACKGROUND: Set if -format option allowed/specified. * OPT_COMPOSITE: Set if -compositingrule option allowed/spec'd. * OPT_FORMAT: Set if -format option allowed/specified. * OPT_FROM: Set if -from option allowed/specified. * OPT_GRAYSCALE: Set if -grayscale option allowed/specified. * OPT_SHRINK: Set if -shrink option allowed/specified. * OPT_SUBSAMPLE: Set if -subsample option allowed/spec'd. * OPT_TO: Set if -to option allowed/specified. + * OPT_WITHALPHA: Set if -withalpha option allowed/specified. * OPT_ZOOM: Set if -zoom option allowed/specified. */ -#define OPT_BACKGROUND 1 -#define OPT_COMPOSITE 2 -#define OPT_FORMAT 4 -#define OPT_FROM 8 -#define OPT_GRAYSCALE 0x10 -#define OPT_SHRINK 0x20 -#define OPT_SUBSAMPLE 0x40 -#define OPT_TO 0x80 -#define OPT_ZOOM 0x100 +#define OPT_ALPHA 1 +#define OPT_BACKGROUND 2 +#define OPT_COMPOSITE 4 +#define OPT_FORMAT 8 +#define OPT_FROM 0x10 +#define OPT_GRAYSCALE 0x20 +#define OPT_SHRINK 0x40 +#define OPT_SUBSAMPLE 0x80 +#define OPT_TO 0x100 +#define OPT_WITHALPHA 0x200 +#define OPT_ZOOM 0x400 /* * List of option names. The order here must match the order of declarations * of the OPT_* constants above. */ static const char *const optionNames[] = { + "-alpha", "-background", "-compositingrule", "-format", "-from", "-grayscale", "-shrink", "-subsample", "-to", + "-withalpha", "-zoom", NULL }; /* @@ -180,13 +186,10 @@ PhotoMaster *masterPtr, int objc, Tcl_Obj *const objv[], int flags); static int ToggleComplexAlphaIfNeeded(PhotoMaster *mPtr); static int ImgPhotoSetSize(PhotoMaster *masterPtr, int width, int height); -static int ImgStringWrite(Tcl_Interp *interp, - Tcl_Obj *formatString, - Tk_PhotoImageBlock *blockPtr); static char * ImgGetPhoto(PhotoMaster *masterPtr, Tk_PhotoImageBlock *blockPtr, struct SubcommandOptions *optPtr); static int MatchFileFormat(Tcl_Interp *interp, Tcl_Channel chan, const char *fileName, Tcl_Obj *formatString, @@ -400,18 +403,17 @@ PHOTO_GET, PHOTO_PUT, PHOTO_READ, PHOTO_REDITHER, PHOTO_TRANS, PHOTO_WRITE }; PhotoMaster *masterPtr = clientData; - int result, index, x, y, width, height, dataWidth, dataHeight, listObjc; + int result, index, x, y, width, height; struct SubcommandOptions options; - Tcl_Obj **listObjv, **srcObjv; unsigned char *pixelPtr; Tk_PhotoImageBlock block; - Tk_Window tkwin; Tk_PhotoImageFormat *imageFormat; - int imageWidth, imageHeight, matched, length, oldformat = 0; + size_t length; + int imageWidth, imageHeight, matched, oldformat = 0; Tcl_Channel chan; Tk_PhotoHandle srcHandle; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -444,16 +446,16 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); return TCL_ERROR; } - arg = Tcl_GetStringFromObj(objv[2], &length); - if (strncmp(arg,"-data", (unsigned) length) == 0) { + arg = TkGetStringFromObj(objv[2], &length); + if (strncmp(arg,"-data", length) == 0) { if (masterPtr->dataString) { Tcl_SetObjResult(interp, masterPtr->dataString); } - } else if (strncmp(arg,"-format", (unsigned) length) == 0) { + } else if (strncmp(arg,"-format", length) == 0) { if (masterPtr->format) { Tcl_SetObjResult(interp, masterPtr->format); } } else { Tk_ConfigureValue(interp, Tk_MainWindow(interp), configSpecs, @@ -493,13 +495,13 @@ Tcl_ListObjAppendList(interp, obj, Tcl_GetObjResult(interp)); Tcl_SetObjResult(interp, obj); return TCL_OK; } else if (objc == 3) { - const char *arg = Tcl_GetStringFromObj(objv[2], &length); + const char *arg = TkGetStringFromObj(objv[2], &length); - if (length > 1 && !strncmp(arg, "-data", (unsigned) length)) { + if (length > 1 && !strncmp(arg, "-data", length)) { Tcl_AppendResult(interp, "-data {} {} {}", NULL); if (masterPtr->dataString) { /* * TODO: Modifying result is bad! */ @@ -509,11 +511,11 @@ } else { Tcl_AppendResult(interp, " {}", NULL); } return TCL_OK; } else if (length > 1 && - !strncmp(arg, "-format", (unsigned) length)) { + !strncmp(arg, "-format", length)) { Tcl_AppendResult(interp, "-format {} {} {}", NULL); if (masterPtr->format) { /* * TODO: Modifying result is bad! */ @@ -571,10 +573,13 @@ } Tk_PhotoGetImage(srcHandle, &block); if ((options.fromX2 > block.width) || (options.fromY2 > block.height) || (options.fromX2 > block.width) || (options.fromY2 > block.height)) { + if (options.background) { + Tk_FreeColor(options.background); + } Tcl_SetObjResult(interp, Tcl_NewStringObj( "coordinates for -from option extend outside source image", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_FROM", NULL); return TCL_ERROR; @@ -619,48 +624,61 @@ / -options.subsampleY; } options.toY2 = options.toY + height * options.zoomY; } - /* - * Set the destination image size if the -shrink option was specified. - */ - - if (options.options & OPT_SHRINK) { - if (ImgPhotoSetSize(masterPtr, options.toX2, - options.toY2) != TCL_OK) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); - Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); - return TCL_ERROR; - } - } - /* * Copy the image data over using Tk_PhotoPutZoomedBlock. */ block.pixelPtr += options.fromX * block.pixelSize + options.fromY * block.pitch; block.width = options.fromX2 - options.fromX; block.height = options.fromY2 - options.fromY; - return Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr, + result = Tk_PhotoPutZoomedBlock(interp, (Tk_PhotoHandle) masterPtr, &block, options.toX, options.toY, options.toX2 - options.toX, options.toY2 - options.toY, options.zoomX, options.zoomY, options.subsampleX, options.subsampleY, options.compositingRule); + /* + * Set the destination image size if the -shrink option was specified. + * This has to be done _after_ copying the data. Otherwise, if source + * and destination are the same image, block.pixelPtr would point to + * an invalid memory block (bug [5239fd749b]). + */ + + if (options.options & OPT_SHRINK) { + if (ImgPhotoSetSize(masterPtr, options.toX2, + options.toY2) != TCL_OK) { + if (options.background) { + Tk_FreeColor(options.background); + } + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + return TCL_ERROR; + } + } + Tk_ImageChanged(masterPtr->tkMaster, 0, 0, 0, 0, + masterPtr->width, masterPtr->height); + if (options.background) { + Tk_FreeColor(options.background); + } + return result; + case PHOTO_DATA: { - char *data; + char *data = NULL; + Tcl_Obj *freeObj = NULL; /* * photo data command - first parse and check any options given. */ Tk_ImageStringWriteProc *stringWriteProc = NULL; - index = 2; + index = 1; memset(&options, 0, sizeof(options)); options.name = NULL; options.format = NULL; options.fromX = 0; options.fromY = 0; @@ -667,11 +685,11 @@ if (ParseSubcommandOptions(&options, interp, OPT_FORMAT | OPT_FROM | OPT_GRAYSCALE | OPT_BACKGROUND, &index, objc, objv) != TCL_OK) { return TCL_ERROR; } - if ((options.name != NULL) || (index < objc)) { + if ((options.name == NULL) || (index < objc)) { Tcl_WrongNumArgs(interp, 2, objv, "?-option value ...?"); return TCL_ERROR; } if ((options.fromX > masterPtr->width) || (options.fromY > masterPtr->height) @@ -689,54 +707,54 @@ if (!(options.options & OPT_FROM) || (options.fromX2 < 0)) { options.fromX2 = masterPtr->width; options.fromY2 = masterPtr->height; } + if (!(options.options & OPT_FORMAT)) { + options.format = Tcl_NewStringObj("default", -1); + freeObj = options.format; + } /* * Search for an appropriate image string format handler. */ - if (options.options & OPT_FORMAT) { - matched = 0; - for (imageFormat = tsdPtr->formatList; imageFormat != NULL; - imageFormat = imageFormat->nextPtr) { - if ((strncasecmp(Tcl_GetString(options.format), - imageFormat->name, strlen(imageFormat->name)) == 0)) { - matched = 1; - if (imageFormat->stringWriteProc != NULL) { - stringWriteProc = imageFormat->stringWriteProc; - break; - } - } - } - if (stringWriteProc == NULL) { - oldformat = 1; - for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL; - imageFormat = imageFormat->nextPtr) { - if ((strncasecmp(Tcl_GetString(options.format), - imageFormat->name, - strlen(imageFormat->name)) == 0)) { - matched = 1; - if (imageFormat->stringWriteProc != NULL) { - stringWriteProc = imageFormat->stringWriteProc; - break; - } - } - } - } - if (stringWriteProc == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "image string format \"%s\" is %s", - Tcl_GetString(options.format), - (matched ? "not supported" : "unknown"))); - Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", - Tcl_GetString(options.format), NULL); - return TCL_ERROR; - } - } else { - stringWriteProc = ImgStringWrite; + matched = 0; + for (imageFormat = tsdPtr->formatList; imageFormat != NULL; + imageFormat = imageFormat->nextPtr) { + if ((strncasecmp(Tcl_GetString(options.format), + imageFormat->name, strlen(imageFormat->name)) == 0)) { + matched = 1; + if (imageFormat->stringWriteProc != NULL) { + stringWriteProc = imageFormat->stringWriteProc; + break; + } + } + } + if (stringWriteProc == NULL) { + oldformat = 1; + for (imageFormat = tsdPtr->oldFormatList; imageFormat != NULL; + imageFormat = imageFormat->nextPtr) { + if ((strncasecmp(Tcl_GetString(options.format), + imageFormat->name, + strlen(imageFormat->name)) == 0)) { + matched = 1; + if (imageFormat->stringWriteProc != NULL) { + stringWriteProc = imageFormat->stringWriteProc; + break; + } + } + } + } + if (stringWriteProc == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "image string format \"%s\" is %s", + Tcl_GetString(options.format), + (matched ? "not supported" : "unknown"))); + Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", + Tcl_GetString(options.format), NULL); + goto dataErrorExit; } /* * Call the handler's string write function to write out the image. */ @@ -769,24 +787,51 @@ Tk_FreeColor(options.background); } if (data) { ckfree(data); } + if (freeObj != NULL) { + Tcl_DecrRefCount(freeObj); + } return result; + + dataErrorExit: + if (options.background) { + Tk_FreeColor(options.background); + } + if (data) { + ckfree(data); + } + if (freeObj != NULL) { + Tcl_DecrRefCount(freeObj); + } + return TCL_ERROR; } case PHOTO_GET: { /* * photo get command - first parse and check parameters. */ - Tcl_Obj *channels[3]; + Tcl_Obj *channels[4]; + int channelCount = 3; - if (objc != 4) { - Tcl_WrongNumArgs(interp, 2, objv, "x y"); + index = 3; + memset(&options, 0, sizeof(options)); + options.name = NULL; + if (ParseSubcommandOptions(&options, interp, OPT_WITHALPHA, + &index, objc, objv) != TCL_OK) { + return TCL_ERROR; + } + if (options.name == NULL || index < objc) { + Tcl_WrongNumArgs(interp, 2, objv, "x y ?-withalpha?"); return TCL_ERROR; } + if (options.options & OPT_WITHALPHA) { + channelCount = 4; + } + if ((Tcl_GetIntFromObj(interp, objv[2], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[3], &y) != TCL_OK)) { return TCL_ERROR; } if ((x < 0) || (x >= masterPtr->width) @@ -798,206 +843,86 @@ NULL); return TCL_ERROR; } /* - * Extract the value of the desired pixel and format it as a string. + * Extract the value of the desired pixel and format it as a list. */ pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; channels[0] = Tcl_NewIntObj(pixelPtr[0]); channels[1] = Tcl_NewIntObj(pixelPtr[1]); channels[2] = Tcl_NewIntObj(pixelPtr[2]); - Tcl_SetObjResult(interp, Tcl_NewListObj(3, channels)); + channels[3] = Tcl_NewIntObj(pixelPtr[3]); + Tcl_SetObjResult(interp, Tcl_NewListObj(channelCount, channels)); return TCL_OK; } - case PHOTO_PUT: + case PHOTO_PUT: { + Tcl_Obj *format, *data; + /* - * photo put command - first parse the options and colors specified. + * photo put command - first parse the options. */ index = 2; memset(&options, 0, sizeof(options)); options.name = NULL; + options.format = NULL; if (ParseSubcommandOptions(&options, interp, OPT_TO|OPT_FORMAT, &index, objc, objv) != TCL_OK) { return TCL_ERROR; } if ((options.name == NULL) || (index < objc)) { Tcl_WrongNumArgs(interp, 2, objv, "data ?-option value ...?"); return TCL_ERROR; } - if (MatchStringFormat(interp, options.name ? objv[2]:NULL, - options.format, &imageFormat, &imageWidth, - &imageHeight, &oldformat) == TCL_OK) { - Tcl_Obj *format, *data; - - if (!(options.options & OPT_TO) || (options.toX2 < 0)) { - options.toX2 = options.toX + imageWidth; - options.toY2 = options.toY + imageHeight; - } - if (imageWidth > options.toX2 - options.toX) { - imageWidth = options.toX2 - options.toX; - } - if (imageHeight > options.toY2 - options.toY) { - imageHeight = options.toY2 - options.toY; - } - format = options.format; - data = objv[2]; - if (oldformat) { - if (format) { - format = (Tcl_Obj *) Tcl_GetString(format); - } - data = (Tcl_Obj *) Tcl_GetString(data); - } - if (imageFormat->stringReadProc(interp, data, format, - (Tk_PhotoHandle) masterPtr, options.toX, options.toY, - imageWidth, imageHeight, 0, 0) != TCL_OK) { - return TCL_ERROR; - } - masterPtr->flags |= IMAGE_CHANGED; - return TCL_OK; - } - if (options.options & OPT_FORMAT) { - return TCL_ERROR; - } - Tcl_ResetResult(interp); - if (Tcl_ListObjGetElements(interp, options.name, - &dataHeight, &srcObjv) != TCL_OK) { - return TCL_ERROR; - } - tkwin = Tk_MainWindow(interp); - block.pixelPtr = NULL; - dataWidth = 0; - pixelPtr = NULL; - for (y = 0; y < dataHeight; ++y) { - if (Tcl_ListObjGetElements(interp, srcObjv[y], - &listObjc, &listObjv) != TCL_OK) { - break; - } - - if (y == 0) { - if (listObjc == 0) { - /* - * Lines must be non-empty... - */ - - break; - } - dataWidth = listObjc; - /* - * Memory allocation overflow protection. - * May not be able to trigger/ demo / test this. - */ - - if (dataWidth > (int)((UINT_MAX/3) / dataHeight)) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "photo image dimensions exceed Tcl memory limits", -1)); - Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", - "OVERFLOW", NULL); - break; - } - - pixelPtr = ckalloc(dataWidth * dataHeight * 3); - block.pixelPtr = pixelPtr; - } else if (listObjc != dataWidth) { - Tcl_SetObjResult(interp, Tcl_NewStringObj( - "all elements of color list must have the same" - " number of elements", -1)); - Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", - "NON_RECTANGULAR", NULL); - break; - } - - for (x = 0; x < dataWidth; ++x) { - const char *colorString = Tcl_GetString(listObjv[x]); - XColor color; - int tmpr, tmpg, tmpb; - - /* - * We do not use Tk_GetColorFromObj() because we absolutely do - * not want to invoke the fallback code. - */ - - if (colorString[0] == '#') { - if (isxdigit(UCHAR(colorString[1])) && - isxdigit(UCHAR(colorString[2])) && - isxdigit(UCHAR(colorString[3]))) { - if (colorString[4] == '\0') { - /* Got #rgb */ - sscanf(colorString+1, "%1x%1x%1x", - &tmpr, &tmpg, &tmpb); - *pixelPtr++ = tmpr * 0x11; - *pixelPtr++ = tmpg * 0x11; - *pixelPtr++ = tmpb * 0x11; - continue; - } else if (isxdigit(UCHAR(colorString[4])) && - isxdigit(UCHAR(colorString[5])) && - isxdigit(UCHAR(colorString[6])) && - colorString[7] == '\0') { - /* Got #rrggbb */ - sscanf(colorString+1, "%2x%2x%2x", - &tmpr, &tmpg, &tmpb); - *pixelPtr++ = tmpr; - *pixelPtr++ = tmpg; - *pixelPtr++ = tmpb; - continue; - } - } - } - - if (!TkParseColor(Tk_Display(tkwin), Tk_Colormap(tkwin), - colorString, &color)) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't parse color \"%s\"", colorString)); - Tcl_SetErrorCode(interp, "TK", "VALUE", "COLOR", NULL); - break; - } - *pixelPtr++ = color.red >> 8; - *pixelPtr++ = color.green >> 8; - *pixelPtr++ = color.blue >> 8; - } - if (x < dataWidth) { - break; - } - } - if (y < dataHeight || dataHeight == 0 || dataWidth == 0) { - if (block.pixelPtr != NULL) { - ckfree(block.pixelPtr); - } - if (y < dataHeight) { - return TCL_ERROR; - } - return TCL_OK; - } - - /* - * Fill in default values for the -to option, then copy the block in - * using Tk_PhotoPutBlock. - */ - - if (!(options.options & OPT_TO) || (options.toX2 < 0)) { - options.toX2 = options.toX + dataWidth; - options.toY2 = options.toY + dataHeight; - } - block.width = dataWidth; - block.height = dataHeight; - block.pitch = dataWidth * 3; - block.pixelSize = 3; - block.offset[0] = 0; - block.offset[1] = 1; - block.offset[2] = 2; - block.offset[3] = 0; - result = Tk_PhotoPutBlock(interp, masterPtr, &block, - options.toX, options.toY, options.toX2 - options.toX, - options.toY2 - options.toY, - TK_PHOTO_COMPOSITE_SET); - ckfree(block.pixelPtr); - return result; - + /* + * See if there's a format that can read the data + */ + + if (MatchStringFormat(interp, objv[2], options.format, &imageFormat, + &imageWidth, &imageHeight, &oldformat) != TCL_OK) { + return TCL_ERROR; + } + + if (!(options.options & OPT_TO) || (options.toX2 < 0)) { + options.toX2 = options.toX + imageWidth; + options.toY2 = options.toY + imageHeight; + } + if (imageWidth > options.toX2 - options.toX) { + imageWidth = options.toX2 - options.toX; + } + if (imageHeight > options.toY2 - options.toY) { + imageHeight = options.toY2 - options.toY; + } + format = options.format; + data = objv[2]; + if (oldformat) { + if (format) { + format = (Tcl_Obj *) Tcl_GetString(format); + } + data = (Tcl_Obj *) Tcl_GetString(data); + } + + if (imageFormat->stringReadProc(interp, data, format, + (Tk_PhotoHandle) masterPtr, options.toX, options.toY, + options.toX2 - options.toX, + options.toY2 - options.toY, 0, 0) != TCL_OK) { + return TCL_ERROR; + } + /* + * SB: is the next line really needed? The stringReadProc + * writes image data with Tk_PhotoPutBlock(), which in turn + * takes care to notify the changed image and to set/unset the + * IMAGE_CHANGED bit. + */ + masterPtr->flags |= IMAGE_CHANGED; + + return TCL_OK; + } case PHOTO_READ: { Tcl_Obj *format; /* * photo read command - first parse the options specified. @@ -1163,21 +1088,44 @@ return TCL_ERROR; } switch ((enum transOptions) index) { case PHOTO_TRANS_GET: { - XRectangle testBox; - TkRegion testRegion; + int boolMode; - if (objc != 5) { - Tcl_WrongNumArgs(interp, 3, objv, "x y"); + /* + * parse fixed args and option + */ + + if (objc > 6 || objc < 5) { + Tcl_WrongNumArgs(interp, 3, objv, "x y ?-option?"); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { return TCL_ERROR; } + + index = 4; + memset(&options, 0, sizeof(options)); + if (ParseSubcommandOptions(&options, interp, + OPT_ALPHA, &index, objc, objv) != TCL_OK) { + return TCL_ERROR; + } + if (index < objc) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\": must be -alpha", + Tcl_GetString(objv[index]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", + NULL); + return TCL_ERROR; + } + boolMode = 1; + if (options.options & OPT_ALPHA) { + boolMode = 0; + } + if ((x < 0) || (x >= masterPtr->width) || (y < 0) || (y >= masterPtr->height)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s transparency get: coordinates out of range", Tcl_GetString(objv[0]))); @@ -1184,82 +1132,116 @@ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", NULL); return TCL_ERROR; } - testBox.x = x; - testBox.y = y; - testBox.width = 1; - testBox.height = 1; - /* What a way to do a test! */ - testRegion = TkCreateRegion(); - TkUnionRectWithRegion(&testBox, testRegion, testRegion); - TkIntersectRegion(testRegion, masterPtr->validRegion, testRegion); - TkClipBox(testRegion, &testBox); - TkDestroyRegion(testRegion); - - Tcl_SetObjResult(interp, Tcl_NewBooleanObj( - testBox.width==0 && testBox.height==0)); + /* + * Extract and return the desired value + */ + pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; + if (boolMode) { + Tcl_SetObjResult(interp, Tcl_NewBooleanObj( ! pixelPtr[3])); + } else { + Tcl_SetObjResult(interp, Tcl_NewIntObj(pixelPtr[3])); + } return TCL_OK; } case PHOTO_TRANS_SET: { - int transFlag; + int newVal, boolMode; XRectangle setBox; + TkRegion modRegion; - if (objc != 6) { - Tcl_WrongNumArgs(interp, 3, objv, "x y boolean"); + /* + * Parse args and option, check for valid values + */ + + if (objc < 6 || objc > 7) { + Tcl_WrongNumArgs(interp, 3, objv, "x y newVal ?-option?"); return TCL_ERROR; } if ((Tcl_GetIntFromObj(interp, objv[3], &x) != TCL_OK) - || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) - || (Tcl_GetBooleanFromObj(interp, objv[5], - &transFlag) != TCL_OK)) { + || (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK)) { + return TCL_ERROR; + } + + index = 5; + memset(&options, 0, sizeof(options)); + if (ParseSubcommandOptions(&options, interp, + OPT_ALPHA, &index, objc, objv) != TCL_OK) { + return TCL_ERROR; + } + if (index < objc) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "unknown option \"%s\": must be -alpha", + Tcl_GetString(objv[index]))); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "BAD_OPTION", + NULL); return TCL_ERROR; } + boolMode = 1; + if (options.options & OPT_ALPHA) { + boolMode = 0; + } + if ((x < 0) || (x >= masterPtr->width) || (y < 0) || (y >= masterPtr->height)) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "%s transparency set: coordinates out of range", Tcl_GetString(objv[0]))); Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "COORDINATES", NULL); return TCL_ERROR; } + + if (boolMode) { + if (Tcl_GetBooleanFromObj(interp, objv[5], &newVal) != TCL_OK) { + return TCL_ERROR; + } + } else { + if (Tcl_GetIntFromObj(interp, objv[5], &newVal) != TCL_OK) { + return TCL_ERROR; + } + if (newVal < 0 || newVal > 255) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "invalid alpha value \"%d\": " + "must be integer between 0 and 255", newVal)); + Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", + "BAD_VALUE", NULL); + return TCL_ERROR; + } + } + + /* + * Set new alpha value for the pixel + */ + + pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; + if (boolMode) { + pixelPtr[3] = newVal ? 0 : 255; + } else { + pixelPtr[3] = newVal; + } + + /* + * Update the validRegion of the image + */ setBox.x = x; setBox.y = y; setBox.width = 1; setBox.height = 1; - pixelPtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; - - if (transFlag) { - /* - * Make pixel transparent. - */ - - TkRegion clearRegion = TkCreateRegion(); - - TkUnionRectWithRegion(&setBox, clearRegion, clearRegion); - TkSubtractRegion(masterPtr->validRegion, clearRegion, - masterPtr->validRegion); - TkDestroyRegion(clearRegion); - - /* - * Set the alpha value correctly. - */ - - pixelPtr[3] = 0; - } else { - /* - * Make pixel opaque. - */ - + modRegion = TkCreateRegion(); + TkUnionRectWithRegion(&setBox, modRegion, modRegion); + if (pixelPtr[3]) { TkUnionRectWithRegion(&setBox, masterPtr->validRegion, masterPtr->validRegion); - pixelPtr[3] = 255; + } else { + TkSubtractRegion(masterPtr->validRegion, modRegion, + masterPtr->validRegion); } + TkDestroyRegion(modRegion); /* * Inform the generic image code that the image * has (potentially) changed. */ @@ -1457,17 +1439,22 @@ * * ParseSubcommandOptions -- * * This function is invoked to process one of the options which may be * specified for the photo image subcommands, namely, -from, -to, -zoom, - * -subsample, -format, -shrink, and -compositingrule. + * -subsample, -format, -shrink, -compositingrule, -alpha, -boolean and + * -withalpha. + * Parsing starts at the index in *optIndexPtr and stops at the end of + * objv[] or at the first value that does not belong to an option. * * Results: * A standard Tcl result. * * Side effects: - * Fields in *optPtr get filled in. + * Fields in *optPtr get filled in. The value of optIndexPtr is updated + * to contain the index of the first element in argv[] that was not + * parsed, or argc if the end of objv[] was reached. * *---------------------------------------------------------------------- */ static int @@ -1487,11 +1474,12 @@ static const char *const compositingRules[] = { "overlay", "set", /* Note that these must match the * TK_PHOTO_COMPOSITE_* constants. */ NULL }; - int index, c, bit, currentBit, length; + size_t length; + int index, c, bit, currentBit; int values[4], numValues, maxValues, argIndex; const char *option, *expandedOption, *needed; const char *const *listPtr; Tcl_Obj *msgObj; @@ -1499,11 +1487,11 @@ /* * We can have one value specified without an option; it goes into * optPtr->name. */ - expandedOption = option = Tcl_GetStringFromObj(objv[index], &length); + expandedOption = option = TkGetStringFromObj(objv[index], &length); if (option[0] != '-') { if (optPtr->name == NULL) { optPtr->name = objv[index]; continue; } @@ -1517,11 +1505,11 @@ c = option[0]; bit = 0; currentBit = 1; for (listPtr = optionNames; *listPtr != NULL; ++listPtr) { if ((c == *listPtr[0]) - && (strncmp(option, *listPtr, (size_t) length) == 0)) { + && (strncmp(option, *listPtr, length) == 0)) { expandedOption = *listPtr; if (bit != 0) { goto unknownOrAmbiguousOption; } bit = currentBit; @@ -1533,11 +1521,15 @@ * If this option is not recognized and allowed, put an error message * in the interpreter and return. */ if (!(allowedOptions & bit)) { - goto unknownOrAmbiguousOption; + if (optPtr->name != NULL) { + goto unknownOrAmbiguousOption; + } + optPtr->name = objv[index]; + continue; } /* * For the -from, -to, -zoom and -subsample options, parse the values * given. Report an error if too few or too many values are given. @@ -1582,11 +1574,12 @@ "compositing rule", 0, &optPtr->compositingRule) != TCL_OK) { return TCL_ERROR; } *optIndexPtr = index; - } else if ((bit != OPT_SHRINK) && (bit != OPT_GRAYSCALE)) { + } else if (bit == OPT_TO || bit == OPT_FROM + || bit == OPT_SUBSAMPLE || bit == OPT_ZOOM) { const char *val; maxValues = ((bit == OPT_FROM) || (bit == OPT_TO)) ? 4 : 2; argIndex = index + 1; for (numValues = 0; numValues < maxValues; ++numValues) { @@ -1763,22 +1756,23 @@ { PhotoInstance *instancePtr; const char *oldFileString, *oldPaletteString; Tcl_Obj *oldData, *data = NULL, *oldFormat, *format = NULL; Tcl_Obj *tempdata, *tempformat; - int length, i, j, result, imageWidth, imageHeight, oldformat; + size_t length; + int i, j, result, imageWidth, imageHeight, oldformat; double oldGamma; Tcl_Channel chan; Tk_PhotoImageFormat *imageFormat; const char **args; args = ckalloc((objc + 1) * sizeof(char *)); for (i = 0, j = 0; i < objc; i++,j++) { - args[j] = Tcl_GetStringFromObj(objv[i], &length); + args[j] = TkGetStringFromObj(objv[i], &length); if ((length > 1) && (args[j][0] == '-')) { if ((args[j][1] == 'd') && - !strncmp(args[j], "-data", (size_t) length)) { + !strncmp(args[j], "-data", length)) { if (++i < objc) { data = objv[i]; j--; } else { ckfree(args); @@ -1787,11 +1781,11 @@ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "MISSING_VALUE", NULL); return TCL_ERROR; } } else if ((args[j][1] == 'f') && - !strncmp(args[j], "-format", (size_t) length)) { + !strncmp(args[j], "-format", length)) { if (++i < objc) { format = objv[i]; j--; } else { ckfree(args); @@ -1850,13 +1844,14 @@ if (data) { /* * Force into ByteArray format, which most (all) image handlers will * use anyway. Empty length means ignore the -data option. */ + size_t bytesize; - (void) Tcl_GetByteArrayFromObj(data, &length); - if (length) { + (void) TkGetByteArrayFromObj(data, &bytesize); + if (bytesize) { Tcl_IncrRefCount(data); } else { data = NULL; } if (masterPtr->dataString) { @@ -1868,12 +1863,12 @@ /* * Stringify to ignore -format "". It may come in as a list or other * object. */ - (void) Tcl_GetStringFromObj(format, &length); - if (length) { + (void) Tcl_GetString(format); + if (format->length) { Tcl_IncrRefCount(format); } else { format = NULL; } if (masterPtr->format) { @@ -2535,11 +2530,11 @@ /* The dimensions of the image are returned * here. */ int *oldformat) /* Returns 1 if the old image API is used. */ { int matched = 0, useoldformat = 0; - Tk_PhotoImageFormat *formatPtr; + Tk_PhotoImageFormat *formatPtr, *defaultFormatPtr = NULL; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); const char *formatString = NULL; if (formatObj) { @@ -2551,10 +2546,20 @@ * handle the image. */ for (formatPtr = tsdPtr->formatList; formatPtr != NULL; formatPtr = formatPtr->nextPtr) { + /* + * To keep the behaviour of older versions (Tk <= 8.6), the default + * list-of-lists string format is checked last. Remember its position. + */ + + if (strncasecmp("default", formatPtr->name, strlen(formatPtr->name)) + == 0) { + defaultFormatPtr = formatPtr; + } + if (formatObj != NULL) { if (strncasecmp(formatString, formatPtr->name, strlen(formatPtr->name)) != 0) { continue; } @@ -2566,10 +2571,20 @@ Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "NOT_DATA_FORMAT", NULL); return TCL_ERROR; } } + + /* + * If this is the default format, and it was not passed as -format + * option, skip the stringMatchProc test. It'll be done later + */ + + if (formatObj == NULL && formatPtr == defaultFormatPtr) { + continue; + } + if ((formatPtr->stringMatchProc != NULL) && (formatPtr->stringReadProc != NULL) && formatPtr->stringMatchProc(data, formatObj, widthPtr, heightPtr, interp)) { break; @@ -2603,27 +2618,50 @@ widthPtr, heightPtr, interp)) { break; } } } + if (formatPtr == NULL) { - if ((formatObj != NULL) && !matched) { + /* + * Try the default format as last resort (only if no -format option + * was passed). + */ + + if ( formatObj == NULL && defaultFormatPtr == NULL) { + Tcl_Panic("default image format handler not registered"); + } + if ( formatObj == NULL + && defaultFormatPtr->stringMatchProc != NULL + && defaultFormatPtr->stringReadProc != NULL + && defaultFormatPtr->stringMatchProc(data, formatObj, + widthPtr, heightPtr, interp) != 0) { + useoldformat = 0; + formatPtr = defaultFormatPtr; + } else if ((formatObj != NULL) && !matched) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "image format \"%s\" is not supported", formatString)); Tcl_SetErrorCode(interp, "TK", "LOOKUP", "PHOTO_FORMAT", formatString, NULL); + return TCL_ERROR; } else { Tcl_SetObjResult(interp, Tcl_NewStringObj( "couldn't recognize image data", -1)); Tcl_SetErrorCode(interp, "TK", "IMAGE", "PHOTO", "UNRECOGNIZED_DATA", NULL); + return TCL_ERROR; } - return TCL_ERROR; } *imageFormatPtr = formatPtr; *oldformat = useoldformat; + + /* + * Some stringMatchProc might have left error messages and error codes in + * interp. Clear them before return. + */ + Tcl_ResetResult(interp); return TCL_OK; } /* *---------------------------------------------------------------------- @@ -2684,11 +2722,11 @@ Tk_PhotoPutBlock( Tcl_Interp *interp, /* Interpreter for passing back error * messages, or NULL. */ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be * updated. */ - register Tk_PhotoImageBlock *blockPtr, + Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the pixel * data to be copied into the image. */ int x, int y, /* Coordinates of the top-left pixel to be * updated in the image. */ int width, int height, /* Dimensions of the area of the image to be @@ -2695,10 +2733,12 @@ * updated. */ int compRule) /* Compositing rule to use when processing * transparent pixels. */ { register PhotoMaster *masterPtr = (PhotoMaster *) handle; + Tk_PhotoImageBlock sourceBlock; + unsigned char *memToFree; int xEnd, yEnd, greenOffset, blueOffset, alphaOffset; int wLeft, hLeft, wCopy, hCopy, pitch; unsigned char *srcPtr, *srcLinePtr, *destPtr, *destLinePtr; int sourceIsSimplePhoto = compRule & SOURCE_IS_SIMPLE_ALPHA_PHOTO; XRectangle rect; @@ -2722,27 +2762,55 @@ } if ((width <= 0) || (height <= 0)) { return TCL_OK; } - xEnd = x + width; - yEnd = y + height; - if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { - int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); - - if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), - MAX(yEnd, masterPtr->height)) == TCL_ERROR) { + /* + * Fix for bug e4336bef5d: + * + * Make a local copy of *blockPtr, as we might have to change some + * of its fields and don't want to interfere with the caller's data. + * + * If source and destination are the same image, create a copy of the + * source data in our local sourceBlock. + * + * To find out, just comparing the pointers is not enough - they might have + * different values and still point to the same block of memory. (e.g. + * if the -from option was passed to [imageName copy]) + */ + sourceBlock = *blockPtr; + memToFree = NULL; + if (sourceBlock.pixelPtr >= masterPtr->pix32 + && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width + * masterPtr->height * 4) { + sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height + * sourceBlock.pitch); + if (sourceBlock.pixelPtr == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } return TCL_ERROR; } - if (sameSrc) { - blockPtr->pixelPtr = masterPtr->pix32; - blockPtr->pitch = masterPtr->width * 4; + memToFree = sourceBlock.pixelPtr; + memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height + * sourceBlock.pitch); + } + + + xEnd = x + width; + yEnd = y + height; + if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { + if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), + MAX(yEnd, masterPtr->height)) == TCL_ERROR) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + } + goto errorExit; } } if ((y < masterPtr->ditherY) || ((y == masterPtr->ditherY) && (x < masterPtr->ditherX))) { @@ -2757,18 +2825,18 @@ /* * If this image block could have different red, green and blue * components, mark it as a color image. */ - greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; - blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - alphaOffset = blockPtr->offset[3]; - if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) { + greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0]; + blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0]; + alphaOffset = sourceBlock.offset[3]; + if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) { alphaOffset = 0; sourceIsSimplePhoto = 1; } else { - alphaOffset -= blockPtr->offset[0]; + alphaOffset -= sourceBlock.offset[0]; } if ((greenOffset != 0) || (blueOffset != 0)) { masterPtr->flags |= COLOR_IMAGE; } @@ -2784,17 +2852,17 @@ * Test to see if we can do the whole write in a single copy. This test is * probably too restrictive. We should also be able to do a memmove if * pixelSize == 3 and alphaOffset == 0. Maybe other cases too. */ - if ((blockPtr->pixelSize == 4) + if ((sourceBlock.pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) - && (width <= blockPtr->width) && (height <= blockPtr->height) + && (width <= sourceBlock.width) && (height <= sourceBlock.height) && ((height == 1) || ((x == 0) && (width == masterPtr->width) - && (blockPtr->pitch == pitch))) + && (sourceBlock.pitch == pitch))) && (compRule == TK_PHOTO_COMPOSITE_SET)) { - memmove(destLinePtr, blockPtr->pixelPtr + blockPtr->offset[0], + memmove(destLinePtr, sourceBlock.pixelPtr + sourceBlock.offset[0], ((size_t)height * width * 4)); /* * We know there's an alpha offset and we're setting the data, so skip * directly to the point when we recompute the photo validity region. @@ -2806,15 +2874,15 @@ /* * Copy and merge pixels according to the compositing rule. */ for (hLeft = height; hLeft > 0;) { - int pixelSize = blockPtr->pixelSize; + int pixelSize = sourceBlock.pixelSize; int compRuleSet = (compRule == TK_PHOTO_COMPOSITE_SET); - srcLinePtr = blockPtr->pixelPtr + blockPtr->offset[0]; - hCopy = MIN(hLeft, blockPtr->height); + srcLinePtr = sourceBlock.pixelPtr + sourceBlock.offset[0]; + hCopy = MIN(hLeft, sourceBlock.height); hLeft -= hCopy; for (; hCopy > 0; --hCopy) { /* * If the layout of the source line matches our memory layout and * we're setting, we can just copy the bytes directly, which is @@ -2821,14 +2889,14 @@ * much faster. */ if ((pixelSize == 4) && (greenOffset == 1) && (blueOffset == 2) && (alphaOffset == 3) - && (width <= blockPtr->width) + && (width <= sourceBlock.width) && compRuleSet) { memcpy(destLinePtr, srcLinePtr, ((size_t)width * 4)); - srcLinePtr += blockPtr->pitch; + srcLinePtr += sourceBlock.pitch; destLinePtr += pitch; continue; } /* @@ -2835,11 +2903,11 @@ * Have to copy the slow way. */ destPtr = destLinePtr; for (wLeft = width; wLeft > 0;) { - wCopy = MIN(wLeft, blockPtr->width); + wCopy = MIN(wLeft, sourceBlock.width); wLeft -= wCopy; srcPtr = srcLinePtr; /* * But we might be lucky and be able to use fairly fast loops. @@ -2925,11 +2993,11 @@ } destPtr += 4; } } - srcLinePtr += blockPtr->pitch; + srcLinePtr += sourceBlock.pitch; destLinePtr += pitch; } } /* @@ -3041,11 +3109,19 @@ * Tell the core image code that this image has changed. */ Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, masterPtr->height); + + if (memToFree) ckfree(memToFree); + return TCL_OK; + + errorExit: + if (memToFree) ckfree(memToFree); + + return TCL_ERROR; } /* *---------------------------------------------------------------------- * @@ -3068,11 +3144,11 @@ Tk_PhotoPutZoomedBlock( Tcl_Interp *interp, /* Interpreter for passing back error * messages, or NULL. */ Tk_PhotoHandle handle, /* Opaque handle for the photo image to be * updated. */ - register Tk_PhotoImageBlock *blockPtr, + Tk_PhotoImageBlock *blockPtr, /* Pointer to a structure describing the pixel * data to be copied into the image. */ int x, int y, /* Coordinates of the top-left pixel to be * updated in the image. */ int width, int height, /* Dimensions of the area of the image to be @@ -3083,10 +3159,12 @@ * axes. */ int compRule) /* Compositing rule to use when processing * transparent pixels. */ { register PhotoMaster *masterPtr = (PhotoMaster *) handle; + register Tk_PhotoImageBlock sourceBlock; + unsigned char *memToFree; int xEnd, yEnd, greenOffset, blueOffset, alphaOffset; int wLeft, hLeft, wCopy, hCopy, blockWid, blockHt; unsigned char *srcPtr, *srcLinePtr, *srcOrigPtr, *destPtr, *destLinePtr; int pitch, xRepeat, yRepeat, blockXSkip, blockYSkip, sourceIsSimplePhoto; XRectangle rect; @@ -3119,27 +3197,53 @@ } if (width <= 0 || height <= 0) { return TCL_OK; } - xEnd = x + width; - yEnd = y + height; - if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { - int sameSrc = (blockPtr->pixelPtr == masterPtr->pix32); - - if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), - MAX(yEnd, masterPtr->height)) == TCL_ERROR) { + /* + * Fix for Bug e4336bef5d: + * Make a local copy of *blockPtr, as we might have to change some + * of its fields and don't want to interfere with the caller's data. + * + * If source and destination are the same image, create a copy of the + * source data in our local sourceBlock. + * + * To find out, just comparing the pointers is not enough - they might have + * different values and still point to the same block of memory. (e.g. + * if the -from option was passed to [imageName copy]) + */ + sourceBlock = *blockPtr; + memToFree = NULL; + if (sourceBlock.pixelPtr >= masterPtr->pix32 + && sourceBlock.pixelPtr <= masterPtr->pix32 + masterPtr->width + * masterPtr->height * 4) { + sourceBlock.pixelPtr = attemptckalloc(sourceBlock.height + * sourceBlock.pitch); + if (sourceBlock.pixelPtr == NULL) { if (interp != NULL) { Tcl_SetObjResult(interp, Tcl_NewStringObj( TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); } return TCL_ERROR; } - if (sameSrc) { - blockPtr->pixelPtr = masterPtr->pix32; - blockPtr->pitch = masterPtr->width * 4; + memToFree = sourceBlock.pixelPtr; + memcpy(sourceBlock.pixelPtr, blockPtr->pixelPtr, sourceBlock.height + * sourceBlock.pitch); + } + + xEnd = x + width; + yEnd = y + height; + if ((xEnd > masterPtr->width) || (yEnd > masterPtr->height)) { + if (ImgPhotoSetSize(masterPtr, MAX(xEnd, masterPtr->width), + MAX(yEnd, masterPtr->height)) == TCL_ERROR) { + if (interp != NULL) { + Tcl_SetObjResult(interp, Tcl_NewStringObj( + TK_PHOTO_ALLOC_FAILURE_MESSAGE, -1)); + Tcl_SetErrorCode(interp, "TK", "MALLOC", NULL); + } + goto errorExit; } } if ((y < masterPtr->ditherY) || ((y == masterPtr->ditherY) && (x < masterPtr->ditherX))) { @@ -3154,18 +3258,18 @@ /* * If this image block could have different red, green and blue * components, mark it as a color image. */ - greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; - blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - alphaOffset = blockPtr->offset[3]; - if ((alphaOffset >= blockPtr->pixelSize) || (alphaOffset < 0)) { + greenOffset = sourceBlock.offset[1] - sourceBlock.offset[0]; + blueOffset = sourceBlock.offset[2] - sourceBlock.offset[0]; + alphaOffset = sourceBlock.offset[3]; + if ((alphaOffset >= sourceBlock.pixelSize) || (alphaOffset < 0)) { alphaOffset = 0; sourceIsSimplePhoto = 1; } else { - alphaOffset -= blockPtr->offset[0]; + alphaOffset -= sourceBlock.offset[0]; } if ((greenOffset != 0) || (blueOffset != 0)) { masterPtr->flags |= COLOR_IMAGE; } @@ -3172,38 +3276,38 @@ /* * Work out what area the pixel data in the block expands to after * subsampling and zooming. */ - blockXSkip = subsampleX * blockPtr->pixelSize; - blockYSkip = subsampleY * blockPtr->pitch; + blockXSkip = subsampleX * sourceBlock.pixelSize; + blockYSkip = subsampleY * sourceBlock.pitch; if (subsampleX > 0) { - blockWid = ((blockPtr->width + subsampleX - 1) / subsampleX) * zoomX; + blockWid = ((sourceBlock.width + subsampleX - 1) / subsampleX) * zoomX; } else if (subsampleX == 0) { blockWid = width; } else { - blockWid = ((blockPtr->width - subsampleX - 1) / -subsampleX) * zoomX; + blockWid = ((sourceBlock.width - subsampleX - 1) / -subsampleX) * zoomX; } if (subsampleY > 0) { - blockHt = ((blockPtr->height + subsampleY - 1) / subsampleY) * zoomY; + blockHt = ((sourceBlock.height + subsampleY - 1) / subsampleY) * zoomY; } else if (subsampleY == 0) { blockHt = height; } else { - blockHt = ((blockPtr->height - subsampleY - 1) / -subsampleY) * zoomY; + blockHt = ((sourceBlock.height - subsampleY - 1) / -subsampleY) * zoomY; } /* * Copy the data into our local 32-bit/pixel array. */ destLinePtr = masterPtr->pix32 + (y * masterPtr->width + x) * 4; - srcOrigPtr = blockPtr->pixelPtr + blockPtr->offset[0]; + srcOrigPtr = sourceBlock.pixelPtr + sourceBlock.offset[0]; if (subsampleX < 0) { - srcOrigPtr += (blockPtr->width - 1) * blockPtr->pixelSize; + srcOrigPtr += (sourceBlock.width - 1) * sourceBlock.pixelSize; } if (subsampleY < 0) { - srcOrigPtr += (blockPtr->height - 1) * blockPtr->pitch; + srcOrigPtr += (sourceBlock.height - 1) * sourceBlock.pitch; } pitch = masterPtr->width * 4; for (hLeft = height; hLeft > 0; ) { hCopy = MIN(hLeft, blockHt); @@ -3349,11 +3453,19 @@ * Tell the core image code that this image has changed. */ Tk_ImageChanged(masterPtr->tkMaster, x, y, width, height, masterPtr->width, masterPtr->height); + + if (memToFree) ckfree(memToFree); + return TCL_OK; + + errorExit: + if (memToFree) ckfree(memToFree); + + return TCL_ERROR; } /* *---------------------------------------------------------------------- * @@ -3837,61 +3949,10 @@ } /* *---------------------------------------------------------------------- * - * ImgStringWrite -- - * - * Default string write function. The data is formatted in the default - * format as accepted by the " put" command. - * - * Results: - * A standard Tcl result. - * - * Side effects: - * See the user documentation. - * - *---------------------------------------------------------------------- - */ - -static int -ImgStringWrite( - Tcl_Interp *interp, - Tcl_Obj *formatString, - Tk_PhotoImageBlock *blockPtr) -{ - int greenOffset, blueOffset; - Tcl_Obj *data; - - greenOffset = blockPtr->offset[1] - blockPtr->offset[0]; - blueOffset = blockPtr->offset[2] - blockPtr->offset[0]; - - data = Tcl_NewObj(); - if ((blockPtr->width > 0) && (blockPtr->height > 0)) { - int row, col; - - for (row=0; rowheight; row++) { - Tcl_Obj *line = Tcl_NewObj(); - unsigned char *pixelPtr = blockPtr->pixelPtr + blockPtr->offset[0] - + row * blockPtr->pitch; - - for (col=0; colwidth; col++) { - Tcl_AppendPrintfToObj(line, "%s#%02x%02x%02x", - col ? " " : "", *pixelPtr, - pixelPtr[greenOffset], pixelPtr[blueOffset]); - pixelPtr += blockPtr->pixelSize; - } - Tcl_ListObjAppendElement(NULL, data, line); - } - } - Tcl_SetObjResult(interp, data); - return TCL_OK; -} - -/* - *---------------------------------------------------------------------- - * * Tk_PhotoGetImage -- * * This function is called to obtain image data from a photo image. This * function fills in the Tk_PhotoImageBlock structure pointed to by * `blockPtr' with details of the address and layout of the image data in @@ -3930,11 +3991,11 @@ } /* *-------------------------------------------------------------- * - * TkPostscriptPhoto -- + * ImgPostscriptPhoto -- * * This function is called to output the contents of a photo image in * Postscript by calling the Tk_PostscriptPhoto function. * * Results: @@ -3975,11 +4036,11 @@ * always "overlay" and the function always panics on memory-allocation * failure. * *---------------------------------------------------------------------- */ - +#if !defined(TK_NO_DEPRECATED) && TCL_MAJOR_VERSION < 9 void Tk_PhotoPutBlock_NoComposite( Tk_PhotoHandle handle, Tk_PhotoImageBlock *blockPtr, int x, int y, int width, int height) @@ -4061,13 +4122,15 @@ { if (Tk_PhotoSetSize(NULL, handle, width, height) != TCL_OK) { Tcl_Panic(TK_PHOTO_ALLOC_FAILURE_MESSAGE); } } +#endif /* TK_NO_DEPRECATED */ /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 + * tab-width: 8 * End: */ Index: generic/tkImgPhoto.h ================================================================== --- generic/tkImgPhoto.h +++ generic/tkImgPhoto.h @@ -91,14 +91,21 @@ */ struct ColorTable { ColorTableId id; /* Information used in selecting this color * table. */ +#if TCL_MAJOR_VERSION > 8 + size_t refCount; /* Number of instances using this map. */ + size_t liveRefCount; /* Number of instances which are actually in + * use, using this map. */ + int flags; /* See below. */ +#else int flags; /* See below. */ - int refCount; /* Number of instances using this map. */ - int liveRefCount; /* Number of instances which are actually in + unsigned int refCount; /* Number of instances using this map. */ + unsigned int liveRefCount; /* Number of instances which are actually in * use, using this map. */ +#endif int numColors; /* Number of colors allocated for this map. */ XVisualInfo visualInfo; /* Information about the visual for windows * using this color table. */ @@ -199,11 +206,15 @@ Display *display; /* Display for windows using this instance. */ Colormap colormap; /* The image may only be used in windows with * this particular colormap. */ PhotoInstance *nextPtr; /* Pointer to the next instance in the list of * instances associated with this master. */ - int refCount; /* Number of instances using this structure. */ +#if TCL_MAJOR_VERSION > 8 + size_t refCount; /* Number of instances using this structure. */ +#else + unsigned int refCount; /* Number of instances using this structure. */ +#endif Tk_Uid palette; /* Palette for these particular instances. */ double gamma; /* Gamma value for these instances. */ Tk_Uid defaultPalette; /* Default palette to use if a palette is not * specified for the master. */ ColorTable *colorTablePtr; /* Pointer to information about colors Index: generic/tkInt.decls ================================================================== --- generic/tkInt.decls +++ generic/tkInt.decls @@ -97,11 +97,11 @@ declare 21 { int TkFindStateNum(Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey) } declare 22 { - CONST86 char *TkFindStateString(const TkStateMap *mapPtr, int numKey) + const char *TkFindStateString(const TkStateMap *mapPtr, int numKey) } declare 23 { void TkFocusDeadWindow(TkWindow *winPtr) } declare 24 { @@ -180,11 +180,11 @@ } declare 45 { void TkInstallFrameMenu(Tk_Window tkwin) } declare 46 { - CONST86 char *TkKeysymToString(KeySym keysym) + const char *TkKeysymToString(KeySym keysym) } declare 47 { int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[]) } declare 48 { @@ -387,11 +387,11 @@ declare 108 { int TkGetWindowFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr) } declare 109 { - CONST86 char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr) + const char *TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr) } declare 110 { void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont) } declare 111 { @@ -568,51 +568,51 @@ declare 169 { int TkStateParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 170 { - CONST86 char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin, + const char *TkStatePrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 171 { int TkCanvasDashParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 172 { - CONST86 char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin, + const char *TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 173 { int TkOffsetParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 174 { - CONST86 char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin, + const char *TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 175 { int TkPixelParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 176 { - CONST86 char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin, + const char *TkPixelPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 177 { int TkOrientParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 178 { - CONST86 char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin, + const char *TkOrientPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } declare 179 { int TkSmoothParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset) } declare 180 { - CONST86 char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin, + const char *TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr) } # Angled text API, exposed for Emiliano Gavilán's RBC work. declare 181 { @@ -632,10 +632,17 @@ declare 184 { void TkDrawAngledChars(Display *display,Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle) } + +# Debugging / testing functions for photo images +declare 185 { + int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, Tcl_Obj *data, + Tcl_Obj *formatString, int *widthPtr, int *heightPtr) +} + ############################################################################## # Define the platform specific internal Tcl interface. These functions are # only available on the designated platform. @@ -981,13 +988,13 @@ int TkSetMacColor(unsigned long pixel, void *macColor) } declare 39 aqua { void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid) } -declare 40 aqua { - void TkSuspendClipboard(void) -} +# +# Slot 40 unused (WAS: TkSuspendClipboard) +# declare 41 aqua { int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart) } declare 42 aqua { Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, int rootY, @@ -1420,32 +1427,86 @@ int x, int y, unsigned int width, unsigned int height) } # New in Tk 8.6 declare 107 win { - int XFlush(Display *display) + int XFlush(Display *display) } declare 108 win { - int XGrabServer(Display *display) + int XGrabServer(Display *display) } declare 109 win { - int XUngrabServer(Display *display) + int XUngrabServer(Display *display) } declare 110 win { - int XFree(void *data) + int XFree(void *data) } declare 111 win { - int XNoOp(Display *display) + int XNoOp(Display *display) } declare 112 win { - XAfterFunction XSynchronize(Display *display, Bool onoff) + XAfterFunction XSynchronize(Display *display, Bool onoff) } declare 113 win { - int XSync(Display *display, Bool discard) + int XSync(Display *display, Bool discard) } declare 114 win { - VisualID XVisualIDFromVisual(Visual *visual) + VisualID XVisualIDFromVisual(Visual *visual) +} + +# For tktreectrl +declare 120 win { + int XOffsetRegion(Region rgn, int dx, int dy) +} +declare 121 win { + int XUnionRegion(Region srca, Region srcb, Region dr_return) +} + +# For 3dcanvas +declare 122 win { + Window XCreateWindow(Display *display, Window parent, int x, int y, + unsigned int width, unsigned int height, + unsigned int border_width, int depth, unsigned int clazz, + Visual *visual, unsigned long value_mask, + XSetWindowAttributes *attributes) +} + +# Various, e.g. for stub-enabled BLT +declare 129 win { + int XLowerWindow(Display *d, Window w) +} +declare 130 win { + int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, int n) +} +declare 131 win { + int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, int n) +} +declare 132 win { + int XDrawRectangles(Display *d, Drawable dr, GC gc, XRectangle *r, int n) +} +declare 133 win { + int XDrawSegments(Display *d, Drawable dr, GC gc, XSegment *s, int n) +} +declare 134 win { + int XDrawPoint(Display *d, Drawable dr, GC gc, int x, int y) +} +declare 135 win { + int XDrawPoints(Display *d, Drawable dr, GC gc, XPoint *p, int n, int m) +} +declare 136 win { + int XReparentWindow(Display *d, Window w, Window p, int x, int y) +} +declare 137 win { + int XPutImage(Display *d, Drawable dr, GC gc, XImage *im, + int sx, int sy, int dx, int dy, + unsigned int w, unsigned int h) +} +declare 138 win { + Region XPolygonRegion(XPoint *pts, int n, int rule) +} +declare 139 win { + int XPointInRegion(Region rgn, int x, int y) } ################################ # X functions for Aqua @@ -1723,11 +1784,11 @@ declare 79 aqua { Status XStringListToTextProperty(char **list, int count, XTextProperty *text_prop_return) } declare 80 aqua { - void XDrawSegments(Display *display, Drawable d, GC gc, + int XDrawSegments(Display *display, Drawable d, GC gc, XSegment *segments, int nsegments) } declare 81 aqua { void XForceScreenSaver(Display *display, int mode) } @@ -1741,14 +1802,14 @@ } declare 84 aqua { void XClearWindow(Display *d, Window w) } declare 85 aqua { - void XDrawPoint(Display *display, Drawable d, GC gc, int x, int y) + int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y) } declare 86 aqua { - void XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points, + int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode) } declare 87 aqua { int XWarpPointer(Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, Index: generic/tkInt.h ================================================================== --- generic/tkInt.h +++ generic/tkInt.h @@ -23,11 +23,10 @@ * Ensure WORDS_BIGENDIAN is defined correctly: * Needs to happen here in addition to configure to work with fat compiles on * Darwin (where configure runs only once for multiple architectures). */ -#include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_PARAM_H # include @@ -57,34 +56,56 @@ # else # define MODULE_SCOPE extern # endif #endif +#ifndef TkSizeT +# if TCL_MAJOR_VERSION > 8 +# define TkSizeT size_t +# else +# define TkSizeT int +# endif +#endif + /* * Macros used to cast between pointers and integers (e.g. when storing an int * in ClientData), on 64-bit architectures they avoid gcc warning about "cast * to/from pointer from/to integer of different size". */ #if !defined(INT2PTR) && !defined(PTR2INT) # if defined(HAVE_INTPTR_T) || defined(intptr_t) # define INT2PTR(p) ((void*)(intptr_t)(p)) -# define PTR2INT(p) ((int)(intptr_t)(p)) +# define PTR2INT(p) ((intptr_t)(p)) # else # define INT2PTR(p) ((void*)(p)) -# define PTR2INT(p) ((int)(p)) +# define PTR2INT(p) ((long)(p)) # endif #endif #if !defined(UINT2PTR) && !defined(PTR2UINT) # if defined(HAVE_UINTPTR_T) || defined(uintptr_t) # define UINT2PTR(p) ((void*)(uintptr_t)(p)) -# define PTR2UINT(p) ((unsigned int)(uintptr_t)(p)) +# define PTR2UINT(p) ((uintptr_t)(p)) # else # define UINT2PTR(p) ((void*)(p)) -# define PTR2UINT(p) ((unsigned int)(p)) +# define PTR2UINT(p) ((unsigned long)(p)) +# endif +#endif + +#ifndef TCL_AUTO_LENGTH +# define TCL_AUTO_LENGTH (-1) +#endif + +#ifndef TCL_Z_MODIFIER +# if defined(_WIN64) +# define TCL_Z_MODIFIER "I" +# elif defined(__GNUC__) && !defined(_WIN32) +# define TCL_Z_MODIFIER "z" +# else +# define TCL_Z_MODIFIER "" # endif -#endif +#endif /* !TCL_Z_MODIFIER */ /* * Opaque type declarations: */ @@ -105,20 +126,20 @@ typedef struct TkCursor { Tk_Cursor cursor; /* System specific identifier for cursor. */ Display *display; /* Display containing cursor. Needed for * disposal and retrieval of cursors. */ - int resourceRefCount; /* Number of active uses of this cursor (each + TkSizeT resourceRefCount; /* Number of active uses of this cursor (each * active use corresponds to a call to * Tk_AllocPreserveFromObj or Tk_Preserve). If * this count is 0, then this structure is no * longer valid and it isn't present in a hash * table: it is being kept around only because * there are objects referring to it. The * structure is freed when resourceRefCount * and objRefCount are both 0. */ - int objRefCount; /* Number of Tcl objects that reference this + TkSizeT objRefCount; /* Number of Tcl objects that reference this * structure.. */ Tcl_HashTable *otherTable; /* Second table (other than idTable) used to * index this entry. */ Tcl_HashEntry *hashPtr; /* Entry in otherTable for this structure * (needed when deleting). */ @@ -264,11 +285,11 @@ struct TkErrorHandler *errorPtr; /* First in list of error handlers for this * display. NULL means no handlers exist at * present. */ - int deleteCount; /* Counts # of handlers deleted since last + TkSizeT deleteCount; /* Counts # of handlers deleted since last * time inactive handlers were garbage- * collected. When this number gets big, * handlers get cleaned up. */ /* @@ -421,10 +442,11 @@ Atom compoundTextAtom; /* Atom for COMPOUND_TEXT. */ Atom applicationAtom; /* Atom for TK_APPLICATION. */ Atom windowAtom; /* Atom for TK_WINDOW. */ Atom clipboardAtom; /* Atom for CLIPBOARD. */ Atom utf8Atom; /* Atom for UTF8_STRING. */ + Atom atomPairAtom; /* Atom for ATOM_PAIR. */ Tk_Window clipWindow; /* Window used for clipboard ownership and to * retrieve selections between processes. NULL * means clipboard info hasn't been * initialized. */ @@ -476,11 +498,11 @@ XIMStyle inputStyle; /* Input style selected for this display. */ XFontSet inputXfs; /* XFontSet cached for over-the-spot XIM. */ #endif /* TK_USE_INPUT_METHODS */ Tcl_HashTable winTable; /* Maps from X window ids to TkWindow ptrs. */ - int refCount; /* Reference count of how many Tk applications + TkSizeT refCount; /* Reference count of how many Tk applications * are using this display. Used to clean up * the display when we no longer have any Tk * applications using it. */ /* @@ -506,10 +528,13 @@ TkCaret caret; /* Information about the caret for this * display. This is not a pointer. */ int iconDataSize; /* Size of default iconphoto image data. */ unsigned char *iconDataPtr; /* Default iconphoto image data, if set. */ +#ifdef TK_USE_INPUT_METHODS + int ximGeneration; /* Used to invalidate XIC */ +#endif /* TK_USE_INPUT_METHODS */ } TkDisplay; /* * Flag values for TkDisplay flags. * TK_DISPLAY_COLLAPSE_MOTION_EVENTS: (default on) @@ -577,11 +602,11 @@ * by a call to TkCreateMainWindow). It stores information that is shared by * all of the windows associated with a particular main window. */ typedef struct TkMainInfo { - int refCount; /* Number of windows whose "mainPtr" fields + TkSizeT refCount; /* Number of windows whose "mainPtr" fields * point here. When this becomes zero, can * free up the structure (the reference count * is zero because windows can get deleted in * almost any order; the main window isn't * necessarily the last one deleted). */ @@ -588,11 +613,15 @@ struct TkWindow *winPtr; /* Pointer to main window. */ Tcl_Interp *interp; /* Interpreter associated with application. */ Tcl_HashTable nameTable; /* Hash table mapping path names to TkWindow * structs for all windows related to this * main window. Managed by tkWindow.c. */ - long deletionEpoch; /* Incremented by window deletions. */ +#if TCL_MAJOR_VERSION > 8 + size_t deletionEpoch; /* Incremented by window deletions. */ +#else + long deletionEpoch; +#endif Tk_BindingTable bindingTable; /* Used in conjunction with "bind" command to * bind events to Tcl commands. */ TkBindInfo bindInfo; /* Information used by tkBind.c on a per * application basis. */ @@ -807,25 +836,28 @@ int internalBorderBottom; int minReqWidth; /* Minimum requested width. */ int minReqHeight; /* Minimum requested height. */ char *geometryMaster; +#ifdef TK_USE_INPUT_METHODS + int ximGeneration; /* Used to invalidate XIC */ +#endif /* TK_USE_INPUT_METHODS */ } TkWindow; /* * Real definition of some events. Note that these events come from outside * but have internally generated pieces added to them. */ typedef struct { - XKeyEvent keyEvent; /* The real event from X11. */ - char *charValuePtr; /* A pointer to a string that holds the key's + XKeyEvent keyEvent; /* The real event from X11. */ + char *charValuePtr; /* A pointer to a string that holds the key's * %A substitution text (before backslash * adding), or NULL if that has not been * computed yet. If non-NULL, this string was * allocated with ckalloc(). */ - int charValueLen; /* Length of string in charValuePtr when that + TkSizeT charValueLen; /* Length of string in charValuePtr when that * is non-NULL. */ KeySym keysym; /* Key symbol computed after input methods * have been invoked */ } TkKeyEvent; @@ -834,10 +866,15 @@ */ #define TK_MAKE_MENU_TEAROFF 0 /* Only non-transient case. */ #define TK_MAKE_MENU_POPUP 1 #define TK_MAKE_MENU_DROPDOWN 2 + +/* See TIP #494 */ +#ifndef TCL_IO_FAILURE +# define TCL_IO_FAILURE (-1) +#endif /* * The following structure is used with TkMakeEnsemble to create ensemble * commands and optionally to create sub-ensembles. */ @@ -937,10 +974,11 @@ MODULE_SCOPE const Tk_SmoothMethod tkBezierSmoothMethod; MODULE_SCOPE Tk_ImageType tkBitmapImageType; MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtGIF; MODULE_SCOPE void (*tkHandleEventProc) (XEvent* eventPtr); +MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtDefault; MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPNG; MODULE_SCOPE Tk_PhotoImageFormat tkImgFmtPPM; MODULE_SCOPE TkMainInfo *tkMainWindowList; MODULE_SCOPE Tk_ImageType tkPhotoImageType; MODULE_SCOPE Tcl_HashTable tkPredefBitmapTable; @@ -1194,11 +1232,11 @@ MODULE_SCOPE void TkUnderlineCharsInContext(Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *string, int numBytes, int x, int y, int firstByte, int lastByte); MODULE_SCOPE void TkpGetFontAttrsForChar(Tk_Window tkwin, Tk_Font tkfont, - Tcl_UniChar c, struct TkFontAttributes *faPtr); + int c, struct TkFontAttributes *faPtr); MODULE_SCOPE Tcl_Obj * TkNewWindowObj(Tk_Window tkwin); MODULE_SCOPE void TkpShowBusyWindow(TkBusy busy); MODULE_SCOPE void TkpHideBusyWindow(TkBusy busy); MODULE_SCOPE void TkpMakeTransparentWindowExist(Tk_Window tkwin, Window parent); @@ -1215,10 +1253,11 @@ MODULE_SCOPE int TkInitTkCmd(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE int TkInitFontchooser(Tcl_Interp *interp, ClientData clientData); MODULE_SCOPE void TkpWarpPointer(TkDisplay *dispPtr); +MODULE_SCOPE void TkpCancelWarp(TkDisplay *dispPtr); MODULE_SCOPE int TkListCreateFrame(ClientData clientData, Tcl_Interp *interp, Tcl_Obj *listObj, int toplevel, Tcl_Obj *nameObj); #ifdef _WIN32 @@ -1230,10 +1269,25 @@ #endif #ifdef HAVE_XFT MODULE_SCOPE void TkUnixSetXftClipRegion(TkRegion clipRegion); #endif +#if TCL_UTF_MAX > 4 +# define TkUtfToUniChar (size_t)Tcl_UtfToUniChar +# define TkUniCharToUtf (size_t)Tcl_UniCharToUtf +#else + MODULE_SCOPE size_t TkUtfToUniChar(const char *, int *); + MODULE_SCOPE size_t TkUniCharToUtf(int, char *); +#endif + +#define TkGetStringFromObj(objPtr, lenPtr) \ + (((objPtr)->bytes ? 0 : Tcl_GetString(objPtr)), \ + *(lenPtr) = (objPtr)->length, (objPtr)->bytes) + +MODULE_SCOPE unsigned char *TkGetByteArrayFromObj(Tcl_Obj *objPtr, + size_t *lengthPtr); + /* * Unsupported commands. */ MODULE_SCOPE int TkUnsupported1ObjCmd(ClientData clientData, Index: generic/tkIntDecls.h ================================================================== --- generic/tkIntDecls.h +++ generic/tkIntDecls.h @@ -102,11 +102,11 @@ /* 21 */ EXTERN int TkFindStateNum(Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey); /* 22 */ -EXTERN CONST86 char * TkFindStateString(const TkStateMap *mapPtr, +EXTERN const char * TkFindStateString(const TkStateMap *mapPtr, int numKey); /* 23 */ EXTERN void TkFocusDeadWindow(TkWindow *winPtr); /* 24 */ EXTERN int TkFocusFilterEvent(TkWindow *winPtr, @@ -165,11 +165,11 @@ TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 45 */ EXTERN void TkInstallFrameMenu(Tk_Window tkwin); /* 46 */ -EXTERN CONST86 char * TkKeysymToString(KeySym keysym); +EXTERN const char * TkKeysymToString(KeySym keysym); /* 47 */ EXTERN int TkLineToArea(double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 48 */ EXTERN double TkLineToPoint(double end1Ptr[], double end2Ptr[], @@ -322,11 +322,11 @@ /* 108 */ EXTERN int TkGetWindowFromObj(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 109 */ -EXTERN CONST86 char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr, +EXTERN const char * TkpGetString(TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 110 */ EXTERN void TkpGetSubFonts(Tcl_Interp *interp, Tk_Font tkfont); /* 111 */ EXTERN Tcl_Obj * TkpGetSystemDefault(Tk_Window tkwin, @@ -486,51 +486,51 @@ /* 169 */ EXTERN int TkStateParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 170 */ -EXTERN CONST86 char * TkStatePrintProc(ClientData clientData, +EXTERN const char * TkStatePrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 171 */ EXTERN int TkCanvasDashParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 172 */ -EXTERN CONST86 char * TkCanvasDashPrintProc(ClientData clientData, +EXTERN const char * TkCanvasDashPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 173 */ EXTERN int TkOffsetParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 174 */ -EXTERN CONST86 char * TkOffsetPrintProc(ClientData clientData, +EXTERN const char * TkOffsetPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 175 */ EXTERN int TkPixelParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 176 */ -EXTERN CONST86 char * TkPixelPrintProc(ClientData clientData, +EXTERN const char * TkPixelPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 177 */ EXTERN int TkOrientParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 178 */ -EXTERN CONST86 char * TkOrientPrintProc(ClientData clientData, +EXTERN const char * TkOrientPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 179 */ EXTERN int TkSmoothParseProc(ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 180 */ -EXTERN CONST86 char * TkSmoothPrintProc(ClientData clientData, +EXTERN const char * TkSmoothPrintProc(ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 181 */ EXTERN void TkDrawAngledTextLayout(Display *display, Drawable drawable, GC gc, @@ -548,10 +548,14 @@ /* 184 */ EXTERN void TkDrawAngledChars(Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); +/* 185 */ +EXTERN int TkDebugPhotoStringMatchDef(Tcl_Interp *inter, + Tcl_Obj *data, Tcl_Obj *formatString, + int *widthPtr, int *heightPtr); typedef struct TkIntStubs { int magic; void *hooks; @@ -575,11 +579,11 @@ void (*tkDoConfigureNotify) (TkWindow *winPtr); /* 17 */ void (*tkDrawInsetFocusHighlight) (Tk_Window tkwin, GC gc, int width, Drawable drawable, int padding); /* 18 */ void (*tkEventDeadWindow) (TkWindow *winPtr); /* 19 */ void (*tkFillPolygon) (Tk_Canvas canvas, double *coordPtr, int numPoints, Display *display, Drawable drawable, GC gc, GC outlineGC); /* 20 */ int (*tkFindStateNum) (Tcl_Interp *interp, const char *option, const TkStateMap *mapPtr, const char *strKey); /* 21 */ - CONST86 char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */ + const char * (*tkFindStateString) (const TkStateMap *mapPtr, int numKey); /* 22 */ void (*tkFocusDeadWindow) (TkWindow *winPtr); /* 23 */ int (*tkFocusFilterEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 24 */ TkWindow * (*tkFocusKeyEvent) (TkWindow *winPtr, XEvent *eventPtr); /* 25 */ void (*tkFontPkgInit) (TkMainInfo *mainPtr); /* 26 */ void (*tkFontPkgFree) (TkMainInfo *mainPtr); /* 27 */ @@ -599,11 +603,11 @@ void (*tkGrabDeadWindow) (TkWindow *winPtr); /* 41 */ int (*tkGrabState) (TkWindow *winPtr); /* 42 */ void (*tkIncludePoint) (Tk_Item *itemPtr, double *pointPtr); /* 43 */ void (*tkInOutEvents) (XEvent *eventPtr, TkWindow *sourcePtr, TkWindow *destPtr, int leaveType, int enterType, Tcl_QueuePosition position); /* 44 */ void (*tkInstallFrameMenu) (Tk_Window tkwin); /* 45 */ - CONST86 char * (*tkKeysymToString) (KeySym keysym); /* 46 */ + const char * (*tkKeysymToString) (KeySym keysym); /* 46 */ int (*tkLineToArea) (double end1Ptr[], double end2Ptr[], double rectPtr[]); /* 47 */ double (*tkLineToPoint) (double end1Ptr[], double end2Ptr[], double pointPtr[]); /* 48 */ int (*tkMakeBezierCurve) (Tk_Canvas canvas, double *pointPtr, int numPoints, int numSteps, XPoint xPoints[], double dblPoints[]); /* 49 */ void (*tkMakeBezierPostscript) (Tcl_Interp *interp, Tk_Canvas canvas, double *pointPtr, int numPoints); /* 50 */ void (*tkOptionClassChanged) (TkWindow *winPtr); /* 51 */ @@ -662,11 +666,11 @@ int (*tkFindStateNumObj) (Tcl_Interp *interp, Tcl_Obj *optionPtr, const TkStateMap *mapPtr, Tcl_Obj *keyPtr); /* 104 */ Tcl_HashTable * (*tkGetBitmapPredefTable) (void); /* 105 */ TkDisplay * (*tkGetDisplayList) (void); /* 106 */ TkMainInfo * (*tkGetMainInfoList) (void); /* 107 */ int (*tkGetWindowFromObj) (Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, Tk_Window *windowPtr); /* 108 */ - CONST86 char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */ + const char * (*tkpGetString) (TkWindow *winPtr, XEvent *eventPtr, Tcl_DString *dsPtr); /* 109 */ void (*tkpGetSubFonts) (Tcl_Interp *interp, Tk_Font tkfont); /* 110 */ Tcl_Obj * (*tkpGetSystemDefault) (Tk_Window tkwin, const char *dbName, const char *className); /* 111 */ void (*tkpMenuThreadInit) (void); /* 112 */ void (*tkClipBox) (TkRegion rgn, XRectangle *rect_return); /* 113 */ TkRegion (*tkCreateRegion) (void); /* 114 */ @@ -750,25 +754,26 @@ int (*tkTextXviewCmd) (struct TkText *textPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); /* 165 */ void (*tkTextChanged) (struct TkSharedText *sharedTextPtr, struct TkText *textPtr, const struct TkTextIndex *index1Ptr, const struct TkTextIndex *index2Ptr); /* 166 */ int (*tkBTreeNumLines) (TkTextBTree tree, const struct TkText *textPtr); /* 167 */ void (*tkTextInsertDisplayProc) (struct TkText *textPtr, struct TkTextDispChunk *chunkPtr, int x, int y, int height, int baseline, Display *display, Drawable dst, int screenY); /* 168 */ int (*tkStateParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 169 */ - CONST86 char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */ + const char * (*tkStatePrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 170 */ int (*tkCanvasDashParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 171 */ - CONST86 char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */ + const char * (*tkCanvasDashPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 172 */ int (*tkOffsetParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 173 */ - CONST86 char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */ + const char * (*tkOffsetPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 174 */ int (*tkPixelParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 175 */ - CONST86 char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */ + const char * (*tkPixelPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 176 */ int (*tkOrientParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 177 */ - CONST86 char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */ + const char * (*tkOrientPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 178 */ int (*tkSmoothParseProc) (ClientData clientData, Tcl_Interp *interp, Tk_Window tkwin, const char *value, char *widgRec, int offset); /* 179 */ - CONST86 char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */ + const char * (*tkSmoothPrintProc) (ClientData clientData, Tk_Window tkwin, char *widgRec, int offset, Tcl_FreeProc **freeProcPtr); /* 180 */ void (*tkDrawAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int firstChar, int lastChar); /* 181 */ void (*tkUnderlineAngledTextLayout) (Display *display, Drawable drawable, GC gc, Tk_TextLayout layout, int x, int y, double angle, int underline); /* 182 */ int (*tkIntersectAngledTextLayout) (Tk_TextLayout layout, int x, int y, int width, int height, double angle); /* 183 */ void (*tkDrawAngledChars) (Display *display, Drawable drawable, GC gc, Tk_Font tkfont, const char *source, int numBytes, double x, double y, double angle); /* 184 */ + int (*tkDebugPhotoStringMatchDef) (Tcl_Interp *inter, Tcl_Obj *data, Tcl_Obj *formatString, int *widthPtr, int *heightPtr); /* 185 */ } TkIntStubs; extern const TkIntStubs *tkIntStubsPtr; #ifdef __cplusplus @@ -1137,10 +1142,12 @@ (tkIntStubsPtr->tkUnderlineAngledTextLayout) /* 182 */ #define TkIntersectAngledTextLayout \ (tkIntStubsPtr->tkIntersectAngledTextLayout) /* 183 */ #define TkDrawAngledChars \ (tkIntStubsPtr->tkDrawAngledChars) /* 184 */ +#define TkDebugPhotoStringMatchDef \ + (tkIntStubsPtr->tkDebugPhotoStringMatchDef) /* 185 */ #endif /* defined(USE_TK_STUBS) */ /* !END!: Do not edit above this line. */ Index: generic/tkIntPlatDecls.h ================================================================== --- generic/tkIntPlatDecls.h +++ generic/tkIntPlatDecls.h @@ -222,12 +222,11 @@ int *yOffset); /* 38 */ EXTERN int TkSetMacColor(unsigned long pixel, void *macColor); /* 39 */ EXTERN void TkSetWMName(TkWindow *winPtr, Tk_Uid titleUid); -/* 40 */ -EXTERN void TkSuspendClipboard(void); +/* Slot 40 is reserved */ /* 41 */ EXTERN int TkMacOSXZoomToplevel(void *whichWindow, short zoomPart); /* 42 */ EXTERN Tk_Window Tk_TopCoordsToWindow(Tk_Window tkwin, int rootX, @@ -382,11 +381,11 @@ TkRegion (*tkMacOSXVisableClipRgn) (TkWindow *winPtr); /* 35 */ void (*tkMacOSXWinBounds) (TkWindow *winPtr, void *geometry); /* 36 */ void (*tkMacOSXWindowOffset) (void *wRef, int *xOffset, int *yOffset); /* 37 */ int (*tkSetMacColor) (unsigned long pixel, void *macColor); /* 38 */ void (*tkSetWMName) (TkWindow *winPtr, Tk_Uid titleUid); /* 39 */ - void (*tkSuspendClipboard) (void); /* 40 */ + void (*reserved40)(void); int (*tkMacOSXZoomToplevel) (void *whichWindow, short zoomPart); /* 41 */ Tk_Window (*tk_TopCoordsToWindow) (Tk_Window tkwin, int rootX, int rootY, int *newX, int *newY); /* 42 */ MacDrawable * (*tkMacOSXContainerId) (TkWindow *winPtr); /* 43 */ MacDrawable * (*tkMacOSXGetHostToplevel) (TkWindow *winPtr); /* 44 */ void (*tkMacOSXPreprocessMenu) (void); /* 45 */ @@ -597,12 +596,11 @@ (tkIntPlatStubsPtr->tkMacOSXWindowOffset) /* 37 */ #define TkSetMacColor \ (tkIntPlatStubsPtr->tkSetMacColor) /* 38 */ #define TkSetWMName \ (tkIntPlatStubsPtr->tkSetWMName) /* 39 */ -#define TkSuspendClipboard \ - (tkIntPlatStubsPtr->tkSuspendClipboard) /* 40 */ +/* Slot 40 is reserved */ #define TkMacOSXZoomToplevel \ (tkIntPlatStubsPtr->tkMacOSXZoomToplevel) /* 41 */ #define Tk_TopCoordsToWindow \ (tkIntPlatStubsPtr->tk_TopCoordsToWindow) /* 42 */ #define TkMacOSXContainerId \ @@ -664,6 +662,9 @@ /* !END!: Do not edit above this line. */ #undef TCL_STORAGE_CLASS #define TCL_STORAGE_CLASS DLLIMPORT +#undef TkWinGetPlatformId +#define TkWinGetPlatformId() (2) /* VER_PLATFORM_WIN32_NT */ + #endif /* _TKINTPLATDECLS */ Index: generic/tkIntXlibDecls.h ================================================================== --- generic/tkIntXlibDecls.h +++ generic/tkIntXlibDecls.h @@ -21,15 +21,29 @@ #ifndef _TCL # include #endif +#ifndef EXTERN +# define EXTERN extern TCL_STORAGE_CLASS +#endif + +/* Some (older) versions of X11/Xutil.h have a wrong signature of those + two functions, so move them out of the way temporarly. */ +#define XOffsetRegion _XOffsetRegion +#define XUnionRegion _XUnionRegion #include "X11/Xutil.h" +#undef XOffsetRegion +#undef XUnionRegion #ifdef BUILD_tk -#undef TCL_STORAGE_CLASS -#define TCL_STORAGE_CLASS DLLEXPORT +# undef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLEXPORT +#else +# ifndef TCL_STORAGE_CLASS +# define TCL_STORAGE_CLASS DLLIMPORT +# endif #endif typedef int (*XAfterFunction) ( /* WARNING, this type not in Xlib spec */ Display* /* display */ ); @@ -354,10 +368,65 @@ EXTERN XAfterFunction XSynchronize(Display *display, Bool onoff); /* 113 */ EXTERN int XSync(Display *display, Bool discard); /* 114 */ EXTERN VisualID XVisualIDFromVisual(Visual *visual); +/* Slot 115 is reserved */ +/* Slot 116 is reserved */ +/* Slot 117 is reserved */ +/* Slot 118 is reserved */ +/* Slot 119 is reserved */ +/* 120 */ +EXTERN int XOffsetRegion(Region rgn, int dx, int dy); +/* 121 */ +EXTERN int XUnionRegion(Region srca, Region srcb, + Region dr_return); +/* 122 */ +EXTERN Window XCreateWindow(Display *display, Window parent, int x, + int y, unsigned int width, + unsigned int height, + unsigned int border_width, int depth, + unsigned int clazz, Visual *visual, + unsigned long value_mask, + XSetWindowAttributes *attributes); +/* Slot 123 is reserved */ +/* Slot 124 is reserved */ +/* Slot 125 is reserved */ +/* Slot 126 is reserved */ +/* Slot 127 is reserved */ +/* Slot 128 is reserved */ +/* 129 */ +EXTERN int XLowerWindow(Display *d, Window w); +/* 130 */ +EXTERN int XFillArcs(Display *d, Drawable dr, GC gc, XArc *a, + int n); +/* 131 */ +EXTERN int XDrawArcs(Display *d, Drawable dr, GC gc, XArc *a, + int n); +/* 132 */ +EXTERN int XDrawRectangles(Display *d, Drawable dr, GC gc, + XRectangle *r, int n); +/* 133 */ +EXTERN int XDrawSegments(Display *d, Drawable dr, GC gc, + XSegment *s, int n); +/* 134 */ +EXTERN int XDrawPoint(Display *d, Drawable dr, GC gc, int x, + int y); +/* 135 */ +EXTERN int XDrawPoints(Display *d, Drawable dr, GC gc, + XPoint *p, int n, int m); +/* 136 */ +EXTERN int XReparentWindow(Display *d, Window w, Window p, + int x, int y); +/* 137 */ +EXTERN int XPutImage(Display *d, Drawable dr, GC gc, XImage *im, + int sx, int sy, int dx, int dy, + unsigned int w, unsigned int h); +/* 138 */ +EXTERN Region XPolygonRegion(XPoint *pts, int n, int rule); +/* 139 */ +EXTERN int XPointInRegion(Region rgn, int x, int y); #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ /* 0 */ EXTERN int XSetDashes(Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); @@ -582,11 +651,11 @@ XTextProperty *text_prop); /* 79 */ EXTERN Status XStringListToTextProperty(char **list, int count, XTextProperty *text_prop_return); /* 80 */ -EXTERN void XDrawSegments(Display *display, Drawable d, GC gc, +EXTERN int XDrawSegments(Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 81 */ EXTERN void XForceScreenSaver(Display *display, int mode); /* 82 */ EXTERN int XDrawLine(Display *d, Drawable dr, GC g, int x1, @@ -596,14 +665,14 @@ int x, int y, unsigned int width, unsigned int height); /* 84 */ EXTERN void XClearWindow(Display *d, Window w); /* 85 */ -EXTERN void XDrawPoint(Display *display, Drawable d, GC gc, +EXTERN int XDrawPoint(Display *display, Drawable d, GC gc, int x, int y); /* 86 */ -EXTERN void XDrawPoints(Display *display, Drawable d, GC gc, +EXTERN int XDrawPoints(Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 87 */ EXTERN int XWarpPointer(Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, @@ -740,10 +809,35 @@ int (*xFree) (void *data); /* 110 */ int (*xNoOp) (Display *display); /* 111 */ XAfterFunction (*xSynchronize) (Display *display, Bool onoff); /* 112 */ int (*xSync) (Display *display, Bool discard); /* 113 */ VisualID (*xVisualIDFromVisual) (Visual *visual); /* 114 */ + void (*reserved115)(void); + void (*reserved116)(void); + void (*reserved117)(void); + void (*reserved118)(void); + void (*reserved119)(void); + int (*xOffsetRegion) (Region rgn, int dx, int dy); /* 120 */ + int (*xUnionRegion) (Region srca, Region srcb, Region dr_return); /* 121 */ + Window (*xCreateWindow) (Display *display, Window parent, int x, int y, unsigned int width, unsigned int height, unsigned int border_width, int depth, unsigned int clazz, Visual *visual, unsigned long value_mask, XSetWindowAttributes *attributes); /* 122 */ + void (*reserved123)(void); + void (*reserved124)(void); + void (*reserved125)(void); + void (*reserved126)(void); + void (*reserved127)(void); + void (*reserved128)(void); + int (*xLowerWindow) (Display *d, Window w); /* 129 */ + int (*xFillArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 130 */ + int (*xDrawArcs) (Display *d, Drawable dr, GC gc, XArc *a, int n); /* 131 */ + int (*xDrawRectangles) (Display *d, Drawable dr, GC gc, XRectangle *r, int n); /* 132 */ + int (*xDrawSegments) (Display *d, Drawable dr, GC gc, XSegment *s, int n); /* 133 */ + int (*xDrawPoint) (Display *d, Drawable dr, GC gc, int x, int y); /* 134 */ + int (*xDrawPoints) (Display *d, Drawable dr, GC gc, XPoint *p, int n, int m); /* 135 */ + int (*xReparentWindow) (Display *d, Window w, Window p, int x, int y); /* 136 */ + int (*xPutImage) (Display *d, Drawable dr, GC gc, XImage *im, int sx, int sy, int dx, int dy, unsigned int w, unsigned int h); /* 137 */ + Region (*xPolygonRegion) (XPoint *pts, int n, int rule); /* 138 */ + int (*xPointInRegion) (Region rgn, int x, int y); /* 139 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ int (*xSetDashes) (Display *display, GC gc, int dash_offset, _Xconst char *dash_list, int n); /* 0 */ XModifierKeymap * (*xGetModifierMapping) (Display *d); /* 1 */ XImage * (*xCreateImage) (Display *d, Visual *v, unsigned int ui1, int i1, int i2, char *cp, unsigned int ui2, unsigned int ui3, int i3, int i4); /* 2 */ @@ -822,17 +916,17 @@ int (*_XInitImageFuncPtrs) (XImage *image); /* 75 */ XIC (*xCreateIC) (void); /* 76 */ XVisualInfo * (*xGetVisualInfo) (Display *display, long vinfo_mask, XVisualInfo *vinfo_template, int *nitems_return); /* 77 */ void (*xSetWMClientMachine) (Display *display, Window w, XTextProperty *text_prop); /* 78 */ Status (*xStringListToTextProperty) (char **list, int count, XTextProperty *text_prop_return); /* 79 */ - void (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */ + int (*xDrawSegments) (Display *display, Drawable d, GC gc, XSegment *segments, int nsegments); /* 80 */ void (*xForceScreenSaver) (Display *display, int mode); /* 81 */ int (*xDrawLine) (Display *d, Drawable dr, GC g, int x1, int y1, int x2, int y2); /* 82 */ int (*xFillRectangle) (Display *display, Drawable d, GC gc, int x, int y, unsigned int width, unsigned int height); /* 83 */ void (*xClearWindow) (Display *d, Window w); /* 84 */ - void (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */ - void (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */ + int (*xDrawPoint) (Display *display, Drawable d, GC gc, int x, int y); /* 85 */ + int (*xDrawPoints) (Display *display, Drawable d, GC gc, XPoint *points, int npoints, int mode); /* 86 */ int (*xWarpPointer) (Display *display, Window src_w, Window dest_w, int src_x, int src_y, unsigned int src_width, unsigned int src_height, int dest_x, int dest_y); /* 87 */ void (*xQueryColor) (Display *display, Colormap colormap, XColor *def_in_out); /* 88 */ void (*xQueryColors) (Display *display, Colormap colormap, XColor *defs_in_out, int ncolors); /* 89 */ Status (*xQueryTree) (Display *d, Window w1, Window *w2, Window *w3, Window **w4, unsigned int *ui); /* 90 */ int (*xSync) (Display *display, Bool flag); /* 91 */ @@ -1079,10 +1173,49 @@ (tkIntXlibStubsPtr->xSynchronize) /* 112 */ #define XSync \ (tkIntXlibStubsPtr->xSync) /* 113 */ #define XVisualIDFromVisual \ (tkIntXlibStubsPtr->xVisualIDFromVisual) /* 114 */ +/* Slot 115 is reserved */ +/* Slot 116 is reserved */ +/* Slot 117 is reserved */ +/* Slot 118 is reserved */ +/* Slot 119 is reserved */ +#define XOffsetRegion \ + (tkIntXlibStubsPtr->xOffsetRegion) /* 120 */ +#define XUnionRegion \ + (tkIntXlibStubsPtr->xUnionRegion) /* 121 */ +#define XCreateWindow \ + (tkIntXlibStubsPtr->xCreateWindow) /* 122 */ +/* Slot 123 is reserved */ +/* Slot 124 is reserved */ +/* Slot 125 is reserved */ +/* Slot 126 is reserved */ +/* Slot 127 is reserved */ +/* Slot 128 is reserved */ +#define XLowerWindow \ + (tkIntXlibStubsPtr->xLowerWindow) /* 129 */ +#define XFillArcs \ + (tkIntXlibStubsPtr->xFillArcs) /* 130 */ +#define XDrawArcs \ + (tkIntXlibStubsPtr->xDrawArcs) /* 131 */ +#define XDrawRectangles \ + (tkIntXlibStubsPtr->xDrawRectangles) /* 132 */ +#define XDrawSegments \ + (tkIntXlibStubsPtr->xDrawSegments) /* 133 */ +#define XDrawPoint \ + (tkIntXlibStubsPtr->xDrawPoint) /* 134 */ +#define XDrawPoints \ + (tkIntXlibStubsPtr->xDrawPoints) /* 135 */ +#define XReparentWindow \ + (tkIntXlibStubsPtr->xReparentWindow) /* 136 */ +#define XPutImage \ + (tkIntXlibStubsPtr->xPutImage) /* 137 */ +#define XPolygonRegion \ + (tkIntXlibStubsPtr->xPolygonRegion) /* 138 */ +#define XPointInRegion \ + (tkIntXlibStubsPtr->xPointInRegion) /* 139 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ #define XSetDashes \ (tkIntXlibStubsPtr->xSetDashes) /* 0 */ #define XGetModifierMapping \ Index: generic/tkListbox.c ================================================================== --- generic/tkListbox.c +++ generic/tkListbox.c @@ -10,12 +10,12 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" +#include "default.h" #ifdef _WIN32 #include "tkWinInt.h" #endif @@ -565,11 +565,11 @@ Tk_CreateEventHandler(listPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, ListboxEventProc, listPtr); Tk_CreateSelHandler(listPtr->tkwin, XA_PRIMARY, XA_STRING, ListboxFetchSelection, listPtr, XA_STRING); - if (Tk_InitOptions(interp, (char *)listPtr, + if (Tk_InitOptions(interp, listPtr, optionTables->listboxOptionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(listPtr->tkwin); return TCL_ERROR; } @@ -680,11 +680,11 @@ Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; break; } - objPtr = Tk_GetOptionValue(interp, (char *) listPtr, + objPtr = Tk_GetOptionValue(interp, listPtr, listPtr->optionTable, objv[2], listPtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; break; } @@ -692,11 +692,11 @@ result = TCL_OK; break; case COMMAND_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) listPtr, + objPtr = Tk_GetOptionInfo(interp, listPtr, listPtr->optionTable, (objc == 3) ? objv[2] : NULL, listPtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; break; @@ -924,11 +924,11 @@ break; } attrPtr = ListboxGetItemAttributes(interp, listPtr, index); if (objc <= 4) { - objPtr = Tk_GetOptionInfo(interp, (char *) attrPtr, + objPtr = Tk_GetOptionInfo(interp, attrPtr, listPtr->itemAttrOptionTable, (objc == 4) ? objv[3] : NULL, listPtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; break; @@ -1100,11 +1100,12 @@ */ if ((listPtr->topIndex <= index) && (index < lastVisibleIndex)) { Tcl_Obj *el, *results[4]; const char *stringRep; - int pixelWidth, stringLen, x, y, result; + int pixelWidth, x, y, result; + size_t stringLen; Tk_FontMetrics fm; /* * Compute the pixel width of the requested element. */ @@ -1112,11 +1113,11 @@ result = Tcl_ListObjIndex(interp, listPtr->listObj, index, &el); if (result != TCL_OK) { return result; } - stringRep = Tcl_GetStringFromObj(el, &stringLen); + stringRep = TkGetStringFromObj(el, &stringLen); Tk_GetFontMetrics(listPtr->tkfont, &fm); pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); if (listPtr->justify == TK_JUSTIFY_LEFT) { x = (listPtr->inset + listPtr->selBorderWidth) - listPtr->xOffset; @@ -1413,11 +1414,11 @@ attrs = ckalloc(sizeof(ItemAttr)); attrs->border = NULL; attrs->selBorder = NULL; attrs->fgColor = NULL; attrs->selFgColor = NULL; - Tk_InitOptions(interp, (char *)attrs, listPtr->itemAttrOptionTable, + Tk_InitOptions(interp, attrs, listPtr->itemAttrOptionTable, listPtr->tkwin); Tcl_SetHashValue(entry, attrs); } else { attrs = Tcl_GetHashValue(entry); } @@ -1563,11 +1564,11 @@ Tk_SavedOptions savedOptions; Tcl_Obj *oldListObj = NULL; Tcl_Obj *errorResult = NULL; int oldExport, error; - oldExport = listPtr->exportSelection; + oldExport = (listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp)); if (listPtr->listVarName != NULL) { Tcl_UntraceVar2(interp, listPtr->listVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, ListboxListVarProc, listPtr); } @@ -1576,11 +1577,11 @@ if (!error) { /* * First pass: set options to new values. */ - if (Tk_SetOptions(interp, (char *) listPtr, + if (Tk_SetOptions(interp, listPtr, listPtr->optionTable, objc, objv, listPtr->tkwin, &savedOptions, NULL) != TCL_OK) { continue; } } else { @@ -1605,14 +1606,15 @@ } listPtr->inset = listPtr->highlightWidth + listPtr->borderWidth; /* * Claim the selection if we've suddenly started exporting it and - * there is a selection to export. + * there is a selection to export and this interp is unsafe. */ - if (listPtr->exportSelection && !oldExport + if (listPtr->exportSelection && (!oldExport) + && (!Tcl_IsSafe(listPtr->interp)) && (listPtr->numSelected != 0)) { Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, ListboxLostSelection, listPtr); } @@ -1721,11 +1723,11 @@ Tcl_Obj *const objv[], /* Arguments. */ int index) /* Index of the listbox item being configure */ { Tk_SavedOptions savedOptions; - if (Tk_SetOptions(interp, (char *)attrs, + if (Tk_SetOptions(interp, attrs, listPtr->itemAttrOptionTable, objc, objv, listPtr->tkwin, &savedOptions, NULL) != TCL_OK) { Tk_RestoreSavedOptions(&savedOptions); return TCL_ERROR; } @@ -1837,11 +1839,12 @@ ClientData clientData) /* Information about window. */ { register Listbox *listPtr = clientData; register Tk_Window tkwin = listPtr->tkwin; GC gc; - int i, limit, x, y, prevSelected, freeGC, stringLen; + int i, limit, x, y, prevSelected, freeGC; + size_t stringLen; Tk_FontMetrics fm; Tcl_Obj *curElement; Tcl_HashEntry *entry; const char *stringRep; ItemAttr *attrs; @@ -2071,11 +2074,11 @@ /* * Draw the actual text of this item. */ Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); - stringRep = Tcl_GetStringFromObj(curElement, &stringLen); + stringRep = TkGetStringFromObj(curElement, &stringLen); textWidth = Tk_TextWidth(listPtr->tkfont, stringRep, stringLen); Tk_GetFontMetrics(listPtr->tkfont, &fm); y += fm.ascent + listPtr->selBorderWidth; @@ -2233,11 +2236,12 @@ * must be 1. */ int updateGrid) /* Non-zero means call Tk_SetGrid or * Tk_UnsetGrid to update gridding for the * window. */ { - int width, height, pixelWidth, pixelHeight, textLength, i, result; + int width, height, pixelWidth, pixelHeight, i, result; + size_t textLength; Tk_FontMetrics fm; Tcl_Obj *element; const char *text; if (fontChanged || maxIsStale) { @@ -2254,11 +2258,11 @@ result = Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &element); if (result != TCL_OK) { continue; } - text = Tcl_GetStringFromObj(element, &textLength); + text = TkGetStringFromObj(element, &textLength); Tk_GetFontMetrics(listPtr->tkfont, &fm); pixelWidth = Tk_TextWidth(listPtr->tkfont, text, textLength); if (pixelWidth > listPtr->maxWidth) { listPtr->maxWidth = pixelWidth; } @@ -2320,11 +2324,12 @@ int index, /* Add the new elements before this * element. */ int objc, /* Number of new elements to add. */ Tcl_Obj *const objv[]) /* New elements (one per entry). */ { - int i, oldMaxWidth, pixelWidth, result, length; + int i, oldMaxWidth, pixelWidth, result; + size_t length; Tcl_Obj *newListObj; const char *stringRep; oldMaxWidth = listPtr->maxWidth; for (i = 0; i < objc; i++) { @@ -2331,11 +2336,11 @@ /* * Check if any of the new elements are wider than the current widest; * if so, update our notion of "widest." */ - stringRep = Tcl_GetStringFromObj(objv[i], &length); + stringRep = TkGetStringFromObj(objv[i], &length); pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length); if (pixelWidth > listPtr->maxWidth) { listPtr->maxWidth = pixelWidth; } } @@ -2434,11 +2439,12 @@ ListboxDeleteSubCmd( register Listbox *listPtr, /* Listbox widget to modify. */ int first, /* Index of first element to delete. */ int last) /* Index of last element to delete. */ { - int count, i, widthChanged, length, result, pixelWidth; + int count, i, widthChanged, result, pixelWidth; + size_t length; Tcl_Obj *newListObj, *element; const char *stringRep; Tcl_HashEntry *entry; /* @@ -2489,11 +2495,11 @@ * element to disappear for us to have to recompute the width. */ if (widthChanged == 0) { Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &element); - stringRep = Tcl_GetStringFromObj(element, &length); + stringRep = TkGetStringFromObj(element, &length); pixelWidth = Tk_TextWidth(listPtr->tkfont, stringRep, length); if (pixelWidth == listPtr->maxWidth) { widthChanged = 1; } } @@ -3077,11 +3083,12 @@ if (firstRedisplay >= 0) { EventuallyRedrawRange(listPtr, first, last); } if ((oldCount == 0) && (listPtr->numSelected > 0) - && listPtr->exportSelection) { + && (listPtr->exportSelection) + && (!Tcl_IsSafe(listPtr->interp))) { Tk_OwnSelection(listPtr->tkwin, XA_PRIMARY, ListboxLostSelection, listPtr); } return TCL_OK; } @@ -3118,16 +3125,17 @@ * not including terminating NULL * character. */ { register Listbox *listPtr = clientData; Tcl_DString selection; - int length, count, needNewline, stringLen, i; + int count, needNewline, i; + size_t length, stringLen; Tcl_Obj *curElement; const char *stringRep; Tcl_HashEntry *entry; - if (!listPtr->exportSelection) { + if ((!listPtr->exportSelection) || Tcl_IsSafe(listPtr->interp)) { return -1; } /* * Use a dynamic string to accumulate the contents of the selection. @@ -3141,11 +3149,11 @@ if (needNewline) { Tcl_DStringAppend(&selection, "\n", 1); } Tcl_ListObjIndex(listPtr->interp, listPtr->listObj, i, &curElement); - stringRep = Tcl_GetStringFromObj(curElement, &stringLen); + stringRep = TkGetStringFromObj(curElement, &stringLen); Tcl_DStringAppend(&selection, stringRep, stringLen); needNewline = 1; } } @@ -3156,18 +3164,18 @@ /* * Copy the requested portion of the selection to the buffer. */ - count = length - offset; - if (count <= 0) { + if (length <= (size_t)offset) { count = 0; } else { + count = length - offset; if (count > maxBytes) { count = maxBytes; } - memcpy(buffer, Tcl_DStringValue(&selection) + offset, (size_t) count); + memcpy(buffer, Tcl_DStringValue(&selection) + offset, count); } buffer[count] = '\0'; Tcl_DStringFree(&selection); return count; } @@ -3194,11 +3202,12 @@ ListboxLostSelection( ClientData clientData) /* Information about listbox widget. */ { register Listbox *listPtr = clientData; - if ((listPtr->exportSelection) && (listPtr->nElements > 0)) { + if ((listPtr->exportSelection) && (!Tcl_IsSafe(listPtr->interp)) + && (listPtr->nElements > 0)) { ListboxSelect(listPtr, 0, listPtr->nElements-1, 0); GenerateListboxSelectEvent(listPtr); } } @@ -3426,18 +3435,31 @@ static char * ListboxListVarProc( ClientData clientData, /* Information about button. */ Tcl_Interp *interp, /* Interpreter containing variable. */ - const char *name1, /* Not used. */ - const char *name2, /* Not used. */ + const char *name1, /* Name of variable. */ + const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { Listbox *listPtr = clientData; Tcl_Obj *oldListObj, *varListObj; int oldLength, i; Tcl_HashEntry *entry; + + /* + * See ticket [5d991b82]. + */ + + if (listPtr->listVarName == NULL) { + if (!(flags & TCL_INTERP_DESTROYED)) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ListboxListVarProc, clientData); + } + return NULL; + } /* * Bwah hahahaha! Puny mortal, you can't unset a -listvar'd variable! */ Index: generic/tkMain.c ================================================================== --- generic/tkMain.c +++ generic/tkMain.c @@ -28,18 +28,10 @@ # define _UNICODE # endif #endif #include "tkInt.h" -#include -#include -#include -#ifdef NO_STDLIB_H -# include "../compat/stdlib.h" -#else -# include -#endif extern int TkCygwinMainEx(int, char **, Tcl_AppInitProc *, Tcl_Interp *); /* * The default prompt used when the user has not overridden it. @@ -194,11 +186,11 @@ /* * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { abort(); } else { Tcl_Panic("%s", Tcl_GetString(Tcl_GetObjResult(interp))); } @@ -233,11 +225,15 @@ is.interp = interp; is.gotPartial = 0; Tcl_Preserve(interp); -#if defined(_WIN32) && !defined(__CYGWIN__) +#if defined(_WIN32) +#if !defined(STATIC_BUILD) + /* If compiled for Win32 but running on Cygwin, don't use console */ + if (!tclStubsPtr->reserved9) +#endif Tk_InitConsoleChannels(interp); #endif #ifdef MAC_OSX_TK if (Tcl_GetStartupScript(NULL) == NULL) { @@ -418,18 +414,19 @@ StdinProc( ClientData clientData, /* The state of interactive cmd line */ int mask) /* Not used. */ { char *cmd; - int code, count; + int code; + size_t count; InteractiveState *isPtr = clientData; Tcl_Channel chan = isPtr->input; Tcl_Interp *interp = isPtr->interp; count = Tcl_Gets(chan, &isPtr->line); - if (count < 0 && !isPtr->gotPartial) { + if (count == (size_t)-1 && !isPtr->gotPartial) { if (isPtr->tty) { Tcl_Exit(0); } else { Tcl_DeleteChannelHandler(chan, StdinProc, isPtr); } Index: generic/tkMenu.c ================================================================== --- generic/tkMenu.c +++ generic/tkMenu.c @@ -36,11 +36,11 @@ * * To handle all of the constraints, Tk menubars and tearoff menus are * implemented using menu clones. Menu clones are full menus in their own * right; they have a Tk window and pathname associated with them; they have a * TkMenu structure and array of entries. However, they are linked with the - * original menu that they were cloned from. The reflect the attributes of the + * original menu that they were cloned from. They reflect the attributes of the * original, or "master", menu. So if an item is added to a menu, and that * menu has clones, then the item must be added to all of its clones also. * Menus are cloned when a menu is torn-off or when a menu is assigned as a * menubar using the "-menu" option of the toplevel's pathname configure * subcommand. When a clone is destroyed, only the clone is destroyed, but @@ -257,10 +257,13 @@ Tk_Offset(TkMenu, activeBorderWidthPtr), -1, 0, NULL, 0}, {TK_OPTION_COLOR, "-activeforeground", "activeForeground", "Background", DEF_MENU_ACTIVE_FG_COLOR, Tk_Offset(TkMenu, activeFgPtr), -1, 0, (ClientData) DEF_MENU_ACTIVE_FG_MONO, 0}, + {TK_OPTION_RELIEF, "-activerelief", "activeRelief", "Relief", + DEF_MENU_ACTIVE_RELIEF, Tk_Offset(TkMenu, activeReliefPtr), + -1, 0, NULL, 0}, {TK_OPTION_BORDER, "-background", "background", "Background", DEF_MENU_BG_COLOR, Tk_Offset(TkMenu, borderPtr), -1, 0, (ClientData) DEF_MENU_BG_MONO, 0}, {TK_OPTION_SYNONYM, "-bd", NULL, NULL, NULL, 0, -1, 0, "-borderwidth", 0}, @@ -463,11 +466,11 @@ Tk_SetClass(menuPtr->tkwin, "Menu"); Tk_SetClassProcs(menuPtr->tkwin, &menuClass, menuPtr); Tk_CreateEventHandler(newWin, ExposureMask|StructureNotifyMask|ActivateMask, TkMenuEventProc, menuPtr); - if (Tk_InitOptions(interp, (char *) menuPtr, + if (Tk_InitOptions(interp, menuPtr, tsdPtr->menuOptionTable, menuPtr->tkwin) != TCL_OK) { Tk_DestroyWindow(menuPtr->tkwin); return TCL_ERROR; } @@ -670,11 +673,11 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); goto error; } - resultPtr = Tk_GetOptionValue(interp, (char *) menuPtr, + resultPtr = Tk_GetOptionValue(interp, menuPtr, tsdPtr->menuOptionTable, objv[2], menuPtr->tkwin); if (resultPtr == NULL) { goto error; } @@ -690,21 +693,21 @@ break; case MENU_CONFIGURE: { Tcl_Obj *resultPtr; if (objc == 2) { - resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, + resultPtr = Tk_GetOptionInfo(interp, menuPtr, tsdPtr->menuOptionTable, NULL, menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; } else { result = TCL_OK; Tcl_SetObjResult(interp, resultPtr); } } else if (objc == 3) { - resultPtr = Tk_GetOptionInfo(interp, (char *) menuPtr, + resultPtr = Tk_GetOptionInfo(interp, menuPtr, tsdPtr->menuOptionTable, objv[2], menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; } else { @@ -774,11 +777,11 @@ if (index < 0) { goto done; } mePtr = menuPtr->entries[index]; Tcl_Preserve(mePtr); - resultPtr = Tk_GetOptionValue(interp, (char *) mePtr, + resultPtr = Tk_GetOptionValue(interp, mePtr, mePtr->optionTable, objv[3], menuPtr->tkwin); Tcl_Release(mePtr); if (resultPtr == NULL) { goto error; } @@ -800,20 +803,20 @@ goto done; } mePtr = menuPtr->entries[index]; Tcl_Preserve(mePtr); if (objc == 3) { - resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr, + resultPtr = Tk_GetOptionInfo(interp, mePtr, mePtr->optionTable, NULL, menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; } else { result = TCL_OK; Tcl_SetObjResult(interp, resultPtr); } } else if (objc == 4) { - resultPtr = Tk_GetOptionInfo(interp, (char *) mePtr, + resultPtr = Tk_GetOptionInfo(interp, mePtr, mePtr->optionTable, objv[3], menuPtr->tkwin); if (resultPtr == NULL) { result = TCL_ERROR; } else { result = TCL_OK; @@ -1526,11 +1529,11 @@ Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); for (menuListPtr = menuPtr->masterMenuPtr; menuListPtr != NULL; menuListPtr = menuListPtr->nextInstancePtr) { menuListPtr->errorStructPtr = ckalloc(sizeof(Tk_SavedOptions)); - result = Tk_SetOptions(interp, (char *) menuListPtr, + result = Tk_SetOptions(interp, menuListPtr, tsdPtr->menuOptionTable, objc, objv, menuListPtr->tkwin, menuListPtr->errorStructPtr, NULL); if (result != TCL_OK) { for (cleanupPtr = menuPtr->masterMenuPtr; cleanupPtr != menuListPtr; @@ -1698,16 +1701,16 @@ */ if (mePtr->labelPtr == NULL) { mePtr->labelLength = 0; } else { - (void)Tcl_GetStringFromObj(mePtr->labelPtr, &mePtr->labelLength); + (void)TkGetStringFromObj(mePtr->labelPtr, &mePtr->labelLength); } if (mePtr->accelPtr == NULL) { mePtr->accelLength = 0; } else { - (void)Tcl_GetStringFromObj(mePtr->accelPtr, &mePtr->accelLength); + (void)TkGetStringFromObj(mePtr->accelPtr, &mePtr->accelLength); } /* * If this is a cascade entry, the platform-specific data of the child * menu has to be updated. Also, the links that point to parents and @@ -1922,11 +1925,11 @@ MenuVarProc, mePtr); } result = TCL_OK; if (menuPtr->tkwin != NULL) { - if (Tk_SetOptions(menuPtr->interp, (char *) mePtr, + if (Tk_SetOptions(menuPtr->interp, mePtr, mePtr->optionTable, objc, objv, menuPtr->tkwin, &errorStruct, NULL) != TCL_OK) { return TCL_ERROR; } result = PostProcessEntry(mePtr); @@ -2296,11 +2299,11 @@ mePtr->onValuePtr = NULL; mePtr->offValuePtr = NULL; mePtr->entryFlags = 0; mePtr->index = index; mePtr->nextCascadePtr = NULL; - if (Tk_InitOptions(menuPtr->interp, (char *) mePtr, + if (Tk_InitOptions(menuPtr->interp, mePtr, mePtr->optionTable, menuPtr->tkwin) != TCL_OK) { ckfree(mePtr); return NULL; } TkMenuInitializeEntryDrawingFields(mePtr); @@ -2493,10 +2496,26 @@ return NULL; } menuPtr = mePtr->menuPtr; + + if (menuPtr->menuFlags & MENU_DELETION_PENDING) { + return NULL; + } + + /* + * See ticket [5d991b82]. + */ + + if (mePtr->namePtr == NULL) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuVarProc, clientData); + return NULL; + } + name = Tcl_GetString(mePtr->namePtr); /* * If the variable is being unset, then re-establish the trace. */ Index: generic/tkMenu.h ================================================================== --- generic/tkMenu.h +++ generic/tkMenu.h @@ -66,15 +66,15 @@ struct TkMenu *menuPtr; /* Menu with which this entry is * associated. */ Tk_OptionTable optionTable; /* Option table for this menu entry. */ Tcl_Obj *labelPtr; /* Main text label displayed in entry (NULL if * no label). */ - int labelLength; /* Number of non-NULL characters in label. */ + TkSizeT labelLength; /* Number of non-NULL characters in label. */ int state; /* State of button for display purposes: * normal, active, or disabled. */ int underline; /* Value of -underline option: specifies index - * of character to underline (<0 means don't + * of character to underline (-1 means don't * underline anything). */ Tcl_Obj *underlinePtr; /* Index of character to underline. */ Tcl_Obj *bitmapPtr; /* Bitmap to display in menu entry, or None. * If not None then label is ignored. */ Tcl_Obj *imagePtr; /* Name of image to display, or NULL. If not @@ -87,11 +87,11 @@ Tk_Image selectImage; /* Image to display in entry when selected, or * NULL if none. Ignored if image is NULL. */ Tcl_Obj *accelPtr; /* Accelerator string displayed at right of * menu entry. NULL means no such accelerator. * Malloc'ed. */ - int accelLength; /* Number of non-NULL characters in + TkSizeT accelLength; /* Number of non-NULL characters in * accelerator. */ int indicatorOn; /* True means draw indicator, false means * don't draw it. This field is ignored unless * the entry is a radio or check button. */ /* @@ -380,10 +380,11 @@ * this widget to be extended. */ Tk_SavedOptions *errorStructPtr; /* We actually have to allocate these because * multiple menus get changed during one * ConfigureMenu call. */ + Tcl_Obj *activeReliefPtr; /* 3-d effect for active element. */ } TkMenu; /* * When the toplevel configure -menu command is executed, the menu may not * exist yet. We need to keep a linked list of windows that reference a Index: generic/tkMenuDraw.c ================================================================== --- generic/tkMenuDraw.c +++ generic/tkMenuDraw.c @@ -622,11 +622,10 @@ Tk_Font tkfont; Tk_FontMetrics menuMetrics; int width; int borderWidth; Tk_3DBorder border; - int activeBorderWidth; int relief; menuPtr->menuFlags &= ~REDRAW_PENDING; if ((menuPtr->tkwin == NULL) || !Tk_IsMapped(tkwin)) { @@ -634,12 +633,10 @@ } Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, menuPtr->borderWidthPtr, &borderWidth); border = Tk_Get3DBorderFromObj(menuPtr->tkwin, menuPtr->borderPtr); - Tk_GetPixelsFromObj(NULL, menuPtr->tkwin, - menuPtr->activeBorderWidthPtr, &activeBorderWidth); if (menuPtr->menuType == MENUBAR) { Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, borderWidth, borderWidth, Tk_Width(tkwin) - 2 * borderWidth, Tk_Height(tkwin) - 2 * borderWidth, 0, TK_RELIEF_FLAT); @@ -666,53 +663,40 @@ continue; } } mePtr->entryFlags &= ~ENTRY_NEEDS_REDISPLAY; - if (menuPtr->menuType == MENUBAR) { - width = mePtr->width; - } else { - if (mePtr->entryFlags & ENTRY_LAST_COLUMN) { - width = Tk_Width(menuPtr->tkwin) - mePtr->x - - activeBorderWidth; - } else { - width = mePtr->width + borderWidth; - } - } TkpDrawMenuEntry(mePtr, Tk_WindowId(menuPtr->tkwin), tkfont, - &menuMetrics, mePtr->x, mePtr->y, width, + &menuMetrics, mePtr->x, mePtr->y, mePtr->width, mePtr->height, strictMotif, 1); if ((index > 0) && (menuPtr->menuType != MENUBAR) && mePtr->columnBreak) { mePtr = menuPtr->entries[index - 1]; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, - mePtr->x, mePtr->y + mePtr->height, - mePtr->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - - activeBorderWidth, 0, - TK_RELIEF_FLAT); + mePtr->x, mePtr->y + mePtr->height, mePtr->width, + Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth, + 0, TK_RELIEF_FLAT); } } if (menuPtr->menuType != MENUBAR) { int x, y, height; if (menuPtr->numEntries == 0) { x = y = borderWidth; - width = Tk_Width(tkwin) - 2 * activeBorderWidth; - height = Tk_Height(tkwin) - 2 * activeBorderWidth; + width = Tk_Width(tkwin) - 2 * borderWidth; + height = Tk_Height(tkwin) - 2 * borderWidth; } else { mePtr = menuPtr->entries[menuPtr->numEntries - 1]; Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, mePtr->x, mePtr->y + mePtr->height, mePtr->width, - Tk_Height(tkwin) - mePtr->y - mePtr->height - - activeBorderWidth, 0, - TK_RELIEF_FLAT); + Tk_Height(tkwin) - mePtr->y - mePtr->height - borderWidth, + 0, TK_RELIEF_FLAT); x = mePtr->x + mePtr->width; y = mePtr->y + mePtr->height; - width = Tk_Width(tkwin) - x - activeBorderWidth; - height = Tk_Height(tkwin) - y - activeBorderWidth; + width = Tk_Width(tkwin) - x - borderWidth; + height = Tk_Height(tkwin) - y - borderWidth; } Tk_Fill3DRectangle(tkwin, Tk_WindowId(tkwin), border, x, y, width, height, 0, TK_RELIEF_FLAT); } Index: generic/tkMenubutton.c ================================================================== --- generic/tkMenubutton.c +++ generic/tkMenubutton.c @@ -306,11 +306,11 @@ Tk_CreateEventHandler(mbPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, MenuButtonEventProc, mbPtr); - if (Tk_InitOptions(interp, (char *) mbPtr, optionTable, tkwin) != TCL_OK) { + if (Tk_InitOptions(interp, mbPtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(mbPtr->tkwin); return TCL_ERROR; } if (ConfigureMenuButton(interp, mbPtr, objc-2, objv+2) != TCL_OK) { @@ -367,21 +367,21 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "cget option"); goto error; } - objPtr = Tk_GetOptionValue(interp, (char *) mbPtr, + objPtr = Tk_GetOptionValue(interp, mbPtr, mbPtr->optionTable, objv[2], mbPtr->tkwin); if (objPtr == NULL) { goto error; } Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) mbPtr, + objPtr = Tk_GetOptionInfo(interp, mbPtr, mbPtr->optionTable, (objc == 3) ? objv[2] : NULL, mbPtr->tkwin); if (objPtr == NULL) { goto error; } @@ -522,11 +522,11 @@ if (!error) { /* * First pass: set options to new values. */ - if (Tk_SetOptions(interp, (char *) mbPtr, + if (Tk_SetOptions(interp, mbPtr, mbPtr->optionTable, objc, objv, mbPtr->tkwin, &savedOptions, NULL) != TCL_OK) { continue; } } else { @@ -878,10 +878,23 @@ int flags) /* Information about what happened. */ { register TkMenuButton *mbPtr = clientData; const char *value; unsigned len; + + /* + * See ticket [5d991b82]. + */ + + if (mbPtr->textVarName == NULL) { + if (!(flags & TCL_INTERP_DESTROYED)) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MenuButtonTextVarProc, clientData); + } + return NULL; + } /* * If the variable is unset, then immediately recreate it unless the whole * interpreter is going away. */ Index: generic/tkMessage.c ================================================================== --- generic/tkMessage.c +++ generic/tkMessage.c @@ -11,12 +11,12 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" +#include "default.h" /* * A data structure of the following type is kept for each message widget * managed by this file: */ @@ -240,11 +240,11 @@ */ optionTable = Tk_CreateOptionTable(interp, optionSpecs); msgPtr = ckalloc(sizeof(Message)); - memset(msgPtr, 0, (size_t) sizeof(Message)); + memset(msgPtr, 0, sizeof(Message)); /* * Set values for those fields that don't take a 0 or NULL value. */ @@ -265,11 +265,11 @@ Tk_SetClass(msgPtr->tkwin, "Message"); Tk_SetClassProcs(msgPtr->tkwin, &messageClass, msgPtr); Tk_CreateEventHandler(msgPtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, MessageEventProc, msgPtr); - if (Tk_InitOptions(interp, (char *)msgPtr, optionTable, tkwin) != TCL_OK) { + if (Tk_InitOptions(interp, msgPtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(msgPtr->tkwin); return TCL_ERROR; } if (ConfigureMessage(interp, msgPtr, objc-2, objv+2, 0) != TCL_OK) { @@ -329,11 +329,11 @@ case MESSAGE_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; } else { - objPtr = Tk_GetOptionValue(interp, (char *) msgPtr, + objPtr = Tk_GetOptionValue(interp, msgPtr, msgPtr->optionTable, objv[2], msgPtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, objPtr); @@ -341,11 +341,11 @@ } } break; case MESSAGE_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) msgPtr, + objPtr = Tk_GetOptionInfo(interp, msgPtr, msgPtr->optionTable, (objc == 3) ? objv[2] : NULL, msgPtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; } else { @@ -453,11 +453,11 @@ Tcl_UntraceVar2(interp, msgPtr->textVarName, NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, MessageTextVarProc, msgPtr); } - if (Tk_SetOptions(interp, (char *) msgPtr, msgPtr->optionTable, objc, objv, + if (Tk_SetOptions(interp, msgPtr, msgPtr->optionTable, objc, objv, msgPtr->tkwin, &savedOptions, NULL) != TCL_OK) { Tk_RestoreSavedOptions(&savedOptions); return TCL_ERROR; } @@ -835,10 +835,23 @@ const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { register Message *msgPtr = clientData; const char *value; + + /* + * See ticket [5d991b82]. + */ + + if (msgPtr->textVarName == NULL) { + if (!(flags & TCL_INTERP_DESTROYED)) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + MessageTextVarProc, clientData); + } + return NULL; + } /* * If the variable is unset, then immediately recreate it unless the whole * interpreter is going away. */ Index: generic/tkObj.c ================================================================== --- generic/tkObj.c +++ generic/tkObj.c @@ -71,12 +71,16 @@ */ typedef struct WindowRep { Tk_Window tkwin; /* Cached window; NULL if not found. */ TkMainInfo *mainPtr; /* MainWindow associated with tkwin. */ - long epoch; /* Value of mainPtr->deletionEpoch at last +#if TCL_MAJOR_VERSION > 8 + size_t epoch; /* Value of mainPtr->deletionEpoch at last * successful lookup. */ +#else + long epoch; +#endif } WindowRep; /* * Prototypes for functions defined later in this file: */ @@ -102,11 +106,11 @@ static const Tcl_ObjType pixelObjType = { "pixel", /* name */ FreePixelInternalRep, /* freeIntRepProc */ DupPixelInternalRep, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetPixelFromAny /* setFromAnyProc */ + NULL /* setFromAnyProc */ }; /* * The following structure defines the implementation of the "pixel" Tcl * object, used for measuring distances. The pixel object remembers its @@ -116,11 +120,11 @@ static const Tcl_ObjType mmObjType = { "mm", /* name */ FreeMMInternalRep, /* freeIntRepProc */ DupMMInternalRep, /* dupIntRepProc */ UpdateStringOfMM, /* updateStringProc */ - SetMMFromAny /* setFromAnyProc */ + NULL /* setFromAnyProc */ }; /* * The following structure defines the implementation of the "window" * Tcl object. @@ -129,11 +133,11 @@ static const Tcl_ObjType windowObjType = { "window", /* name */ FreeWindowInternalRep, /* freeIntRepProc */ DupWindowInternalRep, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetWindowFromAny /* setFromAnyProc */ + NULL /* setFromAnyProc */ }; /* *---------------------------------------------------------------------- * @@ -151,12 +155,23 @@ { ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); if (tsdPtr->doubleTypePtr == NULL) { - tsdPtr->doubleTypePtr = Tcl_GetObjType("double"); - tsdPtr->intTypePtr = Tcl_GetObjType("int"); + /* Smart initialization of doubleTypePtr/intTypePtr without + * hash-table lookup or creating complete Tcl_Obj's */ + Tcl_Obj obj; + obj.length = 3; + obj.bytes = (char *)"0.0"; + obj.typePtr = NULL; + Tcl_GetDoubleFromObj(NULL, &obj, &obj.internalRep.doubleValue); + tsdPtr->doubleTypePtr = obj.typePtr; + obj.bytes += 2; + obj.length = 1; + obj.typePtr = NULL; + Tcl_GetLongFromObj(NULL, &obj, &obj.internalRep.longValue); + tsdPtr->intTypePtr = obj.typePtr; } return tsdPtr; } /* @@ -655,20 +670,20 @@ UpdateStringOfMM( register Tcl_Obj *objPtr) /* pixel obj with string rep to update. */ { MMRep *mmPtr; char buffer[TCL_DOUBLE_SPACE]; - register int len; + size_t len; mmPtr = objPtr->internalRep.twoPtrValue.ptr1; /* assert( mmPtr->units == -1 && objPtr->bytes == NULL ); */ if ((mmPtr->units != -1) || (objPtr->bytes != NULL)) { Tcl_Panic("UpdateStringOfMM: false precondition"); } Tcl_PrintDouble(NULL, mmPtr->value, buffer); - len = (int)strlen(buffer); + len = strlen(buffer); objPtr->bytes = ckalloc(len + 1); strcpy(objPtr->bytes, buffer); objPtr->length = len; } @@ -879,11 +894,11 @@ /* * Free the old internalRep before setting the new one. */ - (void)Tcl_GetString(objPtr); + Tcl_GetString(objPtr); typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { typePtr->freeIntRepProc(objPtr); } @@ -1110,11 +1125,11 @@ * * Results: * None * * Side effects: - * All instances of Tcl_ObjType structues used in Tk are registered with + * All instances of Tcl_ObjType structures used in Tk are registered with * Tcl. * *---------------------------------------------------------------------- */ Index: generic/tkOldConfig.c ================================================================== --- generic/tkOldConfig.c +++ generic/tkOldConfig.c @@ -23,24 +23,28 @@ * Tk_Uid's. */ #define INIT 0x20 +#ifndef TK_CONFIG_OPTION_SPECIFIED +# define TK_CONFIG_OPTION_SPECIFIED (1 << 4) +#endif + /* * Forward declarations for functions defined later in this file: */ static int DoConfig(Tcl_Interp *interp, Tk_Window tkwin, Tk_ConfigSpec *specPtr, Tk_Uid value, - int valueIsUid, char *widgRec); + int valueIsUid, void *widgRec); static Tk_ConfigSpec * FindConfigSpec(Tcl_Interp *interp, Tk_ConfigSpec *specs, const char *argvName, int needFlags, int hateFlags); static char * FormatConfigInfo(Tcl_Interp *interp, Tk_Window tkwin, - const Tk_ConfigSpec *specPtr, char *widgRec); + const Tk_ConfigSpec *specPtr, void *widgRec); static const char * FormatConfigValue(Tcl_Interp *interp, Tk_Window tkwin, - const Tk_ConfigSpec *specPtr, char *widgRec, + const Tk_ConfigSpec *specPtr, void *widgRec, char *buffer, Tcl_FreeProc **freeProcPtr); static Tk_ConfigSpec * GetCachedSpecs(Tcl_Interp *interp, const Tk_ConfigSpec *staticSpecs); static void DeleteSpecCacheTable(ClientData clientData, Tcl_Interp *interp); @@ -338,24 +342,24 @@ * X resources). */ Tk_ConfigSpec *specPtr, /* Specifier to apply. */ Tk_Uid value, /* Value to use to fill in widgRec. */ int valueIsUid, /* Non-zero means value is a Tk_Uid; zero * means it's an ordinary string. */ - char *widgRec) /* Record whose fields are to be modified. + void *widgRec) /* Record whose fields are to be modified. * Values must be properly initialized. */ { - char *ptr; + void *ptr; Tk_Uid uid; int nullValue; nullValue = 0; if ((*value == 0) && (specPtr->specFlags & TK_CONFIG_NULL_OK)) { nullValue = 1; } do { - ptr = widgRec + specPtr->offset; + ptr = (char *)widgRec + specPtr->offset; switch (specPtr->type) { case TK_CONFIG_BOOLEAN: if (Tcl_GetBoolean(interp, value, (int *) ptr) != TCL_OK) { return TCL_ERROR; } @@ -687,11 +691,11 @@ * floating-point precision. */ Tk_Window tkwin, /* Window corresponding to widget. */ register const Tk_ConfigSpec *specPtr, /* Pointer to information describing * option. */ - char *widgRec) /* Pointer to record holding current values of + void *widgRec) /* Pointer to record holding current values of * info for widget. */ { const char *argv[6]; char *result; char buffer[200]; @@ -753,22 +757,23 @@ FormatConfigValue( Tcl_Interp *interp, /* Interpreter for use in real conversions. */ Tk_Window tkwin, /* Window corresponding to widget. */ const Tk_ConfigSpec *specPtr, /* Pointer to information describing option. * Must not point to a synonym option. */ - char *widgRec, /* Pointer to record holding current values of + void *widgRec, /* Pointer to record holding current values of * info for widget. */ char *buffer, /* Static buffer to use for small values. * Must have at least 200 bytes of storage. */ Tcl_FreeProc **freeProcPtr) /* Pointer to word to fill in with address of * function to free the result, or NULL if * result is static. */ { - const char *ptr, *result; + void *ptr; + const char *result; *freeProcPtr = NULL; - ptr = widgRec + specPtr->offset; + ptr = (char *)widgRec + specPtr->offset; result = ""; switch (specPtr->type) { case TK_CONFIG_BOOLEAN: if (*((int *) ptr) == 0) { result = "0"; Index: generic/tkOldTest.c ================================================================== --- generic/tkOldTest.c +++ generic/tkOldTest.c @@ -170,13 +170,13 @@ timPtr = ckalloc(sizeof(TImageMaster)); timPtr->master = master; timPtr->interp = interp; timPtr->width = 30; timPtr->height = 15; - timPtr->imageName = ckalloc((unsigned) (strlen(name) + 1)); + timPtr->imageName = ckalloc(strlen(name) + 1); strcpy(timPtr->imageName, name); - timPtr->varName = ckalloc((unsigned) (strlen(varName) + 1)); + timPtr->varName = ckalloc(strlen(varName) + 1); strcpy(timPtr->varName, varName); Tcl_CreateObjCommand(interp, name, ImageObjCmd, timPtr, NULL); *clientDataPtr = timPtr; Tk_ImageChanged(master, 0, 0, 30, 15, 30, 15); return TCL_OK; Index: generic/tkOption.c ================================================================== --- generic/tkOption.c +++ generic/tkOption.c @@ -258,11 +258,11 @@ register Element *elPtr; Element newEl; register const char *p; const char *field; int count, firstField; - ptrdiff_t length; + size_t length; #define TMP_SIZE 100 char tmp[TMP_SIZE+1]; ThreadSpecificData *tsdPtr = Tcl_GetThreadData(&dataKey, sizeof(ThreadSpecificData)); @@ -309,11 +309,11 @@ } length = p - field; if (length > TMP_SIZE) { length = TMP_SIZE; } - strncpy(tmp, field, (size_t) length); + strncpy(tmp, field, length); tmp[length] = 0; newEl.nameUid = Tk_GetUid(tmp); if (isupper(UCHAR(*field))) { newEl.flags |= CLASS; } @@ -1079,11 +1079,12 @@ * TK_INTERACTIVE_PRIO. Must be between 0 and * TK_MAX_PRIO. */ { const char *realName; Tcl_Obj *buffer; - int result, bufferSize; + int result; + size_t bufferSize; Tcl_Channel chan; Tcl_DString newName; /* * Prevent file system access in a safe interpreter. @@ -1110,11 +1111,11 @@ buffer = Tcl_NewObj(); Tcl_IncrRefCount(buffer); Tcl_SetChannelOption(NULL, chan, "-encoding", "utf-8"); bufferSize = Tcl_ReadChars(chan, buffer, -1, 0); - if (bufferSize < 0) { + if (bufferSize == (size_t)-1) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "error reading file \"%s\": %s", fileName, Tcl_PosixError(interp))); Tcl_Close(NULL, chan); return TCL_ERROR; Index: generic/tkPack.c ================================================================== --- generic/tkPack.c +++ generic/tkPack.c @@ -120,12 +120,14 @@ static void ArrangePacking(ClientData clientData); static int ConfigureSlaves(Tcl_Interp *interp, Tk_Window tkwin, int objc, Tcl_Obj *const objv[]); static void DestroyPacker(void *memPtr); static Packer * GetPacker(Tk_Window tkwin); +#ifndef TK_NO_DEPRECATED static int PackAfter(Tcl_Interp *interp, Packer *prevPtr, Packer *masterPtr, int objc,Tcl_Obj *const objv[]); +#endif /* !TK_NO_DEPRECATED */ static void PackStructureProc(ClientData clientData, XEvent *eventPtr); static void Unlink(Packer *packPtr); static int XExpansion(Packer *slavePtr, int cavityWidth); static int YExpansion(Packer *slavePtr, int cavityHeight); @@ -195,15 +197,18 @@ Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_Window tkwin = clientData; const char *argv2; static const char *const optionStrings[] = { - /* after, append, before and unpack are deprecated */ +#ifndef TK_NO_DEPRECATED "after", "append", "before", "unpack", +#endif /* !TK_NO_DEPRECATED */ "configure", "forget", "info", "propagate", "slaves", NULL }; enum options { +#ifndef TK_NO_DEPRECATED PACK_AFTER, PACK_APPEND, PACK_BEFORE, PACK_UNPACK, +#endif /* !TK_NO_DEPRECATED */ PACK_CONFIGURE, PACK_FORGET, PACK_INFO, PACK_PROPAGATE, PACK_SLAVES }; int index; if (objc >= 2) { const char *string = Tcl_GetString(objv[1]); @@ -217,24 +222,27 @@ return TCL_ERROR; } if (Tcl_GetIndexFromObjStruct(interp, objv[1], optionStrings, sizeof(char *), "option", 0, &index) != TCL_OK) { +#ifndef TK_NO_DEPRECATED /* * Call it again without the deprecated ones to get a proper error * message. This works well since there can't be any ambiguity between * deprecated and new options. */ Tcl_ResetResult(interp); Tcl_GetIndexFromObjStruct(interp, objv[1], &optionStrings[4], sizeof(char *), "option", 0, &index); +#endif /* TK_NO_DEPRECATED */ return TCL_ERROR; } argv2 = Tcl_GetString(objv[2]); switch ((enum options) index) { +#ifndef TK_NO_DEPRECATED case PACK_AFTER: { Packer *prevPtr; Tk_Window tkwin2; if (TkGetWindowFromObj(interp, tkwin, objv[2], &tkwin2) != TCL_OK) { @@ -295,10 +303,11 @@ } } } return PackAfter(interp, prevPtr, masterPtr, objc-3, objv+3); } +#endif /* !TK_NO_DEPRECATED */ case PACK_CONFIGURE: if (argv2[0] != '.') { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad argument \"%s\": must be name of window", argv2)); Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL); @@ -456,10 +465,11 @@ TkNewWindowObj(slavePtr->tkwin)); } Tcl_SetObjResult(interp, resultObj); break; } +#ifndef TK_NO_DEPRECATED case PACK_UNPACK: { Tk_Window tkwin2; Packer *packPtr; if (objc != 3) { @@ -479,10 +489,11 @@ Unlink(packPtr); Tk_UnmapWindow(packPtr->tkwin); } break; } +#endif /* !TK_NO_DEPRECATED */ } return TCL_OK; } @@ -597,19 +608,16 @@ int maxWidth, maxHeight, tmp; masterPtr->flags &= ~REQUESTED_REPACK; /* - * If the master has no slaves anymore, then don't do anything at all: - * just leave the master's size as-is, but signal the master with the - * <> virtual event. + * If the master has no slaves anymore, then leave the master's size as-is. * Otherwise there is no way to "relinquish" control over the master * so another geometry manager can take over. */ if (masterPtr->slavePtr == NULL) { - TkSendVirtualEvent(masterPtr->tkwin, "GeometryManager", NULL); return; } /* * Abort any nested call to ArrangePacking for this window, since we'll do @@ -1089,10 +1097,11 @@ * in the future. * *------------------------------------------------------------------------ */ +#ifndef TK_NO_DEPRECATED static int PackAfter( Tcl_Interp *interp, /* Interpreter for error reporting. */ Packer *prevPtr, /* Pack windows in argv just after this * window; NULL means pack as first child of @@ -1171,12 +1180,12 @@ packPtr->iPadX = packPtr->iPadY = 0; packPtr->flags &= ~(FILLX|FILLY|EXPAND); packPtr->flags |= OLD_STYLE; for (index = 0 ; index < optionCount; index++) { Tcl_Obj *curOptPtr = options[index]; - const char *curOpt = Tcl_GetString(curOptPtr); - size_t length = curOptPtr->length; + size_t length; + const char *curOpt = TkGetStringFromObj(curOptPtr, &length); c = curOpt[0]; if ((c == 't') && (strncmp(curOpt, "top", length)) == 0) { @@ -1309,10 +1318,11 @@ masterPtr->flags |= REQUESTED_REPACK; Tcl_DoWhenIdle(ArrangePacking, masterPtr); } return TCL_OK; } +#endif /* !TK_NO_DEPRECATED */ /* *---------------------------------------------------------------------- * * Unlink -- @@ -1362,15 +1372,19 @@ packPtr->masterPtr = NULL; /* * If we have emptied this master from slaves it means we are no longer * handling it and should mark it as free. + * + * Send the event "NoManagedChild" to the master to inform it about there + * being no managed children inside it. */ - if (masterPtr->slavePtr == NULL && masterPtr->flags & ALLOCED_MASTER) { + if ((masterPtr->slavePtr == NULL) && (masterPtr->flags & ALLOCED_MASTER)) { TkFreeGeometryMaster(masterPtr->tkwin, "pack"); masterPtr->flags &= ~ALLOCED_MASTER; + TkSendVirtualEvent(masterPtr->tkwin, "NoManagedChild", NULL); } } /* Index: generic/tkPanedWindow.c ================================================================== --- generic/tkPanedWindow.c +++ generic/tkPanedWindow.c @@ -11,12 +11,12 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" +#include "default.h" /* * Flag values for "sticky"ness. The 16 combinations subsume the packer's * notion of anchor and fill. * @@ -234,11 +234,11 @@ static void AdjustForSticky(int sticky, int cavityWidth, int cavityHeight, int *xPtr, int *yPtr, int *slaveWidthPtr, int *slaveHeightPtr); static void MoveSash(PanedWindow *pwPtr, int sash, int diff); static int ObjectIsEmpty(Tcl_Obj *objPtr); -static char * ComputeSlotAddress(char *recordPtr, int offset); +static void * ComputeSlotAddress(void *recordPtr, int offset); static int PanedWindowIdentifyCoords(PanedWindow *pwPtr, Tcl_Interp *interp, int x, int y); /* * Sashes are between panes only, so there is one less sash than slaves @@ -457,11 +457,11 @@ * otherwise Tk might free it while we still need it. */ Tcl_Preserve(pwPtr->tkwin); - if (Tk_InitOptions(interp, (char *) pwPtr, pwOpts->pwOptions, + if (Tk_InitOptions(interp, pwPtr, pwOpts->pwOptions, tkwin) != TCL_OK) { Tk_DestroyWindow(pwPtr->tkwin); return TCL_ERROR; } @@ -576,11 +576,11 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; break; } - resultObj = Tk_GetOptionValue(interp, (char *) pwPtr, + resultObj = Tk_GetOptionValue(interp, pwPtr, pwPtr->optionTable, objv[2], pwPtr->tkwin); if (resultObj == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, resultObj); @@ -588,11 +588,11 @@ break; case PW_CONFIGURE: resultObj = NULL; if (objc <= 3) { - resultObj = Tk_GetOptionInfo(interp, (char *) pwPtr, + resultObj = Tk_GetOptionInfo(interp, pwPtr, pwPtr->optionTable, (objc == 3) ? objv[2] : NULL, pwPtr->tkwin); if (resultObj == NULL) { result = TCL_ERROR; } else { @@ -667,11 +667,11 @@ } resultObj = NULL; for (i = 0; i < pwPtr->numSlaves; i++) { if (pwPtr->slaves[i]->tkwin == tkwin) { resultObj = Tk_GetOptionValue(interp, - (char *) pwPtr->slaves[i], pwPtr->slaveOpts, + pwPtr->slaves[i], pwPtr->slaveOpts, objv[3], tkwin); } } if (resultObj == NULL) { if (i == pwPtr->numSlaves) { @@ -707,11 +707,11 @@ break; } for (i = 0; i < pwPtr->numSlaves; i++) { if (pwPtr->slaves[i]->tkwin == tkwin) { resultObj = Tk_GetOptionInfo(interp, - (char *) pwPtr->slaves[i], pwPtr->slaveOpts, + pwPtr->slaves[i], pwPtr->slaveOpts, (objc == 4) ? objv[3] : NULL, pwPtr->tkwin); if (resultObj == NULL) { result = TCL_ERROR; } else { @@ -846,11 +846,11 @@ * return from Tk_SetOptions once, here, so we can save a little bit of * extra testing in the for loop below. */ memset((void *)&options, 0, sizeof(Slave)); - if (Tk_SetOptions(interp, (char *) &options, pwPtr->slaveOpts, + if (Tk_SetOptions(interp, &options, pwPtr->slaveOpts, objc - firstOptionArg, objv + firstOptionArg, pwPtr->tkwin, NULL, NULL) != TCL_OK) { return TCL_ERROR; } @@ -923,11 +923,11 @@ pwPtr->tkwin); found = 0; for (j = 0; j < pwPtr->numSlaves; j++) { if (pwPtr->slaves[j] != NULL && pwPtr->slaves[j]->tkwin == tkwin) { - Tk_SetOptions(interp, (char *) pwPtr->slaves[j], + Tk_SetOptions(interp, pwPtr->slaves[j], pwPtr->slaveOpts, objc - firstOptionArg, objv + firstOptionArg, pwPtr->tkwin, NULL, NULL); if (pwPtr->slaves[j]->minSize < 0) { pwPtr->slaves[j]->minSize = 0; } @@ -970,13 +970,13 @@ * out with their "natural" dimensions. */ slavePtr = ckalloc(sizeof(Slave)); memset(slavePtr, 0, sizeof(Slave)); - Tk_InitOptions(interp, (char *)slavePtr, pwPtr->slaveOpts, + Tk_InitOptions(interp, slavePtr, pwPtr->slaveOpts, pwPtr->tkwin); - Tk_SetOptions(interp, (char *)slavePtr, pwPtr->slaveOpts, + Tk_SetOptions(interp, slavePtr, pwPtr->slaveOpts, objc - firstOptionArg, objv + firstOptionArg, pwPtr->tkwin, NULL, NULL); slavePtr->tkwin = tkwin; slavePtr->masterPtr = pwPtr; doubleBw = 2 * Tk_Changes(slavePtr->tkwin)->border_width; @@ -1247,11 +1247,11 @@ Tcl_Obj *const objv[]) /* Argument values. */ { Tk_SavedOptions savedOptions; int typemask = 0; - if (Tk_SetOptions(interp, (char *) pwPtr, pwPtr->optionTable, objc, objv, + if (Tk_SetOptions(interp, pwPtr, pwPtr->optionTable, objc, objv, pwPtr->tkwin, &savedOptions, &typemask) != TCL_OK) { Tk_RestoreSavedOptions(&savedOptions); return TCL_ERROR; } @@ -1482,14 +1482,14 @@ * Set up boilerplate geometry values for sashes (width, height, common * coordinates). */ if (horizontal) { - sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderWidth(tkwin)); + sashHeight = Tk_Height(tkwin) - (2 * Tk_InternalBorderLeft(tkwin)); sashWidth = pwPtr->sashWidth; } else { - sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderWidth(tkwin)); + sashWidth = Tk_Width(tkwin) - (2 * Tk_InternalBorderLeft(tkwin)); sashHeight = pwPtr->sashWidth; } /* * Draw the sashes. @@ -1752,11 +1752,11 @@ /* * First pass; compute sizes */ paneDynSize = paneDynMinSize = 0; - internalBW = Tk_InternalBorderWidth(pwPtr->tkwin); + internalBW = Tk_InternalBorderLeft(pwPtr->tkwin); pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW); pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW); x = y = internalBW; stretchReserve = (horizontal ? pwWidth : pwHeight); @@ -1787,14 +1787,22 @@ * Compute the total size needed by all the slaves and the left-over, * or shortage of space available. */ if (horizontal) { - paneSize = slavePtr->paneWidth; + if (slavePtr->width > 0) { + paneSize = slavePtr->width; + } else { + paneSize = slavePtr->paneWidth; + } stretchReserve -= paneSize + (2 * slavePtr->padx); } else { - paneSize = slavePtr->paneHeight; + if (slavePtr->height > 0) { + paneSize = slavePtr->height; + } else { + paneSize = slavePtr->paneHeight; + } stretchReserve -= paneSize + (2 * slavePtr->pady); } if (IsStretchable(slavePtr->stretch,i,first,last) && Tk_IsMapped(pwPtr->tkwin)) { paneDynSize += paneSize; @@ -1840,14 +1848,22 @@ /* * Calculate pane width and height. */ if (horizontal) { - paneSize = slavePtr->paneWidth; + if (slavePtr->width > 0) { + paneSize = slavePtr->width; + } else { + paneSize = slavePtr->paneWidth; + } pwSize = pwWidth; } else { - paneSize = slavePtr->paneHeight; + if (slavePtr->height > 0) { + paneSize = slavePtr->height; + } else { + paneSize = slavePtr->paneHeight; + } pwSize = pwHeight; } if (IsStretchable(slavePtr->stretch, i, first, last)) { double frac; @@ -2182,11 +2198,11 @@ Slave *slavePtr; const int horizontal = (pwPtr->orient == ORIENT_HORIZONTAL); pwPtr->flags |= REQUESTED_RELAYOUT; - x = y = internalBw = Tk_InternalBorderWidth(pwPtr->tkwin); + x = y = internalBw = Tk_InternalBorderLeft(pwPtr->tkwin); reqWidth = reqHeight = 0; /* * Sashes and handles share space on the display. To simplify processing * below, precompute the x and y offsets of the handles and sashes within @@ -2437,11 +2453,12 @@ * internal value is to be stored. */ char *oldInternalPtr, /* Pointer to storage for the old value. */ int flags) /* Flags for the option, set Tk_SetOptions. */ { int sticky = 0; - char c, *internalPtr; + char c; + void *internalPtr; const char *string; internalPtr = ComputeSlotAddress(recordPtr, internalOffset); if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) { @@ -2888,35 +2905,35 @@ if (Tcl_GetIntFromObj(interp, objv[4], &y) != TCL_OK) { return TCL_ERROR; } - internalBW = Tk_InternalBorderWidth(pwPtr->tkwin); + internalBW = Tk_InternalBorderLeft(pwPtr->tkwin); if (pwPtr->orient == ORIENT_HORIZONTAL) { if (x < 0) { x = 0; } pwWidth = Tk_Width(pwPtr->tkwin) - (2 * internalBW); if (x > pwWidth) { x = pwWidth; } - y = Tk_InternalBorderWidth(pwPtr->tkwin); + y = Tk_InternalBorderLeft(pwPtr->tkwin); sashWidth = pwPtr->sashWidth; sashHeight = Tk_Height(pwPtr->tkwin) - - (2 * Tk_InternalBorderWidth(pwPtr->tkwin)); + (2 * Tk_InternalBorderLeft(pwPtr->tkwin)); } else { if (y < 0) { y = 0; } pwHeight = Tk_Height(pwPtr->tkwin) - (2 * internalBW); if (y > pwHeight) { y = pwHeight; } - x = Tk_InternalBorderWidth(pwPtr->tkwin); + x = Tk_InternalBorderLeft(pwPtr->tkwin); sashHeight = pwPtr->sashWidth; sashWidth = Tk_Width(pwPtr->tkwin) - - (2 * Tk_InternalBorderWidth(pwPtr->tkwin)); + (2 * Tk_InternalBorderLeft(pwPtr->tkwin)); } if (sashWidth < 1) { sashWidth = 1; } @@ -2974,20 +2991,17 @@ static int ObjectIsEmpty( Tcl_Obj *objPtr) /* Object to test. May be NULL. */ { - int length; - if (objPtr == NULL) { return 1; } - if (objPtr->bytes != NULL) { - return (objPtr->length == 0); + if (objPtr->bytes == NULL) { + Tcl_GetString(objPtr); } - (void)Tcl_GetStringFromObj(objPtr, &length); - return (length == 0); + return (objPtr->length == 0); } /* *---------------------------------------------------------------------- * @@ -3004,17 +3018,17 @@ * None. * *---------------------------------------------------------------------- */ -static char * +static void * ComputeSlotAddress( - char *recordPtr, /* Pointer to the start of a record. */ + void *recordPtr, /* Pointer to the start of a record. */ int offset) /* Offset of a slot within that record; may be < 0. */ { if (offset >= 0) { - return recordPtr + offset; + return (char *)recordPtr + offset; } else { return NULL; } } @@ -3051,11 +3065,11 @@ if (Tk_IsMapped(pwPtr->tkwin)) { sashHeight = Tk_Height(pwPtr->tkwin); } else { sashHeight = Tk_ReqHeight(pwPtr->tkwin); } - sashHeight -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin); + sashHeight -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin); if (pwPtr->showHandle && pwPtr->handleSize > pwPtr->sashWidth) { sashWidth = pwPtr->handleSize; lpad = (pwPtr->handleSize - pwPtr->sashWidth) / 2; rpad = pwPtr->handleSize - lpad; lpad += pwPtr->sashPad; @@ -3079,11 +3093,11 @@ if (Tk_IsMapped(pwPtr->tkwin)) { sashWidth = Tk_Width(pwPtr->tkwin); } else { sashWidth = Tk_ReqWidth(pwPtr->tkwin); } - sashWidth -= 2 * Tk_InternalBorderWidth(pwPtr->tkwin); + sashWidth -= 2 * Tk_InternalBorderLeft(pwPtr->tkwin); lpad = rpad = 0; } GetFirstLastVisiblePane(pwPtr, &first, &last); isHandle = 0; Index: generic/tkPlace.c ================================================================== --- generic/tkPlace.c +++ generic/tkPlace.c @@ -288,11 +288,11 @@ slavePtr = FindSlave(tkwin); if (slavePtr == NULL) { return TCL_OK; } - objPtr = Tk_GetOptionInfo(interp, (char *) slavePtr, optionTable, + objPtr = Tk_GetOptionInfo(interp, slavePtr, optionTable, (objc == 4) ? objv[3] : NULL, tkwin); if (objPtr == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, objPtr); @@ -626,11 +626,11 @@ return TCL_ERROR; } slavePtr = CreateSlave(tkwin, table); - if (Tk_SetOptions(interp, (char *) slavePtr, table, objc, objv, + if (Tk_SetOptions(interp, slavePtr, table, objc, objv, slavePtr->tkwin, &savedOptions, &mask) != TCL_OK) { goto error; } /* Index: generic/tkRectOval.c ================================================================== --- generic/tkRectOval.c +++ generic/tkRectOval.c @@ -757,15 +757,107 @@ Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[0],rectOvalPtr->bbox[1], &x1, &y1); Tk_CanvasDrawableCoords(canvas, rectOvalPtr->bbox[2],rectOvalPtr->bbox[3], &x2, &y2); - if (x2 <= x1) { - x2 = x1+1; + if (x2 == x1) { + + /* + * The width of the bounding box corresponds to less than one pixel + * on screen. Adjustment is needed to avoid drawing attempts with zero + * width items (which would draw nothing). The bounding box spans + * either 1 or 2 pixels. Select which pixel will be drawn. + */ + + short ix1 = (short) (rectOvalPtr->bbox[0]); + short ix2 = (short) (rectOvalPtr->bbox[2]); + + if (ix1 == ix2) { + + /* + * x1 and x2 are "within the same pixel". Use this pixel. + * Note: the degenerated case (bbox[0]==bbox[2]) of a completely + * flat box results in arbitrary selection of the pixel at the + * right (with positive coordinate) or left (with negative + * coordinate) of the box. There is no "best choice" here. + */ + + if (ix1 > 0) { + x2 += 1; + } else { + x1 -= 1; + } + } else { + + /* + * (x1,x2) span two pixels. Select the one with the larger + * covered "area". + */ + + if (ix1 > 0) { + if ((rectOvalPtr->bbox[2] - ix2) > (ix2 - rectOvalPtr->bbox[0])) { + x2 += 1; + } else { + x1 -= 1; + } + } else { + if ((rectOvalPtr->bbox[2] - ix1) > (ix1 - rectOvalPtr->bbox[0])) { + x2 += 1; + } else { + x1 -= 1; + } + } + } } - if (y2 <= y1) { - y2 = y1+1; + if (y2 == y1) { + + /* + * The height of the bounding box corresponds to less than one pixel + * on screen. Adjustment is needed to avoid drawing attempts with zero + * height items (which would draw nothing). The bounding box spans + * either 1 or 2 pixels. Select which pixel will be drawn. + */ + + short iy1 = (short) (rectOvalPtr->bbox[1]); + short iy2 = (short) (rectOvalPtr->bbox[3]); + + if (iy1 == iy2) { + + /* + * y1 and y2 are "within the same pixel". Use this pixel. + * Note: the degenerated case (bbox[1]==bbox[3]) of a completely + * flat box results in arbitrary selection of the pixel below + * (with positive coordinate) or above (with negative coordinate) + * the box. There is no "best choice" here. + */ + + if (iy1 > 0) { + y2 += 1; + } else { + y1 -= 1; + } + } else { + + /* + * (y1,y2) span two pixels. Select the one with the larger + * covered "area". + */ + + if (iy1 > 0) { + if ((rectOvalPtr->bbox[3] - iy2) > (iy2 - rectOvalPtr->bbox[1])) { + y2 += 1; + } else { + y1 -= 1; + } + } else { + if ((rectOvalPtr->bbox[3] - iy1) > (iy1 - rectOvalPtr->bbox[1])) { + y2 += 1; + } else { + y1 -= 1; + } + } + } } /* * Display filled part first (if wanted), then outline. If we're * stippling, then modify the stipple offset in the GC. Be sure to reset Index: generic/tkScale.c ================================================================== --- generic/tkScale.c +++ generic/tkScale.c @@ -15,13 +15,17 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" #include "tkScale.h" +#include "default.h" + +#if defined(_WIN32) +#define snprintf _snprintf +#endif /* * The following table defines the legal values for the -orient option. It is * used together with the "enum orient" declaration in tkScale.h. */ @@ -294,11 +298,11 @@ Tk_SetClassProcs(scalePtr->tkwin, &scaleClass, scalePtr); Tk_CreateEventHandler(scalePtr->tkwin, ExposureMask|StructureNotifyMask|FocusChangeMask, ScaleEventProc, scalePtr); - if ((Tk_InitOptions(interp, (char *) scalePtr, optionTable, tkwin) + if ((Tk_InitOptions(interp, scalePtr, optionTable, tkwin) != TCL_OK) || (ConfigureScale(interp, scalePtr, objc - 2, objv + 2) != TCL_OK)) { Tk_DestroyWindow(scalePtr->tkwin); return TCL_ERROR; } @@ -357,20 +361,20 @@ case COMMAND_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "cget option"); goto error; } - objPtr = Tk_GetOptionValue(interp, (char *) scalePtr, + objPtr = Tk_GetOptionValue(interp, scalePtr, scalePtr->optionTable, objv[2], scalePtr->tkwin); if (objPtr == NULL) { goto error; } Tcl_SetObjResult(interp, objPtr); break; case COMMAND_CONFIGURE: if (objc <= 3) { - objPtr = Tk_GetOptionInfo(interp, (char *) scalePtr, + objPtr = Tk_GetOptionInfo(interp, scalePtr, scalePtr->optionTable, (objc == 3) ? objv[2] : NULL, scalePtr->tkwin); if (objPtr == NULL) { goto error; } @@ -576,11 +580,11 @@ if (!error) { /* * First pass: set options to new values. */ - if (Tk_SetOptions(interp, (char *) scalePtr, + if (Tk_SetOptions(interp, scalePtr, scalePtr->optionTable, objc, objv, scalePtr->tkwin, &savedOptions, NULL) != TCL_OK) { continue; } } else { @@ -632,11 +636,11 @@ scalePtr->tickInterval = -scalePtr->tickInterval; } ComputeFormat(scalePtr); - scalePtr->labelLength = scalePtr->label ? (int)strlen(scalePtr->label) : 0; + scalePtr->labelLength = scalePtr->label ? strlen(scalePtr->label) : 0; Tk_SetBackgroundFromBorder(scalePtr->tkwin, scalePtr->bgBorder); if (scalePtr->highlightWidth < 0) { scalePtr->highlightWidth = 0; @@ -675,13 +679,13 @@ valuePtr, &varValue) != TCL_OK)) { ScaleSetVariable(scalePtr); } else { char varString[TCL_DOUBLE_SPACE], scaleString[TCL_DOUBLE_SPACE]; - sprintf(varString, scalePtr->format, varValue); - sprintf(scaleString, scalePtr->format, scalePtr->value); - if (strcmp(varString, scaleString)) { + Tcl_PrintDouble(NULL, varValue, varString); + Tcl_PrintDouble(NULL, scalePtr->value, scaleString); + if (strcmp(varString, scaleString)) { ScaleSetVariable(scalePtr); } } Tcl_TraceVar2(interp, Tcl_GetString(scalePtr->varNamePtr), NULL, TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, @@ -934,14 +938,20 @@ * Vertical scale: compute the amount of space needed to display the * scales value by formatting strings for the two end points; use * whichever length is longer. */ - sprintf(valueString, scalePtr->format, scalePtr->fromValue); + if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format, + scalePtr->fromValue) < 0) { + valueString[TCL_DOUBLE_SPACE - 1] = '\0'; + } valuePixels = Tk_TextWidth(scalePtr->tkfont, valueString, -1); - sprintf(valueString, scalePtr->format, scalePtr->toValue); + if (snprintf(valueString, TCL_DOUBLE_SPACE, scalePtr->format, + scalePtr->toValue) < 0) { + valueString[TCL_DOUBLE_SPACE - 1] = '\0'; + } tmp = Tk_TextWidth(scalePtr->tkfont, valueString, -1); if (valuePixels < tmp) { valuePixels = tmp; } @@ -1179,10 +1189,23 @@ register TkScale *scalePtr = clientData; const char *resultStr; double value; Tcl_Obj *valuePtr; int result; + + /* + * See ticket [5d991b82]. + */ + + if (scalePtr->varNamePtr == NULL) { + if (!(flags & TCL_INTERP_DESTROYED)) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + ScaleVarProc, clientData); + } + return NULL; + } /* * If the variable is unset, then immediately recreate it unless the whole * interpreter is going away. */ @@ -1312,11 +1335,14 @@ register TkScale *scalePtr) /* Info about widget. */ { if (scalePtr->varNamePtr != NULL) { char string[TCL_DOUBLE_SPACE]; - sprintf(string, scalePtr->format, scalePtr->value); + if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format, + scalePtr->value) < 0) { + string[TCL_DOUBLE_SPACE - 1] = '\0'; + } scalePtr->flags |= SETTING_VAR; Tcl_ObjSetVar2(scalePtr->interp, scalePtr->varNamePtr, NULL, Tcl_NewStringObj(string, -1), TCL_GLOBAL_ONLY); scalePtr->flags &= ~SETTING_VAR; } Index: generic/tkScale.h ================================================================== --- generic/tkScale.h +++ generic/tkScale.h @@ -71,11 +71,11 @@ * multiple of this value. */ int digits; /* Number of significant digits to print in * values. 0 means we get to choose the number * based on resolution and/or the range of the * scale. */ - char format[10]; /* Sprintf conversion specifier computed from + char format[16]; /* Sprintf conversion specifier computed from * digits and other information. */ double bigIncrement; /* Amount to use for large increments to scale * value. (0 means we pick a value). */ char *command; /* Command prefix to use when invoking Tcl * commands because the scale value changed. @@ -83,11 +83,11 @@ int repeatDelay; /* How long to wait before auto-repeating on * scrolling actions (in ms). */ int repeatInterval; /* Interval between autorepeats (in ms). */ char *label; /* Label to display above or to right of * scale; NULL means don't display a label. */ - int labelLength; /* Number of non-NULL chars. in label. */ + TkSizeT labelLength; /* Number of non-NULL chars. in label. */ enum state state; /* Values are active, normal, or disabled. * Value of scale cannot be changed when * disabled. */ /* Index: generic/tkScrollbar.c ================================================================== --- generic/tkScrollbar.c +++ generic/tkScrollbar.c @@ -177,14 +177,16 @@ scrollPtr->arrowLength = 0; scrollPtr->sliderFirst = 0; scrollPtr->sliderLast = 0; scrollPtr->activeField = 0; scrollPtr->activeRelief = TK_RELIEF_RAISED; +#ifndef TK_NO_DEPRECATED scrollPtr->totalUnits = 0; scrollPtr->windowUnits = 0; scrollPtr->firstUnit = 0; scrollPtr->lastUnit = 0; +#endif /* TK_NO_DEPRECATED */ scrollPtr->firstFraction = 0.0; scrollPtr->lastFraction = 0.0; scrollPtr->cursor = None; scrollPtr->takeFocus = NULL; scrollPtr->flags = 0; @@ -222,12 +224,12 @@ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument strings. */ { register TkScrollbar *scrollPtr = clientData; - int result = TCL_OK; - int length, cmdIndex; + int result = TCL_OK, cmdIndex; + size_t length; static const char *const commandNames[] = { "activate", "cget", "configure", "delta", "fraction", "get", "identify", "set", NULL }; enum command { @@ -267,11 +269,11 @@ } if (objc != 3) { Tcl_WrongNumArgs(interp, 1, objv, "activate element"); goto error; } - c = Tcl_GetStringFromObj(objv[2], &length)[0]; + c = TkGetStringFromObj(objv[2], &length)[0]; oldActiveField = scrollPtr->activeField; if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow1") == 0)) { scrollPtr->activeField = TOP_ARROW; } else if ((c == 'a') && (strcmp(Tcl_GetString(objv[2]), "arrow2") == 0)) { scrollPtr->activeField = BOTTOM_ARROW; @@ -375,21 +377,23 @@ if (objc != 2) { Tcl_WrongNumArgs(interp, 1, objv, "get"); goto error; } - if (scrollPtr->flags & NEW_STYLE_COMMANDS) { - resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction); - resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction); - Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs)); - } else { +#ifndef TK_NO_DEPRECATED + if (scrollPtr->flags & OLD_STYLE_COMMANDS) { resObjs[0] = Tcl_NewIntObj(scrollPtr->totalUnits); resObjs[1] = Tcl_NewIntObj(scrollPtr->windowUnits); resObjs[2] = Tcl_NewIntObj(scrollPtr->firstUnit); resObjs[3] = Tcl_NewIntObj(scrollPtr->lastUnit); Tcl_SetObjResult(interp, Tcl_NewListObj(4, resObjs)); + break; } +#endif /* TK_NO_DEPRECATED */ + resObjs[0] = Tcl_NewDoubleObj(scrollPtr->firstFraction); + resObjs[1] = Tcl_NewDoubleObj(scrollPtr->lastFraction); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, resObjs)); break; } case COMMAND_IDENTIFY: { int x, y; const char *zone = ""; @@ -411,12 +415,10 @@ } Tcl_SetObjResult(interp, Tcl_NewStringObj(zone, -1)); break; } case COMMAND_SET: { - int totalUnits, windowUnits, firstUnit, lastUnit; - if (objc == 4) { double first, last; if (Tcl_GetDoubleFromObj(interp, objv[2], &first) != TCL_OK) { goto error; @@ -436,12 +438,14 @@ } else if (last > 1.0) { scrollPtr->lastFraction = 1.0; } else { scrollPtr->lastFraction = last; } - scrollPtr->flags |= NEW_STYLE_COMMANDS; +#ifndef TK_NO_DEPRECATED + scrollPtr->flags &= ~OLD_STYLE_COMMANDS; } else if (objc == 6) { + int totalUnits, windowUnits, firstUnit, lastUnit; if (Tcl_GetIntFromObj(interp, objv[2], &totalUnits) != TCL_OK) { goto error; } if (totalUnits < 0) { totalUnits = 0; @@ -474,15 +478,14 @@ scrollPtr->lastFraction = 1.0; } else { scrollPtr->firstFraction = ((double) firstUnit)/totalUnits; scrollPtr->lastFraction = ((double) (lastUnit+1))/totalUnits; } - scrollPtr->flags &= ~NEW_STYLE_COMMANDS; + scrollPtr->flags |= OLD_STYLE_COMMANDS; +#endif /* !TK_NO_DEPRECATED */ } else { Tcl_WrongNumArgs(interp, 1, objv, "set firstFraction lastFraction"); - Tcl_AppendResult(interp, " or \"", Tcl_GetString(objv[0]), - " set totalUnits windowUnits firstUnit lastUnit\"", NULL); goto error; } TkpComputeScrollbarGeometry(scrollPtr); TkScrollbarEventuallyRedraw(scrollPtr); break; Index: generic/tkScrollbar.h ================================================================== --- generic/tkScrollbar.h +++ generic/tkScrollbar.h @@ -91,25 +91,29 @@ * information is provided by the application by invoking the "set" widget * command. This information can now be provided in two ways: the "old" * form (totalUnits, windowUnits, firstUnit, and lastUnit), or the "new" * form (firstFraction and lastFraction). FirstFraction and lastFraction * will always be valid, but the old-style information is only valid if - * the NEW_STYLE_COMMANDS flag is 0. + * the OLD_STYLE_COMMANDS flag is 1. */ +#ifndef TK_NO_DEPRECATED int totalUnits; /* Total dimension of application, in units. - * Valid only if the NEW_STYLE_COMMANDS flag - * isn't set. */ + * Valid only if the OLD_STYLE_COMMANDS flag + * is set. */ int windowUnits; /* Maximum number of units that can be * displayed in the window at once. Valid only - * if the NEW_STYLE_COMMANDS flag isn't set. */ + * if the OLD_STYLE_COMMANDS flag is set. */ int firstUnit; /* Number of last unit visible in * application's window. Valid only if the - * NEW_STYLE_COMMANDS flag isn't set. */ + * OLD_STYLE_COMMANDS flag is set. */ int lastUnit; /* Index of last unit visible in window. - * Valid only if the NEW_STYLE_COMMANDS flag + * Valid only if the OLD_STYLE_COMMANDS flag * isn't set. */ +#else + int dummy1,dummy2,dummy3,dummy4; /* sizeof(TkScrollbar) should not depend on TK_NO_DEPRECATED */ +#endif /* TK_NO_DEPRECATED */ double firstFraction; /* Position of first visible thing in window, * specified as a fraction between 0 and * 1.0. */ double lastFraction; /* Position of last visible thing in window, * specified as a fraction between 0 and @@ -142,20 +146,22 @@ /* * Flag bits for scrollbars: * * REDRAW_PENDING: Non-zero means a DoWhenIdle handler has * already been queued to redraw this window. - * NEW_STYLE_COMMANDS: Non-zero means the new style of commands + * OLD_STYLE_COMMANDS: Non-zero means the old style of commands * should be used to communicate with the widget: - * ".t yview scroll 2 lines", instead of - * ".t yview 40", for example. + * ".t yview 40", instead of + * ".t yview scroll 2 lines", for example. * GOT_FOCUS: Non-zero means this window has the input * focus. */ #define REDRAW_PENDING 1 -#define NEW_STYLE_COMMANDS 2 +#ifndef TK_NO_DEPRECATED +# define OLD_STYLE_COMMANDS 2 +#endif /* TK_NO_DEPRECATED */ #define GOT_FOCUS 4 /* * Declaration of scrollbar class functions structure * and default scrollbar width, for use in configSpec. Index: generic/tkSelect.c ================================================================== --- generic/tkSelect.c +++ generic/tkSelect.c @@ -24,11 +24,11 @@ Tcl_Interp *interp; /* Interpreter in which to invoke command. */ int cmdLength; /* # of non-NULL bytes in command. */ int charOffset; /* The offset of the next char to retrieve. */ int byteOffset; /* The expected byte offset of the next * chunk. */ - char buffer[TCL_UTF_MAX]; /* A buffer to hold part of a UTF character + char buffer[4]; /* A buffer to hold part of a UTF character * that is split across chunks. */ char command[1]; /* Command to invoke. Actual space is * allocated as large as necessary. This must * be the last entry in the structure. */ } CommandInfo; @@ -188,12 +188,12 @@ /* * The clientData is selection controlled memory, so we * should make a copy for this selPtr. */ - unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + - ((CommandInfo *)clientData)->cmdLength + 1; + unsigned cmdInfoLen = Tk_Offset(CommandInfo, command) + 1 + + ((CommandInfo *)clientData)->cmdLength; selPtr->clientData = ckalloc(cmdInfoLen); memcpy(selPtr->clientData, clientData, cmdInfoLen); } else { selPtr->clientData = clientData; @@ -355,11 +355,11 @@ { register TkWindow *winPtr = (TkWindow *) tkwin; TkDisplay *dispPtr = winPtr->dispPtr; TkSelectionInfo *infoPtr; Tk_LostSelProc *clearProc = NULL; - ClientData clearData = NULL;/* Initialization needed only to prevent + void *clearData = NULL;/* Initialization needed only to prevent * compiler warning. */ if (dispPtr->multipleAtom == None) { TkSelInit(tkwin); } @@ -464,11 +464,11 @@ TkDisplay *dispPtr = winPtr->dispPtr; TkSelectionInfo *infoPtr; TkSelectionInfo *prevPtr; TkSelectionInfo *nextPtr; Tk_LostSelProc *clearProc = NULL; - ClientData clearData = NULL;/* Initialization needed only to prevent + void *clearData = NULL;/* Initialization needed only to prevent * compiler warning. */ if (dispPtr->multipleAtom == None) { TkSelInit(tkwin); } @@ -829,11 +829,11 @@ case SELECTION_HANDLE: { Atom target, format; const char *targetName = NULL; const char *formatName = NULL; register CommandInfo *cmdInfoPtr; - int cmdLength; + size_t cmdLength; static const char *const handleOptionStrings[] = { "-format", "-selection", "-type", NULL }; enum handleOptions { HANDLE_FORMAT, HANDLE_SELECTION, HANDLE_TYPE @@ -898,11 +898,11 @@ } else if (formatName != NULL) { format = Tk_InternAtom(tkwin, formatName); } else { format = XA_STRING; } - string = Tcl_GetStringFromObj(objs[1], &cmdLength); + string = TkGetStringFromObj(objs[1], &cmdLength); if (cmdLength == 0) { Tk_DeleteSelHandler(tkwin, selection, target); } else { cmdInfoPtr = ckalloc(Tk_Offset(CommandInfo, command) + 1 + cmdLength); @@ -1183,10 +1183,11 @@ dispPtr->textAtom = Tk_InternAtom(tkwin, "TEXT"); dispPtr->compoundTextAtom = Tk_InternAtom(tkwin, "COMPOUND_TEXT"); dispPtr->applicationAtom = Tk_InternAtom(tkwin, "TK_APPLICATION"); dispPtr->windowAtom = Tk_InternAtom(tkwin, "TK_WINDOW"); dispPtr->clipboardAtom = Tk_InternAtom(tkwin, "CLIPBOARD"); + dispPtr->atomPairAtom = Tk_InternAtom(tkwin, "ATOM_PAIR"); /* * Using UTF8_STRING instead of the XA_UTF8_STRING macro allows us to * support older X servers that didn't have UTF8_STRING yet. This is * necessary on Unix systems. For more information, see: @@ -1243,11 +1244,11 @@ } prevPtr = infoPtr; } if (infoPtr != NULL && (infoPtr->owner == tkwin) && - (eventPtr->xselectionclear.serial >= (unsigned) infoPtr->serial)) { + (eventPtr->xselectionclear.serial >= (unsigned long) infoPtr->serial)) { if (prevPtr == NULL) { dispPtr->selectionInfoPtr = infoPtr->nextPtr; } else { prevPtr->nextPtr = infoPtr->nextPtr; } Index: generic/tkSelect.h ================================================================== --- generic/tkSelect.h +++ generic/tkSelect.h @@ -23,18 +23,22 @@ */ typedef struct TkSelectionInfo { Atom selection; /* Selection name, e.g. XA_PRIMARY. */ Tk_Window owner; /* Current owner of this selection. */ - int serial; /* Serial number of last XSelectionSetOwner +#if TCL_MAJOR_VERSION > 8 + unsigned long serial; /* Serial number of last XSelectionSetOwner * request made to server for this selection * (used to filter out redundant * SelectionClear events). */ +#else + int serial; +#endif Time time; /* Timestamp used to acquire selection. */ Tk_LostSelProc *clearProc; /* Procedure to call when owner loses * selection. */ - ClientData clearData; /* Info to pass to clearProc. */ + void *clearData; /* Info to pass to clearProc. */ struct TkSelectionInfo *nextPtr; /* Next in list of current selections on this * display. NULL means end of list. */ } TkSelectionInfo; @@ -50,12 +54,12 @@ * as TARGETS or STRING. */ Atom format; /* Format in which selection info will be * returned, such as STRING or ATOM. */ Tk_SelectionProc *proc; /* Procedure to generate selection in this * format. */ - ClientData clientData; /* Argument to pass to proc. */ - int size; /* Size of units returned by proc (8 for + void *clientData; /* Argument to pass to proc. */ + TkSizeT size; /* Size of units returned by proc (8 for * STRING, 32 for almost anything else). */ struct TkSelHandler *nextPtr; /* Next selection handler associated with same * window (NULL for end of list). */ } TkSelHandler; Index: generic/tkSquare.c ================================================================== --- generic/tkSquare.c +++ generic/tkSquare.c @@ -170,20 +170,20 @@ Tk_PathName(squarePtr->tkwin), SquareWidgetObjCmd, squarePtr, SquareDeletedProc); squarePtr->gc = None; squarePtr->optionTable = optionTable; - if (Tk_InitOptions(interp, (char *) squarePtr, optionTable, tkwin) + if (Tk_InitOptions(interp, squarePtr, optionTable, tkwin) != TCL_OK) { Tk_DestroyWindow(squarePtr->tkwin); ckfree(squarePtr); return TCL_ERROR; } Tk_CreateEventHandler(squarePtr->tkwin, ExposureMask|StructureNotifyMask, SquareObjEventProc, squarePtr); - if (Tk_SetOptions(interp, (char *) squarePtr, optionTable, objc - 2, + if (Tk_SetOptions(interp, squarePtr, optionTable, objc - 2, objv + 2, tkwin, NULL, NULL) != TCL_OK) { goto error; } if (SquareConfigure(interp, squarePtr) != TCL_OK) { goto error; @@ -248,11 +248,11 @@ case SQUARE_CGET: if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); goto error; } - resultObjPtr = Tk_GetOptionValue(interp, (char *) squarePtr, + resultObjPtr = Tk_GetOptionValue(interp, squarePtr, squarePtr->optionTable, objv[2], squarePtr->tkwin); if (resultObjPtr == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, resultObjPtr); @@ -259,23 +259,23 @@ } break; case SQUARE_CONFIGURE: resultObjPtr = NULL; if (objc == 2) { - resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr, + resultObjPtr = Tk_GetOptionInfo(interp, squarePtr, squarePtr->optionTable, NULL, squarePtr->tkwin); if (resultObjPtr == NULL) { result = TCL_ERROR; } } else if (objc == 3) { - resultObjPtr = Tk_GetOptionInfo(interp, (char *) squarePtr, + resultObjPtr = Tk_GetOptionInfo(interp, squarePtr, squarePtr->optionTable, objv[2], squarePtr->tkwin); if (resultObjPtr == NULL) { result = TCL_ERROR; } } else { - result = Tk_SetOptions(interp, (char *) squarePtr, + result = Tk_SetOptions(interp, squarePtr, squarePtr->optionTable, objc - 2, objv + 2, squarePtr->tkwin, NULL, NULL); if (result == TCL_OK) { result = SquareConfigure(interp, squarePtr); } Index: generic/tkStubInit.c ================================================================== --- generic/tkStubInit.c +++ generic/tkStubInit.c @@ -36,10 +36,47 @@ /* * Remove macro that might interfere with the definition below. */ #undef Tk_MainEx +#undef Tk_FreeXId +#undef Tk_FreeStyleFromObj +#undef Tk_GetStyleFromObj +#undef TkWinGetPlatformId + +#if defined(TK_NO_DEPRECATED) || TCL_MAJOR_VERSION > 8 +#define Tk_MainEx 0 +#define Tk_FreeXId 0 +#define Tk_FreeStyleFromObj 0 +#define Tk_GetStyleFromObj 0 +#define TkWinGetPlatformId 0 +#define Tk_PhotoPutBlock_NoComposite 0 +#define Tk_PhotoPutZoomedBlock_NoComposite 0 +#define Tk_PhotoExpand_Panic 0 +#define Tk_PhotoPutBlock_Panic 0 +#define Tk_PhotoPutZoomedBlock_Panic 0 +#define Tk_PhotoSetSize_Panic 0 +#else +static void +doNothing(void) +{ + /* dummy implementation, no need to do anything */ +} +#define Tk_FreeXId ((void (*)(Display *, XID)) doNothing) +#define Tk_FreeStyleFromObj ((void (*)(Tcl_Obj *)) doNothing) +#define Tk_GetStyleFromObj getStyleFromObj +static Tk_Style Tk_GetStyleFromObj(Tcl_Obj *obj) +{ + return Tk_AllocStyleFromObj(NULL, obj); +} +#if defined(_WIN32) || defined(__CYGWIN__) +#define TkWinGetPlatformId winGetPlatformId +static int TkWinGetPlatformId(void) { + return 2; +} +#endif /* defined(_WIN32) || defined(__CYGWIN__) */ +#endif /* !TK_NO_DEPRECATED */ #ifdef _WIN32 int TkpCmapStressed(Tk_Window tkwin, Colormap colormap) @@ -60,10 +97,15 @@ } # define TkUnixContainerId 0 # define TkUnixDoOneXEvent 0 # define TkUnixSetMenubar 0 +# define XCreateWindow 0 +# define XOffsetRegion 0 +# define XUnionRegion 0 +# define XPolygonRegion 0 +# define XPointInRegion 0 # define TkWmCleanup (void (*)(TkDisplay *)) TkpSync # define TkSendCleanup (void (*)(TkDisplay *)) TkpSync # define TkpTestsendCmd 0 #else /* !_WIN32 */ @@ -198,11 +240,10 @@ # define TkWinXCleanup 0 # define TkWinXInit 0 # define TkWinSetForegroundWindow 0 # define TkWinDialogDebug 0 # define TkWinGetMenuSystemDefault 0 -# define TkWinGetPlatformId 0 # define TkWinSetHINSTANCE 0 # define TkWinGetPlatformTheme 0 # define TkWinChildProc 0 # elif !defined(MAC_OSX_TK) /* UNIX */ @@ -231,10 +272,18 @@ * WARNING: The contents of this file is automatically generated by the * tools/genStubs.tcl script. Any modifications to the function declarations * below should be made in the generic/tk.decls script. */ +#ifdef __GNUC__ +/* + * The rest of this file shouldn't warn about deprecated functions; they're + * there because we intend them to be so and know that this file is OK to + * touch those fields. + */ +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" +#endif /* !BEGIN!: Do not edit below this line. */ static const TkIntStubs tkIntStubs = { TCL_STUB_MAGIC, 0, @@ -448,10 +497,11 @@ TkSmoothPrintProc, /* 180 */ TkDrawAngledTextLayout, /* 181 */ TkUnderlineAngledTextLayout, /* 182 */ TkIntersectAngledTextLayout, /* 183 */ TkDrawAngledChars, /* 184 */ + TkDebugPhotoStringMatchDef, /* 185 */ }; static const TkIntPlatStubs tkIntPlatStubs = { TCL_STUB_MAGIC, 0, @@ -542,11 +592,11 @@ TkMacOSXVisableClipRgn, /* 35 */ TkMacOSXWinBounds, /* 36 */ TkMacOSXWindowOffset, /* 37 */ TkSetMacColor, /* 38 */ TkSetWMName, /* 39 */ - TkSuspendClipboard, /* 40 */ + 0, /* 40 */ TkMacOSXZoomToplevel, /* 41 */ Tk_TopCoordsToWindow, /* 42 */ TkMacOSXContainerId, /* 43 */ TkMacOSXGetHostToplevel, /* 44 */ TkMacOSXPreprocessMenu, /* 45 */ @@ -696,10 +746,35 @@ XFree, /* 110 */ XNoOp, /* 111 */ XSynchronize, /* 112 */ XSync, /* 113 */ XVisualIDFromVisual, /* 114 */ + 0, /* 115 */ + 0, /* 116 */ + 0, /* 117 */ + 0, /* 118 */ + 0, /* 119 */ + XOffsetRegion, /* 120 */ + XUnionRegion, /* 121 */ + XCreateWindow, /* 122 */ + 0, /* 123 */ + 0, /* 124 */ + 0, /* 125 */ + 0, /* 126 */ + 0, /* 127 */ + 0, /* 128 */ + XLowerWindow, /* 129 */ + XFillArcs, /* 130 */ + XDrawArcs, /* 131 */ + XDrawRectangles, /* 132 */ + XDrawSegments, /* 133 */ + XDrawPoint, /* 134 */ + XDrawPoints, /* 135 */ + XReparentWindow, /* 136 */ + XPutImage, /* 137 */ + XPolygonRegion, /* 138 */ + XPointInRegion, /* 139 */ #endif /* WIN */ #ifdef MAC_OSX_TK /* AQUA */ XSetDashes, /* 0 */ XGetModifierMapping, /* 1 */ XCreateImage, /* 2 */ Index: generic/tkStyle.c ================================================================== --- generic/tkStyle.c +++ generic/tkStyle.c @@ -153,11 +153,11 @@ static const Tcl_ObjType styleObjType = { "style", /* name */ FreeStyleObjProc, /* freeIntRepProc */ DupStyleObjProc, /* dupIntRepProc */ NULL, /* updateStringProc */ - SetStyleFromAny /* setFromAnyProc */ + NULL /* setFromAnyProc */ }; /* *--------------------------------------------------------------------------- * @@ -1074,11 +1074,11 @@ void Tk_GetElementSize( Tk_Style style, /* The widget style. */ Tk_StyledElement element, /* The styled element, previously returned by * Tk_GetStyledElement. */ - char *recordPtr, /* The widget record. */ + void *recordPtr, /* The widget record. */ Tk_Window tkwin, /* The widget window. */ int width, int height, /* Requested size. */ int inner, /* If TRUE, compute the outer size according * to the requested minimum inner size. If * FALSE, compute the inner size according to @@ -1115,11 +1115,11 @@ void Tk_GetElementBox( Tk_Style style, /* The widget style. */ Tk_StyledElement element, /* The styled element, previously returned by * Tk_GetStyledElement. */ - char *recordPtr, /* The widget record. */ + void *recordPtr, /* The widget record. */ Tk_Window tkwin, /* The widget window. */ int x, int y, /* Top left corner of available area. */ int width, int height, /* Size of available area. */ int inner, /* Boolean. If TRUE, compute the bounding box * according to the requested inscribed box @@ -1157,11 +1157,11 @@ int Tk_GetElementBorderWidth( Tk_Style style, /* The widget style. */ Tk_StyledElement element, /* The styled element, previously returned by * Tk_GetStyledElement. */ - char *recordPtr, /* The widget record. */ + void *recordPtr, /* The widget record. */ Tk_Window tkwin) /* The widget window. */ { Style *stylePtr = (Style *) style; StyledWidgetSpec *widgetSpecPtr = (StyledWidgetSpec *) element; @@ -1188,11 +1188,11 @@ void Tk_DrawElement( Tk_Style style, /* The widget style. */ Tk_StyledElement element, /* The styled element, previously returned by * Tk_GetStyledElement. */ - char *recordPtr, /* The widget record. */ + void *recordPtr, /* The widget record. */ Tk_Window tkwin, /* The widget window. */ Drawable d, /* Where to draw element. */ int x, int y, /* Top left corner of element. */ int width, int height, /* Size of element. */ int state) /* Drawing state flags. */ @@ -1403,63 +1403,16 @@ Tk_AllocStyleFromObj( Tcl_Interp *interp, /* Interp for error return. */ Tcl_Obj *objPtr) /* Object containing name of the style to * retrieve. */ { - Style *stylePtr; - - if (objPtr->typePtr != &styleObjType) { - SetStyleFromAny(interp, objPtr); - } - stylePtr = objPtr->internalRep.twoPtrValue.ptr1; - - return (Tk_Style) stylePtr; -} - -/* - *---------------------------------------------------------------------- - * - * Tk_GetStyleFromObj -- - * - * Find the style that corresponds to a given object. The style must have - * already been created by Tk_CreateStyle. - * - * Results: - * The return value is a token for the style that matches objPtr, or NULL - * if none found. - * - * Side effects: - * If the object is not already a style ref, the conversion will free any - * old internal representation. - * - *---------------------------------------------------------------------- - */ - -Tk_Style -Tk_GetStyleFromObj( - Tcl_Obj *objPtr) /* The object from which to get the style. */ -{ - if (objPtr->typePtr != &styleObjType) { - SetStyleFromAny(NULL, objPtr); - } - - return objPtr->internalRep.twoPtrValue.ptr1; -} - -/* - *--------------------------------------------------------------------------- - * - * Tk_FreeStyleFromObj -- - * - * No-op. Present only for stubs compatibility. - * - *--------------------------------------------------------------------------- - */ -void -Tk_FreeStyleFromObj( - Tcl_Obj *objPtr) -{ + if (objPtr->typePtr != &styleObjType) { + if (SetStyleFromAny(interp, objPtr) != TCL_OK) { + return NULL; + } + } + return objPtr->internalRep.twoPtrValue.ptr1; } /* *---------------------------------------------------------------------- * @@ -1467,12 +1420,12 @@ * * Convert the internal representation of a Tcl object to the style * internal form. * * Results: - * Always returns TCL_OK. If an error occurs is returned (e.g. the style - * doesn't exist), an error message will be left in interp's result. + * If an error occurs is returned (e.g. the style doesn't exist), an + * error message will be left in interp's result and TCL_ERROR is returned. * * Side effects: * The object is left with its typePtr pointing to styleObjType. * *---------------------------------------------------------------------- @@ -1483,10 +1436,11 @@ Tcl_Interp *interp, /* Used for error reporting if not NULL. */ Tcl_Obj *objPtr) /* The object to convert. */ { const Tcl_ObjType *typePtr; const char *name; + Tk_Style style; /* * Free the old internalRep before setting the new one. */ @@ -1494,12 +1448,16 @@ typePtr = objPtr->typePtr; if ((typePtr != NULL) && (typePtr->freeIntRepProc != NULL)) { typePtr->freeIntRepProc(objPtr); } + style = Tk_GetStyle(interp, name); + if (style == NULL) { + return TCL_ERROR; + } objPtr->typePtr = &styleObjType; - objPtr->internalRep.twoPtrValue.ptr1 = Tk_GetStyle(interp, name); + objPtr->internalRep.twoPtrValue.ptr1 = style; return TCL_OK; } /* Index: generic/tkTest.c ================================================================== --- generic/tkTest.c +++ generic/tkTest.c @@ -166,11 +166,11 @@ #if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) static int TestmenubarObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]); #endif -#if defined(_WIN32) || defined(MAC_OSX_TK) +#if defined(_WIN32) static int TestmetricsObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]); #endif static int TestobjconfigObjCmd(ClientData dummy, @@ -189,10 +189,13 @@ char *saveInternalPtr); static void CustomOptionFree(ClientData clientData, Tk_Window tkwin, char *internalPtr); static int TestpropObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); +static int TestprintfObjCmd(ClientData dummy, + Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]); #if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) static int TestwrapperObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]); @@ -201,10 +204,13 @@ static int TrivialConfigObjCmd(ClientData dummy, Tcl_Interp *interp, int objc, Tcl_Obj * const objv[]); static void TrivialEventProc(ClientData clientData, XEvent *eventPtr); +static int TestPhotoStringMatchCmd(ClientData dummy, + Tcl_Interp *interp, int objc, + Tcl_Obj * const objv[]); /* *---------------------------------------------------------------------- * * Tktest_Init -- @@ -225,11 +231,11 @@ Tktest_Init( Tcl_Interp *interp) /* Interpreter for application. */ { static int initialized = 0; - if (Tcl_InitStubs(interp, "8.1", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return TCL_ERROR; } if (Tk_InitStubs(interp, TK_VERSION, 0) == NULL) { return TCL_ERROR; } @@ -237,11 +243,11 @@ /* * Create additional commands for testing Tk. */ if (Tcl_PkgProvideEx(interp, "Tktest", TK_PATCH_LEVEL, NULL) == TCL_ERROR) { - return TCL_ERROR; + return TCL_ERROR; } Tcl_CreateObjCommand(interp, "square", SquareObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testbitmap", TestbitmapObjCmd, (ClientData) Tk_MainWindow(interp), NULL); @@ -261,24 +267,28 @@ (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testmakeexist", TestmakeexistObjCmd, (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testprop", TestpropObjCmd, (ClientData) Tk_MainWindow(interp), NULL); + Tcl_CreateObjCommand(interp, "testprintf", TestprintfObjCmd, NULL, NULL); Tcl_CreateObjCommand(interp, "testtext", TkpTesttextCmd, (ClientData) Tk_MainWindow(interp), NULL); + Tcl_CreateObjCommand(interp, "testphotostringmatch", + TestPhotoStringMatchCmd, (ClientData) Tk_MainWindow(interp), + NULL); -#if defined(_WIN32) || defined(MAC_OSX_TK) +#if defined(_WIN32) Tcl_CreateObjCommand(interp, "testmetrics", TestmetricsObjCmd, (ClientData) Tk_MainWindow(interp), NULL); -#elif !defined(__CYGWIN__) +#elif !defined(__CYGWIN__) && !defined(MAC_OSX_TK) Tcl_CreateObjCommand(interp, "testmenubar", TestmenubarObjCmd, (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testsend", TkpTestsendCmd, (ClientData) Tk_MainWindow(interp), NULL); Tcl_CreateObjCommand(interp, "testwrapper", TestwrapperObjCmd, (ClientData) Tk_MainWindow(interp), NULL); -#endif /* _WIN32 || MAC_OSX_TK */ +#endif /* _WIN32 */ /* * Create test image type. */ @@ -450,11 +460,11 @@ * * Results: * A standard Tcl result. * * Side effects: - * All the intepreters created by previous calls to "testnewapp" get + * All the interpreters created by previous calls to "testnewapp" get * deleted. * *---------------------------------------------------------------------- */ @@ -663,19 +673,19 @@ recordPtr->anchorPtr = NULL; recordPtr->pixelPtr = NULL; recordPtr->mmPtr = NULL; recordPtr->stringTablePtr = NULL; recordPtr->customPtr = NULL; - result = Tk_InitOptions(interp, (char *) recordPtr, optionTable, + result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin); if (result == TCL_OK) { recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), TrivialConfigObjCmd, (ClientData) recordPtr, TrivialCmdDeletedProc); Tk_CreateEventHandler(tkwin, StructureNotifyMask, TrivialEventProc, (ClientData) recordPtr); - result = Tk_SetOptions(interp, (char *) recordPtr, optionTable, + result = Tk_SetOptions(interp, recordPtr, optionTable, objc-3, objv+3, tkwin, NULL, NULL); if (result != TCL_OK) { Tk_DestroyWindow(tkwin); } } else { @@ -706,16 +716,16 @@ recordPtr->header.interp = interp; recordPtr->header.optionTable = optionTable; recordPtr->header.tkwin = tkwin; recordPtr->base1ObjPtr = recordPtr->base2ObjPtr = NULL; recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL; - result = Tk_InitOptions(interp, (char *)recordPtr, optionTable, tkwin); + result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin); if (result == TCL_OK) { - result = Tk_SetOptions(interp, (char *) recordPtr, optionTable, + result = Tk_SetOptions(interp, recordPtr, optionTable, objc-3, objv+3, tkwin, NULL, NULL); if (result != TCL_OK) { - Tk_FreeConfigOptions((char *) recordPtr, optionTable, tkwin); + Tk_FreeConfigOptions(recordPtr, optionTable, tkwin); } } if (result == TCL_OK) { recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), TrivialConfigObjCmd, @@ -760,13 +770,13 @@ recordPtr->header.optionTable = optionTable; recordPtr->header.tkwin = tkwin; recordPtr->base1ObjPtr = recordPtr->base2ObjPtr = NULL; recordPtr->extension3ObjPtr = recordPtr->extension4ObjPtr = NULL; recordPtr->extension5ObjPtr = NULL; - result = Tk_InitOptions(interp, (char *)recordPtr, optionTable, tkwin); + result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin); if (result == TCL_OK) { - result = Tk_SetOptions(interp, (char *) recordPtr, optionTable, + result = Tk_SetOptions(interp, recordPtr, optionTable, objc-3, objv+3, tkwin, NULL, NULL); if (result != TCL_OK) { Tk_FreeConfigOptions((char *) recordPtr, optionTable, tkwin); } } @@ -794,11 +804,11 @@ Tk_OptionTable optionTable; widgetRecord.intPtr = NULL; optionTable = Tk_CreateOptionTable(interp, errorSpecs); tables[index] = optionTable; - return Tk_InitOptions(interp, (char *) &widgetRecord, optionTable, + return Tk_InitOptions(interp, &widgetRecord, optionTable, (Tk_Window) NULL); } case DEL: if (objc != 3) { @@ -942,19 +952,19 @@ recordPtr->anchor = TK_ANCHOR_N; recordPtr->pixels = 0; recordPtr->mm = 0.0; recordPtr->tkwin = NULL; recordPtr->custom = NULL; - result = Tk_InitOptions(interp, (char *) recordPtr, optionTable, + result = Tk_InitOptions(interp, recordPtr, optionTable, tkwin); if (result == TCL_OK) { recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), TrivialConfigObjCmd, recordPtr, TrivialCmdDeletedProc); Tk_CreateEventHandler(tkwin, StructureNotifyMask, TrivialEventProc, recordPtr); - result = Tk_SetOptions(interp, (char *) recordPtr, optionTable, + result = Tk_SetOptions(interp, recordPtr, optionTable, objc - 3, objv + 3, tkwin, NULL, NULL); if (result != TCL_OK) { Tk_DestroyWindow(tkwin); } } else { @@ -1003,22 +1013,22 @@ tables[index] = recordPtr->header.optionTable; recordPtr->header.tkwin = NULL; recordPtr->one = recordPtr->two = recordPtr->three = NULL; recordPtr->four = recordPtr->five = NULL; Tcl_SetObjResult(interp, objv[2]); - result = Tk_InitOptions(interp, (char *) recordPtr, + result = Tk_InitOptions(interp, recordPtr, recordPtr->header.optionTable, (Tk_Window) NULL); if (result == TCL_OK) { - result = Tk_SetOptions(interp, (char *) recordPtr, + result = Tk_SetOptions(interp, recordPtr, recordPtr->header.optionTable, objc - 3, objv + 3, (Tk_Window) NULL, NULL, NULL); if (result == TCL_OK) { recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), TrivialConfigObjCmd, (ClientData) recordPtr, TrivialCmdDeletedProc); } else { - Tk_FreeConfigOptions((char *) recordPtr, + Tk_FreeConfigOptions(recordPtr, recordPtr->header.optionTable, (Tk_Window) NULL); } } if (result != TCL_OK) { ckfree(recordPtr); @@ -1043,12 +1053,12 @@ tkwin = Tk_CreateWindowFromPath(interp, mainWin, ".config", NULL); Tk_SetClass(tkwin, "Config"); optionTable = Tk_CreateOptionTable(interp, errorSpecs); tables[index] = optionTable; - Tk_InitOptions(interp, (char *) &record, optionTable, tkwin); - if (Tk_SetOptions(interp, (char *) &record, optionTable, 1, + Tk_InitOptions(interp, &record, optionTable, tkwin); + if (Tk_SetOptions(interp, &record, optionTable, 1, &newObjPtr, tkwin, NULL, NULL) != TCL_OK) { result = TCL_ERROR; } Tcl_DecrRefCount(newObjPtr); Tk_FreeConfigOptions( (char *) &record, optionTable, tkwin); @@ -1081,14 +1091,14 @@ slaveSpecs); tables[index] = recordPtr->header.optionTable; recordPtr->header.tkwin = tkwin; recordPtr->windowPtr = NULL; - result = Tk_InitOptions(interp, (char *) recordPtr, + result = Tk_InitOptions(interp, recordPtr, recordPtr->header.optionTable, tkwin); if (result == TCL_OK) { - result = Tk_SetOptions(interp, (char *) recordPtr, + result = Tk_SetOptions(interp, recordPtr, recordPtr->header.optionTable, objc - 3, objv + 3, tkwin, NULL, NULL); if (result == TCL_OK) { recordPtr->header.widgetCmd = Tcl_CreateObjCommand(interp, Tcl_GetString(objv[2]), TrivialConfigObjCmd, @@ -1095,11 +1105,11 @@ recordPtr, TrivialCmdDeletedProc); Tk_CreateEventHandler(tkwin, StructureNotifyMask, TrivialEventProc, recordPtr); Tcl_SetObjResult(interp, objv[2]); } else { - Tk_FreeConfigOptions((char *) recordPtr, + Tk_FreeConfigOptions(recordPtr, recordPtr->header.optionTable, tkwin); } } if (result != TCL_OK) { Tk_DestroyWindow(tkwin); @@ -1166,11 +1176,11 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; goto done; } - resultObjPtr = Tk_GetOptionValue(interp, (char *) clientData, + resultObjPtr = Tk_GetOptionValue(interp, clientData, headerPtr->optionTable, objv[2], tkwin); if (resultObjPtr != NULL) { Tcl_SetObjResult(interp, resultObjPtr); result = TCL_OK; } else { @@ -1177,36 +1187,36 @@ result = TCL_ERROR; } break; case CONFIGURE: if (objc == 2) { - resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData, + resultObjPtr = Tk_GetOptionInfo(interp, clientData, headerPtr->optionTable, NULL, tkwin); if (resultObjPtr == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, resultObjPtr); } } else if (objc == 3) { - resultObjPtr = Tk_GetOptionInfo(interp, (char *) clientData, + resultObjPtr = Tk_GetOptionInfo(interp, clientData, headerPtr->optionTable, objv[2], tkwin); if (resultObjPtr == NULL) { result = TCL_ERROR; } else { Tcl_SetObjResult(interp, resultObjPtr); } } else { - result = Tk_SetOptions(interp, (char *) clientData, + result = Tk_SetOptions(interp, clientData, headerPtr->optionTable, objc - 2, objv + 2, tkwin, NULL, &mask); if (result == TCL_OK) { Tcl_SetObjResult(interp, Tcl_NewIntObj(mask)); } } break; case CSAVE: - result = Tk_SetOptions(interp, (char *) clientData, + result = Tk_SetOptions(interp, clientData, headerPtr->optionTable, objc - 2, objv + 2, tkwin, &saved, &mask); Tk_FreeSavedOptions(&saved); if (result == TCL_OK) { Tcl_SetObjResult(interp, Tcl_NewIntObj(mask)); @@ -1548,13 +1558,12 @@ * imageX and imageY. */ { TImageInstance *instPtr = (TImageInstance *) clientData; char buffer[200 + TCL_INTEGER_SPACE * 6]; - sprintf(buffer, "%s display %d %d %d %d %d %d", - instPtr->masterPtr->imageName, imageX, imageY, width, height, - drawableX, drawableY); + sprintf(buffer, "%s display %d %d %d %d", + instPtr->masterPtr->imageName, imageX, imageY, width, height); Tcl_SetVar2(instPtr->masterPtr->interp, instPtr->masterPtr->varName, NULL, buffer, TCL_GLOBAL_ONLY|TCL_APPEND_VALUE|TCL_LIST_ELEMENT); if (width > (instPtr->masterPtr->width - imageX)) { width = instPtr->masterPtr->width - imageX; } @@ -1763,11 +1772,11 @@ * None. * *---------------------------------------------------------------------- */ -#if defined(_WIN32) || defined(MAC_OSX_TK) +#if defined(_WIN32) static int TestmetricsObjCmd( ClientData clientData, /* Main window for application. */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ @@ -1774,42 +1783,19 @@ Tcl_Obj *const objv[]) /* Argument strings. */ { char buf[TCL_INTEGER_SPACE]; int val; -#ifdef _WIN32 if (objc < 2) { Tcl_WrongNumArgs(interp, 1, objv, "option ?arg ...?"); return TCL_ERROR; } -#else - Tk_Window tkwin = (Tk_Window) clientData; - TkWindow *winPtr; - - if (objc != 3) { - Tcl_WrongNumArgs(interp, 1, objv, "option window"); - return TCL_ERROR; - } - - winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); - if (winPtr == NULL) { - return TCL_ERROR; - } -#endif if (strcmp(Tcl_GetString(objv[1]), "cyvscroll") == 0) { -#ifdef _WIN32 val = GetSystemMetrics(SM_CYVSCROLL); -#else - val = ((TkScrollbar *) winPtr->instanceData)->width; -#endif } else if (strcmp(Tcl_GetString(objv[1]), "cxhscroll") == 0) { -#ifdef _WIN32 val = GetSystemMetrics(SM_CXHSCROLL); -#else - val = ((TkScrollbar *) winPtr->instanceData)->width; -#endif } else { Tcl_AppendResult(interp, "bad option \"", Tcl_GetString(objv[1]), "\": must be cxhscroll or cyvscroll", NULL); return TCL_ERROR; } @@ -1893,10 +1879,64 @@ if (property != NULL) { XFree(property); } return TCL_OK; } + +/* + *---------------------------------------------------------------------- + * + * TestpropObjCmd -- + * + * This function implements the "testprop" command. It fetches and prints + * the value of a property on a window. + * + * Results: + * A standard Tcl result. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestprintfObjCmd( + ClientData clientData, /* Not used */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ +{ + char buffer[256]; + Tcl_WideInt wideInt; +#ifdef _WIN32 + __int64 longLongInt; +#else + long long longLongInt; +#endif + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "wideint"); + return TCL_ERROR; + } + if (Tcl_GetWideIntFromObj(interp, objv[1], &wideInt) != TCL_OK) { + return TCL_ERROR; + } + longLongInt = wideInt; + + /* Just add a lot of arguments to sprintf. Reason: on AMD64, the first + * 4 or 6 arguments (we assume 8, just in case) might be put in registers, + * which still woudn't tell if the assumed size is correct: We want this + * test-case to fail if the 64-bit value is printed as truncated to 32-bit. + */ + sprintf(buffer, "%s%s%s%s%s%s%s%s%" TCL_LL_MODIFIER "d %" + TCL_LL_MODIFIER "u", "", "", "", "", "", "", "", "", + (Tcl_WideInt)longLongInt, (Tcl_WideUInt)longLongInt); + Tcl_AppendResult(interp, buffer, NULL); + return TCL_OK; +} #if !(defined(_WIN32) || defined(MAC_OSX_TK) || defined(__CYGWIN__)) /* *---------------------------------------------------------------------- * @@ -1988,11 +2028,11 @@ int objEmpty; char *newStr, *string, *internalPtr; objEmpty = 0; - if (internalOffset >= 0) { + if (internalOffset != -1) { internalPtr = recordPtr + internalOffset; } else { internalPtr = NULL; } @@ -2064,13 +2104,61 @@ { if (*(char **)internalPtr != NULL) { ckfree(*(char **)internalPtr); } } +/* + *---------------------------------------------------------------------- + * + * TestPhotoStringMatchCmd -- + * + * This function implements the "testphotostringmatch" command. It + * provides a way from Tcl to call the string match function for the + * default image handler directly. + * + * Results: + * A standard Tcl result. If data is in the proper format, the result in + * interp will contain width and height as a list. If the data cannot be + * parsed as default image format, returns TCL_ERROR and leaves an + * appropriate error message in interp. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + + /* ARGSUSED */ +static int +TestPhotoStringMatchCmd( + ClientData clientData, /* Main window for application. */ + Tcl_Interp *interp, /* Current interpreter. */ + int objc, /* Number of arguments. */ + Tcl_Obj *const objv[]) /* Argument strings. */ +{ + Tcl_Obj *dummy = NULL; + Tcl_Obj *resultObj[2]; + int width, height; + + if (objc != 2) { + Tcl_WrongNumArgs(interp, 1, objv, "imageData"); + return TCL_ERROR; + } + if (TkDebugPhotoStringMatchDef(interp, objv[1], dummy, &width, &height)) { + resultObj[0] = Tcl_NewIntObj(width); + resultObj[1] = Tcl_NewIntObj(height); + Tcl_SetObjResult(interp, Tcl_NewListObj(2, resultObj)); + return TCL_OK; + } else { + return TCL_ERROR; + } +} + + /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ Index: generic/tkText.c ================================================================== --- generic/tkText.c +++ generic/tkText.c @@ -12,13 +12,13 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" #include "tkUndo.h" +#include "default.h" #if defined(MAC_OSX_TK) #define Style TkStyle #define DInfo TkDInfo #endif @@ -659,11 +659,11 @@ |LeaveWindowMask|PointerMotionMask|VirtualEventMask, TkTextBindProc, textPtr); Tk_CreateSelHandler(textPtr->tkwin, XA_PRIMARY, XA_STRING, TextFetchSelection, textPtr, XA_STRING); - if (Tk_InitOptions(interp, (char *) textPtr, optionTable, textPtr->tkwin) + if (Tk_InitOptions(interp, textPtr, optionTable, textPtr->tkwin) != TCL_OK) { Tk_DestroyWindow(textPtr->tkwin); return TCL_ERROR; } if (ConfigureText(interp, textPtr, objc-2, objv+2) != TCL_OK) { @@ -762,11 +762,11 @@ if (objc != 3) { Tcl_WrongNumArgs(interp, 2, objv, "option"); result = TCL_ERROR; goto done; } else { - Tcl_Obj *objPtr = Tk_GetOptionValue(interp, (char *) textPtr, + Tcl_Obj *objPtr = Tk_GetOptionValue(interp, textPtr, textPtr->optionTable, objv[2], textPtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; goto done; @@ -825,11 +825,11 @@ result = TCL_ERROR; goto done; } case TEXT_CONFIGURE: if (objc <= 3) { - Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) textPtr, + Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, textPtr, textPtr->optionTable, ((objc == 3) ? objv[2] : NULL), textPtr->tkwin); if (objPtr == NULL) { result = TCL_ERROR; @@ -862,32 +862,32 @@ result = TCL_ERROR; goto done; } for (i = 2; i < objc-2; i++) { - int value, length; - const char *option = Tcl_GetString(objv[i]); + int value; + size_t length; + const char *option = TkGetStringFromObj(objv[i], &length); char c; - length = objv[i]->length; if (length < 2 || option[0] != '-') { goto badOption; } c = option[1]; - if (c == 'c' && !strncmp("-chars", option, (unsigned) length)) { + if (c == 'c' && !strncmp("-chars", option, length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_CHARS); } else if (c == 'd' && (length > 8) - && !strncmp("-displaychars", option, (unsigned) length)) { + && !strncmp("-displaychars", option, length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_DISPLAY_CHARS); } else if (c == 'd' && (length > 8) - && !strncmp("-displayindices", option,(unsigned)length)) { + && !strncmp("-displayindices", option,length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_DISPLAY_INDICES); } else if (c == 'd' && (length > 8) - && !strncmp("-displaylines", option, (unsigned) length)) { + && !strncmp("-displaylines", option, length)) { TkTextLine *fromPtr, *lastPtr; TkTextIndex index, index2; int compare = TkTextIndexCmp(indexFromPtr, indexToPtr); value = 0; @@ -981,33 +981,33 @@ if (compare > 0) { value = -value; } } else if (c == 'i' - && !strncmp("-indices", option, (unsigned) length)) { + && !strncmp("-indices", option, length)) { value = CountIndices(textPtr, indexFromPtr, indexToPtr, COUNT_INDICES); } else if (c == 'l' - && !strncmp("-lines", option, (unsigned) length)) { + && !strncmp("-lines", option, length)) { value = TkBTreeLinesTo(textPtr, indexToPtr->linePtr) - TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); } else if (c == 'u' - && !strncmp("-update", option, (unsigned) length)) { + && !strncmp("-update", option, length)) { update = 1; continue; } else if (c == 'x' - && !strncmp("-xpixels", option, (unsigned) length)) { + && !strncmp("-xpixels", option, length)) { int x1, x2; TkTextIndex index; index = *indexFromPtr; TkTextFindDisplayLineEnd(textPtr, &index, 0, &x1); index = *indexToPtr; TkTextFindDisplayLineEnd(textPtr, &index, 0, &x2); value = x2 - x1; } else if (c == 'y' - && !strncmp("-ypixels", option, (unsigned) length)) { + && !strncmp("-ypixels", option, length)) { if (update) { TkTextUpdateLineMetrics(textPtr, TkBTreeLinesTo(textPtr, indexFromPtr->linePtr), TkBTreeLinesTo(textPtr, indexToPtr->linePtr), -1); } @@ -1153,18 +1153,18 @@ TkTextIndexForwChars(NULL, &indices[i], 1, &indices[i], COUNT_INDICES); objc++; } useIdx = ckalloc(objc); - memset(useIdx, 0, (unsigned) objc); + memset(useIdx, 0, objc); /* * Do a decreasing order sort so that we delete the end ranges * first to maintain index consistency. */ - qsort(indices, (unsigned) objc / 2, + qsort(indices, objc / 2, 2 * sizeof(TkTextIndex), TextIndexSortProc); lastStart = NULL; /* * Second pass will handle bogus ranges (end < start) and @@ -1258,11 +1258,11 @@ break; case TEXT_GET: { Tcl_Obj *objPtr = NULL; int i, found = 0, visible = 0; const char *name; - int length; + size_t length; if (objc < 3) { Tcl_WrongNumArgs(interp, 2, objv, "?-displaychars? ?--? index1 ?index2 ...?"); result = TCL_ERROR; @@ -1274,18 +1274,16 @@ * -displaychars (or any unique prefix). */ i = 2; if (objc > 3) { - name = Tcl_GetString(objv[i]); - length = objv[i]->length; + name = TkGetStringFromObj(objv[i], &length); if (length > 1 && name[0] == '-') { - if (strncmp("-displaychars", name, (unsigned) length) == 0) { + if (strncmp("-displaychars", name, length) == 0) { i++; visible = 1; - name = Tcl_GetString(objv[i]); - length = objv[i]->length; + name = TkGetStringFromObj(objv[i], &length); } if ((i < objc-1) && (length == 2) && !strcmp("--", name)) { i++; } } @@ -1463,11 +1461,11 @@ * The insertion point is inside the range to be replaced, so * we have to do some calculations to ensure it doesn't move * unnecessarily. */ - int deleteInsertOffset, insertLength, j; + int deleteInsertOffset, insertLength, j, indexFromLine, indexFromByteOffset; insertLength = 0; for (j = 4; j < objc; j += 2) { insertLength += Tcl_GetCharLength(objv[j]); } @@ -1481,19 +1479,26 @@ &index, COUNT_CHARS); if (deleteInsertOffset > insertLength) { deleteInsertOffset = insertLength; } + indexFromLine = TkBTreeLinesTo(textPtr, indexFromPtr->linePtr); + indexFromByteOffset = indexFromPtr->byteIndex; + result = TextReplaceCmd(textPtr, interp, indexFromPtr, indexToPtr, objc, objv, 0); if (result == TCL_OK) { /* * Move the insertion position to the correct place. */ - TkTextIndexForwChars(NULL, indexFromPtr, + TkTextIndex indexTmp; + + TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, indexFromLine, + indexFromByteOffset, &indexTmp); + TkTextIndexForwChars(NULL, &indexTmp, deleteInsertOffset, &index, COUNT_INDICES); TkBTreeUnlinkSegment(textPtr->insertMarkPtr, textPtr->insertMarkPtr->body.mark.linePtr); TkBTreeLinkSegment(textPtr->insertMarkPtr, &index); } @@ -1568,12 +1573,11 @@ result = TkTextYviewCmd(textPtr, interp, objc, objv); break; } done: - textPtr->refCount--; - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } return result; } @@ -1962,13 +1966,11 @@ * * When the refCount reaches zero, it's time to clean up the shared * portion of the text widget. */ - sharedTextPtr->refCount--; - - if (sharedTextPtr->refCount > 0) { + if (sharedTextPtr->refCount-- > 1) { TkBTreeRemoveClient(sharedTextPtr->tree, textPtr); /* * Free up any embedded windows which belong to this widget. */ @@ -2040,17 +2042,16 @@ if (textPtr->insertBlinkHandler != NULL) { Tcl_DeleteTimerHandler(textPtr->insertBlinkHandler); } textPtr->tkwin = NULL; - textPtr->refCount--; Tcl_DeleteCommandFromToken(textPtr->interp, textPtr->widgetCmd); if (textPtr->afterSyncCmd){ Tcl_DecrRefCount(textPtr->afterSyncCmd); textPtr->afterSyncCmd = NULL; } - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } } /* @@ -2079,11 +2080,11 @@ * already have values for some fields. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { Tk_SavedOptions savedOptions; - int oldExport = textPtr->exportSelection; + int oldExport = (textPtr->exportSelection) && (!Tcl_IsSafe(textPtr->interp)); int mask = 0; if (Tk_SetOptions(interp, (char *) textPtr, textPtr->optionTable, objc, objv, textPtr->tkwin, &savedOptions, &mask) != TCL_OK) { return TCL_ERROR; @@ -2308,11 +2309,11 @@ /* * Claim the selection if we've suddenly started exporting it and there * are tagged characters. */ - if (textPtr->exportSelection && (!oldExport)) { + if (textPtr->exportSelection && (!oldExport) && (!Tcl_IsSafe(textPtr->interp))) { TkTextSearch search; TkTextIndex first, last; TkTextMakeByteIndex(textPtr->sharedTextPtr->tree, textPtr, 0, 0, &first); @@ -2628,18 +2629,18 @@ * insertion (e.g. if at "end"). */ Tcl_Obj *stringPtr, /* Null-terminated string containing new * information to add to text. */ int viewUpdate) /* Update the view if set. */ { - int lineIndex, length; + int lineIndex; + size_t length; TkText *tPtr; int *lineAndByteIndex; int resetViewCount; int pixels[2*PIXEL_CLIENTS]; - const char *string = Tcl_GetString(stringPtr); + const char *string = TkGetStringFromObj(stringPtr, &length); - length = stringPtr->length; if (sharedTextPtr == NULL) { sharedTextPtr = textPtr->sharedTextPtr; } /* @@ -2727,14 +2728,18 @@ if (sharedTextPtr->refCount > PIXEL_CLIENTS) { ckfree(lineAndByteIndex); } /* - * Invalidate any selection retrievals in progress. + * Invalidate any selection retrievals in progress, and send an event + * that the selection changed if that is the case. */ for (tPtr = sharedTextPtr->peers; tPtr != NULL ; tPtr = tPtr->next) { + if (TkBTreeCharTagged(indexPtr, tPtr->selTagPtr)) { + TkTextSelectionEvent(tPtr); + } tPtr->abortSelections = 1; } /* * For convenience, return the length of the string. @@ -2772,10 +2777,13 @@ const TkTextIndex *index2Ptr) /* Index describing second location. */ { TkUndoSubAtom *iAtom, *dAtom; int canUndo, canRedo; + char lMarkName[20] = "tk::undoMarkL"; + char rMarkName[20] = "tk::undoMarkR"; + char stringUndoMarkId[7] = ""; /* * Create the helpers. */ @@ -2782,10 +2790,14 @@ Tcl_Obj *seeInsertObj = Tcl_NewObj(); Tcl_Obj *markSet1InsertObj = Tcl_NewObj(); Tcl_Obj *markSet2InsertObj = NULL; Tcl_Obj *insertCmdObj = Tcl_NewObj(); Tcl_Obj *deleteCmdObj = Tcl_NewObj(); + Tcl_Obj *markSetLUndoMarkCmdObj = Tcl_NewObj(); + Tcl_Obj *markSetRUndoMarkCmdObj = NULL; + Tcl_Obj *markGravityLUndoMarkCmdObj = Tcl_NewObj(); + Tcl_Obj *markGravityRUndoMarkCmdObj = NULL; /* * Get the index positions. */ @@ -2831,10 +2843,44 @@ Tcl_ListObjAppendElement(NULL, deleteCmdObj, Tcl_NewStringObj("delete", 6)); Tcl_ListObjAppendElement(NULL, deleteCmdObj, index1Obj); Tcl_ListObjAppendElement(NULL, deleteCmdObj, index2Obj); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj("mark", 4)); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj("set", 3)); + markSetRUndoMarkCmdObj = Tcl_DuplicateObj(markSetLUndoMarkCmdObj); + textPtr->sharedTextPtr->undoMarkId++; + sprintf(stringUndoMarkId, "%d", textPtr->sharedTextPtr->undoMarkId); + strcat(lMarkName, stringUndoMarkId); + strcat(rMarkName, stringUndoMarkId); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, + Tcl_NewStringObj(lMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj, + Tcl_NewStringObj(rMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markSetLUndoMarkCmdObj, index1Obj); + Tcl_ListObjAppendElement(NULL, markSetRUndoMarkCmdObj, index2Obj); + + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj(Tk_PathName(textPtr->tkwin), -1)); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj("mark", 4)); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj("gravity", 7)); + markGravityRUndoMarkCmdObj = Tcl_DuplicateObj(markGravityLUndoMarkCmdObj); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj(lMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj, + Tcl_NewStringObj(rMarkName, -1)); + Tcl_ListObjAppendElement(NULL, markGravityLUndoMarkCmdObj, + Tcl_NewStringObj("left", 4)); + Tcl_ListObjAppendElement(NULL, markGravityRUndoMarkCmdObj, + Tcl_NewStringObj("right", 5)); + /* * Note: we don't wish to use textPtr->widgetCmd in these callbacks * because if we delete the textPtr, but peers still exist, we will then * have references to a non-existent Tcl_Command in the undo stack, which * will lead to crashes later. Also, the behaviour of the widget w.r.t. @@ -2848,15 +2894,23 @@ iAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr, insertCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet2InsertObj, iAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, iAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, iAtom); dAtom = TkUndoMakeSubAtom(&TextUndoRedoCallback, textPtr->sharedTextPtr, deleteCmdObj, NULL); TkUndoMakeCmdSubAtom(NULL, markSet1InsertObj, dAtom); TkUndoMakeCmdSubAtom(NULL, seeInsertObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markSetLUndoMarkCmdObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markSetRUndoMarkCmdObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityLUndoMarkCmdObj, dAtom); + TkUndoMakeCmdSubAtom(NULL, markGravityRUndoMarkCmdObj, dAtom); Tcl_DecrRefCount(seeInsertObj); Tcl_DecrRefCount(index1Obj); Tcl_DecrRefCount(index2Obj); @@ -3070,10 +3124,13 @@ TkTextIndex index1, index2; TkText *tPtr; int *lineAndByteIndex; int resetViewCount; int pixels[2*PIXEL_CLIENTS]; + Tcl_HashSearch search; + Tcl_HashEntry *hPtr; + int i; if (sharedTextPtr == NULL) { sharedTextPtr = textPtr->sharedTextPtr; } @@ -3134,46 +3191,40 @@ } ckfree(arrayPtr); } } - if (line1 < line2) { - /* - * We are deleting more than one line. For speed, we remove all tags - * from the range first. If we don't do this, the code below can (when - * there are many tags) grow non-linearly in execution time. - */ - - Tcl_HashSearch search; - Tcl_HashEntry *hPtr; - int i; - - for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); - hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { - TkTextTag *tagPtr = Tcl_GetHashValue(hPtr); - - TkBTreeTag(&index1, &index2, tagPtr, 0); - } - - /* - * Special case for the sel tag which is not in the hash table. We - * need to do this once for each peer text widget. - */ - - for (tPtr = sharedTextPtr->peers; tPtr != NULL ; - tPtr = tPtr->next) { - if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) { - /* - * Send an event that the selection changed. This is - * equivalent to: - * event generate $textWidget <> - */ - - TkTextSelectionEvent(textPtr); - tPtr->abortSelections = 1; - } - } + /* + * For speed, we remove all tags from the range first. If we don't + * do this, the code below can (when there are many tags) grow + * non-linearly in execution time. + */ + + for (i=0, hPtr=Tcl_FirstHashEntry(&sharedTextPtr->tagTable, &search); + hPtr != NULL; i++, hPtr = Tcl_NextHashEntry(&search)) { + TkTextTag *tagPtr = Tcl_GetHashValue(hPtr); + + TkBTreeTag(&index1, &index2, tagPtr, 0); + } + + /* + * Special case for the sel tag which is not in the hash table. We + * need to do this once for each peer text widget. + */ + + for (tPtr = sharedTextPtr->peers; tPtr != NULL ; + tPtr = tPtr->next) { + if (TkBTreeTag(&index1, &index2, tPtr->selTagPtr, 0)) { + /* + * Send an event that the selection changed. This is + * equivalent to: + * event generate $textWidget <> + */ + + TkTextSelectionEvent(textPtr); + tPtr->abortSelections = 1; + } } /* * Tell the display what's about to happen so it can discard obsolete * display information, then do the deletion. Also, if the deletion @@ -3379,11 +3430,11 @@ TkTextIndex eof; int count, chunkSize, offsetInSeg; TkTextSearch search; TkTextSegment *segPtr; - if (!textPtr->exportSelection) { + if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) { return -1; } /* * Find the beginning of the next range of selected text. Note: if the @@ -3509,11 +3560,11 @@ register TkText *textPtr = clientData; if (TkpAlwaysShowSelection(textPtr->tkwin)) { TkTextIndex start, end; - if (!textPtr->exportSelection) { + if ((!textPtr->exportSelection) || Tcl_IsSafe(textPtr->interp)) { return; } /* * On Windows and Mac systems, we want to remember the selection for @@ -3756,14 +3807,14 @@ "-hidden", "--", "-all", "-backwards", "-count", "-elide", "-exact", "-forwards", "-nocase", "-nolinestop", "-overlap", "-regexp", "-strictlimits", NULL }; enum SearchSwitches { - SEARCH_HIDDEN, - SEARCH_END, SEARCH_ALL, SEARCH_BACK, SEARCH_COUNT, SEARCH_ELIDE, - SEARCH_EXACT, SEARCH_FWD, SEARCH_NOCASE, - SEARCH_NOLINESTOP, SEARCH_OVERLAP, SEARCH_REGEXP, SEARCH_STRICTLIMITS + TK_TEXT_SEARCH_HIDDEN, + TK_TEXT_SEARCH_END, TK_TEXT_SEARCH_ALL, TK_TEXT_SEARCH_BACK, TK_TEXT_SEARCH_COUNT, TK_TEXT_SEARCH_ELIDE, + TK_TEXT_SEARCH_EXACT, TK_TEXT_SEARCH_FWD, TK_TEXT_SEARCH_NOCASE, + TK_TEXT_SEARCH_NOLINESTOP, TK_TEXT_SEARCH_OVERLAP, TK_TEXT_SEARCH_REGEXP, TK_TEXT_SEARCH_STRICTLIMITS }; /* * Set up the search specification, including the last 4 fields which are * text widget specific. @@ -3809,20 +3860,20 @@ sizeof(char *), "switch", 0, &index); return TCL_ERROR; } switch ((enum SearchSwitches) index) { - case SEARCH_END: + case TK_TEXT_SEARCH_END: i++; goto endOfSwitchProcessing; - case SEARCH_ALL: + case TK_TEXT_SEARCH_ALL: searchSpec.all = 1; break; - case SEARCH_BACK: + case TK_TEXT_SEARCH_BACK: searchSpec.backwards = 1; break; - case SEARCH_COUNT: + case TK_TEXT_SEARCH_COUNT: if (i >= objc-1) { Tcl_SetObjResult(interp, Tcl_NewStringObj( "no value given for \"-count\" option", -1)); Tcl_SetErrorCode(interp, "TK", "TEXT", "VALUE", NULL); return TCL_ERROR; @@ -3834,33 +3885,33 @@ * function, which is fair. */ searchSpec.varPtr = objv[i]; break; - case SEARCH_ELIDE: - case SEARCH_HIDDEN: + case TK_TEXT_SEARCH_ELIDE: + case TK_TEXT_SEARCH_HIDDEN: searchSpec.searchElide = 1; break; - case SEARCH_EXACT: + case TK_TEXT_SEARCH_EXACT: searchSpec.exact = 1; break; - case SEARCH_FWD: + case TK_TEXT_SEARCH_FWD: searchSpec.backwards = 0; break; - case SEARCH_NOCASE: + case TK_TEXT_SEARCH_NOCASE: searchSpec.noCase = 1; break; - case SEARCH_NOLINESTOP: + case TK_TEXT_SEARCH_NOLINESTOP: searchSpec.noLineStop = 1; break; - case SEARCH_OVERLAP: + case TK_TEXT_SEARCH_OVERLAP: searchSpec.overlap = 1; break; - case SEARCH_STRICTLIMITS: + case TK_TEXT_SEARCH_STRICTLIMITS: searchSpec.strictLimits = 1; break; - case SEARCH_REGEXP: + case TK_TEXT_SEARCH_REGEXP: searchSpec.exact = 0; break; default: Tcl_Panic("unexpected switch fallthrough"); } @@ -4176,11 +4227,11 @@ Tcl_SetObjLength(theLine, Tcl_UtfToLower(Tcl_GetString(theLine))); } if (lenPtr != NULL) { if (searchSpecPtr->exact) { - (void)Tcl_GetString(theLine); + Tcl_GetString(theLine); *lenPtr = theLine->length; } else { *lenPtr = Tcl_GetCharLength(theLine); } } @@ -4457,11 +4508,11 @@ { int objc, i, count; Tcl_Obj **objv; TkTextTabArray *tabArrayPtr; TkTextTab *tabPtr; - Tcl_UniChar ch; + int ch; double prevStop, lastStop; /* * Map these strings to TkTextTabAlign values. */ static const char *const tabOptionStrings[] = { @@ -4564,11 +4615,11 @@ /* * There may be a more efficient way of getting this. */ - Tcl_UtfToUniChar(Tcl_GetString(objv[i+1]), &ch); + TkUtfToUniChar(Tcl_GetString(objv[i+1]), &ch); if (!Tcl_UniCharIsAlpha(ch)) { continue; } i += 1; @@ -4701,19 +4752,18 @@ arg++; atEnd = 0; if (objc == arg) { TkTextIndexForwChars(NULL, &index1, 1, &index2, COUNT_INDICES); } else { - int length; + size_t length; const char *str; if (TkTextGetObjIndex(interp, textPtr, objv[arg], &index2) != TCL_OK) { return TCL_ERROR; } - str = Tcl_GetString(objv[arg]); - length = objv[arg]->length; - if (strncmp(str, "end", (unsigned) length) == 0) { + str = TkGetStringFromObj(objv[arg], &length); + if (strncmp(str, "end", length) == 0) { atEnd = 1; } } if (TkTextIndexCmp(&index1, &index2) >= 0) { return TCL_OK; @@ -5024,11 +5074,11 @@ if (command == NULL) { Tcl_ListObjAppendList(NULL, Tcl_GetObjResult(interp), tuple); Tcl_DecrRefCount(tuple); return 0; } else { - int oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree); + TkSizeT oldStateEpoch = TkBTreeEpoch(textPtr->sharedTextPtr->tree); Tcl_DString buf; int code; Tcl_DStringInit(&buf); Tcl_DStringAppend(&buf, Tcl_GetString(command), -1); @@ -5067,10 +5117,12 @@ static int TextEditUndo( TkText *textPtr) /* Overall information about text widget. */ { int status; + Tcl_Obj *cmdObj; + int code; if (!textPtr->sharedTextPtr->undo) { return TCL_OK; } @@ -5090,10 +5142,26 @@ if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) { textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; } textPtr->sharedTextPtr->undo = 1; + /* + * Convert undo/redo temporary marks set by TkUndoRevert() into + * indices left in the interp result. + */ + + cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s", + Tk_PathName(textPtr->tkwin)); + Tcl_IncrRefCount(cmdObj); + code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL); + if (code != TCL_OK) { + Tcl_AddErrorInfo(textPtr->interp, + "\n (on undoing)"); + Tcl_BackgroundException(textPtr->interp, code); + } + Tcl_DecrRefCount(cmdObj); + return status; } /* *---------------------------------------------------------------------- @@ -5115,10 +5183,12 @@ static int TextEditRedo( TkText *textPtr) /* Overall information about text widget. */ { int status; + Tcl_Obj *cmdObj; + int code; if (!textPtr->sharedTextPtr->undo) { return TCL_OK; } @@ -5137,10 +5207,27 @@ if (textPtr->sharedTextPtr->dirtyMode != TK_TEXT_DIRTY_FIXED) { textPtr->sharedTextPtr->dirtyMode = TK_TEXT_DIRTY_NORMAL; } textPtr->sharedTextPtr->undo = 1; + + /* + * Convert undo/redo temporary marks set by TkUndoApply() into + * indices left in the interp result. + */ + + cmdObj = Tcl_ObjPrintf("::tk::TextUndoRedoProcessMarks %s", + Tk_PathName(textPtr->tkwin)); + Tcl_IncrRefCount(cmdObj); + code = Tcl_EvalObjEx(textPtr->interp, cmdObj, TCL_EVAL_GLOBAL); + if (code != TCL_OK) { + Tcl_AddErrorInfo(textPtr->interp, + "\n (on undoing)"); + Tcl_BackgroundException(textPtr->interp, code); + } + Tcl_DecrRefCount(cmdObj); + return status; } /* *---------------------------------------------------------------------- @@ -5524,11 +5611,11 @@ if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { /* * The widget has been deleted. Don't do anything. */ - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree((char *) textPtr); } return; } @@ -5744,12 +5831,11 @@ * We only need to set the matchLength once for exact searches, and we * do it here. It is also used below as the actual pattern length, so * it has dual purpose. */ - pattern = Tcl_GetString(patObj); - matchLength = patObj->length; + pattern = Tcl_GetStringFromObj(patObj, &matchLength); nl = strchr(pattern, '\n'); /* * If there is no newline, or it is the very end of the string, then * we don't need any special treatment, since single-line matching @@ -5815,11 +5901,11 @@ firstOffset = searchSpecPtr->stopOffset; } else { firstOffset = 0; } - if (alreadySearchOffset != -1) { + if (alreadySearchOffset >= 0) { if (searchSpecPtr->backwards) { if (alreadySearchOffset < lastOffset) { lastOffset = alreadySearchOffset; } } else { @@ -5878,11 +5964,11 @@ int maxExtraLines = 0; const char *startOfLine = Tcl_GetString(theLine); CLANG_ASSERT(pattern); do { - Tcl_UniChar ch; + int ch; const char *p; int lastFullLine = lastOffset; if (firstNewLine == -1) { if (searchSpecPtr->strictLimits @@ -5904,21 +5990,21 @@ * Search back either from the previous match or from * 'startOfLine + lastOffset - 1' until we find a * match. */ - const char c = pattern[0]; + const char c = matchLength ? pattern[0] : '\0'; - if (alreadySearchOffset != -1) { + if (alreadySearchOffset >= 0) { p = startOfLine + alreadySearchOffset; alreadySearchOffset = -1; } else { p = startOfLine + lastOffset -1; } while (p >= startOfLine + firstOffset) { - if (p[0] == c && !strncmp(p, pattern, - (unsigned) matchLength)) { + if (matchLength == 0 || (p[0] == c && !strncmp( + p, pattern, (size_t) matchLength))) { goto backwardsMatch; } p--; } break; @@ -6009,11 +6095,11 @@ * We now have enough text to match, so we * make a final test and break whatever the * result. */ - if (strncmp(p,pattern,(unsigned)matchLength)) { + if (strncmp(p,pattern,(size_t)matchLength)) { p = NULL; } break; } else { /* @@ -6077,14 +6163,18 @@ if (searchSpecPtr->backwards) { alreadySearchOffset = p - startOfLine; if (firstNewLine != -1) { break; } else { - alreadySearchOffset -= matchLength; + alreadySearchOffset -= (matchLength ? matchLength : 1); + if (alreadySearchOffset < 0) { + break; + } } } else { - firstOffset = p - startOfLine + matchLength; + firstOffset = matchLength ? p - startOfLine + matchLength + : p - startOfLine + 1; if (firstOffset >= lastOffset) { /* * Now, we have to be careful not to find * overlapping matches either on the same or * following lines. Assume that if we did find @@ -6108,11 +6198,11 @@ if (alreadySearchOffset < 0) { break; } } else { firstOffset = p - startOfLine + - Tcl_UtfToUniChar(startOfLine+matchOffset,&ch); + TkUtfToUniChar(startOfLine+matchOffset,&ch); } } } while (searchSpecPtr->all); } else { int maxExtraLines = 0; @@ -6741,11 +6831,11 @@ TkTextLine *linePtr = NULL; char *internalPtr; TkText *textPtr = (TkText *) recordPtr; if (internalOffset >= 0) { - internalPtr = recordPtr + internalOffset; + internalPtr = (char *)recordPtr + internalOffset; } else { internalPtr = NULL; } if (flags & TK_OPTION_NULL_OK && ObjectIsEmpty(*value)) { @@ -6816,14 +6906,13 @@ Tcl_Obj *objPtr) /* Object to test. May be NULL. */ { if (objPtr == NULL) { return 1; } - if (objPtr->bytes != NULL) { - return (objPtr->length == 0); + if (objPtr->bytes == NULL) { + Tcl_GetString(objPtr); } - (void)Tcl_GetString(objPtr); return (objPtr->length == 0); } /* *---------------------------------------------------------------------- Index: generic/tkText.h ================================================================== --- generic/tkText.h +++ generic/tkText.h @@ -529,13 +529,21 @@ /* * A data structure of the following type is shared between each text widget * that are peers. */ + +#ifndef TkSizeT +# if TCL_MAJOR_VERSION > 8 +# define TkSizeT size_t +# else +# define TkSizeT int +# endif +#endif typedef struct TkSharedText { - int refCount; /* Reference count this shared object. */ + TkSizeT refCount; /* Reference count this shared object. */ TkTextBTree tree; /* B-tree representation of text and tags for * widget. */ Tcl_HashTable tagTable; /* Hash table that maps from tag names to * pointers to TkTextTag structures. The "sel" * tag does not feature in this table, since @@ -560,11 +568,11 @@ /* Table of all bindings currently defined for * this widget. NULL means that no bindings * exist, so the table hasn't been created. * Each "object" used for this table is the * name of a tag. */ - int stateEpoch; /* This is incremented each time the B-tree's + TkSizeT stateEpoch; /* This is incremented each time the B-tree's * contents change structurally, or when the * start/end limits change, and means that any * cached TkTextIndex objects are no longer * valid. */ @@ -578,10 +586,12 @@ int maxUndo; /* The maximum depth of the undo stack * expressed as the maximum number of compound * statements. */ int autoSeparators; /* Non-zero means the separators will be * inserted automatically. */ + int undoMarkId; /* Counts undo marks temporarily used during + undo and redo operations. */ int isDirty; /* Flag indicating the 'dirtyness' of the * text widget. If the flag is not zero, * unsaved modifications have been applied to * the text widget. */ TkTextDirtyMode dirtyMode; /* The nature of the dirtyness characterized @@ -779,11 +789,11 @@ * vertical scrollbar when view changes. */ int flags; /* Miscellaneous flags; see below for * definitions. */ Tk_OptionTable optionTable; /* Token representing the configuration * specifications. */ - int refCount; /* Number of cached TkTextIndex objects + TkSizeT refCount; /* Number of cached TkTextIndex objects * refering to us. */ int insertCursorType; /* 0 = standard insertion cursor, 1 = block * cursor. */ /* @@ -1005,11 +1015,11 @@ MODULE_SCOPE void TkBTreeRemoveClient(TkTextBTree tree, TkText *textPtr); MODULE_SCOPE void TkBTreeDestroy(TkTextBTree tree); MODULE_SCOPE void TkBTreeDeleteIndexRange(TkTextBTree tree, TkTextIndex *index1Ptr, TkTextIndex *index2Ptr); -MODULE_SCOPE int TkBTreeEpoch(TkTextBTree tree); +MODULE_SCOPE TkSizeT TkBTreeEpoch(TkTextBTree tree); MODULE_SCOPE TkTextLine *TkBTreeFindLine(TkTextBTree tree, const TkText *textPtr, int line); MODULE_SCOPE TkTextLine *TkBTreeFindPixelLine(TkTextBTree tree, const TkText *textPtr, int pixels, int *pixelOffset); Index: generic/tkTextBTree.c ================================================================== --- generic/tkTextBTree.c +++ generic/tkTextBTree.c @@ -103,11 +103,11 @@ typedef struct BTree { Node *rootPtr; /* Pointer to root of B-tree. */ int clients; /* Number of clients of this B-tree. */ int pixelReferences; /* Number of clients of this B-tree which care * about pixel heights. */ - int stateEpoch; /* Updated each time any aspect of the B-tree + TkSizeT stateEpoch; /* Updated each time any aspect of the B-tree * changes. */ TkSharedText *sharedTextPtr;/* Used to find tagTable in consistency * checking code, and to access list of all * B-tree clients. */ int startEndCount; @@ -138,14 +138,14 @@ /* * Macros that determine how much space to allocate for new segments: */ -#define CSEG_SIZE(chars) ((unsigned) (Tk_Offset(TkTextSegment, body) \ - + 1 + (chars))) -#define TSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \ - + sizeof(TkTextToggle))) +#define CSEG_SIZE(chars) (Tk_Offset(TkTextSegment, body) \ + + 1 + (chars)) +#define TSEG_SIZE (Tk_Offset(TkTextSegment, body) \ + + sizeof(TkTextToggle)) /* * Forward declarations for functions defined in this file: */ @@ -499,11 +499,11 @@ * None. * *---------------------------------------------------------------------- */ -int +TkSizeT TkBTreeEpoch( TkTextBTree tree) /* Tree to get epoch for. */ { BTree *treePtr = (BTree *) tree; return treePtr->stateEpoch; @@ -797,10 +797,11 @@ if (overwriteWithLast != -1) { nodePtr->numPixels[overwriteWithLast] = nodePtr->numPixels[treePtr->pixelReferences-1]; } if (treePtr->pixelReferences == 1) { + ckfree(nodePtr->numPixels); nodePtr->numPixels = NULL; } else { nodePtr->numPixels = ckrealloc(nodePtr->numPixels, sizeof(int) * (treePtr->pixelReferences - 1)); } @@ -1018,11 +1019,11 @@ * insert at beginning of line. */ TkTextLine *linePtr; /* Current line (new segments are added to * this line). */ register TkTextSegment *segPtr; TkTextLine *newLinePtr; - int chunkSize; /* # characters in current chunk. */ + size_t chunkSize; /* # characters in current chunk. */ register const char *eol; /* Pointer to character just after last one in * current chunk. */ int changeToLineCount; /* Counts change to total number of lines in * file. */ int *changeToPixelCount; /* Counts change to total number of pixels in @@ -1067,11 +1068,11 @@ } else { segPtr->nextPtr = curPtr->nextPtr; curPtr->nextPtr = segPtr; } segPtr->size = chunkSize; - memcpy(segPtr->body.chars, string, (size_t) chunkSize); + memcpy(segPtr->body.chars, string, chunkSize); segPtr->body.chars[chunkSize] = 0; if (eol[-1] != '\n') { break; } @@ -1437,10 +1438,12 @@ prevNodePtr = prevNodePtr->nextPtr; } prevNodePtr->nextPtr = curNodePtr->nextPtr; } parentPtr->numChildren--; + DeleteSummaries(curNodePtr->summaryPtr); + ckfree(curNodePtr->numPixels); ckfree(curNodePtr); curNodePtr = parentPtr; } curNodePtr = curLinePtr->parentPtr; continue; @@ -4183,10 +4186,11 @@ if (nodePtr->parentPtr == NULL) { if ((nodePtr->numChildren == 1) && (nodePtr->level > 0)) { treePtr->rootPtr = nodePtr->children.nodePtr; treePtr->rootPtr->parentPtr = NULL; DeleteSummaries(nodePtr->summaryPtr); + ckfree(nodePtr->numPixels); ckfree(nodePtr); } return; } @@ -4272,10 +4276,11 @@ if (totalChildren <= MAX_CHILDREN) { RecomputeNodeCounts(treePtr, nodePtr); nodePtr->nextPtr = otherPtr->nextPtr; nodePtr->parentPtr->numChildren--; DeleteSummaries(otherPtr->summaryPtr); + ckfree(otherPtr->numPixels); ckfree(otherPtr); continue; } /* @@ -4556,11 +4561,11 @@ newPtr1 = ckalloc(CSEG_SIZE(index)); newPtr2 = ckalloc(CSEG_SIZE(segPtr->size - index)); newPtr1->typePtr = &tkTextCharType; newPtr1->nextPtr = newPtr2; newPtr1->size = index; - memcpy(newPtr1->body.chars, segPtr->body.chars, (size_t) index); + memcpy(newPtr1->body.chars, segPtr->body.chars, index); newPtr1->body.chars[index] = 0; newPtr2->typePtr = &tkTextCharType; newPtr2->nextPtr = segPtr->nextPtr; newPtr2->size = segPtr->size - index; memcpy(newPtr2->body.chars, segPtr->body.chars + index, newPtr2->size); Index: generic/tkTextDisp.c ================================================================== --- generic/tkTextDisp.c +++ generic/tkTextDisp.c @@ -14,16 +14,10 @@ */ #include "tkInt.h" #include "tkText.h" -#ifdef _WIN32 -#include "tkWinInt.h" -#elif defined(__CYGWIN__) -#include "tkUnixInt.h" -#endif - #ifdef MAC_OSX_TK #include "tkMacOSXInt.h" #endif /* @@ -166,11 +160,11 @@ * graphics contexts used to actually draw the characters. The entries in * dInfoPtr->styleTable point to structures of this type. */ typedef struct TextStyle { - int refCount; /* Number of times this structure is + TkSizeT refCount; /* Number of times this structure is * referenced in Chunks. */ GC bgGC; /* Graphics context for background. None means * use widget background. */ GC fgGC; /* Graphics context for foreground. */ GC ulGC; /* Graphics context for underline. */ @@ -404,11 +398,11 @@ * into very many display lines, then this is * used to keep track of what index we've got * to so far... */ int metricPixelHeight; /* ...and this is for the height calculation * so far...*/ - int metricEpoch; /* ...and this for the epoch of the partial + TkSizeT metricEpoch; /* ...and this for the epoch of the partial * calculation so it can be cancelled if * things change once more. This field will be * -1 if there is no long-line calculation in * progress, and take a non-negative value if * there is such a calculation in progress. */ @@ -608,11 +602,11 @@ int *intPtr); static void AsyncUpdateLineMetrics(ClientData clientData); static void GenerateWidgetViewSyncEvent(TkText *textPtr, Bool InSync); static void AsyncUpdateYScrollbar(ClientData clientData); static int IsStartOfNotMergedLine(TkText *textPtr, - CONST TkTextIndex *indexPtr); + const TkTextIndex *indexPtr); /* * Result values returned by TextGetScrollInfoObj: */ @@ -1056,12 +1050,11 @@ FreeStyle( TkText *textPtr, /* Information about overall widget. */ register TextStyle *stylePtr) /* Information about style to free. */ { - stylePtr->refCount--; - if (stylePtr->refCount == 0) { + if (stylePtr->refCount-- <= 1) { if (stylePtr->bgGC != None) { Tk_FreeGC(textPtr->display, stylePtr->bgGC); } if (stylePtr->fgGC != None) { Tk_FreeGC(textPtr->display, stylePtr->fgGC); @@ -3003,11 +2996,11 @@ || !Tk_IsMapped(textPtr->tkwin)) { /* * The widget has been deleted, or is not mapped. Don't do anything. */ - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } return; } @@ -3048,11 +3041,11 @@ /* * If we're not in the middle of a long-line calculation (metricEpoch==-1) * and we've reached the last line, then we're done. */ - if (dInfoPtr->metricEpoch == -1 + if (dInfoPtr->metricEpoch == TCL_AUTO_LENGTH && lineNum == dInfoPtr->lastMetricUpdateLine) { /* * We have looped over all lines, so we're done. We must release our * refCount on the widget (the timer token was already set to NULL * above). If there is a registered aftersync command, run that first. @@ -3078,12 +3071,11 @@ * through the event loop, because the widget redraws at idle-time). */ GenerateWidgetViewSyncEvent(textPtr, 1); - textPtr->refCount--; - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } return; } @@ -3199,11 +3191,11 @@ /* * If we're in the middle of a partial-line height calculation, * then we can't be done. */ - if (textPtr->dInfoPtr->metricEpoch == -1 && lineNum == endLine) { + if (textPtr->dInfoPtr->metricEpoch == TCL_AUTO_LENGTH && lineNum == endLine) { /* * We have looped over all lines, so we're done. */ break; @@ -4119,12 +4111,12 @@ */ TkWindow *winPtr = (TkWindow *)(textPtr->tkwin); MacDrawable *macWin = winPtr->privatePtr; if (macWin && (macWin->flags & TK_DO_NOT_DRAW)){ dInfoPtr->flags &= ~REDRAW_PENDING; - return; - } + return; + } #endif if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { /* * The widget has been deleted. Don't do anything. @@ -4161,11 +4153,11 @@ while (dInfoPtr->flags & REPICK_NEEDED) { textPtr->refCount++; dInfoPtr->flags &= ~REPICK_NEEDED; TkTextPickCurrent(textPtr, &textPtr->pickEvent); - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); goto end; } if ((textPtr->tkwin == NULL) || (textPtr->flags & DESTROYED)) { goto end; @@ -4273,11 +4265,10 @@ if (dlPtr->nextPtr == dlPtr2) { break; } dlPtr = dlPtr->nextPtr; } - /* * Scan through the lines following the copied ones to see if we are * going to overwrite them with the copy operation. If so, mark them * for redisplay. */ @@ -4298,11 +4289,10 @@ damageRgn = TkCreateRegion(); if (TkScrollWindow(textPtr->tkwin, dInfoPtr->scrollGC, dInfoPtr->x, oldY, dInfoPtr->maxX-dInfoPtr->x, height, 0, y-oldY, damageRgn)) { TextInvalidateRegion(textPtr, damageRgn); - } numCopies++; TkDestroyRegion(damageRgn); } @@ -4440,15 +4430,42 @@ #endif /* TK_NO_DOUBLE_BUFFERING */ return; } dlPtr->oldY = dlPtr->y; dlPtr->flags &= ~(NEW_LAYOUT | OLD_Y_INVALID); +#ifdef MAC_OSX_TK + } else if (dlPtr->chunkPtr != NULL) { + /* + * On macOS we need to redisplay all embedded windows which + * were moved by the call to TkScrollWindows above. This is + * not necessary on Unix or Windows because XScrollWindow will + * have included the bounding rectangles of all of these + * windows in the damage region. The macosx implementation of + * TkScrollWindow does not do this. It simply generates a + * damage region which is the scroll source rectangle minus + * the scroll destination rectangle. This is because there is + * no efficient process available for iterating through the + * subwindows which meet the scrolled area. (On Unix this is + * handled by GraphicsExpose events generated by XCopyArea and + * on Windows by ScrollWindowEx. On macOS the low level + * scrolling is accomplished by calling [view scrollRect:by:]. + * This method does not provide any damage information and, in + * any case, could not be aware of Tk windows which were not + * based on NSView objects. + * + * On the other hand, this loop is already iterating through + * all embedded windows which could possibly have been moved + * by the scrolling. So it is as efficient to redisplay them + * here as it would have been if they had been redisplayed by + * the call to TextInvalidateRegion above. + */ +#else } else if (dlPtr->chunkPtr != NULL && ((dlPtr->y < 0) || (dlPtr->y + dlPtr->height > dInfoPtr->maxY))) { - register TkTextDispChunk *chunkPtr; - /* + * On platforms other than the Mac: + * * It's the first or last DLine which are also overlapping the * top or bottom of the window, but we decided above it wasn't * necessary to display them (we were able to update them by * scrolling). This is fine, except that if the lines contain * any embedded windows, we must still call the display proc @@ -4458,10 +4475,12 @@ * doesn't! * * So, we loop through all the chunks, calling the display * proc of embedded windows only. */ +#endif + register TkTextDispChunk *chunkPtr; for (chunkPtr = dlPtr->chunkPtr; (chunkPtr != NULL); chunkPtr = chunkPtr->nextPtr) { int x; if (chunkPtr->displayProc != TkTextEmbWinDisplayProc) { @@ -4480,17 +4499,22 @@ * right). */ x = -chunkPtr->width; } + if (tkTextDebug) { + char string[TK_POS_CHARS]; + + TkTextPrintIndex(textPtr, &dlPtr->index, string); + LOG("tk_textEmbWinDisplay", string); + } TkTextEmbWinDisplayProc(textPtr, chunkPtr, x, dlPtr->spaceAbove, dlPtr->height-dlPtr->spaceAbove-dlPtr->spaceBelow, dlPtr->baseline - dlPtr->spaceAbove, NULL, (Drawable) None, dlPtr->y + dlPtr->spaceAbove); } - } } #ifndef TK_NO_DOUBLE_BUFFERING Tk_FreePixmap(Tk_Display(textPtr->tkwin), pixmap); #endif /* TK_NO_DOUBLE_BUFFERING */ @@ -6056,11 +6080,11 @@ * objv[1] is "yview". */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; int pickPlace, type; int pixels, count; - int switchLength; + size_t switchLength; double fraction; TkTextIndex index; if (dInfoPtr->flags & DINFO_OUT_OF_DATE) { UpdateDisplayInfo(textPtr); @@ -6076,11 +6100,11 @@ */ pickPlace = 0; if (Tcl_GetString(objv[2])[0] == '-') { register const char *switchStr = - Tcl_GetStringFromObj(objv[2], &switchLength); + TkGetStringFromObj(objv[2], &switchLength); if ((switchLength >= 2) && (strncmp(switchStr, "-pickplace", (unsigned) switchLength) == 0)) { pickPlace = 1; if (objc != 4) { @@ -6231,11 +6255,11 @@ TkText *textPtr) /* Information about text widget. */ { TextDInfo *dInfoPtr = textPtr->dInfoPtr; return ( - ((dInfoPtr->metricEpoch == -1) && + ((dInfoPtr->metricEpoch == TCL_AUTO_LENGTH) && (dInfoPtr->lastMetricUpdateLine == dInfoPtr->currentMetricUpdateLine)) ? 0 : 1); } /* @@ -6750,11 +6774,11 @@ if (!(textPtr->flags & DESTROYED)) { GetYView(textPtr->interp, textPtr, 1); } - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } } /* @@ -6888,11 +6912,11 @@ */ static int IsStartOfNotMergedLine( TkText *textPtr, /* Widget record for text widget. */ - CONST TkTextIndex *indexPtr) /* Index to check. */ + const TkTextIndex *indexPtr) /* Index to check. */ { TkTextIndex indexPtr2; if (indexPtr->byteIndex != 0) { /* @@ -7540,10 +7564,13 @@ * characters yet (i.e. the line isn't wide enough to hold even a * single character). * (b) at least one pixel of the character is visible, we have not * already exceeded the character limit, and the next character is a * white space character. + * In the specific case of 'word' wrapping mode however, include all space + * characters following the characters that fit in the space we've got, + * even if no pixel of them is visible. */ p = segPtr->body.chars + byteOffset; tkfont = chunkPtr->stylePtr->sValuePtr->tkfont; @@ -7579,12 +7606,12 @@ chunkPtr->x, maxX, TK_ISOLATE_END, &nextX); #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ if (bytesThatFit < maxBytes) { if ((bytesThatFit == 0) && noCharsYet) { - Tcl_UniChar ch; - int chLen = Tcl_UtfToUniChar(p, &ch); + int ch; + int chLen = TkUtfToUniChar(p, &ch); #if TK_LAYOUT_WITH_BASE_CHUNKS bytesThatFit = CharChunkMeasureChars(chunkPtr, line, lineOffset+chLen, lineOffset, -1, chunkPtr->x, -1, 0, &nextX); @@ -7602,10 +7629,25 @@ */ nextX = maxX; bytesThatFit++; } + if (wrapMode == TEXT_WRAPMODE_WORD) { + while (p[bytesThatFit] == ' ') { + /* + * Space characters that would go at the beginning of the + * next line are allocated to the current line. This gives + * the effect of trimming white spaces that would otherwise + * be seen at the beginning of wrapped lines. + * Note that testing for '\t' is useless here because the + * chunk always includes at most one trailing \t, see + * LayoutDLine. + */ + + bytesThatFit++; + } + } if (p[bytesThatFit] == '\n') { /* * A newline character takes up no space, so if the previous * character fits then so does the newline. */ @@ -7645,11 +7687,11 @@ chunkPtr->minHeight = 0; chunkPtr->width = nextX - chunkPtr->x; chunkPtr->breakIndex = -1; #if !TK_LAYOUT_WITH_BASE_CHUNKS - ciPtr = ckalloc((Tk_Offset(CharInfo, chars) + 1) + bytesThatFit); + ciPtr = ckalloc(Tk_Offset(CharInfo, chars) + 1 + bytesThatFit); chunkPtr->clientData = ciPtr; memcpy(ciPtr->chars, p, (unsigned) bytesThatFit); #endif /* TK_LAYOUT_WITH_BASE_CHUNKS */ ciPtr->numBytes = bytesThatFit; @@ -7799,11 +7841,11 @@ } else { int widthUntilStart = 0; MeasureChars(tkfont, chars, charsLen, 0, bstart, 0, -1, 0, &widthUntilStart); - xDisplacement = startX - widthUntilStart - chunkPtr->x; + xDisplacement = startX - widthUntilStart - ciPtr->baseChunkPtr->x; } fit = MeasureChars(tkfont, chars, charsLen, 0, bend, ciPtr->baseChunkPtr->x + xDisplacement, maxX, flags, nextXPtr); @@ -8773,11 +8815,11 @@ ciPtr->chars = baseChars + ciPtr->baseOffset; #if TK_DRAW_IN_CONTEXT newwidth = 0; CharChunkMeasureChars(chunkPtr, NULL, 0, 0, -1, 0, -1, 0, &newwidth); - if (newwidth != chunkPtr->width) { + if (newwidth < chunkPtr->width) { widthAdjust += newwidth - chunkPtr->width; chunkPtr->width = newwidth; } #endif /* TK_DRAW_IN_CONTEXT */ } @@ -8961,17 +9003,17 @@ * Remove the chunk data from the base chunk data. */ bciPtr = baseCharChunkPtr->clientData; +#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS if ((ciPtr->baseOffset + ciPtr->numBytes) != Tcl_DStringLength(&bciPtr->baseChars)) { -#ifdef DEBUG_LAYOUT_WITH_BASE_CHUNKS fprintf(stderr,"RemoveFromBaseChunk called with wrong chunk " "(not last)\n"); -#endif } +#endif Tcl_DStringSetLength(&bciPtr->baseChars, ciPtr->baseOffset); /* * Invalidate the stored pixel width of the base chunk. Index: generic/tkTextImage.c ================================================================== --- generic/tkTextImage.c +++ generic/tkTextImage.c @@ -16,11 +16,11 @@ /* * Macro that determines the size of an embedded image segment: */ #define EI_SEG_SIZE \ - ((unsigned) (Tk_Offset(TkTextSegment, body) + sizeof(TkTextEmbImage))) + (Tk_Offset(TkTextSegment, body) + sizeof(TkTextEmbImage)) /* * Prototypes for functions defined in this file: */ @@ -159,11 +159,11 @@ "no embedded image at index \"%s\"", Tcl_GetString(objv[3]))); Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL); return TCL_ERROR; } - objPtr = Tk_GetOptionValue(interp, (char *) &eiPtr->body.ei, + objPtr = Tk_GetOptionValue(interp, &eiPtr->body.ei, eiPtr->body.ei.optionTable, objv[4], textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } else { Tcl_SetObjResult(interp, objPtr); @@ -186,11 +186,11 @@ Tcl_SetErrorCode(interp, "TK", "TEXT", "NO_IMAGE", NULL); return TCL_ERROR; } if (objc <= 5) { Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, - (char *) &eiPtr->body.ei, eiPtr->body.ei.optionTable, + &eiPtr->body.ei, eiPtr->body.ei.optionTable, (objc == 5) ? objv[4] : NULL, textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } else { @@ -335,11 +335,11 @@ int dummy; int count = 0; /* The counter for picking a unique name */ int conflict = 0; /* True if we have a name conflict */ size_t len; /* length of image name */ - if (Tk_SetOptions(textPtr->interp, (char *) &eiPtr->body.ei, + if (Tk_SetOptions(textPtr->interp, &eiPtr->body.ei, eiPtr->body.ei.optionTable, objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) { return TCL_ERROR; } Index: generic/tkTextIndex.c ================================================================== --- generic/tkTextIndex.c +++ generic/tkTextIndex.c @@ -9,13 +9,13 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" #include "tkText.h" +#include "default.h" /* * Index to use to select last character in line (very large integer): */ @@ -38,13 +38,13 @@ static const char * StartEnd(TkText *textPtr, const char *string, TkTextIndex *indexPtr); static int GetIndex(Tcl_Interp *interp, TkSharedText *sharedPtr, TkText *textPtr, const char *string, TkTextIndex *indexPtr, int *canCachePtr); -static int IndexCountBytesOrdered(CONST TkText *textPtr, - CONST TkTextIndex *indexPtr1, - CONST TkTextIndex *indexPtr2); +static int IndexCountBytesOrdered(const TkText *textPtr, + const TkTextIndex *indexPtr1, + const TkTextIndex *indexPtr2); /* * The "textindex" Tcl_Obj definition: */ @@ -62,11 +62,11 @@ #define GET_INDEXEPOCH(objPtr) \ (PTR2INT((objPtr)->internalRep.twoPtrValue.ptr2)) #define SET_TEXTINDEX(objPtr, indexPtr) \ ((objPtr)->internalRep.twoPtrValue.ptr1 = (void *) (indexPtr)) #define SET_INDEXEPOCH(objPtr, epoch) \ - ((objPtr)->internalRep.twoPtrValue.ptr2 = INT2PTR(epoch)) + ((objPtr)->internalRep.twoPtrValue.ptr2 = (void *) (size_t) (epoch)) /* * Define the 'textindex' object type, which Tk uses to represent indices in * text widgets internally. */ @@ -85,11 +85,11 @@ * free. */ { TkTextIndex *indexPtr = GET_TEXTINDEX(indexObjPtr); if (indexPtr->textPtr != NULL) { - if (--indexPtr->textPtr->refCount == 0) { + if (indexPtr->textPtr->refCount-- <= 1) { /* * The text widget has been deleted and we need to free it now. */ ckfree(indexPtr->textPtr); @@ -102,11 +102,11 @@ static void DupTextIndexInternalRep( Tcl_Obj *srcPtr, /* TextIndex obj with internal rep to copy. */ Tcl_Obj *copyPtr) /* TextIndex obj with internal rep to set. */ { - int epoch; + TkSizeT epoch; TkTextIndex *dupIndexPtr, *indexPtr; dupIndexPtr = ckalloc(sizeof(TkTextIndex)); indexPtr = GET_TEXTINDEX(srcPtr); epoch = GET_INDEXEPOCH(srcPtr); @@ -132,11 +132,11 @@ static void UpdateStringOfTextIndex( Tcl_Obj *objPtr) { char buffer[TK_POS_CHARS]; - register int len; + size_t len; const TkTextIndex *indexPtr = GET_TEXTINDEX(objPtr); len = TkTextPrintIndex(indexPtr->textPtr, indexPtr, buffer); objPtr->bytes = ckalloc(len + 1); @@ -204,11 +204,11 @@ TkTextIndex index; TkTextIndex *indexPtr = NULL; int cache; if (objPtr->typePtr == &tkTextIndexType) { - int epoch; + TkSizeT epoch; indexPtr = GET_TEXTINDEX(objPtr); epoch = GET_INDEXEPOCH(objPtr); if (epoch == textPtr->sharedTextPtr->stateEpoch) { @@ -385,11 +385,11 @@ TkTextIndex *indexPtr) /* Structure to fill in. */ { TkTextSegment *segPtr; int index; const char *p, *start; - Tcl_UniChar ch; + int ch; indexPtr->tree = tree; if (lineIndex < 0) { lineIndex = 0; byteIndex = 0; @@ -435,11 +435,11 @@ * adjusted to the end of that UTF-8 character. */ start = segPtr->body.chars + (byteIndex - index); p = Tcl_UtfPrev(start, segPtr->body.chars); - p += Tcl_UtfToUniChar(p, &ch); + p += TkUtfToUniChar(p, &ch); indexPtr->byteIndex += p - start; } break; } index += segPtr->size; @@ -478,11 +478,11 @@ TkTextIndex *indexPtr) /* Structure to fill in. */ { register TkTextSegment *segPtr; char *p, *start, *end; int index, offset; - Tcl_UniChar ch; + int ch; indexPtr->tree = tree; if (lineIndex < 0) { lineIndex = 0; charIndex = 0; @@ -525,11 +525,11 @@ if (charIndex == 0) { indexPtr->byteIndex = index; return indexPtr; } charIndex--; - offset = Tcl_UtfToUniChar(p, &ch); + offset = TkUtfToUniChar(p, &ch); index += offset; } } else { if (charIndex < segPtr->size) { indexPtr->byteIndex = index; @@ -921,11 +921,11 @@ goto gotBase; } } if ((string[0] == 'e') && (strncmp(string, "end", - (size_t) (endOfBase-Tcl_DStringValue(©))) == 0)) { + endOfBase-Tcl_DStringValue(©)) == 0)) { /* * Base position is end of text. */ TkTextMakeByteIndex(sharedPtr->tree, textPtr, @@ -1473,11 +1473,11 @@ TkTextLine *linePtr; TkTextSegment *segPtr; TkTextElideInfo *infoPtr = NULL; int byteOffset; char *start, *end, *p; - Tcl_UniChar ch; + int ch; int elide = 0; int checkElided = (type & COUNT_DISPLAY); if (charCount < 0) { TkTextIndexBackChars(textPtr, srcPtr, -charCount, dstPtr, type); @@ -1572,11 +1572,11 @@ if (!elide) { if (segPtr->typePtr == &tkTextCharType) { start = segPtr->body.chars + byteOffset; end = segPtr->body.chars + segPtr->size; - for (p = start; p < end; p += Tcl_UtfToUniChar(p, &ch)) { + for (p = start; p < end; p += TkUtfToUniChar(p, &ch)) { if (charCount == 0) { dstPtr->byteIndex += (p - start); goto forwardCharDone; } charCount--; @@ -1634,13 +1634,13 @@ *--------------------------------------------------------------------------- */ int TkTextIndexCountBytes( - CONST TkText *textPtr, - CONST TkTextIndex *indexPtr1, /* Index describing one location. */ - CONST TkTextIndex *indexPtr2) /* Index describing second location. */ + const TkText *textPtr, + const TkTextIndex *indexPtr1, /* Index describing one location. */ + const TkTextIndex *indexPtr2) /* Index describing second location. */ { int compare = TkTextIndexCmp(indexPtr1, indexPtr2); if (compare == 0) { return 0; @@ -1651,15 +1651,15 @@ } } static int IndexCountBytesOrdered( - CONST TkText *textPtr, - CONST TkTextIndex *indexPtr1, + const TkText *textPtr, + const TkTextIndex *indexPtr1, /* Index describing location of character from * which to count. */ - CONST TkTextIndex *indexPtr2) + const TkTextIndex *indexPtr2) /* Index describing location of last character * at which to stop the count. */ { int byteCount, offset; TkTextSegment *segPtr, *segPtr1; @@ -2296,13 +2296,13 @@ segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { - Tcl_UniChar ch; + int ch; - chSize = Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); + chSize = TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } firstChar = 0; } @@ -2341,13 +2341,13 @@ segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { int chSize = 1; if (segPtr->typePtr == &tkTextCharType) { - Tcl_UniChar ch; - Tcl_UtfToUniChar(segPtr->body.chars + offset, &ch); + int ch; + TkUtfToUniChar(segPtr->body.chars + offset, &ch); if (!Tcl_UniCharIsWordChar(ch)) { break; } if (offset > 0) { chSize = (segPtr->body.chars + offset Index: generic/tkTextMark.c ================================================================== --- generic/tkTextMark.c +++ generic/tkTextMark.c @@ -17,12 +17,12 @@ /* * Macro that determines the size of a mark segment: */ -#define MSEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \ - + sizeof(TkTextMark))) +#define MSEG_SIZE (Tk_Offset(TkTextSegment, body) \ + + sizeof(TkTextMark)) /* * Forward references for functions defined in this file: */ @@ -124,18 +124,18 @@ } switch ((enum markOptions) optionIndex) { case MARK_GRAVITY: { char c; - int length; + size_t length; const char *str; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 3, objv, "markName ?gravity?"); return TCL_ERROR; } - str = Tcl_GetStringFromObj(objv[3], &length); + str = TkGetStringFromObj(objv[3], &length); if (length == 6 && !strcmp(str, "insert")) { markPtr = textPtr->insertMarkPtr; } else if (length == 7 && !strcmp(str, "current")) { markPtr = textPtr->currentMarkPtr; } else { @@ -158,11 +158,11 @@ typeStr = "left"; } Tcl_SetObjResult(interp, Tcl_NewStringObj(typeStr, -1)); return TCL_OK; } - str = Tcl_GetStringFromObj(objv[4],&length); + str = TkGetStringFromObj(objv[4],&length); c = str[0]; if ((c == 'l') && (strncmp(str, "left", (unsigned) length) == 0)) { newTypePtr = &tkTextLeftMarkType; } else if ((c == 'r') && (strncmp(str, "right", (unsigned) length) == 0)) { Index: generic/tkTextTag.c ================================================================== --- generic/tkTextTag.c +++ generic/tkTextTag.c @@ -10,13 +10,13 @@ * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include "default.h" #include "tkInt.h" #include "tkText.h" +#include "default.h" /* * The 'TkWrapMode' enum in tkText.h is used to define a type for the -wrap * option of tags in a Text widget. These values are used as indices into the * string table below. Tags are allowed an empty wrap value, but the widget as @@ -28,11 +28,11 @@ }; /* * The 'TkTextTabStyle' enum in tkText.h is used to define a type for the * -tabstyle option of the Text widget. These values are used as indices into - * the string table below. Tags are allowed an empty wrap value, but the + * the string table below. Tags are allowed an empty tabstyle value, but the * widget as a whole is not. */ static const char *const tabStyleStrings[] = { "tabular", "wordprocessor", "", NULL @@ -241,10 +241,11 @@ */ TkTextSelectionEvent(textPtr); if (addTag && textPtr->exportSelection + && (!Tcl_IsSafe(textPtr->interp)) && !(textPtr->flags & GOT_SELECTION)) { Tk_OwnSelection(textPtr->tkwin, XA_PRIMARY, TkTextLostSelection, textPtr); textPtr->flags |= GOT_SELECTION; } @@ -340,11 +341,11 @@ tagPtr = FindTag(interp, textPtr, objv[3]); if (tagPtr == NULL) { return TCL_ERROR; } - objPtr = Tk_GetOptionValue(interp, (char *) tagPtr, + objPtr = Tk_GetOptionValue(interp, tagPtr, tagPtr->optionTable, objv[4], textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, objPtr); @@ -359,11 +360,11 @@ "tagName ?-option? ?value? ?-option value ...?"); return TCL_ERROR; } tagPtr = TkTextCreateTag(textPtr, Tcl_GetString(objv[3]), &newTag); if (objc <= 5) { - Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, (char *) tagPtr, + Tcl_Obj *objPtr = Tk_GetOptionInfo(interp, tagPtr, tagPtr->optionTable, (objc == 5) ? objv[4] : NULL, textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; @@ -371,11 +372,11 @@ Tcl_SetObjResult(interp, objPtr); return TCL_OK; } else { int result = TCL_OK; - if (Tk_SetOptions(interp, (char *) tagPtr, tagPtr->optionTable, + if (Tk_SetOptions(interp, tagPtr, tagPtr->optionTable, objc-4, objv+4, textPtr->tkwin, NULL, NULL) != TCL_OK) { return TCL_ERROR; } /* @@ -1105,14 +1106,14 @@ * message. */ TkText *textPtr, /* Widget in which tag is being used. */ Tcl_Obj *tagName) /* Name of desired tag. */ { Tcl_HashEntry *hPtr; - int len; + size_t len; const char *str; - str = Tcl_GetStringFromObj(tagName, &len); + str = TkGetStringFromObj(tagName, &len); if (len == 3 && !strcmp(str, "sel")) { return textPtr->selTagPtr; } hPtr = Tcl_FindHashEntry(&textPtr->sharedTextPtr->tagTable, Tcl_GetString(tagName)); @@ -1256,12 +1257,11 @@ if (tagPtr->textPtr != NULL) { if (textPtr != tagPtr->textPtr) { Tcl_Panic("Tag being deleted from wrong widget"); } - textPtr->refCount--; - if (textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } tagPtr->textPtr = NULL; } @@ -1520,11 +1520,11 @@ } eventPtr->xbutton.state = oldState; } done: - if (--textPtr->refCount == 0) { + if (textPtr->refCount-- <= 1) { ckfree(textPtr); } } /* @@ -1561,11 +1561,12 @@ TkTextIndex index; TkTextTag **oldArrayPtr, **newArrayPtr; TkTextTag **copyArrayPtr = NULL; /* Initialization needed to prevent compiler * warning. */ - int numOldTags, numNewTags, i, j, size, nearby; + int numOldTags, numNewTags, i, j, nearby; + size_t size; XEvent event; /* * If a button is down, then don't do anything at all; we'll be called * again when all buttons are up, and we can repick then. This implements @@ -1654,11 +1655,11 @@ SortTags(textPtr->numCurTags, textPtr->curTagArrayPtr); if (numNewTags > 0) { size = numNewTags * sizeof(TkTextTag *); copyArrayPtr = ckalloc(size); - memcpy(copyArrayPtr, newArrayPtr, (size_t) size); + memcpy(copyArrayPtr, newArrayPtr, size); for (i = 0; i < textPtr->numCurTags; i++) { for (j = 0; j < numNewTags; j++) { if (textPtr->curTagArrayPtr[i] == copyArrayPtr[j]) { textPtr->curTagArrayPtr[i] = NULL; copyArrayPtr[j] = NULL; Index: generic/tkTextWind.c ================================================================== --- generic/tkTextWind.c +++ generic/tkTextWind.c @@ -33,12 +33,12 @@ /* * Macro that determines the size of an embedded window segment: */ -#define EW_SEG_SIZE ((unsigned) (Tk_Offset(TkTextSegment, body) \ - + sizeof(TkTextEmbWindow))) +#define EW_SEG_SIZE (Tk_Offset(TkTextSegment, body) \ + + sizeof(TkTextEmbWindow)) /* * Prototypes for functions defined in this file: */ @@ -189,11 +189,11 @@ ewPtr->body.ew.tkwin = client->tkwin; } else { ewPtr->body.ew.tkwin = NULL; } - objPtr = Tk_GetOptionValue(interp, (char *) &ewPtr->body.ew, + objPtr = Tk_GetOptionValue(interp, &ewPtr->body.ew, ewPtr->body.ew.optionTable, objv[4], textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } Tcl_SetObjResult(interp, objPtr); @@ -231,11 +231,11 @@ ewPtr->body.ew.tkwin = client->tkwin; } else { ewPtr->body.ew.tkwin = NULL; } - objPtr = Tk_GetOptionInfo(interp, (char *) &ewPtr->body.ew, + objPtr = Tk_GetOptionInfo(interp, &ewPtr->body.ew, ewPtr->body.ew.optionTable, (objc == 5) ? objv[4] : NULL, textPtr->tkwin); if (objPtr == NULL) { return TCL_ERROR; } @@ -401,11 +401,11 @@ } else { ewPtr->body.ew.tkwin = NULL; } oldWindow = ewPtr->body.ew.tkwin; - if (Tk_SetOptions(textPtr->interp, (char *) &ewPtr->body.ew, + if (Tk_SetOptions(textPtr->interp, &ewPtr->body.ew, ewPtr->body.ew.optionTable, objc, objv, textPtr->tkwin, NULL, NULL) != TCL_OK) { return TCL_ERROR; } Index: generic/tkUtil.c ================================================================== --- generic/tkUtil.c +++ generic/tkUtil.c @@ -727,15 +727,15 @@ double *dblPtr, /* Filled in with argument "moveto" option, if * any. */ int *intPtr) /* Filled in with number of pages or lines to * scroll, if any. */ { - const char *arg = Tcl_GetString(objv[2]); - size_t length = objv[2]->length; + size_t length; + const char *arg = TkGetStringFromObj(objv[2], &length); #define ArgPfxEq(str) \ - ((arg[0] == str[0]) && !strncmp(arg, str, (unsigned)length)) + ((arg[0] == str[0]) && !strncmp(arg, str, length)) if (ArgPfxEq("moveto")) { if (objc != 4) { Tcl_WrongNumArgs(interp, 2, objv, "moveto fraction"); return TK_SCROLL_ERROR; @@ -751,12 +751,11 @@ } if (Tcl_GetIntFromObj(interp, objv[3], intPtr) != TCL_OK) { return TK_SCROLL_ERROR; } - arg = Tcl_GetString(objv[4]); - length = objv[4]->length; + arg = TkGetStringFromObj(objv[4], &length); if (ArgPfxEq("pages")) { return TK_SCROLL_PAGES; } else if (ArgPfxEq("units")) { return TK_SCROLL_UNITS; } @@ -1185,17 +1184,117 @@ event.general.xany.send_event = False; event.general.xany.window = Tk_WindowId(target); event.general.xany.display = Tk_Display(target); event.virtual.name = Tk_GetUid(eventName); if (detail != NULL) { - event.virtual.user_data = detail; + event.virtual.user_data = detail; } Tk_QueueWindowEvent(&event.general, TCL_QUEUE_TAIL); } + +#if TCL_UTF_MAX <= 4 +/* + *--------------------------------------------------------------------------- + * + * TkUtfToUniChar -- + * + * Almost the same as Tcl_UtfToUniChar but using int instead of Tcl_UniChar. + * This function is capable of collapsing a upper/lower surrogate pair to a + * single unicode character. So, up to 6 bytes might be consumed. + * + * Results: + * *chPtr is filled with the Tcl_UniChar, and the return value is the + * number of bytes from the UTF-8 string that were consumed. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +size_t +TkUtfToUniChar( + const char *src, /* The UTF-8 string. */ + int *chPtr) /* Filled with the Tcl_UniChar represented by + * the UTF-8 string. */ +{ + Tcl_UniChar uniChar = 0; + + size_t len = Tcl_UtfToUniChar(src, &uniChar); + if ((uniChar & 0xfc00) == 0xd800) { + Tcl_UniChar high = uniChar; + /* This can only happen if Tcl is compiled with TCL_UTF_MAX=4, + * or when a high surrogate character is detected in UTF-8 form */ + size_t len2 = Tcl_UtfToUniChar(src+len, &uniChar); + if ((uniChar & 0xfc00) == 0xdc00) { + *chPtr = (((high & 0x3ff) << 10) | (uniChar & 0x3ff)) + 0x10000; + len += len2; + } else { + *chPtr = high; + } + } else { + *chPtr = uniChar; + } + return len; +} + +/* + *--------------------------------------------------------------------------- + * + * TkUniCharToUtf -- + * + * Almost the same as Tcl_UniCharToUtf but producing surrogates if + * TCL_UTF_MAX==3. So, up to 6 bytes might be produced. + * + * Results: + * *buf is filled with the UTF-8 string, and the return value is the + * number of bytes produced. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +size_t TkUniCharToUtf(int ch, char *buf) +{ + size_t size = Tcl_UniCharToUtf(ch, buf); + if ((((unsigned)(ch - 0x10000) <= 0xFFFFF)) && (size < 4)) { + /* Hey, this is wrong, we must be running TCL_UTF_MAX==3 + * The best thing we can do is spit out 2 surrogates */ + ch -= 0x10000; + size = Tcl_UniCharToUtf(((ch >> 10) | 0xd800), buf); + size += Tcl_UniCharToUtf(((ch & 0x3ff) | 0xdc00), buf+size); + } + return size; +} + + +#endif + +unsigned char * +TkGetByteArrayFromObj( + Tcl_Obj *objPtr, + size_t *lengthPtr +) { + int length; + + unsigned char *result = Tcl_GetByteArrayFromObj(objPtr, &length); +#if TCL_MAJOR_VERSION > 8 + if (sizeof(TCL_HASH_TYPE) > sizeof(int)) { + /* 64-bit and TIP #494 situation: */ + *lengthPtr = *(TCL_HASH_TYPE *) objPtr->internalRep.twoPtrValue.ptr1; + } else +#endif + /* 32-bit or without TIP #494 */ + *lengthPtr = (size_t) (unsigned) length; + return result; +} + /* * Local Variables: * mode: c * c-basic-offset: 4 * fill-column: 78 * End: */ Index: generic/tkVisual.c ================================================================== --- generic/tkVisual.c +++ generic/tkVisual.c @@ -19,13 +19,13 @@ * associated X class symbols. */ typedef struct VisualDictionary { const char *name; /* Textual name of class. */ - int minLength; /* Minimum # characters that must be specified + unsigned short minLength; /* Minimum # characters that must be specified * for an unambiguous match. */ - int class; /* X symbol for class. */ + short class; /* X symbol for class. */ } VisualDictionary; static const VisualDictionary visualNames[] = { {"best", 1, 0}, {"directcolor", 2, DirectColor}, {"grayscale", 1, GrayScale}, @@ -44,11 +44,11 @@ */ struct TkColormap { Colormap colormap; /* X's identifier for the colormap. */ Visual *visual; /* Visual for which colormap was allocated. */ - int refCount; /* How many uses of the colormap are still + size_t refCount; /* How many uses of the colormap are still * outstanding (calls to Tk_GetColormap minus * calls to Tk_FreeColormap). */ int shareable; /* 0 means this colormap was allocated by a * call to Tk_GetColormap with "new", implying * that the window wants it all for itself. 1 @@ -97,11 +97,11 @@ { Tk_Window tkwin2; XVisualInfo template, *visInfoList, *bestPtr; long mask; Visual *visual; - ptrdiff_t length; + size_t length; int c, numVisuals, prio, bestPrio, i; const char *p; const VisualDictionary *dictPtr; TkColormap *cmapPtr; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; @@ -135,11 +135,11 @@ *colormapPtr = Tk_Colormap(tkwin2); for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == *colormapPtr) { - cmapPtr->refCount += 1; + cmapPtr->refCount++; break; } } } return visual; @@ -193,12 +193,11 @@ } length = p - string; template.class = -1; for (dictPtr = visualNames; dictPtr->name != NULL; dictPtr++) { if ((dictPtr->name[0] == c) && (length >= dictPtr->minLength) - && (strncmp(string, dictPtr->name, - (size_t) length) == 0)) { + && (strncmp(string, dictPtr->name, length) == 0)) { template.class = dictPtr->class; break; } } if (template.class == -1) { @@ -322,11 +321,11 @@ } else { for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->shareable && (cmapPtr->visual == visual)) { *colormapPtr = cmapPtr->colormap; - cmapPtr->refCount += 1; + cmapPtr->refCount++; goto done; } } cmapPtr = ckalloc(sizeof(TkColormap)); cmapPtr->colormap = XCreateColormap(Tk_Display(tkwin), @@ -425,11 +424,11 @@ */ for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == colormap) { - cmapPtr->refCount += 1; + cmapPtr->refCount++; } } return colormap; } @@ -474,12 +473,11 @@ Tcl_Panic("unknown display passed to Tk_FreeColormap"); } for (prevPtr = NULL, cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; prevPtr = cmapPtr, cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == colormap) { - cmapPtr->refCount -= 1; - if (cmapPtr->refCount == 0) { + if (cmapPtr->refCount-- <= 1) { XFreeColormap(display, colormap); if (prevPtr == NULL) { dispPtr->cmapPtr = cmapPtr->nextPtr; } else { prevPtr->nextPtr = cmapPtr->nextPtr; @@ -532,11 +530,11 @@ Tcl_Panic("unknown display passed to Tk_PreserveColormap"); } for (cmapPtr = dispPtr->cmapPtr; cmapPtr != NULL; cmapPtr = cmapPtr->nextPtr) { if (cmapPtr->colormap == colormap) { - cmapPtr->refCount += 1; + cmapPtr->refCount++; return; } } } Index: generic/tkWindow.c ================================================================== --- generic/tkWindow.c +++ generic/tkWindow.c @@ -236,10 +236,12 @@ static void TkCloseDisplay( TkDisplay *dispPtr) { TkClipCleanup(dispPtr); + + TkpCancelWarp(dispPtr); if (dispPtr->name != NULL) { ckfree(dispPtr->name); } @@ -332,10 +334,11 @@ /* * Create built-in photo image formats. */ + Tk_CreatePhotoImageFormat(&tkImgFmtDefault); Tk_CreatePhotoImageFormat(&tkImgFmtGIF); Tk_CreatePhotoImageFormat(&tkImgFmtPNG); Tk_CreatePhotoImageFormat(&tkImgFmtPPM); } @@ -353,10 +356,13 @@ /* * Set the flags specified in the call. */ +#ifdef TK_USE_INPUT_METHODS + winPtr->ximGeneration = 0; +#endif /*TK_USE_INPUT_METHODS*/ winPtr->flags |= flags; /* * Force the window to use a border pixel instead of border pixmap. This * is needed for the case where the window doesn't use the default visual. @@ -648,10 +654,11 @@ } winPtr->dirtyAtts = CWEventMask|CWColormap|CWBitGravity; winPtr->flags = 0; winPtr->handlerList = NULL; #ifdef TK_USE_INPUT_METHODS + winPtr->ximGeneration = 0; winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ winPtr->tagPtr = NULL; winPtr->numTags = 0; winPtr->optionLevel = -1; @@ -941,11 +948,11 @@ Tcl_HideCommand(interp, cmdPtr->name, cmdPtr->name); } } /* - * Set variables for the intepreter. + * Set variables for the interpreter. */ Tcl_SetVar2(interp, "tk_patchLevel", NULL, TK_PATCH_LEVEL, TCL_GLOBAL_ONLY); Tcl_SetVar2(interp, "tk_version", NULL, TK_VERSION, TCL_GLOBAL_ONLY); @@ -1127,11 +1134,11 @@ { #define FIXED_SPACE 5 char fixedSpace[FIXED_SPACE+1]; char *p; Tk_Window parent; - int numChars; + size_t numChars; /* * Strip the parent's name out of pathName (it's everything up to the last * dot). There are two tricky parts: (a) must copy the parent's name * somewhere else to avoid modifying the pathName string (for large names, @@ -1144,21 +1151,21 @@ Tcl_SetObjResult(interp, Tcl_ObjPrintf( "bad window path name \"%s\"", pathName)); Tcl_SetErrorCode(interp, "TK", "VALUE", "WINDOW_PATH", NULL); return NULL; } - numChars = (int) (p-pathName); + numChars = p-pathName; if (numChars > FIXED_SPACE) { p = ckalloc(numChars + 1); } else { p = fixedSpace; } if (numChars == 0) { *p = '.'; p[1] = '\0'; } else { - strncpy(p, pathName, (size_t) numChars); + strncpy(p, pathName, numChars); p[numChars] = '\0'; } /* * Find the parent window. @@ -1440,14 +1447,15 @@ winPtr->window = None; } UnlinkWindow(winPtr); TkEventDeadWindow(winPtr); #ifdef TK_USE_INPUT_METHODS - if (winPtr->inputContext != NULL) { + if (winPtr->inputContext != NULL && + winPtr->ximGeneration == winPtr->dispPtr->ximGeneration) { XDestroyIC(winPtr->inputContext); - winPtr->inputContext = NULL; } + winPtr->inputContext = NULL; #endif /* TK_USE_INPUT_METHODS */ if (winPtr->tagPtr != NULL) { TkFreeBindingTags(winPtr); } TkOptionDeadWindow(winPtr); @@ -1477,12 +1485,11 @@ * window. */ winPtr->mainPtr->deletionEpoch++; } - winPtr->mainPtr->refCount--; - if (winPtr->mainPtr->refCount == 0) { + if (winPtr->mainPtr->refCount-- <= 1) { register const TkCmd *cmdPtr; /* * We just deleted the last window in the application. Delete the * TkMainInfo structure too and replace all of Tk's commands with @@ -2776,10 +2783,22 @@ interp = tsdPtr->mainWindowList->interp; Tcl_Preserve(interp); Tk_DestroyWindow((Tk_Window) tsdPtr->mainWindowList->winPtr); Tcl_Release(interp); } + + /* + * Let error handlers catch up before actual close of displays. + * Must be done before tsdPtr->displayList is cleared, otherwise + * ErrorProc() in tkError.c cannot associate the pending X errors + * to the remaining error handlers. + */ + + for (dispPtr = tsdPtr->displayList; dispPtr != NULL; + dispPtr = dispPtr->nextPtr) { + XSync(dispPtr->display, False); + } /* * Iterate destroying the displays until no more displays remain. It is * possible for displays to get recreated during exit by any code that * calls GetScreen, so we must destroy these new displays as well as the @@ -3039,11 +3058,11 @@ /* * Ensure that we are getting a compatible version of Tcl. */ - if (Tcl_InitStubs(interp, "8.6", 0) == NULL) { + if (Tcl_InitStubs(interp, "8.6-", 0) == NULL) { return TCL_ERROR; } /* * Ensure that our obj-types are registered with the Tcl runtime. @@ -3099,11 +3118,11 @@ cmd = Tcl_NewListObj(2, NULL); Tcl_ListObjAppendElement(NULL, cmd, Tcl_NewStringObj("::safe::TkInit", -1)); Tcl_ListObjAppendElement(NULL, cmd, Tcl_GetObjResult(master)); - + /* * Step 2 : Eval in the master. The argument is the *reversed* interp * path of the slave. */ @@ -3181,12 +3200,12 @@ /* * The -class argument is always the ToTitle of the -name */ { - int numBytes; - const char *bytes = Tcl_GetStringFromObj(nameObj, &numBytes); + size_t numBytes; + const char *bytes = TkGetStringFromObj(nameObj, &numBytes); classObj = Tcl_NewStringObj(bytes, numBytes); numBytes = Tcl_UtfToTitle(Tcl_GetString(classObj)); Tcl_SetObjLength(classObj, numBytes); Index: generic/ttk/ttkBlink.c ================================================================== --- generic/ttk/ttkBlink.c +++ generic/ttk/ttkBlink.c @@ -12,11 +12,11 @@ * * TODO: * Add script-level access to configure application-wide blink rate. */ -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #define DEF_CURSOR_ON_TIME 600 /* milliseconds */ #define DEF_CURSOR_OFF_TIME 300 /* milliseconds */ Index: generic/ttk/ttkButton.c ================================================================== --- generic/ttk/ttkButton.c +++ generic/ttk/ttkButton.c @@ -2,12 +2,11 @@ * Copyright (c) 2003, Joe English * * label, button, checkbutton, radiobutton, and menubutton widgets. */ -#include -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" /* Bit fields for OptionSpec mask field: */ @@ -21,10 +20,11 @@ { /* * Text element resources: */ Tcl_Obj *textObj; + Tcl_Obj *justifyObj; Tcl_Obj *textVariableObj; Tcl_Obj *underlineObj; Tcl_Obj *widthObj; Ttk_TraceHandle *textVariableTrace; @@ -54,10 +54,13 @@ BasePart base; } Base; static Tk_OptionSpec BaseOptionSpecs[] = { + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + "left", Tk_Offset(Base,base.justifyObj), -1, + TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, {TK_OPTION_STRING, "-text", "text", "Text", "", Tk_Offset(Base,base.textObj), -1, 0,0,GEOMETRY_CHANGED }, {TK_OPTION_STRING, "-textvariable", "textVariable", "Variable", "", Tk_Offset(Base,base.textVariableObj), -1, @@ -133,10 +136,19 @@ if (basePtr->base.textVariableTrace) Ttk_UntraceVariable(basePtr->base.textVariableTrace); if (basePtr->base.imageSpec) TtkFreeImageSpec(basePtr->base.imageSpec); } + +static void +BaseImageChanged( + ClientData clientData, int x, int y, int width, int height, + int imageWidth, int imageHeight) +{ + Base *basePtr = (Base *)clientData; + TtkResizeWidget(&basePtr->core); +} static int BaseConfigure(Tcl_Interp *interp, void *recordPtr, int mask) { Base *basePtr = recordPtr; Tcl_Obj *textVarName = basePtr->base.textVariableObj; @@ -147,12 +159,12 @@ vt = Ttk_TraceVariable(interp,textVarName,TextVariableChanged,basePtr); if (!vt) return TCL_ERROR; } if (basePtr->base.imageObj) { - imageSpec = TtkGetImageSpec( - interp, basePtr->core.tkwin, basePtr->base.imageObj); + imageSpec = TtkGetImageSpecEx( + interp, basePtr->core.tkwin, basePtr->base.imageObj, BaseImageChanged, basePtr); if (!imageSpec) { goto error; } } @@ -478,24 +490,29 @@ static int CheckbuttonConfigure(Tcl_Interp *interp, void *recordPtr, int mask) { Checkbutton *checkPtr = recordPtr; - Ttk_TraceHandle *vt = Ttk_TraceVariable( - interp, checkPtr->checkbutton.variableObj, - CheckbuttonVariableChanged, checkPtr); + Tcl_Obj *varName = checkPtr->checkbutton.variableObj; + Ttk_TraceHandle *vt = NULL; - if (!vt) { - return TCL_ERROR; + if (varName != NULL && *Tcl_GetString(varName) != '\0') { + vt = Ttk_TraceVariable(interp, varName, + CheckbuttonVariableChanged, checkPtr); + if (!vt) { + return TCL_ERROR; + } } if (BaseConfigure(interp, recordPtr, mask) != TCL_OK){ Ttk_UntraceVariable(vt); return TCL_ERROR; } - Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace); + if (checkPtr->checkbutton.variableTrace) { + Ttk_UntraceVariable(checkPtr->checkbutton.variableTrace); + } checkPtr->checkbutton.variableTrace = vt; return TCL_OK; } @@ -537,14 +554,17 @@ if (corePtr->state & TTK_STATE_SELECTED) newValue = checkPtr->checkbutton.offValueObj; else newValue = checkPtr->checkbutton.onValueObj; - if (Tcl_ObjSetVar2(interp, - checkPtr->checkbutton.variableObj, NULL, newValue, - TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) - == NULL) + if (checkPtr->checkbutton.variableObj == NULL || + *Tcl_GetString(checkPtr->checkbutton.variableObj) == '\0') + CheckbuttonVariableChanged(checkPtr, Tcl_GetString(newValue)); + else if (Tcl_ObjSetVar2(interp, + checkPtr->checkbutton.variableObj, NULL, newValue, + TCL_GLOBAL_ONLY|TCL_LEAVE_ERR_MSG) + == NULL) return TCL_ERROR; if (WidgetDestroyed(corePtr)) return TCL_ERROR; Index: generic/ttk/ttkCache.c ================================================================== --- generic/ttk/ttkCache.c +++ generic/ttk/ttkCache.c @@ -26,12 +26,11 @@ * * @@@ Colormap flashing on PseudoColor visuals is still possible, * but this will be a transient effect. */ -#include /* for sprintf */ -#include +#include "tkInt.h" #include "ttkTheme.h" struct Ttk_ResourceCache_ { Tcl_Interp *interp; /* Interpreter for error reporting */ Tk_Window tkwin; /* Cache window. */ Index: generic/ttk/ttkClamTheme.c ================================================================== --- generic/ttk/ttkClamTheme.c +++ generic/ttk/ttkClamTheme.c @@ -2,15 +2,15 @@ * Copyright (C) 2004 Joe English * * "clam" theme; inspired by the XFCE family of Gnome themes. */ -#include +#include "tkInt.h" #include "ttkTheme.h" -/* - * Under windows, the Tk-provided XDrawLine and XDrawArc have an +/* + * Under windows, the Tk-provided XDrawLine and XDrawArc have an * off-by-one error in the end point. This is especially apparent with this * theme. Defining this macro as true handles this case. */ #if defined(_WIN32) && !defined(WIN32_XDRAWLINE_HACK) # define WIN32_XDRAWLINE_HACK 1 @@ -121,12 +121,12 @@ }; /* * <>: -borderwidth is only partially supported: * in this theme, borders are always exactly 2 pixels thick. - * With -borderwidth 0, border is not drawn at all; - * otherwise a 2-pixel border is used. For -borderwidth > 2, + * With -borderwidth 0, border is not drawn at all; + * otherwise a 2-pixel border is used. For -borderwidth > 2, * the excess is used as padding. */ static void BorderElementSize( void *clientData, void *elementRecord, Tk_Window tkwin, @@ -400,11 +400,11 @@ } MenuIndicatorElement; static Ttk_ElementOptionSpec MenuIndicatorElementOptions[] = { { "-arrowsize", TK_OPTION_PIXELS, - Tk_Offset(MenuIndicatorElement,sizeObj), + Tk_Offset(MenuIndicatorElement,sizeObj), STR(MENUBUTTON_ARROW_SIZE)}, { "-arrowcolor",TK_OPTION_COLOR, Tk_Offset(MenuIndicatorElement,colorObj), "black" }, { "-arrowpadding",TK_OPTION_STRING, @@ -628,11 +628,11 @@ */ Ttk_GetOrientFromObj(NULL, sb->orientObj, &orient); Tcl_GetIntFromObj(NULL, sb->gripCountObj, &gripCount); lightGC = Ttk_GCForColor(tkwin,sb->lightColorObj,d); darkGC = Ttk_GCForColor(tkwin,sb->borderColorObj,d); - + if (orient == TTK_ORIENT_HORIZONTAL) { dx = 1; dy = 0; x1 = x2 = b.x + b.width / 2 - gripCount; y1 = b.y + 2; y2 = b.y + b.height - 3 + w; @@ -708,16 +708,16 @@ static void PbarElementDraw( void *clientData, void *elementRecord, Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned state) { ScrollbarElement *sb = elementRecord; - + b = Ttk_PadBox(b, Ttk_UniformPadding(2)); if (b.width > 4 && b.height > 4) { DrawSmoothBorder(tkwin, d, b, sb->borderColorObj, sb->lightColorObj, sb->darkColorObj); - XFillRectangle(Tk_Display(tkwin), d, + XFillRectangle(Tk_Display(tkwin), d, BackgroundGC(tkwin, sb->backgroundObj), b.x+2, b.y+2, b.width-4, b.height-4); } } @@ -778,12 +778,12 @@ }; /*------------------------------------------------------------------------ * +++ Notebook elements. - * - * Note: Tabs, except for the rightmost, overlap the neighbor to + * + * Note: Tabs, except for the rightmost, overlap the neighbor to * their right by one pixel. */ typedef struct { Tcl_Obj *backgroundObj; Index: generic/ttk/ttkClassicTheme.c ================================================================== --- generic/ttk/ttkClassicTheme.c +++ generic/ttk/ttkClassicTheme.c @@ -3,11 +3,11 @@ * * "classic" theme; implements the classic Motif-like Tk look. * */ -#include +#include "tkInt.h" #include #include #include "ttkTheme.h" #define DEFAULT_BORDERWIDTH "2" @@ -66,11 +66,11 @@ HighlightElementDraw }; /*------------------------------------------------------------------------ * +++ Button Border element: - * + * * The Motif-style button border on X11 consists of (from outside-in): * * + focus indicator (controlled by -highlightcolor and -highlightthickness), * + default ring (if -default active; blank if -default normal) * + shaded border (controlled by -background, -borderwidth, and -relief) @@ -83,17 +83,17 @@ Tcl_Obj *defaultStateObj; } ButtonBorderElement; static Ttk_ElementOptionSpec ButtonBorderElementOptions[] = { - { "-background", TK_OPTION_BORDER, + { "-background", TK_OPTION_BORDER, Tk_Offset(ButtonBorderElement,borderObj), DEFAULT_BACKGROUND }, - { "-borderwidth", TK_OPTION_PIXELS, + { "-borderwidth", TK_OPTION_PIXELS, Tk_Offset(ButtonBorderElement,borderWidthObj), DEFAULT_BORDERWIDTH }, - { "-relief", TK_OPTION_RELIEF, + { "-relief", TK_OPTION_RELIEF, Tk_Offset(ButtonBorderElement,reliefObj), "flat" }, - { "-default", TK_OPTION_ANY, + { "-default", TK_OPTION_ANY, Tk_Offset(ButtonBorderElement,defaultStateObj), "disabled" }, { NULL, 0, 0, NULL } }; static void ButtonBorderElementSize( @@ -113,11 +113,11 @@ *paddingPtr = Ttk_UniformPadding((short)borderWidth); } /* * (@@@ Note: ButtonBorderElement still still still buggy: - * padding for default ring is drawn in the wrong color + * padding for default ring is drawn in the wrong color * when the button is active.) */ static void ButtonBorderElementDraw( void *clientData, void *elementRecord, Tk_Window tkwin, Drawable d, Ttk_Box b, unsigned int state) @@ -279,23 +279,23 @@ /*------------------------------------------------------------------------ * +++ Sash element (for ttk::panedwindow) * - * NOTES: + * NOTES: * * panedwindows with -orient horizontal use vertical sashes, and vice versa. * * Interpretation of -sashrelief 'groove' and 'ridge' are * swapped wrt. the core panedwindow, which (I think) has them backwards. * - * Default -sashrelief is sunken; the core panedwindow has default + * Default -sashrelief is sunken; the core panedwindow has default * -sashrelief raised, but that looks wrong to me. */ static Ttk_Orient SashClientData[] = { - TTK_ORIENT_HORIZONTAL, TTK_ORIENT_VERTICAL + TTK_ORIENT_HORIZONTAL, TTK_ORIENT_VERTICAL }; typedef struct { Tcl_Obj *borderObj; /* background color */ Tcl_Obj *sashReliefObj; /* sash relief */ @@ -304,17 +304,17 @@ Tcl_Obj *handleSizeObj; /* handle width and height */ Tcl_Obj *handlePadObj; /* handle's distance from edge */ } SashElement; static Ttk_ElementOptionSpec SashOptions[] = { - { "-background", TK_OPTION_BORDER, + { "-background", TK_OPTION_BORDER, Tk_Offset(SashElement,borderObj), DEFAULT_BACKGROUND }, - { "-sashrelief", TK_OPTION_RELIEF, + { "-sashrelief", TK_OPTION_RELIEF, Tk_Offset(SashElement,sashReliefObj), "sunken" }, { "-sashthickness", TK_OPTION_PIXELS, Tk_Offset(SashElement,sashThicknessObj), "6" }, - { "-sashpad", TK_OPTION_PIXELS, + { "-sashpad", TK_OPTION_PIXELS, Tk_Offset(SashElement,sashPadObj), "2" }, { "-handlesize", TK_OPTION_PIXELS, Tk_Offset(SashElement,handleSizeObj), "8" }, { "-handlepad", TK_OPTION_PIXELS, Tk_Offset(SashElement,handlePadObj), "8" }, @@ -365,14 +365,14 @@ break; case TK_RELIEF_SUNKEN: case TK_RELIEF_GROOVE: gc1 = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC); gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_LIGHT_GC); break; - case TK_RELIEF_SOLID: + case TK_RELIEF_SOLID: gc1 = gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_DARK_GC); break; - case TK_RELIEF_FLAT: + case TK_RELIEF_FLAT: default: gc1 = gc2 = Tk_3DBorderGC(tkwin, border, TK_3D_FLAT_GC); break; } @@ -396,11 +396,11 @@ hb.x += handlePad; } else { hb = Ttk_StickBox(b, handleSize, handleSize, TTK_STICK_N); hb.y += handlePad; } - Tk_Fill3DRectangle(tkwin, d, border, + Tk_Fill3DRectangle(tkwin, d, border, hb.x, hb.y, hb.width, hb.height, 1, TK_RELIEF_RAISED); } } static Ttk_ElementSpec SashElementSpec = { @@ -493,11 +493,11 @@ Ttk_RegisterElement(interp, theme, "rightarrow", &ArrowElementSpec, &ArrowElements[3]); Ttk_RegisterElement(interp, theme, "arrow", &ArrowElementSpec, &ArrowElements[0]); - Ttk_RegisterElement(interp, theme, "hsash", + Ttk_RegisterElement(interp, theme, "hsash", &SashElementSpec, &SashClientData[0]); Ttk_RegisterElement(interp, theme, "vsash", &SashElementSpec, &SashClientData[1]); /* Index: generic/ttk/ttkDefaultTheme.c ================================================================== --- generic/ttk/ttkDefaultTheme.c +++ generic/ttk/ttkDefaultTheme.c @@ -2,14 +2,11 @@ * Copyright (c) 2003, Joe English * * Tk alternate theme, intended to match the MSUE and Gtk's (old) default theme */ -#include -#include - -#include +#include "tkInt.h" #include #include #include "ttkTheme.h" #if defined(_WIN32) @@ -207,19 +204,25 @@ { XPoint points[4]; ArrowPoints(b, dir, points); XFillPolygon(display, d, gc, points, 3, Convex, CoordModeOrigin); XDrawLines(display, d, gc, points, 4, CoordModeOrigin); + + /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */ + XDrawPoint(display, d, gc, points[2].x, points[2].y); } /*public*/ void TtkDrawArrow( Display *display, Drawable d, GC gc, Ttk_Box b, ArrowDirection dir) { XPoint points[4]; ArrowPoints(b, dir, points); XDrawLines(display, d, gc, points, 4, CoordModeOrigin); + + /* Work around bug [77527326e5] - ttk artifacts on Ubuntu */ + XDrawPoint(display, d, gc, points[2].x, points[2].y); } /* *---------------------------------------------------------------------- * +++ Border element implementation. @@ -678,11 +681,11 @@ Tcl_Obj *directionObj; Tcl_Obj *sizeObj; Tcl_Obj *colorObj; } MenubuttonArrowElement; -static const char *directionStrings[] = { /* See also: button.c */ +static const char *const directionStrings[] = { /* See also: button.c */ "above", "below", "left", "right", "flush", NULL }; enum { POST_ABOVE, POST_BELOW, POST_LEFT, POST_RIGHT, POST_FLUSH }; static Ttk_ElementOptionSpec MenubuttonArrowElementOptions[] = { Index: generic/ttk/ttkElements.c ================================================================== --- generic/ttk/ttkElements.c +++ generic/ttk/ttkElements.c @@ -3,13 +3,11 @@ * * Default implementation for themed elements. * */ -#include -#include -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #define DEFAULT_BORDERWIDTH "2" #define DEFAULT_ARROW_SIZE "15" Index: generic/ttk/ttkEntry.c ================================================================== --- generic/ttk/ttkEntry.c +++ generic/ttk/ttkEntry.c @@ -6,13 +6,11 @@ * Copyright (c) 2000 Ajuba Solutions. * Copyright (c) 2002 ActiveState Corporation. * Copyright (c) 2004 Joe English */ -#include -#include -#include +#include "tkInt.h" #include #include "ttkTheme.h" #include "ttkWidget.h" @@ -71,10 +69,11 @@ */ /* Style parameters: */ typedef struct { + Tcl_Obj *placeholderForegroundObj;/* Foreground color for placeholder text */ Tcl_Obj *foregroundObj; /* Foreground color for normal text */ Tcl_Obj *backgroundObj; /* Entry widget background color */ Tcl_Obj *selBorderObj; /* Border and background for selection */ Tcl_Obj *selBorderWidthObj; /* Width of selection border */ Tcl_Obj *selForegroundObj; /* Foreground color for selected text */ @@ -116,10 +115,12 @@ EntryStyleData styleData; /* Display style data (widget options) */ EntryStyleData styleDefaults;/* Style defaults (fallback values) */ Tcl_Obj *stateObj; /* Compatibility option -- see CheckStateObj */ + Tcl_Obj *placeholderObj; /* Text to display for placeholder text */ + /* * Derived resources: */ Ttk_TraceHandle *textVariableTrace; @@ -145,16 +146,17 @@ #define SCROLLCMD_CHANGED (0x400) /* -xscrollcommand option changed */ /* * Default option values: */ -#define DEF_SELECT_BG "#000000" -#define DEF_SELECT_FG "#ffffff" -#define DEF_INSERT_BG "black" -#define DEF_ENTRY_WIDTH "20" -#define DEF_ENTRY_FONT "TkTextFont" -#define DEF_LIST_HEIGHT "10" +#define DEF_SELECT_BG "#000000" +#define DEF_SELECT_FG "#ffffff" +#define DEF_PLACEHOLDER_FG "#b3b3b3" +#define DEF_INSERT_BG "black" +#define DEF_ENTRY_WIDTH "20" +#define DEF_ENTRY_FONT "TkTextFont" +#define DEF_LIST_HEIGHT "10" static Tk_OptionSpec EntryOptionSpecs[] = { {TK_OPTION_BOOLEAN, "-exportselection", "exportSelection", "ExportSelection", "1", -1, Tk_Offset(Entry, entry.exportSelection), 0,0,0 }, @@ -165,10 +167,13 @@ NULL, -1, Tk_Offset(Entry, entry.invalidCmd), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", "left", -1, Tk_Offset(Entry, entry.justify), 0, 0, GEOMETRY_CHANGED}, + {TK_OPTION_STRING, "-placeholder", "placeHolder", "PlaceHolder", + NULL, Tk_Offset(Entry, entry.placeholderObj), -1, + TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-show", "show", "Show", NULL, -1, Tk_Offset(Entry, entry.showChar), TK_OPTION_NULL_OK, 0, 0}, {TK_OPTION_STRING, "-state", "state", "State", "normal", Tk_Offset(Entry, entry.stateObj), -1, @@ -189,15 +194,19 @@ NULL, -1, Tk_Offset(Entry, entry.xscroll.scrollCmd), TK_OPTION_NULL_OK, 0, SCROLLCMD_CHANGED}, /* EntryStyleData options: */ + {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor", + NULL, Tk_Offset(Entry, entry.styleData.backgroundObj), -1, + TK_OPTION_NULL_OK,0,0}, {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor", NULL, Tk_Offset(Entry, entry.styleData.foregroundObj), -1, TK_OPTION_NULL_OK,0,0}, - {TK_OPTION_COLOR, "-background", "windowColor", "WindowColor", - NULL, Tk_Offset(Entry, entry.styleData.backgroundObj), -1, + {TK_OPTION_COLOR, "-placeholderforeground", "placeholderForeground", + "PlaceholderForeground", NULL, + Tk_Offset(Entry, entry.styleData.placeholderForegroundObj), -1, TK_OPTION_NULL_OK,0,0}, WIDGET_TAKEFOCUS_TRUE, WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs) }; @@ -214,10 +223,11 @@ static void EntryInitStyleDefaults(EntryStyleData *es) { #define INIT(member, value) \ es->member = Tcl_NewStringObj(value, -1); \ Tcl_IncrRefCount(es->member); + INIT(placeholderForegroundObj, DEF_PLACEHOLDER_FG) INIT(foregroundObj, DEFAULT_FOREGROUND) INIT(selBorderObj, DEF_SELECT_BG) INIT(selForegroundObj, DEF_SELECT_FG) INIT(insertColorObj, DEFAULT_FOREGROUND) INIT(selBorderWidthObj, "0") @@ -225,10 +235,11 @@ #undef INIT } static void EntryFreeStyleDefaults(EntryStyleData *es) { + Tcl_DecrRefCount(es->placeholderForegroundObj); Tcl_DecrRefCount(es->foregroundObj); Tcl_DecrRefCount(es->selBorderObj); Tcl_DecrRefCount(es->selForegroundObj); Tcl_DecrRefCount(es->insertColorObj); Tcl_DecrRefCount(es->selBorderWidthObj); @@ -251,10 +262,11 @@ *es = entryPtr->entry.styleDefaults; # define INIT(member, name) \ if ((tmp=Ttk_QueryOption(entryPtr->core.layout,name,state))) \ es->member=tmp; + INIT(placeholderForegroundObj, "-placeholderforeground"); INIT(foregroundObj, "-foreground"); INIT(selBorderObj, "-selectbackground") INIT(selBorderWidthObj, "-selectborderwidth") INIT(selForegroundObj, "-selectforeground") INIT(insertColorObj, "-insertcolor") @@ -261,10 +273,11 @@ INIT(insertWidthObj, "-insertwidth") #undef INIT /* Reacquire color & border resources from resource cache. */ + es->placeholderForegroundObj = Ttk_UseColor(cache, tkwin, es->placeholderForegroundObj); es->foregroundObj = Ttk_UseColor(cache, tkwin, es->foregroundObj); es->selForegroundObj = Ttk_UseColor(cache, tkwin, es->selForegroundObj); es->insertColorObj = Ttk_UseColor(cache, tkwin, es->insertColorObj); es->selBorderObj = Ttk_UseBorder(cache, tkwin, es->selBorderObj); } @@ -280,15 +293,15 @@ */ static char *EntryDisplayString(const char *showChar, int numChars) { char *displayString, *p; int size; - Tcl_UniChar ch; - char buf[TCL_UTF_MAX]; + int ch; + char buf[6]; - Tcl_UtfToUniChar(showChar, &ch); - size = Tcl_UniCharToUtf(ch, buf); + TkUtfToUniChar(showChar, &ch); + size = TkUniCharToUtf(ch, buf); p = displayString = ckalloc(numChars * size + 1); while (numChars--) { memcpy(p, buf, size); p += size; @@ -302,16 +315,27 @@ * Recompute textLayout, layoutWidth, and layoutHeight * from displayString and fontObj. */ static void EntryUpdateTextLayout(Entry *entryPtr) { + size_t length; + char *text; Tk_FreeTextLayout(entryPtr->entry.textLayout); - entryPtr->entry.textLayout = Tk_ComputeTextLayout( + if ((entryPtr->entry.numChars != 0) || (entryPtr->entry.placeholderObj == NULL)) { + entryPtr->entry.textLayout = Tk_ComputeTextLayout( Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj), entryPtr->entry.displayString, entryPtr->entry.numChars, 0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES, &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight); + } else { + text = TkGetStringFromObj(entryPtr->entry.placeholderObj, &length); + entryPtr->entry.textLayout = Tk_ComputeTextLayout( + Tk_GetFontFromObj(entryPtr->core.tkwin, entryPtr->entry.fontObj), + text, length, + 0/*wraplength*/, entryPtr->entry.justify, TK_IGNORE_NEWLINES, + &entryPtr->entry.layoutWidth, &entryPtr->entry.layoutHeight); + } } /* EntryEditable -- * Returns 1 if the entry widget accepts user changes, 0 otherwise */ @@ -335,11 +359,12 @@ Entry *entryPtr = (Entry *) clientData; size_t byteCount; const char *string; const char *selStart, *selEnd; - if (entryPtr->entry.selectFirst < 0 || !entryPtr->entry.exportSelection) { + if (entryPtr->entry.selectFirst < 0 || (!entryPtr->entry.exportSelection) + || Tcl_IsSafe(entryPtr->core.interp)) { return -1; } string = entryPtr->entry.displayString; selStart = Tcl_UtfAtIndex(string, entryPtr->entry.selectFirst); @@ -370,15 +395,16 @@ TtkRedisplayWidget(&entryPtr->core); } /* EntryOwnSelection -- * Assert ownership of the PRIMARY selection, - * if -exportselection set and selection is present. + * if -exportselection set and selection is present and interp is unsafe. */ static void EntryOwnSelection(Entry *entryPtr) { if (entryPtr->entry.exportSelection + && (!Tcl_IsSafe(entryPtr->core.interp)) && !(entryPtr->core.flags & GOT_SELECTION)) { Tk_OwnSelection(entryPtr->core.tkwin, XA_PRIMARY, EntryLostSelection, (ClientData) entryPtr); entryPtr->core.flags |= GOT_SELECTION; } @@ -404,11 +430,11 @@ { int spaceNeeded, cvtFlags; int number, length; const char *string; int stringLength; - Tcl_UniChar ch; + int ch; char numStorage[2*TCL_INTEGER_SPACE]; while (*template) { /* Find everything up to the next % character and append it * to the result string. @@ -428,11 +454,11 @@ /* There's a percent sequence here. Process it. */ ++template; /* skip over % */ if (*template != '\0') { - template += Tcl_UtfToUniChar(template, &ch); + template += TkUtfToUniChar(template, &ch); } else { ch = '%'; } stringLength = -1; @@ -478,11 +504,11 @@ break; case 'W': /* widget name */ string = Tk_PathName(entryPtr->core.tkwin); break; default: - length = Tcl_UniCharToUtf(ch, numStorage); + length = TkUniCharToUtf(ch, numStorage); numStorage[length] = '\0'; string = numStorage; break; } @@ -557,11 +583,11 @@ * Call the -invalidcommand if validation fails. * * Returns: * TCL_OK if the change is accepted * TCL_BREAK if the change is rejected - * TCL_ERROR if any errors occured + * TCL_ERROR if any errors occurred * * The change will be rejected if -validatecommand returns 0, * or if -validatecommand or -invalidcommand modifies the value. */ static int @@ -997,11 +1023,12 @@ entryPtr->entry.textVariableTrace = vt; } /* Claim the selection, in case we've suddenly started exporting it. */ - if (entryPtr->entry.exportSelection && entryPtr->entry.selectFirst != -1) { + if (entryPtr->entry.exportSelection && (entryPtr->entry.selectFirst != -1) + && (!Tcl_IsSafe(entryPtr->core.interp))) { EntryOwnSelection(entryPtr); } /* Handle -state compatibility option: */ @@ -1173,10 +1200,11 @@ GC gc; int showSelection, showCursor; Ttk_Box textarea; TkRegion clipRegion; XRectangle rect; + Tcl_Obj *foregroundObj; EntryInitStyleData(entryPtr, &es); textarea = Ttk_ClientRegion(entryPtr->core.layout, "textarea"); showCursor = @@ -1239,10 +1267,11 @@ #endif /* Draw cursor: */ if (showCursor) { + Ttk_Box field = Ttk_ClientRegion(entryPtr->core.layout, "field"); int cursorX = EntryCharPosition(entryPtr, entryPtr->entry.insertPos), cursorY = entryPtr->entry.layoutY, cursorHeight = entryPtr->entry.layoutHeight, cursorWidth = 1; @@ -1252,20 +1281,40 @@ } /* @@@ should: maybe: SetCaretPos even when blinked off */ Tk_SetCaretPos(tkwin, cursorX, cursorY, cursorHeight); - gc = EntryGetGC(entryPtr, es.insertColorObj, clipRegion); + cursorX -= cursorWidth/2; + if (cursorX < field.x) { + cursorX = field.x; + } else if (cursorX + cursorWidth > field.x + field.width) { + cursorX = field.x + field.width - cursorWidth; + } + + gc = EntryGetGC(entryPtr, es.insertColorObj, None); XFillRectangle(Tk_Display(tkwin), d, gc, - cursorX-cursorWidth/2, cursorY, cursorWidth, cursorHeight); - XSetClipMask(Tk_Display(tkwin), gc, None); + cursorX, cursorY, cursorWidth, cursorHeight); Tk_FreeGC(Tk_Display(tkwin), gc); } /* Draw the text: */ - gc = EntryGetGC(entryPtr, es.foregroundObj, clipRegion); + if ((*(entryPtr->entry.displayString) == '\0') + && (entryPtr->entry.placeholderObj != NULL)) { + /* No text displayed, but -placeholder is given */ + if (Tcl_GetCharLength(es.placeholderForegroundObj) > 0) { + foregroundObj = es.placeholderForegroundObj; + } else { + foregroundObj = es.foregroundObj; + } + /* Use placeholder text width */ + leftIndex = 0; + Tcl_GetStringFromObj(entryPtr->entry.placeholderObj,&rightIndex); + } else { + foregroundObj = es.foregroundObj; + } + gc = EntryGetGC(entryPtr, foregroundObj, clipRegion); Tk_DrawTextLayout( Tk_Display(tkwin), d, gc, entryPtr->entry.textLayout, entryPtr->entry.layoutX, entryPtr->entry.layoutY, leftIndex, rightIndex); XSetClipMask(Tk_Display(tkwin), gc, None); @@ -1313,12 +1362,12 @@ Entry *entryPtr, /* Entry widget to query */ Tcl_Obj *indexObj, /* Symbolic index name */ int *indexPtr) /* Return value */ { # define EntryWidth(e) (Tk_Width(entryPtr->core.tkwin)) /* Not Right */ - const char *string = Tcl_GetString(indexObj); - size_t length = indexObj->length; + size_t length; + const char *string = TkGetStringFromObj(indexObj, &length); if (strncmp(string, "end", length) == 0) { *indexPtr = entryPtr->entry.numChars; } else if (strncmp(string, "insert", length) == 0) { *indexPtr = entryPtr->entry.insertPos; Index: generic/ttk/ttkFrame.c ================================================================== --- generic/ttk/ttkFrame.c +++ generic/ttk/ttkFrame.c @@ -2,12 +2,11 @@ * Copyright (c) 2004, Joe English * * ttk::frame and ttk::labelframe widgets. */ -#include - +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #include "ttkManager.h" /* ====================================================================== DELETED generic/ttk/ttkGenStubs.tcl Index: generic/ttk/ttkGenStubs.tcl ================================================================== --- generic/ttk/ttkGenStubs.tcl +++ /dev/null @@ -1,963 +0,0 @@ -# ttkGenStubs.tcl -- -# -# This script generates a set of stub files for a given -# interface. -# -# -# Copyright (c) 1998-1999 by Scriptics Corporation. -# Copyright (c) 2007 Daniel A. Steffen -# -# See the file "license.terms" for information on usage and redistribution -# of this file, and for a DISCLAIMER OF ALL WARRANTIES. -# -# SOURCE: tcl/tools/genStubs.tcl, revision 1.44 -# -# CHANGES: -# + Second argument to "declare" is used as a status guard -# instead of a platform guard. -# + Allow trailing semicolon in function declarations -# - -namespace eval genStubs { - # libraryName -- - # - # The name of the entire library. This value is used to compute - # the USE_*_STUBS macro and the name of the init file. - - variable libraryName "UNKNOWN" - - # interfaces -- - # - # An array indexed by interface name that is used to maintain - # the set of valid interfaces. The value is empty. - - array set interfaces {} - - # curName -- - # - # The name of the interface currently being defined. - - variable curName "UNKNOWN" - - # scspec -- - # - # Storage class specifier for external function declarations. - # Normally "EXTERN", may be set to something like XYZAPI - # - variable scspec "EXTERN" - - # epoch, revision -- - # - # The epoch and revision numbers of the interface currently being defined. - # (@@@TODO: should be an array mapping interface names -> numbers) - # - - variable epoch {} - variable revision 0 - - # hooks -- - # - # An array indexed by interface name that contains the set of - # subinterfaces that should be defined for a given interface. - - array set hooks {} - - # stubs -- - # - # This three dimensional array is indexed first by interface name, - # second by field name, and third by a numeric offset or the - # constant "lastNum". The lastNum entry contains the largest - # numeric offset used for a given interface. - # - # Field "decl,$i" contains the C function specification that - # should be used for the given entry in the stub table. The spec - # consists of a list in the form returned by parseDecl. - # Other fields TBD later. - - array set stubs {} - - # outDir -- - # - # The directory where the generated files should be placed. - - variable outDir . -} - -# genStubs::library -- -# -# This function is used in the declarations file to set the name -# of the library that the interfaces are associated with (e.g. "tcl"). -# This value will be used to define the inline conditional macro. -# -# Arguments: -# name The library name. -# -# Results: -# None. - -proc genStubs::library {name} { - variable libraryName $name -} - -# genStubs::interface -- -# -# This function is used in the declarations file to set the name -# of the interface currently being defined. -# -# Arguments: -# name The name of the interface. -# -# Results: -# None. - -proc genStubs::interface {name} { - variable curName $name - variable interfaces - variable stubs - - set interfaces($name) {} - set stubs($name,lastNum) 0 - return -} - -# genStubs::scspec -- -# -# Define the storage class macro used for external function declarations. -# Typically, this will be a macro like XYZAPI or EXTERN that -# expands to either DLLIMPORT or DLLEXPORT, depending on whether -# -DBUILD_XYZ has been set. -# -proc genStubs::scspec {value} { - variable scspec $value -} - -# genStubs::epoch -- -# -# Define the epoch number for this library. The epoch -# should be incrememented when a release is made that -# contains incompatible changes to the public API. -# -proc genStubs::epoch {value} { - variable epoch $value -} - -# genStubs::hooks -- -# -# This function defines the subinterface hooks for the current -# interface. -# -# Arguments: -# names The ordered list of interfaces that are reachable through the -# hook vector. -# -# Results: -# None. - -proc genStubs::hooks {names} { - variable curName - variable hooks - - set hooks($curName) $names - return -} - -# genStubs::declare -- -# -# This function is used in the declarations file to declare a new -# interface entry. -# -# Arguments: -# index The index number of the interface. -# status Status of the interface: one of "current", -# "deprecated", or "obsolete". -# decl The C function declaration, or {} for an undefined -# entry. -# -# Results: -# None. - -proc genStubs::declare {args} { - variable stubs - variable curName - variable revision - - incr revision - if {[llength $args] == 2} { - lassign $args index decl - set status current - } elseif {[llength $args] == 3} { - lassign $args index status decl - } else { - puts stderr "wrong # args: declare $args" - return - } - - # Check for duplicate declarations, then add the declaration and - # bump the lastNum counter if necessary. - - if {[info exists stubs($curName,decl,$index)]} { - puts stderr "Duplicate entry: $index" - } - regsub -all "\[ \t\n\]+" [string trim $decl] " " decl - set decl [parseDecl $decl] - - set stubs($curName,status,$index) $status - set stubs($curName,decl,$index) $decl - - if {$index > $stubs($curName,lastNum)} { - set stubs($curName,lastNum) $index - } - return -} - -# genStubs::export -- -# -# This function is used in the declarations file to declare a symbol -# that is exported from the library but is not in the stubs table. -# -# Arguments: -# decl The C function declaration, or {} for an undefined -# entry. -# -# Results: -# None. - -proc genStubs::export {args} { - if {[llength $args] != 1} { - puts stderr "wrong # args: export $args" - } - return -} - -# genStubs::rewriteFile -- -# -# This function replaces the machine generated portion of the -# specified file with new contents. It looks for the !BEGIN! and -# !END! comments to determine where to place the new text. -# -# Arguments: -# file The name of the file to modify. -# text The new text to place in the file. -# -# Results: -# None. - -proc genStubs::rewriteFile {file text} { - if {![file exists $file]} { - puts stderr "Cannot find file: $file" - return - } - set in [open ${file} r] - set out [open ${file}.new w] - fconfigure $out -translation lf - - while {![eof $in]} { - set line [gets $in] - if {[string match "*!BEGIN!*" $line]} { - break - } - puts $out $line - } - puts $out "/* !BEGIN!: Do not edit below this line. */" - puts $out $text - while {![eof $in]} { - set line [gets $in] - if {[string match "*!END!*" $line]} { - break - } - } - puts $out "/* !END!: Do not edit above this line. */" - puts -nonewline $out [read $in] - close $in - close $out - file rename -force ${file}.new ${file} - return -} - -# genStubs::addPlatformGuard -- -# -# Wrap a string inside a platform #ifdef. -# -# Arguments: -# plat Platform to test. -# -# Results: -# Returns the original text inside an appropriate #ifdef. - -proc genStubs::addPlatformGuard {plat iftxt {eltxt {}}} { - set text "" - switch $plat { - win { - append text "#ifdef _WIN32 /* WIN */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* WIN */\n${eltxt}" - } - append text "#endif /* WIN */\n" - } - unix { - append text "#if !defined(_WIN32) && !defined(MAC_OSX_TCL)\ - /* UNIX */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* UNIX */\n${eltxt}" - } - append text "#endif /* UNIX */\n" - } - macosx { - append text "#ifdef MAC_OSX_TCL /* MACOSX */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* MACOSX */\n${eltxt}" - } - append text "#endif /* MACOSX */\n" - } - aqua { - append text "#ifdef MAC_OSX_TK /* AQUA */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* AQUA */\n${eltxt}" - } - append text "#endif /* AQUA */\n" - } - x11 { - append text "#if !(defined(_WIN32) || defined(MAC_OSX_TK))\ - /* X11 */\n${iftxt}" - if {$eltxt ne ""} { - append text "#else /* X11 */\n${eltxt}" - } - append text "#endif /* X11 */\n" - } - default { - append text "${iftxt}${eltxt}" - } - } - return $text -} - -# genStubs::emitSlots -- -# -# Generate the stub table slots for the given interface. If there -# are no generic slots, then one table is generated for each -# platform, otherwise one table is generated for all platforms. -# -# Arguments: -# name The name of the interface being emitted. -# textVar The variable to use for output. -# -# Results: -# None. - -proc genStubs::emitSlots {name textVar} { - upvar $textVar text - - forAllStubs $name makeSlot noGuard text {" void (*reserved$i)(void);\n"} - return -} - -# genStubs::parseDecl -- -# -# Parse a C function declaration into its component parts. -# -# Arguments: -# decl The function declaration. -# -# Results: -# Returns a list of the form {returnType name args}. The args -# element consists of a list of type/name pairs, or a single -# element "void". If the function declaration is malformed -# then an error is displayed and the return value is {}. - -proc genStubs::parseDecl {decl} { - if {![regexp {^(.*)\((.*)\);?$} $decl all prefix args]} { - set prefix $decl - set args {} - } - set prefix [string trim $prefix] - if {![regexp {^(.+[ ][*]*)([^ *]+)$} $prefix all rtype fname]} { - puts stderr "Bad return type: $decl" - return - } - set rtype [string trim $rtype] - if {$args eq ""} { - return [list $rtype $fname {}] - } - foreach arg [split $args ,] { - lappend argList [string trim $arg] - } - if {![string compare [lindex $argList end] "..."]} { - set args TCL_VARARGS - foreach arg [lrange $argList 0 end-1] { - set argInfo [parseArg $arg] - if {[llength $argInfo] == 2 || [llength $argInfo] == 3} { - lappend args $argInfo - } else { - puts stderr "Bad argument: '$arg' in '$decl'" - return - } - } - } else { - set args {} - foreach arg $argList { - set argInfo [parseArg $arg] - if {![string compare $argInfo "void"]} { - lappend args "void" - break - } elseif {[llength $argInfo] == 2 || [llength $argInfo] == 3} { - lappend args $argInfo - } else { - puts stderr "Bad argument: '$arg' in '$decl'" - return - } - } - } - return [list $rtype $fname $args] -} - -# genStubs::parseArg -- -# -# This function parses a function argument into a type and name. -# -# Arguments: -# arg The argument to parse. -# -# Results: -# Returns a list of type and name with an optional third array -# indicator. If the argument is malformed, returns "". - -proc genStubs::parseArg {arg} { - if {![regexp {^(.+[ ][*]*)([^][ *]+)(\[\])?$} $arg all type name array]} { - if {$arg eq "void"} { - return $arg - } else { - return - } - } - set result [list [string trim $type] $name] - if {$array ne ""} { - lappend result $array - } - return $result -} - -# genStubs::makeDecl -- -# -# Generate the prototype for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted declaration string. - -proc genStubs::makeDecl {name decl index} { - variable scspec - lassign $decl rtype fname args - - append text "/* $index */\n" - set line "$scspec $rtype" - set count [expr {2 - ([string length $line] / 8)}] - append line [string range "\t\t\t" 0 $count] - set pad [expr {24 - [string length $line]}] - if {$pad <= 0} { - append line " " - set pad 0 - } - if {$args eq ""} { - append line $fname - append text $line - append text ";\n" - return $text - } - append line $fname - - set arg1 [lindex $args 0] - switch -exact $arg1 { - void { - append line "(void)" - } - TCL_VARARGS { - set sep "(" - foreach arg [lrange $args 1 end] { - append line $sep - set next {} - append next [lindex $arg 0] - if {[string index $next end] ne "*"} { - append next " " - } - append next [lindex $arg 1] [lindex $arg 2] - if {[string length $line] + [string length $next] \ - + $pad > 76} { - append text [string trimright $line] \n - set line "\t\t\t\t" - set pad 28 - } - append line $next - set sep ", " - } - append line ", ...)" - } - default { - set sep "(" - foreach arg $args { - append line $sep - set next {} - append next [lindex $arg 0] - if {[string index $next end] ne "*"} { - append next " " - } - append next [lindex $arg 1] [lindex $arg 2] - if {[string length $line] + [string length $next] \ - + $pad > 76} { - append text [string trimright $line] \n - set line "\t\t\t\t" - set pad 28 - } - append line $next - set sep ", " - } - append line ")" - } - } - return "$text$line;\n" -} - -# genStubs::makeMacro -- -# -# Generate the inline macro for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted macro definition. - -proc genStubs::makeMacro {name decl index} { - lassign $decl rtype fname args - - set lfname [string tolower [string index $fname 0]] - append lfname [string range $fname 1 end] - - set text "#define $fname \\\n\t(" - if {$args eq ""} { - append text "*" - } - append text "${name}StubsPtr->$lfname)" - append text " /* $index */\n" - return $text -} - -# genStubs::makeSlot -- -# -# Generate the stub table entry for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted table entry. - -proc genStubs::makeSlot {name decl index} { - lassign $decl rtype fname args - - set lfname [string tolower [string index $fname 0]] - append lfname [string range $fname 1 end] - - set text " " - if {$args eq ""} { - append text $rtype " *" $lfname "; /* $index */\n" - return $text - } - if {[string range $rtype end-8 end] eq "__stdcall"} { - append text [string trim [string range $rtype 0 end-9]] " (__stdcall *" $lfname ") " - } else { - append text $rtype " (*" $lfname ") " - } - set arg1 [lindex $args 0] - switch -exact $arg1 { - void { - append text "(void)" - } - TCL_VARARGS { - set sep "(" - foreach arg [lrange $args 1 end] { - append text $sep [lindex $arg 0] - if {[string index $text end] ne "*"} { - append text " " - } - append text [lindex $arg 1] [lindex $arg 2] - set sep ", " - } - append text ", ...)" - } - default { - set sep "(" - foreach arg $args { - append text $sep [lindex $arg 0] - if {[string index $text end] ne "*"} { - append text " " - } - append text [lindex $arg 1] [lindex $arg 2] - set sep ", " - } - append text ")" - } - } - - append text "; /* $index */\n" - return $text -} - -# genStubs::makeInit -- -# -# Generate the prototype for a function. -# -# Arguments: -# name The interface name. -# decl The function declaration. -# index The slot index for this function. -# -# Results: -# Returns the formatted declaration string. - -proc genStubs::makeInit {name decl index} { - if {[lindex $decl 2] eq ""} { - append text " &" [lindex $decl 1] ", /* " $index " */\n" - } else { - append text " " [lindex $decl 1] ", /* " $index " */\n" - } - return $text -} - -# genStubs::forAllStubs -- -# -# This function iterates over all of the slots and invokes -# a callback for each slot. The result of the callback is then -# placed inside appropriate guards. -# -# Arguments: -# name The interface name. -# slotProc The proc to invoke to handle the slot. It will -# have the interface name, the declaration, and -# the index appended. -# guardProc The proc to invoke to add guards. It will have -# the slot status and text appended. -# textVar The variable to use for output. -# skipString The string to emit if a slot is skipped. This -# string will be subst'ed in the loop so "$i" can -# be used to substitute the index value. -# -# Results: -# None. - -proc genStubs::forAllStubs {name slotProc guardProc textVar - {skipString {"/* Slot $i is reserved */\n"}}} { - variable stubs - upvar $textVar text - - set lastNum $stubs($name,lastNum) - - for {set i 0} {$i <= $lastNum} {incr i} { - if {[info exists stubs($name,decl,$i)]} { - append text [$guardProc $stubs($name,status,$i) \ - [$slotProc $name $stubs($name,decl,$i) $i]] - } else { - eval {append text} $skipString - } - } -} - -proc genStubs::noGuard {status text} { return $text } - -proc genStubs::addGuard {status text} { - variable libraryName - set upName [string toupper $libraryName] - - switch -- $status { - current { - # No change - } - deprecated { - set text [ifdeffed "${upName}_DEPRECATED" $text] - } - obsolete { - set text "" - } - default { - puts stderr "Unrecognized status code $status" - } - } - return $text -} - -proc genStubs::ifdeffed {macro text} { - join [list "#ifdef $macro" $text "#endif" ""] \n -} - -# genStubs::emitDeclarations -- -# -# This function emits the function declarations for this interface. -# -# Arguments: -# name The interface name. -# textVar The variable to use for output. -# -# Results: -# None. - -proc genStubs::emitDeclarations {name textVar} { - upvar $textVar text - - append text "\n/*\n * Exported function declarations:\n */\n\n" - forAllStubs $name makeDecl noGuard text - return -} - -# genStubs::emitMacros -- -# -# This function emits the inline macros for an interface. -# -# Arguments: -# name The name of the interface being emitted. -# textVar The variable to use for output. -# -# Results: -# None. - -proc genStubs::emitMacros {name textVar} { - variable libraryName - upvar $textVar text - - set upName [string toupper $libraryName] - append text "\n#if defined(USE_${upName}_STUBS)\n" - append text "\n/*\n * Inline function declarations:\n */\n\n" - - forAllStubs $name makeMacro addGuard text - - append text "\n#endif /* defined(USE_${upName}_STUBS) */\n" - return -} - -# genStubs::emitHeader -- -# -# This function emits the body of the Decls.h file for -# the specified interface. -# -# Arguments: -# name The name of the interface being emitted. -# -# Results: -# None. - -proc genStubs::emitHeader {name} { - variable outDir - variable hooks - variable epoch - variable revision - - set capName [string toupper [string index $name 0]] - append capName [string range $name 1 end] - - if {$epoch ne ""} { - set CAPName [string toupper $name] - append text "\n" - append text "#define ${CAPName}_STUBS_EPOCH $epoch\n" - append text "#define ${CAPName}_STUBS_REVISION $revision\n" - } - - append text "\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n" - - emitDeclarations $name text - - if {[info exists hooks($name)]} { - append text "\ntypedef struct {\n" - foreach hook $hooks($name) { - set capHook [string toupper [string index $hook 0]] - append capHook [string range $hook 1 end] - append text " const struct ${capHook}Stubs *${hook}Stubs;\n" - } - append text "} ${capName}StubHooks;\n" - } - append text "\ntypedef struct ${capName}Stubs {\n" - append text " int magic;\n" - if {$epoch ne ""} { - append text " int epoch;\n" - append text " int revision;\n" - } - if {[info exists hooks($name)]} { - append text " const ${capName}StubHooks *hooks;\n\n" - } else { - append text " void *hooks;\n\n" - } - - emitSlots $name text - - append text "} ${capName}Stubs;\n\n" - - append text "extern const ${capName}Stubs *${name}StubsPtr;\n\n" - append text "#ifdef __cplusplus\n}\n#endif\n" - - emitMacros $name text - - rewriteFile [file join $outDir ${name}Decls.h] $text - return -} - -# genStubs::emitInit -- -# -# Generate the table initializers for an interface. -# -# Arguments: -# name The name of the interface to initialize. -# textVar The variable to use for output. -# -# Results: -# Returns the formatted output. - -proc genStubs::emitInit {name textVar} { - variable hooks - variable interfaces - variable epoch - upvar $textVar text - set root 1 - - set capName [string toupper [string index $name 0]] - append capName [string range $name 1 end] - - if {[info exists hooks($name)]} { - append text "\nstatic const ${capName}StubHooks ${name}StubHooks = \{\n" - set sep " " - foreach sub $hooks($name) { - append text $sep "&${sub}Stubs" - set sep ",\n " - } - append text "\n\};\n" - } - foreach intf [array names interfaces] { - if {[info exists hooks($intf)]} { - if {[lsearch -exact $hooks($intf) $name] >= 0} { - set root 0 - break - } - } - } - - append text "\n" - if {!$root} { - append text "static " - } - append text "const ${capName}Stubs ${name}Stubs = \{\n TCL_STUB_MAGIC,\n" - if {$epoch ne ""} { - set CAPName [string toupper $name] - append text " ${CAPName}_STUBS_EPOCH,\n" - append text " ${CAPName}_STUBS_REVISION,\n" - } - if {[info exists hooks($name)]} { - append text " &${name}StubHooks,\n" - } else { - append text " 0,\n" - } - - forAllStubs $name makeInit noGuard text {" 0, /* $i */\n"} - - append text "\};\n" - return -} - -# genStubs::emitInits -- -# -# This function emits the body of the StubInit.c file for -# the specified interface. -# -# Arguments: -# name The name of the interface being emitted. -# -# Results: -# None. - -proc genStubs::emitInits {} { - variable hooks - variable outDir - variable libraryName - variable interfaces - - # Assuming that dependencies only go one level deep, we need to emit - # all of the leaves first to avoid needing forward declarations. - - set leaves {} - set roots {} - foreach name [lsort [array names interfaces]] { - if {[info exists hooks($name)]} { - lappend roots $name - } else { - lappend leaves $name - } - } - foreach name $leaves { - emitInit $name text - } - foreach name $roots { - emitInit $name text - } - - rewriteFile [file join $outDir ${libraryName}StubInit.c] $text -} - -# genStubs::init -- -# -# This is the main entry point. -# -# Arguments: -# None. -# -# Results: -# None. - -proc genStubs::init {} { - global argv argv0 - variable outDir - variable interfaces - - if {[llength $argv] < 2} { - puts stderr "usage: $argv0 outDir declFile ?declFile...?" - exit 1 - } - - set outDir [lindex $argv 0] - - foreach file [lrange $argv 1 end] { - source $file - } - - foreach name [lsort [array names interfaces]] { - puts "Emitting $name" - emitHeader $name - } - - emitInits -} - -# lassign -- -# -# This function emulates the TclX lassign command. -# -# Arguments: -# valueList A list containing the values to be assigned. -# args The list of variables to be assigned. -# -# Results: -# Returns any values that were not assigned to variables. - -if {[string length [namespace which lassign]] == 0} { - proc lassign {valueList args} { - if {[llength $args] == 0} { - error "wrong # args: should be \"lassign list varName ?varName ...?\"" - } - uplevel [list foreach $args $valueList {break}] - return [lrange $valueList [llength $args] end] - } -} - -genStubs::init Index: generic/ttk/ttkImage.c ================================================================== --- generic/ttk/ttkImage.c +++ generic/ttk/ttkImage.c @@ -8,12 +8,11 @@ * is the name of the default image to use, the remainder of the * list is a sequence of statespec/imagename options as per * [style map]. */ -#include -#include +#include "tkInt.h" #include "ttkTheme.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) /*------------------------------------------------------------------------ @@ -23,37 +22,67 @@ struct TtkImageSpec { Tk_Image baseImage; /* Base image to use */ int mapCount; /* #state-specific overrides */ Ttk_StateSpec *states; /* array[mapCount] of states ... */ Tk_Image *images; /* ... per-state images to use */ + Tk_ImageChangedProc *imageChanged; + ClientData imageChangedClientData; }; /* NullImageChanged -- * Do-nothing Tk_ImageChangedProc. */ static void NullImageChanged(ClientData clientData, int x, int y, int width, int height, int imageWidth, int imageHeight) { /* No-op */ } + +/* ImageSpecImageChanged -- + * Image changes should trigger a repaint. + */ +static void ImageSpecImageChanged(ClientData clientData, + int x, int y, int width, int height, int imageWidth, int imageHeight) +{ + Ttk_ImageSpec *imageSpec = (Ttk_ImageSpec *)clientData; + if (imageSpec->imageChanged != NULL) { + imageSpec->imageChanged(imageSpec->imageChangedClientData, + x, y, width, height, + imageWidth, imageHeight); + } +} /* TtkGetImageSpec -- * Constructs a Ttk_ImageSpec * from a Tcl_Obj *. * Result must be released using TtkFreeImageSpec. * - * TODO: Need a variant of this that takes a user-specified ImageChanged proc */ Ttk_ImageSpec * TtkGetImageSpec(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr) { + return TtkGetImageSpecEx(interp, tkwin, objPtr, NULL, NULL); +} + +/* TtkGetImageSpecEx -- + * Constructs a Ttk_ImageSpec * from a Tcl_Obj *. + * Result must be released using TtkFreeImageSpec. + * imageChangedProc will be called when not NULL when + * the image changes to allow widgets to repaint. + */ +Ttk_ImageSpec * +TtkGetImageSpecEx(Tcl_Interp *interp, Tk_Window tkwin, Tcl_Obj *objPtr, + Tk_ImageChangedProc *imageChangedProc, ClientData imageChangedClientData) +{ Ttk_ImageSpec *imageSpec = 0; int i = 0, n = 0, objc; Tcl_Obj **objv; imageSpec = ckalloc(sizeof(*imageSpec)); imageSpec->baseImage = 0; imageSpec->mapCount = 0; imageSpec->states = 0; imageSpec->images = 0; + imageSpec->imageChanged = imageChangedProc; + imageSpec->imageChangedClientData = imageChangedClientData; if (Tcl_ListObjGetElements(interp, objPtr, &objc, &objv) != TCL_OK) { goto error; } @@ -72,11 +101,11 @@ imageSpec->images = ckalloc(n * sizeof(Tk_Image *)); /* Get base image: */ imageSpec->baseImage = Tk_GetImage( - interp, tkwin, Tcl_GetString(objv[0]), NullImageChanged, NULL); + interp, tkwin, Tcl_GetString(objv[0]), ImageSpecImageChanged, imageSpec); if (!imageSpec->baseImage) { goto error; } /* Extract state and image specifications: @@ -313,11 +342,11 @@ void *clientData, Ttk_Theme theme, const char *elementName, int objc, Tcl_Obj *const objv[]) { - static const char *optionStrings[] = + static const char *const optionStrings[] = { "-border","-height","-padding","-sticky","-width",NULL }; enum { O_BORDER, O_HEIGHT, O_PADDING, O_STICKY, O_WIDTH }; Ttk_ImageSpec *imageSpec = 0; ImageData *imageData = 0; Index: generic/ttk/ttkInit.c ================================================================== --- generic/ttk/ttkInit.c +++ generic/ttk/ttkInit.c @@ -2,12 +2,11 @@ * Copyright (c) 2003, Joe English * * Ttk package: initialization routine and miscellaneous utilities. */ -#include -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" /* * Legal values for the button -default option. @@ -60,11 +59,11 @@ /* * Recognized values for the -state compatibility option. * Other options are accepted and interpreted as synonyms for "normal". */ -static const char *ttkStateStrings[] = { +static const char *const ttkStateStrings[] = { "normal", "readonly", "disabled", "active", NULL }; enum { TTK_COMPAT_STATE_NORMAL, TTK_COMPAT_STATE_READONLY, Index: generic/ttk/ttkLabel.c ================================================================== --- generic/ttk/ttkLabel.c +++ generic/ttk/ttkLabel.c @@ -4,12 +4,11 @@ * The label element combines text and image elements, * with layout determined by the "-compound" option. * */ -#include -#include +#include "tkInt.h" #include "ttkTheme.h" /*---------------------------------------------------------------------- * +++ Text element. * @@ -137,11 +136,11 @@ gcValues.foreground = color->pixel; gc1 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues); gcValues.foreground = WhitePixelOfScreen(Tk_Screen(tkwin)); gc2 = Tk_GetGC(tkwin, GCFont | GCForeground, &gcValues); - /* + /* * Place text according to -anchor: */ Tk_GetAnchorFromObj(NULL, text->anchorObj, &anchor); b = Ttk_AnchorBox(b, text->width, text->height, anchor); @@ -340,19 +339,19 @@ return; } Tk_RedrawImage(image->tkimg, 0,0, width, height, d, b.x, b.y); - /* If we're disabled there's no state-specific 'disabled' image, + /* If we're disabled there's no state-specific 'disabled' image, * stipple the image. * @@@ Possibly: Don't do disabled-stippling at all; * @@@ it's ugly and out of fashion. - * Do not stipple at all under Aqua, just draw the image: it shows up + * Do not stipple at all under Aqua, just draw the image: it shows up * as a white rectangle otherwise. */ - + if (state & TTK_STATE_DISABLED) { if (TtkSelectImage(image->imageSpec, 0ul) == image->tkimg) { #ifndef MAC_OSX_TK StippleOver(image, tkwin, d, b.x,b.y); #endif @@ -575,11 +574,11 @@ /* Requested width based on -width option, not actual text width: */ if (label->compound != TTK_COMPOUND_IMAGE) textReqWidth = TextReqWidth(&label->text); - switch (label->compound) + switch (label->compound) { case TTK_COMPOUND_TEXT: *widthPtr = textReqWidth; break; case TTK_COMPOUND_IMAGE: @@ -586,15 +585,15 @@ *widthPtr = label->image.width; break; case TTK_COMPOUND_TOP: case TTK_COMPOUND_BOTTOM: case TTK_COMPOUND_CENTER: - *widthPtr = MAX(label->image.width, textReqWidth); + *widthPtr = MAX(label->image.width, textReqWidth); break; case TTK_COMPOUND_LEFT: case TTK_COMPOUND_RIGHT: - *widthPtr = label->image.width + textReqWidth + label->space; + *widthPtr = label->image.width + textReqWidth + label->space; break; case TTK_COMPOUND_NONE: break; /* Can't happen */ } Index: generic/ttk/ttkLayout.c ================================================================== --- generic/ttk/ttkLayout.c +++ generic/ttk/ttkLayout.c @@ -4,12 +4,11 @@ * Generic layout processing. * * Copyright (c) 2003 Joe English. Freely redistributable. */ -#include -#include +#include "tkInt.h" #include "ttkThemeInt.h" #define MAX(a,b) (a > b ? a : b) #define MIN(a,b) (a < b ? a : b) @@ -602,17 +601,17 @@ * Syntax: * layoutSpec ::= { elementName ?-option value ...? }+ */ /* NB: This must match bit definitions TTK_PACK_LEFT etc. */ -static const char *packSideStrings[] = +static const char *const packSideStrings[] = { "left", "right", "top", "bottom", NULL }; Ttk_LayoutTemplate Ttk_ParseLayoutTemplate(Tcl_Interp *interp, Tcl_Obj *objPtr) { enum { OP_SIDE, OP_STICKY, OP_EXPAND, OP_BORDER, OP_UNIT, OP_CHILDREN }; - static const char *optStrings[] = { + static const char *const optStrings[] = { "-side", "-sticky", "-expand", "-border", "-unit", "-children", 0 }; int i = 0, objc; Tcl_Obj **objv; Ttk_TemplateNode *head = 0, *tail = 0; @@ -700,10 +699,12 @@ head = tail = Ttk_NewTemplateNode(elementName, flags | sticky); } if (childSpec) { tail->child = Ttk_ParseLayoutTemplate(interp, childSpec); if (!tail->child) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf("Invalid -children value")); + Tcl_SetErrorCode(interp, "TTK", "VALUE", "CHILDREN", NULL); goto error; } } } Index: generic/ttk/ttkManager.c ================================================================== --- generic/ttk/ttkManager.c +++ generic/ttk/ttkManager.c @@ -2,12 +2,11 @@ * Copyright 2005, Joe English. Freely redistributable. * * Support routines for geometry managers. */ -#include -#include +#include "tkInt.h" #include "ttkManager.h" /*------------------------------------------------------------------------ * +++ The Geometry Propagation Dance. * @@ -318,11 +317,11 @@ int slaveIndex = Ttk_SlaveIndex(mgr, slaveWindow); int reqWidth = Tk_ReqWidth(slaveWindow); int reqHeight= Tk_ReqHeight(slaveWindow); if (mgr->managerSpec->SlaveRequest( - mgr->managerData, slaveIndex, reqWidth, reqHeight)) + mgr->managerData, slaveIndex, reqWidth, reqHeight)) { ScheduleUpdate(mgr, MGR_RESIZE_REQUIRED); } } Index: generic/ttk/ttkManager.h ================================================================== --- generic/ttk/ttkManager.h +++ generic/ttk/ttkManager.h @@ -20,11 +20,11 @@ * by calling Ttk_PlaceSlave(). * * SlaveRemoved() is called immediately before a slave is removed. * NB: the associated slave window may have been destroyed when this * routine is called. - * + * * SlaveRequest() is called when a slave requests a size change. * It should return 1 if the request should propagate, 0 otherwise. */ typedef struct { /* Manager hooks */ Tk_GeomMgr tkGeomMgr; /* "real" Tk Geometry Manager */ Index: generic/ttk/ttkNotebook.c ================================================================== --- generic/ttk/ttkNotebook.c +++ generic/ttk/ttkNotebook.c @@ -1,14 +1,10 @@ /* * Copyright (c) 2004, Joe English */ -#include -#include -#include -#include - +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #include "ttkManager.h" #define MIN(a,b) ((a) < (b) ? (a) : (b)) @@ -219,11 +215,11 @@ Ttk_Sticky sticky = tab->sticky; Ttk_Padding padding = tab->padding; Tk_SavedOptions savedOptions; int mask = 0; - if (Tk_SetOptions(interp, (ClientData)tab, nb->notebook.paneOptionTable, + if (Tk_SetOptions(interp, tab, nb->notebook.paneOptionTable, objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK) { return TCL_ERROR; } @@ -286,17 +282,18 @@ /* * TabState -- * Return the state of the specified tab, based on * notebook state, currentIndex, activeIndex, and user-specified tab state. - * The USER1 bit is set for the leftmost tab, and USER2 - * is set for the rightmost tab. + * The USER1 bit is set for the leftmost visible tab, and USER2 + * is set for the rightmost visible tab. */ static Ttk_State TabState(Notebook *nb, int index) { Ttk_State state = nb->core.state; Tab *tab = Ttk_SlaveData(nb->notebook.mgr, index); + int i = 0; if (index == nb->notebook.currentIndex) { state |= TTK_STATE_SELECTED; } else { state &= ~TTK_STATE_FOCUS; @@ -303,15 +300,29 @@ } if (index == nb->notebook.activeIndex) { state |= TTK_STATE_ACTIVE; } - if (index == 0) { - state |= TTK_STATE_USER1; + for (i = 0; i < Ttk_NumberSlaves(nb->notebook.mgr); ++i) { + Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i); + if (tab->state == TAB_STATE_HIDDEN) { + continue; + } + if (index == i) { + state |= TTK_STATE_USER1; + } + break; } - if (index == Ttk_NumberSlaves(nb->notebook.mgr) - 1) { - state |= TTK_STATE_USER2; + for (i = Ttk_NumberSlaves(nb->notebook.mgr) - 1; i >= 0; --i) { + Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i); + if (tab->state == TAB_STATE_HIDDEN) { + continue; + } + if (index == i) { + state |= TTK_STATE_USER2; + } + break; } if (tab->state == TAB_STATE_DISABLED) { state |= TTK_STATE_DISABLED; } @@ -323,20 +334,22 @@ */ /* TabrowSize -- * Compute max height and total width of all tabs (horizontal layouts) * or total height and max width (vertical layouts). + * The -mintabwidth style option is taken into account (for the width + * only). * * Side effects: * Sets width and height fields for all tabs. * * Notes: * Hidden tabs are included in the perpendicular computation * (max height/width) but not parallel (total width/height). */ static void TabrowSize( - Notebook *nb, Ttk_Orient orient, int *widthPtr, int *heightPtr) + Notebook *nb, Ttk_Orient orient, int minTabWidth, int *widthPtr, int *heightPtr) { Ttk_Layout tabLayout = nb->notebook.tabLayout; int tabrowWidth = 0, tabrowHeight = 0; int i; @@ -344,10 +357,11 @@ Tab *tab = Ttk_SlaveData(nb->notebook.mgr, i); Ttk_State tabState = TabState(nb,i); Ttk_RebindSublayout(tabLayout, tab); Ttk_LayoutSize(tabLayout,tabState,&tab->width,&tab->height); + tab->width = MAX(tab->width, minTabWidth); if (orient == TTK_ORIENT_HORIZONTAL) { tabrowHeight = MAX(tabrowHeight, tab->height); if (tab->state != TAB_STATE_HIDDEN) { tabrowWidth += tab->width; } } else { @@ -404,11 +418,11 @@ if (reqHeight > 0) clientHeight = reqHeight; /* Tab row: */ - TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight); + TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight); tabrowHeight += Ttk_PaddingHeight(nbstyle.tabMargins); tabrowWidth += Ttk_PaddingWidth(nbstyle.tabMargins); /* Account for exterior and interior padding: */ @@ -434,51 +448,34 @@ * +++ Geometry management - layout. */ /* SqueezeTabs -- * Squeeze or stretch tabs to fit within the tab area parcel. - * - * All tabs are adjusted by an equal amount, but will not be made - * smaller than the minimum width. (If all the tabs still do - * not fit in the available space, the rightmost ones will - * be further squozen by PlaceTabs()). - * - * The algorithm does not always yield an optimal layout, but does - * have the important property that decreasing the available width - * by one pixel will cause at most one tab to shrink by one pixel; - * this means that tabs resize "smoothly" when the window shrinks - * and grows. + * This happens independently of the -mintabwidth style option. + * + * All tabs are adjusted by an equal amount. * * @@@ <> bug: only works for horizontal orientations * @@@ <> does not account for hidden tabs. */ static void SqueezeTabs( - Notebook *nb, int needed, int available, int minTabWidth) + Notebook *nb, int needed, int available) { int nTabs = Ttk_NumberSlaves(nb->notebook.mgr); if (nTabs > 0) { - int difference = available - needed, - delta = difference / nTabs, - remainder = difference % nTabs, - slack = 0; + int difference = available - needed; + double delta = (double)difference / needed; + double slack = 0; int i; - if (remainder < 0) { remainder += nTabs; --delta; } - for (i = 0; i < nTabs; ++i) { Tab *tab = Ttk_SlaveData(nb->notebook.mgr,i); - int adj = delta + (i < remainder) + slack; - - if (tab->width + adj >= minTabWidth) { - tab->width += adj; - slack = 0; - } else { - slack = adj - (minTabWidth - tab->width); - tab->width = minTabWidth; - } + double ad = slack + tab->width * delta; + tab->width += (int)ad; + slack = ad - (int)ad; } } } /* PlaceTabs -- @@ -537,20 +534,25 @@ /* Layout for notebook background (base layout): */ Ttk_PlaceLayout(nb->core.layout, nb->core.state, Ttk_WinBox(nbwin)); /* Place tabs: + * Note: TabrowSize() takes into account -mintabwidth, but the tabs will + * actually have this minimum size when displayed only if there is enough + * space to draw the tabs with this width. Otherwise some of the tabs can + * be squeezed to a size smaller than -mintabwidth because we prefer + * displaying all tabs than than honoring -mintabwidth for all of them. */ - TabrowSize(nb, nbstyle.tabOrient, &tabrowWidth, &tabrowHeight); + TabrowSize(nb, nbstyle.tabOrient, nbstyle.minTabWidth, &tabrowWidth, &tabrowHeight); tabrowBox = Ttk_PadBox( Ttk_PositionBox(&cavity, tabrowWidth + Ttk_PaddingWidth(nbstyle.tabMargins), tabrowHeight + Ttk_PaddingHeight(nbstyle.tabMargins), nbstyle.tabPosition), nbstyle.tabMargins); - SqueezeTabs(nb, tabrowWidth, tabrowBox.width, nbstyle.minTabWidth); + SqueezeTabs(nb, tabrowWidth, tabrowBox.width); PlaceTabs(nb, tabrowBox, nbstyle.tabPlacement); /* Layout for client area frame: */ if (clientNode) { @@ -619,13 +621,16 @@ if (currentIndex >= 0) { Ttk_UnmapSlave(nb->notebook.mgr, currentIndex); } - NotebookPlaceSlave(nb, index); - + /* Must be set before calling NotebookPlaceSlave(), otherwise it may + * happen that NotebookPlaceSlaves(), triggered by an interveaning + * geometry request, will swap to old index. */ nb->notebook.currentIndex = index; + + NotebookPlaceSlave(nb, index); TtkRedisplayWidget(&nb->core); TtkSendVirtualEvent(nb->core.tkwin, "NotebookTabChanged"); } @@ -1042,11 +1047,11 @@ * Returns name of tab element at $x,$y; empty string if none. */ static int NotebookIdentifyCommand( void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - static const char *whatTable[] = { "element", "tab", NULL }; + static const char *const whatTable[] = { "element", "tab", NULL }; enum { IDENTIFY_ELEMENT, IDENTIFY_TAB }; int what = IDENTIFY_ELEMENT; Notebook *nb = recordPtr; Ttk_Element element = NULL; int x, y, tabIndex; Index: generic/ttk/ttkPanedwindow.c ================================================================== --- generic/ttk/ttkPanedwindow.c +++ generic/ttk/ttkPanedwindow.c @@ -4,12 +4,11 @@ * ttk::panedwindow widget implementation. * * TODO: track active/pressed sash. */ -#include -#include +#include "tkInt.h" #include "ttkManager.h" #include "ttkTheme.h" #include "ttkWidget.h" /*------------------------------------------------------------------------ @@ -146,11 +145,11 @@ { Ttk_Manager *mgr = pw->paned.mgr; Tk_SavedOptions savedOptions; int mask = 0; - if (Tk_SetOptions(interp, (void*)pane, pw->paned.paneOptionTable, + if (Tk_SetOptions(interp, pane, pw->paned.paneOptionTable, objc, objv, slaveWindow, &savedOptions, &mask) != TCL_OK) { return TCL_ERROR; } @@ -713,11 +712,11 @@ * Return index of sash at $x,$y */ static int PanedIdentifyCommand( void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - static const char *whatTable[] = { "element", "sash", NULL }; + static const char *const whatTable[] = { "element", "sash", NULL }; enum { IDENTIFY_ELEMENT, IDENTIFY_SASH }; int what = IDENTIFY_SASH; Paned *pw = recordPtr; int sashThickness = pw->paned.sashThickness; int nSashes = Ttk_NumberSlaves(pw->paned.mgr) - 1; Index: generic/ttk/ttkProgress.c ================================================================== --- generic/ttk/ttkProgress.c +++ generic/ttk/ttkProgress.c @@ -2,13 +2,11 @@ * Copyright (c) Joe English, Pat Thoyts, Michael Kirkham * * ttk::progressbar widget. */ -#include -#include - +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" /*------------------------------------------------------------------------ * +++ Widget record: @@ -21,17 +19,23 @@ static const char *const ProgressbarModeStrings[] = { "determinate", "indeterminate", NULL }; typedef struct { - Tcl_Obj *orientObj; + Tcl_Obj *anchorObj; + Tcl_Obj *fontObj; + Tcl_Obj *foregroundObj; + Tcl_Obj *justifyObj; Tcl_Obj *lengthObj; - Tcl_Obj *modeObj; - Tcl_Obj *variableObj; Tcl_Obj *maximumObj; - Tcl_Obj *valueObj; + Tcl_Obj *modeObj; + Tcl_Obj *orientObj; Tcl_Obj *phaseObj; + Tcl_Obj *textObj; + Tcl_Obj *valueObj; + Tcl_Obj *variableObj; + Tcl_Obj *wrapLengthObj; int mode; Ttk_TraceHandle *variableTrace; /* Trace handle for -variable option */ int period; /* Animation period */ int maxPhase; /* Max animation phase */ @@ -44,32 +48,50 @@ ProgressbarPart progress; } Progressbar; static Tk_OptionSpec ProgressbarOptionSpecs[] = { - {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", - "horizontal", Tk_Offset(Progressbar,progress.orientObj), -1, - 0, (ClientData)ttkOrientStrings, STYLE_CHANGED }, + {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", + "w", Tk_Offset(Progressbar,progress.anchorObj), -1, + TK_OPTION_NULL_OK, 0, GEOMETRY_CHANGED}, + {TK_OPTION_FONT, "-font", "font", "Font", + DEFAULT_FONT, Tk_Offset(Progressbar,progress.fontObj), -1, + TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, + {TK_OPTION_COLOR, "-foreground", "textColor", "TextColor", + "black", Tk_Offset(Progressbar,progress.foregroundObj), -1, + TK_OPTION_NULL_OK,0,0 }, + {TK_OPTION_JUSTIFY, "-justify", "justify", "Justify", + "left", Tk_Offset(Progressbar,progress.justifyObj), -1, + TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, {TK_OPTION_PIXELS, "-length", "length", "Length", DEF_PROGRESSBAR_LENGTH, Tk_Offset(Progressbar,progress.lengthObj), -1, 0, 0, GEOMETRY_CHANGED }, + {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum", + "100", Tk_Offset(Progressbar,progress.maximumObj), -1, + 0, 0, 0 }, {TK_OPTION_STRING_TABLE, "-mode", "mode", "ProgressMode", "determinate", Tk_Offset(Progressbar,progress.modeObj), Tk_Offset(Progressbar,progress.mode), 0, (ClientData)ProgressbarModeStrings, 0 }, - {TK_OPTION_DOUBLE, "-maximum", "maximum", "Maximum", - "100", Tk_Offset(Progressbar,progress.maximumObj), -1, + {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", + "horizontal", Tk_Offset(Progressbar,progress.orientObj), -1, + 0, (ClientData)ttkOrientStrings, STYLE_CHANGED }, + {TK_OPTION_INT, "-phase", "phase", "Phase", + "0", Tk_Offset(Progressbar,progress.phaseObj), -1, + 0, 0, 0 }, + {TK_OPTION_STRING, "-text", "text", "Text", "", + Tk_Offset(Progressbar,progress.textObj), -1, + 0,0,GEOMETRY_CHANGED }, + {TK_OPTION_DOUBLE, "-value", "value", "Value", + "0.0", Tk_Offset(Progressbar,progress.valueObj), -1, 0, 0, 0 }, {TK_OPTION_STRING, "-variable", "variable", "Variable", NULL, Tk_Offset(Progressbar,progress.variableObj), -1, TK_OPTION_NULL_OK, 0, 0 }, - {TK_OPTION_DOUBLE, "-value", "value", "Value", - "0.0", Tk_Offset(Progressbar,progress.valueObj), -1, - 0, 0, 0 }, - {TK_OPTION_INT, "-phase", "phase", "Phase", - "0", Tk_Offset(Progressbar,progress.phaseObj), -1, - 0, 0, 0 }, + {TK_OPTION_PIXELS, "-wraplength", "wrapLength", "WrapLength", + "0", Tk_Offset(Progressbar, progress.wrapLengthObj), -1, + TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED}, WIDGET_TAKEFOCUS_FALSE, WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs) }; @@ -396,11 +418,11 @@ static int ProgressbarStepCommand( void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Progressbar *pb = recordPtr; double value = 0.0, stepAmount = 1.0; - Tcl_Obj *newValueObj; + Tcl_Obj *newValueObj; if (objc == 3) { if (Tcl_GetDoubleFromObj(interp, objv[2], &stepAmount) != TCL_OK) { return TCL_ERROR; } @@ -419,34 +441,36 @@ (void)Tcl_GetDoubleFromObj(NULL, pb->progress.maximumObj, &maximum); value = fmod(value, maximum); } newValueObj = Tcl_NewDoubleObj(value); + Tcl_IncrRefCount(newValueObj); TtkRedisplayWidget(&pb->core); - /* Update value by setting the linked -variable, if there is one: + /* Update value by setting the linked -variable, if there is one: */ if (pb->progress.variableTrace) { - return Tcl_ObjSetVar2( - interp, pb->progress.variableObj, 0, newValueObj, - TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) - ? TCL_OK : TCL_ERROR; + int result = Tcl_ObjSetVar2( + interp, pb->progress.variableObj, 0, newValueObj, + TCL_GLOBAL_ONLY | TCL_LEAVE_ERR_MSG) + ? TCL_OK : TCL_ERROR; + Tcl_DecrRefCount(newValueObj); + return result; } /* Otherwise, change the -value directly: */ - Tcl_IncrRefCount(newValueObj); Tcl_DecrRefCount(pb->progress.valueObj); pb->progress.valueObj = newValueObj; CheckAnimation(pb); return TCL_OK; } /* $sb start|stop ?args? -- - * Change [$sb $cmd ...] to [ttk::progressbar::$cmd ...] + * Change [$sb $cmd ...] to [ttk::progressbar::$cmd ...] * and pass to interpreter. */ static int ProgressbarStartStopCommand( Tcl_Interp *interp, const char *cmdName, int objc, Tcl_Obj *const objv[]) { @@ -520,11 +544,12 @@ TTK_NODE("Vertical.Progressbar.pbar", TTK_PACK_BOTTOM|TTK_FILL_X)) TTK_END_LAYOUT TTK_BEGIN_LAYOUT(HorizontalProgressbarLayout) TTK_GROUP("Horizontal.Progressbar.trough", TTK_FILL_BOTH, - TTK_NODE("Horizontal.Progressbar.pbar", TTK_PACK_LEFT|TTK_FILL_Y)) + TTK_NODE("Horizontal.Progressbar.pbar", TTK_PACK_LEFT|TTK_FILL_Y) + TTK_NODE("Horizontal.Progressbar.text", TTK_PACK_LEFT)) TTK_END_LAYOUT /* * Initialization: */ Index: generic/ttk/ttkScale.c ================================================================== --- generic/ttk/ttkScale.c +++ generic/ttk/ttkScale.c @@ -2,21 +2,23 @@ * Copyright (C) 2004 Pat Thoyts * * ttk::scale widget. */ -#include -#include -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #define DEF_SCALE_LENGTH "100" #define MAX(a,b) ((a) > (b) ? (a) : (b)) #define MIN(a,b) ((a) < (b) ? (a) : (b)) +/* Bit fields for OptionSpec mask field: + */ +#define STATE_CHANGED (0x100) /* -state option changed */ + /* * Scale widget record */ typedef struct { @@ -33,10 +35,15 @@ Tcl_Obj *variableObj; /* internal state */ Ttk_TraceHandle *variableTrace; + /* + * Compatibility/legacy options: + */ + Tcl_Obj *stateObj; + } ScalePart; typedef struct { WidgetCore core; @@ -44,29 +51,33 @@ } Scale; static Tk_OptionSpec ScaleOptionSpecs[] = { {TK_OPTION_STRING, "-command", "command", "Command", "", - Tk_Offset(Scale,scale.commandObj), -1, + Tk_Offset(Scale,scale.commandObj), -1, TK_OPTION_NULL_OK,0,0}, {TK_OPTION_STRING, "-variable", "variable", "Variable", "", - Tk_Offset(Scale,scale.variableObj), -1, + Tk_Offset(Scale,scale.variableObj), -1, 0,0,0}, {TK_OPTION_STRING_TABLE, "-orient", "orient", "Orient", "horizontal", Tk_Offset(Scale,scale.orientObj), - Tk_Offset(Scale,scale.orient), 0, + Tk_Offset(Scale,scale.orient), 0, (ClientData)ttkOrientStrings, STYLE_CHANGED }, {TK_OPTION_DOUBLE, "-from", "from", "From", "0", Tk_Offset(Scale,scale.fromObj), -1, 0, 0, 0}, {TK_OPTION_DOUBLE, "-to", "to", "To", "1.0", Tk_Offset(Scale,scale.toObj), -1, 0, 0, 0}, {TK_OPTION_DOUBLE, "-value", "value", "Value", "0", Tk_Offset(Scale,scale.valueObj), -1, 0, 0, 0}, {TK_OPTION_PIXELS, "-length", "length", "Length", - DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0, + DEF_SCALE_LENGTH, Tk_Offset(Scale,scale.lengthObj), -1, 0, 0, GEOMETRY_CHANGED}, + + {TK_OPTION_STRING, "-state", "state", "State", + "normal", Tk_Offset(Scale,scale.stateObj), -1, + 0,0,STATE_CHANGED}, WIDGET_TAKEFOCUS_TRUE, WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs) }; @@ -74,11 +85,11 @@ static double PointToValue(Scale *scalePtr, int x, int y); /* ScaleVariableChanged -- * Variable trace procedure for scale -variable; * Updates the scale's value. - * If the linked variable is not a valid double, + * If the linked variable is not a valid double, * sets the 'invalid' state. */ static void ScaleVariableChanged(void *recordPtr, const char *value) { Scale *scale = recordPtr; @@ -136,10 +147,14 @@ if (scale->scale.variableTrace) { Ttk_UntraceVariable(scale->scale.variableTrace); } scale->scale.variableTrace = vt; + + if (mask & STATE_CHANGED) { + TtkCheckStateOption(&scale->core, scale->scale.stateObj); + } return TCL_OK; } /* ScalePostConfigure -- @@ -170,11 +185,11 @@ } /* ScaleGetLayout -- * getLayout hook. */ -static Ttk_Layout +static Ttk_Layout ScaleGetLayout(Tcl_Interp *interp, Ttk_Theme theme, void *recordPtr) { Scale *scalePtr = recordPtr; return TtkWidgetGetOrientedLayout( interp, theme, recordPtr, scalePtr->scale.orientObj); @@ -234,11 +249,11 @@ return fraction < 0 ? 0 : fraction > 1 ? 1 : fraction; } /* $scale get ?x y? -- - * Returns the current value of the scale widget, or if $x and + * Returns the current value of the scale widget, or if $x and * $y are specified, the value represented by point @x,y. */ static int ScaleGetCommand( void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) Index: generic/ttk/ttkScroll.c ================================================================== --- generic/ttk/ttkScroll.c +++ generic/ttk/ttkScroll.c @@ -32,11 +32,11 @@ * * If the scrollee's -[xy]scrollcommand changes, it should call * TtkScrollbarUpdateRequired, which will invoke step (5) (@@@ Fix this) */ -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" /* Private data: */ Index: generic/ttk/ttkScrollbar.c ================================================================== --- generic/ttk/ttkScrollbar.c +++ generic/ttk/ttkScrollbar.c @@ -2,12 +2,11 @@ * Copyright (c) 2003, Joe English * * ttk::scrollbar widget. */ -#include - +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" /*------------------------------------------------------------------------ * +++ Scrollbar widget record. @@ -20,11 +19,11 @@ Tcl_Obj *orientObj; double first; /* top fraction */ double last; /* bottom fraction */ - Ttk_Box troughBox; /* trough parcel */ + Ttk_Box troughBox; /* trough parcel */ int minSize; /* minimum size of thumb */ } ScrollbarPart; typedef struct { @@ -48,11 +47,11 @@ /*------------------------------------------------------------------------ * +++ Widget hooks. */ -static void +static void ScrollbarInitialize(Tcl_Interp *interp, void *recordPtr) { Scrollbar *sb = recordPtr; sb->scrollbar.first = 0.0; sb->scrollbar.last = 1.0; @@ -239,11 +238,11 @@ return TCL_OK; } /* $sb fraction $x $y -- * Returns a real number between 0 and 1 indicating where the - * point given by x and y lies in the trough area of the scrollbar. + * point given by x and y lies in the trough area of the scrollbar. */ static int ScrollbarFractionCommand( void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { Index: generic/ttk/ttkSeparator.c ================================================================== --- generic/ttk/ttkSeparator.c +++ generic/ttk/ttkSeparator.c @@ -2,12 +2,11 @@ * Copyright (c) 2004, Joe English * * ttk::separator and ttk::sizegrip widgets. */ -#include - +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" /* +++ Separator widget record: */ Index: generic/ttk/ttkSquare.c ================================================================== --- generic/ttk/ttkSquare.c +++ generic/ttk/ttkSquare.c @@ -1,11 +1,11 @@ /* square.c - Copyright (C) 2004 Pat Thoyts * * Minimal sample ttk widget. */ -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #if defined(TTK_SQUARE_WIDGET) || 1 @@ -54,28 +54,28 @@ DEFAULT_BORDERWIDTH, Tk_Offset(Square,square.borderWidthObj), -1, 0,0,GEOMETRY_CHANGED }, {TK_OPTION_BORDER, "-foreground", "foreground", "Foreground", DEFAULT_BACKGROUND, Tk_Offset(Square,square.foregroundObj), -1, 0, 0, 0}, - + {TK_OPTION_PIXELS, "-width", "width", "Width", "50", Tk_Offset(Square,square.widthObj), -1, 0, 0, GEOMETRY_CHANGED}, {TK_OPTION_PIXELS, "-height", "height", "Height", "50", Tk_Offset(Square,square.heightObj), -1, 0, 0, GEOMETRY_CHANGED}, - + {TK_OPTION_STRING, "-padding", "padding", "Pad", NULL, - Tk_Offset(Square,square.paddingObj), -1, + Tk_Offset(Square,square.paddingObj), -1, TK_OPTION_NULL_OK,0,GEOMETRY_CHANGED }, - + {TK_OPTION_RELIEF, "-relief", "relief", "Relief", NULL, Tk_Offset(Square,square.reliefObj), -1, TK_OPTION_NULL_OK, 0, 0}, - + {TK_OPTION_ANCHOR, "-anchor", "anchor", "Anchor", NULL, Tk_Offset(Square,square.anchorObj), -1, TK_OPTION_NULL_OK, 0, 0}, - + WIDGET_TAKEFOCUS_TRUE, WIDGET_INHERIT_OPTIONS(ttkCoreOptionSpecs) }; /* @@ -136,11 +136,11 @@ { "state", TtkWidgetStateCommand,0 }, { 0,0,0 } }; /* - * The Widget specification structure holds all the implementation + * The Widget specification structure holds all the implementation * information about this widget and this is what must be registered * with Tk in the package initialization code (see bottom). */ static WidgetSpec SquareWidgetSpec = @@ -157,11 +157,11 @@ TtkWidgetSize, /* sizeProc */ SquareDoLayout, /* layoutProc */ TtkWidgetDisplay /* displayProc */ }; -/* ---------------------------------------------------------------------- +/* ---------------------------------------------------------------------- * Square element * * In this section we demonstrate what is required to create a new themed * element. */ @@ -174,11 +174,11 @@ Tcl_Obj *reliefObj; Tcl_Obj *widthObj; Tcl_Obj *heightObj; } SquareElement; -static Ttk_ElementOptionSpec SquareElementOptions[] = +static Ttk_ElementOptionSpec SquareElementOptions[] = { { "-background", TK_OPTION_BORDER, Tk_Offset(SquareElement,borderObj), DEFAULT_BACKGROUND }, { "-foreground", TK_OPTION_BORDER, Tk_Offset(SquareElement,foregroundObj), DEFAULT_BACKGROUND }, @@ -246,25 +246,25 @@ * Every widget class needs a layout style that specifies which elements * are part of the widget and how they should be placed. The element layout * engine is similar to the Tk pack geometry manager. Read the documentation * for the details. In this example we just need to have the square element * that has been defined for this widget placed on a background. We will - * also need some padding to keep it away from the edges. + * also need some padding to keep it away from the edges. */ TTK_BEGIN_LAYOUT(SquareLayout) TTK_NODE("Square.background", TTK_FILL_BOTH) TTK_GROUP("Square.padding", TTK_FILL_BOTH, TTK_NODE("Square.square", 0)) TTK_END_LAYOUT -/* ---------------------------------------------------------------------- +/* ---------------------------------------------------------------------- * * Widget initialization. * * This file defines a new element and a new widget. We need to register - * the element with the themes that will need it. In this case we will + * the element with the themes that will need it. In this case we will * register with the default theme that is the root of the theme inheritance * tree. This means all themes will find this element. * We then need to register the widget class style. This is the layout * specification. If a different theme requires an alternative layout, we * could register that here. For instance, in some themes the scrollbars have @@ -285,17 +285,17 @@ { Ttk_Theme theme = Ttk_GetDefaultTheme(interp); /* register the new elements for this theme engine */ Ttk_RegisterElement(interp, theme, "square", &SquareElementSpec, NULL); - + /* register the layout for this theme */ Ttk_RegisterLayout(theme, "TSquare", SquareLayout); - + /* register the widget */ RegisterWidget(interp, "ttk::square", &SquareWidgetSpec); return TCL_OK; } #endif /* TTK_SQUARE_WIDGET */ Index: generic/ttk/ttkState.c ================================================================== --- generic/ttk/ttkState.c +++ generic/ttk/ttkState.c @@ -3,13 +3,11 @@ * * Copyright (c) 2003 Joe English. Freely redistributable. * */ -#include - -#include +#include "tkInt.h" #include "ttkTheme.h" /* * Table of state names. Must be kept in sync with TTK_STATE_* * #defines in ttkTheme.h. @@ -128,11 +126,12 @@ { unsigned int onbits = (objPtr->internalRep.longValue & 0xFFFF0000) >> 16; unsigned int offbits = objPtr->internalRep.longValue & 0x0000FFFF; unsigned int mask = onbits | offbits; Tcl_DString result; - int i, len; + int i; + size_t len; Tcl_DStringInit(&result); for (i=0; stateNames[i] != NULL; ++i) { if (mask & (1<bytes = Tcl_Alloc((unsigned)len); + objPtr->bytes = Tcl_Alloc(len); objPtr->length = len-1; - strncpy(objPtr->bytes, Tcl_DStringValue(&result), (size_t)len-1); + strncpy(objPtr->bytes, Tcl_DStringValue(&result), len-1); objPtr->bytes[len-1] = '\0'; } else { /* empty string */ objPtr->length = 0; objPtr->bytes = Tcl_Alloc(1); Index: generic/ttk/ttkStubLib.c ================================================================== --- generic/ttk/ttkStubLib.c +++ generic/ttk/ttkStubLib.c @@ -65,10 +65,10 @@ Tcl_ResetResult(interp); Tcl_AppendResult(interp, "Error loading ", packageName, " package", " (requested version '", version, "', loaded version '", actualVersion, "'): ", - errMsg, + errMsg, NULL); return NULL; } Index: generic/ttk/ttkTagSet.c ================================================================== --- generic/ttk/ttkTagSet.c +++ generic/ttk/ttkTagSet.c @@ -2,14 +2,11 @@ * Tag tables. 3/4-baked, work in progress. * * Copyright (C) 2005, Joe English. Freely redistributable. */ -#include /* for memset() */ -#include -#include - +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" /*------------------------------------------------------------------------ * +++ Internal data structures. @@ -186,11 +183,11 @@ for (i = 0; i < tagset->nTags; ++i) { if (tagset->tags[i] == tag) { return 0; } } - tagset->tags = ckrealloc(tagset->tags, + tagset->tags = ckrealloc(tagset->tags, (tagset->nTags+1)*sizeof(tagset->tags[0])); tagset->tags[tagset->nTags++] = tag; return 1; } Index: generic/ttk/ttkTheme.c ================================================================== --- generic/ttk/ttkTheme.c +++ generic/ttk/ttkTheme.c @@ -8,14 +8,11 @@ * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ -#include -#include -#include -#include +#include "tkInt.h" #include "ttkThemeInt.h" #define PKG_ASSOC_KEY "Ttk" /*------------------------------------------------------------------------ @@ -143,11 +140,11 @@ if (!optionSpec) return 0; /* Make sure widget option has a Tcl_Obj* entry: */ - if (optionSpec->objOffset < 0) { + if (optionSpec->objOffset == TCL_AUTO_LENGTH) { return 0; } /* Grrr. Ignore accidental mismatches caused by prefix-matching: */ @@ -971,33 +968,33 @@ static int InitializeElementRecord( Ttk_ElementClass *eclass, /* Element instance to initialize */ Ttk_Style style, /* Style table */ - char *widgetRecord, /* Source of widget option values */ + void *widgetRecord, /* Source of widget option values */ Tk_OptionTable optionTable, /* Option table describing widget record */ Tk_Window tkwin, /* Corresponding window */ Ttk_State state) /* Widget or element state */ { - char *elementRecord = eclass->elementRecord; + void *elementRecord = eclass->elementRecord; OptionMap optionMap = GetOptionMap(eclass,optionTable); int nResources = eclass->nResources; Ttk_ResourceCache cache = style->cache; Ttk_ElementOptionSpec *elementOption = eclass->specPtr->options; int i; for (i=0; ioffset); + ((char *)elementRecord + elementOption->offset); const char *optionName = elementOption->optionName; Tcl_Obj *dynamicSetting = Ttk_StyleMap(style, optionName, state); Tcl_Obj *widgetValue = 0; Tcl_Obj *elementDefault = eclass->defaultValues[i]; if (optionMap[i]) { widgetValue = *(Tcl_Obj **) - (widgetRecord + optionMap[i]->objOffset); + ((char *)widgetRecord + optionMap[i]->objOffset); } if (widgetValue) { *dest = widgetValue; } else if (dynamicSetting) { @@ -1065,11 +1062,11 @@ void Ttk_ElementSize( Ttk_ElementClass *eclass, /* Element to query */ Ttk_Style style, /* Style settings */ - char *recordPtr, /* The widget record. */ + void *recordPtr, /* The widget record. */ Tk_OptionTable optionTable, /* Description of widget record */ Tk_Window tkwin, /* The widget window. */ Ttk_State state, /* Current widget state */ int *widthPtr, /* Requested width */ int *heightPtr, /* Reqested height */ @@ -1095,11 +1092,11 @@ void Ttk_DrawElement( Ttk_ElementClass *eclass, /* Element instance */ Ttk_Style style, /* Style settings */ - char *recordPtr, /* The widget record. */ + void *recordPtr, /* The widget record. */ Tk_OptionTable optionTable, /* Description of option table */ Tk_Window tkwin, /* The widget window. */ Drawable d, /* Where to draw element. */ Ttk_Box b, /* Element area */ Ttk_State state) /* Widget or element state flags. */ @@ -1375,11 +1372,11 @@ */ static int StyleThemeCreateCmd( ClientData clientData, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { StylePackageData *pkgPtr = clientData; - static const char *optStrings[] = + static const char *const optStrings[] = { "-parent", "-settings", NULL }; enum { OP_PARENT, OP_SETTINGS }; Ttk_Theme parentTheme = pkgPtr->defaultTheme, newTheme; Tcl_Obj *settingsScript = NULL; const char *themeName; Index: generic/ttk/ttkTheme.h ================================================================== --- generic/ttk/ttkTheme.h +++ generic/ttk/ttkTheme.h @@ -231,16 +231,24 @@ typedef void (Ttk_ElementSizeProc)(void *clientData, void *elementRecord, Tk_Window tkwin, int *widthPtr, int *heightPtr, Ttk_Padding*); typedef void (Ttk_ElementDrawProc)(void *clientData, void *elementRecord, Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state); + +#ifndef TkSizeT +# if TCL_MAJOR_VERSION > 8 +# define TkSizeT size_t +# else +# define TkSizeT int +# endif +#endif typedef struct Ttk_ElementOptionSpec { const char *optionName; /* Command-line name of the widget option */ Tk_OptionType type; /* Accepted option types */ - int offset; /* Offset of Tcl_Obj* field in element record */ + TkSizeT offset; /* Offset of Tcl_Obj* field in element record */ const char *defaultValue; /* Default value to used if resource missing */ } Ttk_ElementOptionSpec; #define TK_OPTION_ANY TK_OPTION_STRING @@ -370,10 +378,12 @@ * +++ Image specifications. */ typedef struct TtkImageSpec Ttk_ImageSpec; TTKAPI Ttk_ImageSpec *TtkGetImageSpec(Tcl_Interp *, Tk_Window, Tcl_Obj *); +TTKAPI Ttk_ImageSpec *TtkGetImageSpecEx(Tcl_Interp *, Tk_Window, Tcl_Obj *, + Tk_ImageChangedProc *, ClientData); TTKAPI void TtkFreeImageSpec(Ttk_ImageSpec *); TTKAPI Tk_Image TtkSelectImage(Ttk_ImageSpec *, Ttk_State); /*------------------------------------------------------------------------ * +++ Miscellaneous enumerations. Index: generic/ttk/ttkThemeInt.h ================================================================== --- generic/ttk/ttkThemeInt.h +++ generic/ttk/ttkThemeInt.h @@ -13,15 +13,15 @@ MODULE_SCOPE Ttk_ElementClass *Ttk_GetElement(Ttk_Theme, const char *name); MODULE_SCOPE const char *Ttk_ElementClassName(Ttk_ElementClass *); MODULE_SCOPE void Ttk_ElementSize( - Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable, + Ttk_ElementClass *, Ttk_Style, void *recordPtr, Tk_OptionTable, Tk_Window tkwin, Ttk_State state, int *widthPtr, int *heightPtr, Ttk_Padding*); MODULE_SCOPE void Ttk_DrawElement( - Ttk_ElementClass *, Ttk_Style, char *recordPtr, Tk_OptionTable, + Ttk_ElementClass *, Ttk_Style, void *recordPtr, Tk_OptionTable, Tk_Window tkwin, Drawable d, Ttk_Box b, Ttk_State state); MODULE_SCOPE Tcl_Obj *Ttk_QueryStyle( Ttk_Style, void *, Tk_OptionTable, const char *, Ttk_State state); Index: generic/ttk/ttkTrace.c ================================================================== --- generic/ttk/ttkTrace.c +++ generic/ttk/ttkTrace.c @@ -1,15 +1,15 @@ /* * Copyright 2003, Joe English * * Simplified interface to Tcl_TraceVariable. * - * PROBLEM: Can't distinguish "variable does not exist" (which is OK) + * PROBLEM: Can't distinguish "variable does not exist" (which is OK) * from other errors (which are not). */ -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" struct TtkTraceHandle_ { @@ -24,21 +24,32 @@ */ static char * VarTraceProc( ClientData clientData, /* Widget record pointer */ Tcl_Interp *interp, /* Interpreter containing variable. */ - const char *name1, /* (unused) */ - const char *name2, /* (unused) */ + const char *name1, /* Name of variable. */ + const char *name2, /* Second part of variable name. */ int flags) /* Information about what happened. */ { Ttk_TraceHandle *tracePtr = clientData; const char *name, *value; Tcl_Obj *valuePtr; if (flags & TCL_INTERP_DESTROYED) { return NULL; } + + /* + * See ticket [5d991b82]. + */ + + if (tracePtr->varnameObj == NULL) { + Tcl_UntraceVar2(interp, name1, name2, + TCL_GLOBAL_ONLY|TCL_TRACE_WRITES|TCL_TRACE_UNSETS, + VarTraceProc, clientData); + return NULL; + } name = Tcl_GetString(tracePtr->varnameObj); /* * If the variable is being unset, then re-establish the trace: Index: generic/ttk/ttkTrack.c ================================================================== --- generic/ttk/ttkTrack.c +++ generic/ttk/ttkTrack.c @@ -21,11 +21,11 @@ * event. * * TODO: Handle "chords" properly (e.g., ) */ -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" typedef struct { WidgetCore *corePtr; /* widget to track */ Index: generic/ttk/ttkTreeview.c ================================================================== --- generic/ttk/ttkTreeview.c +++ generic/ttk/ttkTreeview.c @@ -2,13 +2,11 @@ * Copyright (c) 2004, Joe English * * ttk::treeview widget implementation. */ -#include -#include -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #define DEF_TREE_ROWS "10" #define DEF_COLWIDTH "200" @@ -319,18 +317,18 @@ #define SHOW_TREE (0x1) /* Show tree column? */ #define SHOW_HEADINGS (0x2) /* Show heading row? */ #define DEFAULT_SHOW "tree headings" -static const char *showStrings[] = { +static const char *const showStrings[] = { "tree", "headings", NULL }; static int GetEnumSetFromObj( Tcl_Interp *interp, Tcl_Obj *objPtr, - const char *table[], + const char *const table[], unsigned *resultPtr) { unsigned result = 0; int i, objc; Tcl_Obj **objv; @@ -433,11 +431,11 @@ #define COLUMNS_CHANGED (USER_MASK) #define DCOLUMNS_CHANGED (USER_MASK<<1) #define SCROLLCMD_CHANGED (USER_MASK<<2) #define SHOW_CHANGED (USER_MASK<<3) -static const char *SelectModeStrings[] = { "none", "browse", "extended", NULL }; +static const char *const SelectModeStrings[] = { "none", "browse", "extended", NULL }; static Tk_OptionSpec TreeviewOptionSpecs[] = { {TK_OPTION_STRING, "-columns", "columns", "Columns", "", Tk_Offset(Treeview,tree.columnsObj), -1, 0,0,COLUMNS_CHANGED | GEOMETRY_CHANGED /*| READONLY_OPTION*/ }, @@ -1129,11 +1127,11 @@ Tk_SavedOptions savedOptions; int mask; Ttk_ImageSpec *newImageSpec = NULL; Ttk_TagSet newTagSet = NULL; - if (Tk_SetOptions(interp, (ClientData)item, tv->tree.itemOptionTable, + if (Tk_SetOptions(interp, item, tv->tree.itemOptionTable, objc, objv, tv->core.tkwin, &savedOptions, &mask) != TCL_OK) { return TCL_ERROR; } @@ -1209,11 +1207,11 @@ int objc, Tcl_Obj *const objv[]) { Tk_SavedOptions savedOptions; int mask; - if (Tk_SetOptions(interp, (ClientData)column, + if (Tk_SetOptions(interp, column, tv->tree.columnOptionTable, objc, objv, tv->core.tkwin, &savedOptions,&mask) != TCL_OK) { return TCL_ERROR; } @@ -1255,11 +1253,11 @@ int objc, Tcl_Obj *const objv[]) { Tk_SavedOptions savedOptions; int mask; - if (Tk_SetOptions(interp, (ClientData)column, + if (Tk_SetOptions(interp, column, tv->tree.headingOptionTable, objc, objv, tv->core.tkwin, &savedOptions,&mask) != TCL_OK) { return TCL_ERROR; } @@ -1501,11 +1499,11 @@ REGION_SEPARATOR, REGION_TREE, REGION_CELL } TreeRegion; -static const char *regionStrings[] = { +static const char *const regionStrings[] = { "nothing", "heading", "separator", "tree", "cell", 0 }; static TreeRegion IdentifyRegion(Treeview *tv, int x, int y) { @@ -1823,11 +1821,11 @@ * Row number of the last item drawn. */ static int DrawForest( Treeview *tv, TreeItem *item, Drawable d, int depth, int row) { - while (item && row <= tv->tree.yscroll.last) { + while (item && row < tv->tree.yscroll.last) { row = DrawSubtree(tv, item, d, depth, row); item = item->next; } return row; } @@ -2264,11 +2262,11 @@ */ static int TreeviewIdentifyCommand( void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { - static const char *submethodStrings[] = + static const char *const submethodStrings[] = { "region", "item", "column", "row", "element", NULL }; enum { I_REGION, I_ITEM, I_COLUMN, I_ROW, I_ELEMENT }; Treeview *tv = recordPtr; int submethod; @@ -2930,11 +2928,11 @@ void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { enum { SELECTION_SET, SELECTION_ADD, SELECTION_REMOVE, SELECTION_TOGGLE }; - static const char *selopStrings[] = { + static const char *const selopStrings[] = { "set", "add", "remove", "toggle", NULL }; Treeview *tv = recordPtr; int selop, i; Index: generic/ttk/ttkWidget.c ================================================================== --- generic/ttk/ttkWidget.c +++ generic/ttk/ttkWidget.c @@ -2,12 +2,11 @@ * Copyright (c) 2003, Joe English * * Core widget utilities. */ -#include -#include +#include "tkInt.h" #include "ttkTheme.h" #include "ttkWidget.h" #ifdef MAC_OSX_TK #define TK_NO_DOUBLE_BUFFERING 1 @@ -755,11 +754,11 @@ int TtkWidgetIdentifyCommand( void *recordPtr, Tcl_Interp *interp, int objc, Tcl_Obj *const objv[]) { WidgetCore *corePtr = recordPtr; Ttk_Element element; - static const char *whatTable[] = { "element", NULL }; + static const char *const whatTable[] = { "element", NULL }; int x, y, what; if (objc < 4 || objc > 5) { Tcl_WrongNumArgs(interp, 2, objv, "?what? x y"); return TCL_ERROR; Index: generic/ttk/ttkWidget.h ================================================================== --- generic/ttk/ttkWidget.h +++ generic/ttk/ttkWidget.h @@ -109,12 +109,12 @@ Tcl_CreateObjCommand(interp, name, \ TtkWidgetConstructorObjCmd, (ClientData)specPtr,NULL) /* WIDGET_TAKEFOCUS_TRUE -- * WIDGET_TAKEFOCUS_FALSE -- - * Add one or the other of these to each OptionSpecs table - * to indicate whether the widget should take focus + * Add one or the other of these to each OptionSpecs table + * to indicate whether the widget should take focus * during keyboard traversal. */ #define WIDGET_TAKEFOCUS_TRUE \ {TK_OPTION_STRING, "-takefocus", "takeFocus", "TakeFocus", \ "ttk::takefocus", Tk_Offset(WidgetCore, takeFocusPtr), -1, 0,0,0 } Index: library/console.tcl ================================================================== --- library/console.tcl +++ library/console.tcl @@ -284,10 +284,11 @@ incr HistNum return } .console delete promptEnd end .console insert promptEnd $cmd {input stdin} + .console see end } next { incr HistNum if {$HistNum == 0} { set cmd {history event [expr {[history nextid] -1}]} @@ -300,10 +301,11 @@ if {$cmd ne ""} { catch {consoleinterp eval $cmd} cmd } .console delete promptEnd end .console insert promptEnd $cmd {input stdin} + .console see end } reset { set HistNum 1 } } Index: library/demos/combo.tcl ================================================================== --- library/demos/combo.tcl +++ library/demos/combo.tcl @@ -41,11 +41,12 @@ } set secondValue unchangable set ozCity Sydney ttk::labelframe $w.c1 -text "Fully Editable" -ttk::combobox $w.c1.c -textvariable firstValue +ttk::combobox $w.c1.c -textvariable firstValue -placeholder {Enter text here} +ttk::style configure TEntry -placeholderforeground gray50 ttk::labelframe $w.c2 -text Disabled ttk::combobox $w.c2.c -textvariable secondValue -state disabled ttk::labelframe $w.c3 -text "Defined List Only" ttk::combobox $w.c3.c -textvariable ozCity -state readonly \ -values $australianCities Index: library/demos/en.msg ================================================================== --- library/demos/en.msg +++ library/demos/en.msg @@ -16,11 +16,11 @@ ::msgcat::mcset en "Dismiss" ::msgcat::mcset en "Rerun Demo" ::msgcat::mcset en "Demo code: %s" ::msgcat::mcset en "About Widget Demo" ::msgcat::mcset en "Tk widget demonstration application" -::msgcat::mcset en "Copyright \u00a9 %s" +::msgcat::mcset en "Copyright © %s" ::msgcat::mcset en " @@title Tk Widget Demonstrations @@newline @@normal Index: library/demos/entry1.tcl ================================================================== --- library/demos/entry1.tcl +++ library/demos/entry1.tcl @@ -23,11 +23,11 @@ set btns [addSeeDismiss $w.buttons $w] pack $btns -side bottom -fill x entry $w.e1 entry $w.e2 -entry $w.e3 +entry $w.e3 -placeholder {Enter text here} -placeholderforeground gray75 pack $w.e1 $w.e2 $w.e3 -side top -pady 5 -padx 10 -fill x $w.e1 insert 0 "Initial value" $w.e2 insert end "This entry contains a long value, much too long " $w.e2 insert end "to fit in the window at one time, so long in fact " Index: library/demos/entry2.tcl ================================================================== --- library/demos/entry2.tcl +++ library/demos/entry2.tcl @@ -42,5 +42,6 @@ $w.frame.e1 insert 0 "Initial value" $w.frame.e2 insert end "This entry contains a long value, much too long " $w.frame.e2 insert end "to fit in the window at one time, so long in fact " $w.frame.e2 insert end "that you'll have to scan or scroll to see the end." +$w.frame.e3 configure -placeholder {Enter text here} -placeholderforeground gray75 ADDED library/demos/images/earthmenu.png Index: library/demos/images/earthmenu.png ================================================================== --- /dev/null +++ library/demos/images/earthmenu.png cannot compute difference between binary files Index: library/demos/menu.tcl ================================================================== --- library/demos/menu.tcl +++ library/demos/menu.tcl @@ -112,14 +112,16 @@ set m $w.menu.icon $w.menu add cascade -label "Icons" -menu $m -underline 0 menu $m -tearoff 0 # Main widget program sets variable tk_demoDirectory -$m add command -bitmap @[file join $tk_demoDirectory images pattern.xbm] \ +image create photo lilearth -file [file join $tk_demoDirectory \ +images earthmenu.png] +$m add command -image lilearth \ -hidemargin 1 -command [list \ tk_dialog $w.pattern {Bitmap Menu Entry} \ - "The menu entry you invoked displays a bitmap rather than\ + "The menu entry you invoked displays a photoimage rather than\ a text string. Other than this, it is just like any other\ menu entry." {} 0 OK ] foreach i {info questhead error} { $m add command -bitmap $i -hidemargin 1 -command [list \ puts "You invoked the $i bitmap" ] @@ -127,19 +129,26 @@ $m entryconfigure 2 -columnbreak 1 set m $w.menu.more $w.menu add cascade -label "More" -menu $m -underline 0 menu $m -tearoff 0 -foreach i {{An entry} {Another entry} {Does nothing} {Does almost nothing} {Make life meaningful}} { +foreach i {{An entry} {Another entry} {Does nothing} {Does almost nothing} {Does almost nothing also} {Make life meaningful}} { $m add command -label $i -command [list puts "You invoked \"$i\""] } $m entryconfigure "Does almost nothing" -bitmap questhead -compound left \ -command [list \ tk_dialog $w.compound {Compound Menu Entry} \ "The menu entry you invoked displays both a bitmap and a\ text string. Other than this, it is just like any other\ menu entry." {} 0 OK ] + +$m entryconfigure "Does almost nothing also" -image lilearth -compound left \ + -command [list \ + tk_dialog $w.compound {Compound Menu Entry} \ + "The menu entry you invoked displays both a image and a\ + text string. Other than this, it is just like any other\ + menu entry." {} 0 OK ] set m $w.menu.colors $w.menu add cascade -label "Colors" -menu $m -underline 1 menu $m -tearoff 1 foreach i {red orange yellow green blue} { Index: library/demos/nl.msg ================================================================== --- library/demos/nl.msg +++ library/demos/nl.msg @@ -16,13 +16,13 @@ ::msgcat::mcset nl "Run the \"%s\" sample program" "Start voorbeeld \"%s\"" ::msgcat::mcset nl "Print Code" "Code Afdrukken" ::msgcat::mcset nl "Demo code: %s" "Code van Demo %s" ::msgcat::mcset nl "About Widget Demo" "Over deze demonstratie" ::msgcat::mcset nl "Tk widget demonstration" "Demonstratie van Tk widgets" -::msgcat::mcset nl "Copyright \u00a9 %s" +::msgcat::mcset nl "Copyright © %s" -::msgcat::mcset nl "Tk Widget Demonstrations" "Demostratie van Tk widgets" +::msgcat::mcset nl "Tk Widget Demonstrations" "Demonstratie van Tk widgets" ::msgcat::mcset nl "This application provides a front end for several short scripts" \ "Dit programma is een schil rond enkele korte scripts waarmee" ::msgcat::mcset nl "that demonstrate what you can do with Tk widgets. Each of the" \ "gedemonstreerd wordt wat je kunt doen met Tk widgets. Elk van de" ::msgcat::mcset nl "numbered lines below describes a demonstration; you can click on" \ Index: library/demos/tree.tcl ================================================================== --- library/demos/tree.tcl +++ library/demos/tree.tcl @@ -37,10 +37,11 @@ return } set path [$tree set $node fullpath] $tree delete [$tree children $node] foreach f [lsort -dictionary [glob -nocomplain -dir $path *]] { + set f [file normalize $f] set type [file type $f] set id [$tree insert $node end -text [file tail $f] \ -values [list $f $type]] if {$type eq "directory"} { Index: library/demos/twind.tcl ================================================================== --- library/demos/twind.tcl +++ library/demos/twind.tcl @@ -81,16 +81,16 @@ $t window create end \ -create {button %W.peer -text "Make A Peer" -command "textMakePeer %W" \ -cursor top_left_arrow} -padx 3 $t insert end " widget. Notice how peer widgets can have different " $t insert end "font settings, and by default contain all the images " -$t insert end "of the 'parent', but many of the embedded windows, " -$t insert end "such as buttons will not be there. The easiest way " -$t insert end "to ensure they are in all peers is to use '-create' " -$t insert end "embedded window creation scripts " -$t insert end "(the plot above and the 'Make A Peer' button are " -$t insert end "designed to show up in all peers). A good use of " +$t insert end "of the 'parent', but that the embedded windows, " +$t insert end "such as buttons may not appear in the peer. To ensure " +$t insert end "that embedded windows appear in all peers you can set the " +$t insert end "'-create' option to a script or a string containing %W. " +$t insert end "(The plot above and the 'Make A Peer' button are " +$t insert end "designed to show up in all peers.) A good use of " $t insert end "peers is for " $t window create end \ -create {button %W.split -text "Split Windows" -command "textSplitWindow %W" \ -cursor top_left_arrow} -padx 3 $t insert end " \n\n" @@ -110,10 +110,11 @@ $t insert end "\"Short\", it changes to a longer string so that " $t insert end "you can see how the text widget automatically " $t insert end "changes the layout. Click on the button again " $t insert end "to restore the short string.\n" +$t insert end "\nNOTE: these buttons will not appear in peers!\n" "peer_warning" button $t.default -text Default -command "embDefBg $t" \ -cursor top_left_arrow $t window create end -window $t.default -padx 3 global embToggle set embToggle Short @@ -161,11 +162,10 @@ $t insert end "\n\nFinally, images fit comfortably in text widgets too:" $t image create end -image \ [image create photo -file [file join $tk_demoDirectory images ouster.png]] - proc textWindBigB w { $w configure -borderwidth 15 } @@ -300,10 +300,11 @@ set w [toplevel .peer$n] wm title $w "Text Peer #$n" frame $w.f -highlightthickness 1 -borderwidth 1 -relief sunken set t [$parent peer create $w.f.text -yscrollcommand "$w.scroll set" \ -borderwidth 0 -highlightthickness 0] + $t tag configure peer_warning -font boldFont pack $t -expand yes -fill both ttk::scrollbar $w.scroll -command "$t yview" pack $w.scroll -side right -fill y pack $w.f -expand yes -fill both } @@ -315,11 +316,12 @@ } else { set parent [winfo parent $textW] set w [winfo parent $parent] set t [$textW peer create $w.peer \ -yscrollcommand "$w.scroll set"] + $t tag configure peer_warning -font boldFont $w.pane add $t } } else { return } } Index: library/fontchooser.tcl ================================================================== --- library/fontchooser.tcl +++ library/fontchooser.tcl @@ -63,10 +63,13 @@ if {![winfo exists $S(W)]} { Create wm transient $S(W) [winfo toplevel $S(-parent)] tk::PlaceWindow $S(W) widget $S(-parent) } + set S(fonts) [lsort -dictionary [font families]] + set S(fonts,lcase) {} + foreach font $S(fonts) { lappend S(fonts,lcase) [string tolower $font]} wm deiconify $S(W) } proc ::tk::fontchooser::Hide {} { variable S Index: library/images/logo.eps ================================================================== --- library/images/logo.eps +++ library/images/logo.eps @@ -26,11 +26,11 @@ %AI5_OpenViewLayers: 7 %%EndComments %%BeginProlog %%BeginResource: procset Adobe_level2_AI5 1.0 0 %%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation) -%%Version: 1.0 +%%Version: 1.0 %%CreationDate: (04/10/93) () %%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved) userdict /Adobe_level2_AI5 21 dict dup begin put /packedarray where not @@ -75,11 +75,11 @@ 5 -1 roll pop setcmykcolor } def } if - + /gt38? mark {version cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put userdict /level2? systemdict /languagelevel known dup { @@ -176,11 +176,11 @@ } if end defaultpacking setpacking %%EndResource %%BeginResource: procset Adobe_IllustratorA_AI5 1.1 0 %%Title: (Adobe Illustrator (R) Version 5.0 Abbreviated Prolog) -%%Version: 1.1 +%%Version: 1.1 %%CreationDate: (3/7/1994) () %%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved) currentpacking true setpacking userdict /Adobe_IllustratorA_AI5_vars 70 dict dup begin put @@ -1060,11 +1060,11 @@ { (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard } { /clipForward? true def - + /Tx /pop load def /Tj /pop load def currentdict end clipRenderOff begin begin } ifelse } @@ -1087,11 +1087,11 @@ { currentdict end end begin - + /clipForward? false ddef } if } ifelse } bind def /Pb Index: library/images/pwrdLogo.eps ================================================================== --- library/images/pwrdLogo.eps +++ library/images/pwrdLogo.eps @@ -26,11 +26,11 @@ %AI5_OpenViewLayers: 7 %%EndComments %%BeginProlog %%BeginResource: procset Adobe_level2_AI5 1.0 0 %%Title: (Adobe Illustrator (R) Version 5.0 Level 2 Emulation) -%%Version: 1.0 +%%Version: 1.0 %%CreationDate: (04/10/93) () %%Copyright: ((C) 1987-1993 Adobe Systems Incorporated All Rights Reserved) userdict /Adobe_level2_AI5 21 dict dup begin put /packedarray where not @@ -75,11 +75,11 @@ 5 -1 roll pop setcmykcolor } def } if - + /gt38? mark {version cvx exec} stopped {cleartomark true} {38 gt exch pop} ifelse def userdict /deviceDPI 72 0 matrix defaultmatrix dtransform dup mul exch dup mul add sqrt put userdict /level2? systemdict /languagelevel known dup { @@ -176,11 +176,11 @@ } if end defaultpacking setpacking %%EndResource %%BeginResource: procset Adobe_IllustratorA_AI5 1.1 0 %%Title: (Adobe Illustrator (R) Version 5.0 Abbreviated Prolog) -%%Version: 1.1 +%%Version: 1.1 %%CreationDate: (3/7/1994) () %%Copyright: ((C) 1987-1994 Adobe Systems Incorporated All Rights Reserved) currentpacking true setpacking userdict /Adobe_IllustratorA_AI5_vars 70 dict dup begin put @@ -1060,11 +1060,11 @@ { (%AI5_BeginLayer) 1 (%AI5_EndLayer--) discard } { /clipForward? true def - + /Tx /pop load def /Tj /pop load def currentdict end clipRenderOff begin begin } ifelse } @@ -1087,11 +1087,11 @@ { currentdict end end begin - + /clipForward? false ddef } if } ifelse } bind def /Pb Index: library/listbox.tcl ================================================================== --- library/listbox.tcl +++ library/listbox.tcl @@ -12,11 +12,11 @@ #-------------------------------------------------------------------------- # tk::Priv elements used in this file: # # afterId - Token returned by "after" for autoscanning. -# listboxPrev - The last element to be selected or deselected +# listboxPrev - The last element to be selected or deselected # during a selection operation. # listboxSelection - All of the items that were selected before the # current selection operation (such as a mouse # drag) started; used to cancel an operation. #-------------------------------------------------------------------------- @@ -204,11 +204,11 @@ if {"x11" eq [tk windowingsystem]} { # Support for mousewheels on Linux/Unix commonly comes through mapping # the wheel to the extended buttons. If you have a mousewheel, find # Linux configuration info at: - # http://www.inria.fr/koala/colas/mouse-wheel-scroll/ + # http://linuxreviews.org/howtos/xfree/mouse/ bind Listbox <4> { if {!$tk_strictMotif} { %W yview scroll -5 units } } Index: library/menu.tcl ================================================================== --- library/menu.tcl +++ library/menu.tcl @@ -168,10 +168,11 @@ bind Menu <> { tk::MenuDownArrow %W } bind Menu { tk::TraverseWithinMenu %W %A + break } # The following bindings apply to all windows, and are used to # implement keyboard menu traversal. @@ -606,11 +607,13 @@ if {![winfo viewable $menu]} { return } if {[$menu index active] eq "none"} { - set Priv(window) {} + if {[$menu cget -type] ne "menubar" } { + set Priv(window) {} + } return } $menu postcascade active if {$Priv(postedMb) ne "" && [winfo viewable $Priv(postedMb)]} { grab -global $Priv(postedMb) Index: library/msgbox.tcl ================================================================== --- library/msgbox.tcl +++ library/msgbox.tcl @@ -232,11 +232,12 @@ break } } if {!$valid} { return -code error -errorcode {TK MSGBOX DEFAULT} \ - "invalid default button \"$data(-default)\"" + "bad -default value \"$data(-default)\": must be\ + abort, retry, ignore, ok, cancel, no, or yes" } # 2. Set the dialog to be a child window of $parent # # Index: library/msgs/cs.msg ================================================================== --- library/msgs/cs.msg +++ library/msgs/cs.msg @@ -1,77 +1,77 @@ namespace eval ::tk { - ::msgcat::mcset cs "&Abort" "&P\u0159eru\u0161it" + ::msgcat::mcset cs "&Abort" "&PÅ™eruÅ¡it" ::msgcat::mcset cs "&About..." "&O programu..." - ::msgcat::mcset cs "All Files" "V\u0161echny soubory" + ::msgcat::mcset cs "All Files" "VÅ¡echny soubory" ::msgcat::mcset cs "Application Error" "Chyba programu" ::msgcat::mcset cs "Bold Italic" - ::msgcat::mcset cs "&Blue" "&Modr\341" - ::msgcat::mcset cs "Cancel" "Zru\u0161it" - ::msgcat::mcset cs "&Cancel" "&Zru\u0161it" - ::msgcat::mcset cs "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nemohu zm\u011bnit atku\341ln\355 adres\341\u0159 na \"%1\$s\".\nP\u0159\355stup odm\355tnut." - ::msgcat::mcset cs "Choose Directory" "V\375b\u011br adres\341\u0159e" + ::msgcat::mcset cs "&Blue" "&Modá" + ::msgcat::mcset cs "Cancel" "ZruÅ¡it" + ::msgcat::mcset cs "&Cancel" "&ZruÅ¡it" + ::msgcat::mcset cs "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nemohu zmÄ›nit atkálí adreář na \"%1\$s\".\nPístup odítnut." + ::msgcat::mcset cs "Choose Directory" "ýbÄ›r adreáře" ::msgcat::mcset cs "Cl&ear" "Sma&zat" ::msgcat::mcset cs "&Clear Console" "&Smazat konzolu" ::msgcat::mcset cs "Color" "Barva" ::msgcat::mcset cs "Console" "Konzole" - ::msgcat::mcset cs "&Copy" "&Kop\355rovat" - ::msgcat::mcset cs "Cu&t" "V&y\u0159\355znout" + ::msgcat::mcset cs "&Copy" "&Koírovat" + ::msgcat::mcset cs "Cu&t" "V&yíznout" ::msgcat::mcset cs "&Delete" "&Smazat" ::msgcat::mcset cs "Details >>" "Detaily >>" - ::msgcat::mcset cs "Directory \"%1\$s\" does not exist." "Adres\341\u0159 \"%1\$s\" neexistuje." - ::msgcat::mcset cs "&Directory:" "&Adres\341\u0159:" - ::msgcat::mcset cs "&Edit" "&\332pravy" + ::msgcat::mcset cs "Directory \"%1\$s\" does not exist." "Adreář \"%1\$s\" neexistuje." + ::msgcat::mcset cs "&Directory:" "&Adreář:" + ::msgcat::mcset cs "&Edit" "Úpravy" ::msgcat::mcset cs "Error: %1\$s" "Chyba: %1\$s" ::msgcat::mcset cs "E&xit" "&Konec" ::msgcat::mcset cs "&File" "&Soubor" - ::msgcat::mcset cs "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Soubor \"%1\$s\" ji\u017e existuje.\nChcete jej p\u0159epsat?" - ::msgcat::mcset cs "File \"%1\$s\" already exists.\n\n" "Soubor \"%1\$s\" ji\u017e existuje.\n\n" + ::msgcat::mcset cs "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Soubor \"%1\$s\" již existuje.\nChcete jej pÅ™epsat?" + ::msgcat::mcset cs "File \"%1\$s\" already exists.\n\n" "Soubor \"%1\$s\" již existuje.\n\n" ::msgcat::mcset cs "File \"%1\$s\" does not exist." "Soubor \"%1\$s\" neexistuje." - ::msgcat::mcset cs "File &name:" "&Jm\351no souboru:" - ::msgcat::mcset cs "File &names:" "&Jm\351na soubor\u016f:" - ::msgcat::mcset cs "Files of &type:" "&Typy soubor\u016f:" + ::msgcat::mcset cs "File &name:" "&Jéno souboru:" + ::msgcat::mcset cs "File &names:" "&Jéna souborů:" + ::msgcat::mcset cs "Files of &type:" "&Typy souborů:" ::msgcat::mcset cs "Fi&les:" "Sou&bory:" ::msgcat::mcset cs "&Filter" "&Filtr" ::msgcat::mcset cs "Fil&ter:" "Fil&tr:" ::msgcat::mcset cs "Font st&yle:" - ::msgcat::mcset cs "&Green" "Ze&len\341" - ::msgcat::mcset cs "&Help" "&N\341pov\u011bda" + ::msgcat::mcset cs "&Green" "Ze&leá" + ::msgcat::mcset cs "&Help" "&ápovÄ›da" ::msgcat::mcset cs "Hi" "Ahoj" ::msgcat::mcset cs "&Hide Console" "&Schovat Konzolu" ::msgcat::mcset cs "&Ignore" "&Ignorovat" - ::msgcat::mcset cs "Invalid file name \"%1\$s\"." "\u0160patn\351 jm\351no souboru \"%1\$s\"." + ::msgcat::mcset cs "Invalid file name \"%1\$s\"." "Å paté jéno souboru \"%1\$s\"." ::msgcat::mcset cs "Log Files" "Log soubory" ::msgcat::mcset cs "&No" "&Ne" ::msgcat::mcset cs "&OK" ::msgcat::mcset cs "OK" ::msgcat::mcset cs "Ok" - ::msgcat::mcset cs "Open" "Otev\u0159\355t" - ::msgcat::mcset cs "&Open" "&Otev\u0159\355t" - ::msgcat::mcset cs "Open Multiple Files" "Otev\u0159\355t v\355ce soubor\u016f" - ::msgcat::mcset cs "P&aste" "&Vlo\u017eit" - ::msgcat::mcset cs "&Quit" "&Ukon\u010dit" - ::msgcat::mcset cs "&Red" "\u010ce&rven\341" - ::msgcat::mcset cs "Replace existing file?" "Nahradit st\341vaj\355c\355 soubor?" + ::msgcat::mcset cs "Open" "Otevít" + ::msgcat::mcset cs "&Open" "&Otevít" + ::msgcat::mcset cs "Open Multiple Files" "Otevít íce souborů" + ::msgcat::mcset cs "P&aste" "&Vložit" + ::msgcat::mcset cs "&Quit" "&UkonÄit" + ::msgcat::mcset cs "&Red" "ÄŒe&rveá" + ::msgcat::mcset cs "Replace existing file?" "Nahradit sávaíí soubor?" ::msgcat::mcset cs "&Retry" "Z&novu" - ::msgcat::mcset cs "&Save" "&Ulo\u017eit" - ::msgcat::mcset cs "Save As" "Ulo\u017eit jako" - ::msgcat::mcset cs "Save To Log" "Ulo\u017eit do logu" + ::msgcat::mcset cs "&Save" "&Uložit" + ::msgcat::mcset cs "Save As" "Uložit jako" + ::msgcat::mcset cs "Save To Log" "Uložit do logu" ::msgcat::mcset cs "Select Log File" "Vybrat log soubor" - ::msgcat::mcset cs "Select a file to source" "Vybrat soubor k nahr\341n\355" - ::msgcat::mcset cs "&Selection:" "&V\375b\u011br:" - ::msgcat::mcset cs "Skip Messages" "P\u0159esko\u010dit zpr\341vy" + ::msgcat::mcset cs "Select a file to source" "Vybrat soubor k naháí" + ::msgcat::mcset cs "&Selection:" "&ýbÄ›r:" + ::msgcat::mcset cs "Skip Messages" "PÅ™eskoÄit zpávy" ::msgcat::mcset cs "&Source..." "&Zdroj..." ::msgcat::mcset cs "Tcl Scripts" "Tcl skripty" ::msgcat::mcset cs "Tcl for Windows" "Tcl pro Windows" - ::msgcat::mcset cs "Text Files" "Textov\351 soubory" - ::msgcat::mcset cs "abort" "p\u0159eru\u0161it" - ::msgcat::mcset cs "blue" "modr\341" - ::msgcat::mcset cs "cancel" "zru\u0161it" - ::msgcat::mcset cs "extension" "p\u0159\355pona" - ::msgcat::mcset cs "extensions" "p\u0159\355pony" - ::msgcat::mcset cs "green" "zelen\341" + ::msgcat::mcset cs "Text Files" "Textoé soubory" + ::msgcat::mcset cs "abort" "pÅ™eruÅ¡it" + ::msgcat::mcset cs "blue" "modá" + ::msgcat::mcset cs "cancel" "zruÅ¡it" + ::msgcat::mcset cs "extension" "pípona" + ::msgcat::mcset cs "extensions" "pípony" + ::msgcat::mcset cs "green" "zeleá" ::msgcat::mcset cs "ignore" "ignorovat" ::msgcat::mcset cs "ok" - ::msgcat::mcset cs "red" "\u010derven\341" + ::msgcat::mcset cs "red" "Äerveá" ::msgcat::mcset cs "retry" "znovu" ::msgcat::mcset cs "yes" "ano" } Index: library/msgs/de.msg ================================================================== --- library/msgs/de.msg +++ library/msgs/de.msg @@ -1,34 +1,34 @@ namespace eval ::tk { ::msgcat::mcset de "&Abort" "&Abbruch" - ::msgcat::mcset de "&About..." "&\u00dcber..." + ::msgcat::mcset de "&About..." "&Ãœber..." ::msgcat::mcset de "All Files" "Alle Dateien" ::msgcat::mcset de "Application Error" "Applikationsfehler" ::msgcat::mcset de "&Apply" "&Anwenden" ::msgcat::mcset de "Bold" "Fett" ::msgcat::mcset de "Bold Italic" "Fett kursiv" ::msgcat::mcset de "&Blue" "&Blau" ::msgcat::mcset de "Cancel" "Abbruch" ::msgcat::mcset de "&Cancel" "&Abbruch" ::msgcat::mcset de "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kann nicht in das Verzeichnis \"%1\$s\" wechseln.\nKeine Rechte vorhanden." - ::msgcat::mcset de "Choose Directory" "W\u00e4hle Verzeichnis" - ::msgcat::mcset de "Cl&ear" "&R\u00fccksetzen" - ::msgcat::mcset de "&Clear Console" "&Konsole l\u00f6schen" + ::msgcat::mcset de "Choose Directory" "Wähle Verzeichnis" + ::msgcat::mcset de "Cl&ear" "&Rücksetzen" + ::msgcat::mcset de "&Clear Console" "&Konsole löschen" ::msgcat::mcset de "Color" "Farbe" ::msgcat::mcset de "Console" "Konsole" ::msgcat::mcset de "&Copy" "&Kopieren" ::msgcat::mcset de "Cu&t" "Aus&schneiden" - ::msgcat::mcset de "&Delete" "&L\u00f6schen" + ::msgcat::mcset de "&Delete" "&Löschen" ::msgcat::mcset de "Details >>" ::msgcat::mcset de "Directory \"%1\$s\" does not exist." "Das Verzeichnis \"%1\$s\" existiert nicht." ::msgcat::mcset de "&Directory:" "&Verzeichnis:" ::msgcat::mcset de "&Edit" "&Bearbeiten" ::msgcat::mcset de "Effects" "Effekte" ::msgcat::mcset de "Error: %1\$s" "Fehler: %1\$s" ::msgcat::mcset de "E&xit" "&Ende" ::msgcat::mcset de "&File" "&Datei" - ::msgcat::mcset de "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Die Datei \"%1\$s\" ist bereits vorhanden.\nWollen sie diese Datei \u00fcberschreiben ?" + ::msgcat::mcset de "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Die Datei \"%1\$s\" ist bereits vorhanden.\nWollen sie diese Datei überschreiben ?" ::msgcat::mcset de "File \"%1\$s\" already exists.\n\n" "Die Datei \"%1\$s\" ist bereits vorhanden.\n\n" ::msgcat::mcset de "File \"%1\$s\" does not exist." "Die Datei \"%1\$s\" existiert nicht." ::msgcat::mcset de "File &name:" "Datei&name:" ::msgcat::mcset de "File &names:" "Datei&namen:" ::msgcat::mcset de "Files of &type:" "Dateien des &Typs:" @@ -36,56 +36,56 @@ ::msgcat::mcset de "&Filter" ::msgcat::mcset de "Fil&ter:" ::msgcat::mcset de "Font" "Schriftart" ::msgcat::mcset de "&Font:" "Schriftart:" ::msgcat::mcset de "Font st&yle:" "Schriftschnitt:" - ::msgcat::mcset de "&Green" "&Gr\u00fcn" + ::msgcat::mcset de "&Green" "&Grün" ::msgcat::mcset de "&Help" "&Hilfe" ::msgcat::mcset de "Hi" "Hallo" ::msgcat::mcset de "&Hide Console" "&Konsole unsichtbar machen" ::msgcat::mcset de "&Ignore" "&Ignorieren" - ::msgcat::mcset de "Invalid file name \"%1\$s\"." "Ung\u00fcltiger Dateiname \"%1\$s\"." + ::msgcat::mcset de "Invalid file name \"%1\$s\"." "Ungültiger Dateiname \"%1\$s\"." ::msgcat::mcset de "Italic" "Kursiv" ::msgcat::mcset de "Log Files" "Protokolldatei" ::msgcat::mcset de "&No" "&Nein" ::msgcat::mcset de "&OK" ::msgcat::mcset de "OK" ::msgcat::mcset de "Ok" - ::msgcat::mcset de "Open" "\u00d6ffnen" - ::msgcat::mcset de "&Open" "\u00d6&ffnen" + ::msgcat::mcset de "Open" "Öffnen" + ::msgcat::mcset de "&Open" "Ö&ffnen" ::msgcat::mcset de "Open Multiple Files" "Mehrere Dateien \u00F6ffnen" - ::msgcat::mcset de "P&aste" "E&inf\u00fcgen" + ::msgcat::mcset de "P&aste" "E&infügen" ::msgcat::mcset de "&Quit" "&Beenden" ::msgcat::mcset de "&Red" "&Rot" ::msgcat::mcset de "Regular" "Standard" ::msgcat::mcset de "Replace existing file?" "Existierende Datei ersetzen?" ::msgcat::mcset de "&Retry" "&Wiederholen" ::msgcat::mcset de "Sample" "Beispiel" ::msgcat::mcset de "&Save" "&Speichern" ::msgcat::mcset de "Save As" "Speichern unter" ::msgcat::mcset de "Save To Log" "In Protokoll speichern" - ::msgcat::mcset de "Select Log File" "Protokolldatei ausw\u00e4hlen" - ::msgcat::mcset de "Select a file to source" "Auszuf\u00fchrende Datei ausw\u00e4hlen" + ::msgcat::mcset de "Select Log File" "Protokolldatei auswählen" + ::msgcat::mcset de "Select a file to source" "Auszuführende Datei auswählen" ::msgcat::mcset de "&Selection:" "Auswah&l:" ::msgcat::mcset de "&Size:" "Schriftgrad:" ::msgcat::mcset de "Show &Hidden Directories" "Zeige versteckte Dateien" ::msgcat::mcset de "Show &Hidden Files and Directories" "Zeige versteckte Dateien und Verzeichnisse" - ::msgcat::mcset de "Skip Messages" "Weitere Nachrichten \u00fcberspringen" - ::msgcat::mcset de "&Source..." "&Ausf\u00fchren..." + ::msgcat::mcset de "Skip Messages" "Weitere Nachrichten überspringen" + ::msgcat::mcset de "&Source..." "&Ausführen..." ::msgcat::mcset de "Stri&keout" "&Durchgestrichen" ::msgcat::mcset de "Tcl Scripts" "Tcl-Skripte" - ::msgcat::mcset de "Tcl for Windows" "Tcl f\u00fcr Windows" + ::msgcat::mcset de "Tcl for Windows" "Tcl für Windows" ::msgcat::mcset de "Text Files" "Textdateien" ::msgcat::mcset de "&Underline" "&Unterstrichen" ::msgcat::mcset de "&Yes" "&Ja" ::msgcat::mcset de "abort" "abbrechen" ::msgcat::mcset de "blue" "blau" ::msgcat::mcset de "cancel" "abbrechen" ::msgcat::mcset de "extension" "Erweiterung" ::msgcat::mcset de "extensions" "Erweiterungen" - ::msgcat::mcset de "green" "gr\u00fcn" + ::msgcat::mcset de "green" "grün" ::msgcat::mcset de "ignore" "ignorieren" ::msgcat::mcset de "ok" ::msgcat::mcset de "red" "rot" ::msgcat::mcset de "retry" "wiederholen" ::msgcat::mcset de "yes" "ja" } Index: library/msgs/el.msg ================================================================== --- library/msgs/el.msg +++ library/msgs/el.msg @@ -1,86 +1,86 @@ ## Messages for the Greek (Hellenic - "el") language. ## Please report any changes/suggestions to: ## petasis@iit.demokritos.gr namespace eval ::tk { - ::msgcat::mcset el "&Abort" "\u03a4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2" - ::msgcat::mcset el "About..." "\u03a3\u03c7\u03b5\u03c4\u03b9\u03ba\u03ac..." - ::msgcat::mcset el "All Files" "\u038c\u03bb\u03b1 \u03c4\u03b1 \u0391\u03c1\u03c7\u03b5\u03af\u03b1" - ::msgcat::mcset el "Application Error" "\u039b\u03ac\u03b8\u03bf\u03c2 \u0395\u03c6\u03b1\u03c1\u03bc\u03bf\u03b3\u03ae\u03c2" - ::msgcat::mcset el "&Blue" "\u039c\u03c0\u03bb\u03b5" - ::msgcat::mcset el "&Cancel" "\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7" + ::msgcat::mcset el "&Abort" "ΤεÏματισμός" + ::msgcat::mcset el "About..." "Σχετικά..." + ::msgcat::mcset el "All Files" "Όλα τα ΑÏχεία" + ::msgcat::mcset el "Application Error" "Λάθος ΕφαÏμογής" + ::msgcat::mcset el "&Blue" "Μπλε" + ::msgcat::mcset el "&Cancel" "ΑκÏÏωση" ::msgcat::mcset el \ "Cannot change to the directory \"%1\$s\".\nPermission denied." \ -"\u0394\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b4\u03c5\u03bd\u03b1\u03c4\u03ae \u03b7 \u03b1\u03bb\u03bb\u03b1\u03b3\u03ae \u03ba\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5 \u03c3\u03b5 \"%1\$s\".\n\u0397 \u03c0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7 \u03b4\u03b5\u03bd \u03b5\u03c0\u03b9\u03c4\u03c1\u03ad\u03c0\u03b5\u03c4\u03b1\u03b9." - ::msgcat::mcset el "Choose Directory" "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u039a\u03b1\u03c4\u03b1\u03bb\u03cc\u03b3\u03bf\u03c5" - ::msgcat::mcset el "Clear" "\u039a\u03b1\u03b8\u03b1\u03c1\u03b9\u03c3\u03bc\u03cc\u03c2" - ::msgcat::mcset el "Color" "\u03a7\u03c1\u03ce\u03bc\u03b1" - ::msgcat::mcset el "Console" "\u039a\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1" - ::msgcat::mcset el "Copy" "\u0391\u03bd\u03c4\u03b9\u03b3\u03c1\u03b1\u03c6\u03ae" - ::msgcat::mcset el "Cut" "\u0391\u03c0\u03bf\u03ba\u03bf\u03c0\u03ae" - ::msgcat::mcset el "Delete" "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae" - ::msgcat::mcset el "Details >>" "\u039b\u03b5\u03c0\u03c4\u03bf\u03bc\u03ad\u03c1\u03b5\u03b9\u03b5\u03c2 >>" +"Δεν είναι δυνατή η αλλαγή καταλόγου σε \"%1\$s\".\nΗ Ï€Ïόσβαση δεν επιτÏέπεται." + ::msgcat::mcset el "Choose Directory" "Επιλογή Καταλόγου" + ::msgcat::mcset el "Clear" "ΚαθαÏισμός" + ::msgcat::mcset el "Color" "ΧÏώμα" + ::msgcat::mcset el "Console" "Κονσόλα" + ::msgcat::mcset el "Copy" "ΑντιγÏαφή" + ::msgcat::mcset el "Cut" "Αποκοπή" + ::msgcat::mcset el "Delete" "ΔιαγÏαφή" + ::msgcat::mcset el "Details >>" "ΛεπτομέÏειες >>" ::msgcat::mcset el "Directory \"%1\$s\" does not exist." \ - "\u039f \u03ba\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2 \"%1\$s\" \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9." - ::msgcat::mcset el "&Directory:" "&\u039a\u03b1\u03c4\u03ac\u03bb\u03bf\u03b3\u03bf\u03c2:" - ::msgcat::mcset el "Error: %1\$s" "\u039b\u03ac\u03b8\u03bf\u03c2: %1\$s" - ::msgcat::mcset el "Exit" "\u0388\u03be\u03bf\u03b4\u03bf\u03c2" + "Ο κατάλογος \"%1\$s\" δεν υπάÏχει." + ::msgcat::mcset el "&Directory:" "&Κατάλογος:" + ::msgcat::mcset el "Error: %1\$s" "Λάθος: %1\$s" + ::msgcat::mcset el "Exit" "Έξοδος" ::msgcat::mcset el \ "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \ - "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.\n\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b5\u03c0\u03b9\u03ba\u03b1\u03bb\u03c5\u03c6\u03b8\u03b5\u03af;" + "Το αÏχείο \"%1\$s\" ήδη υπάÏχει.\nΘέλετε να επικαλυφθεί;" ::msgcat::mcset el "File \"%1\$s\" already exists.\n\n" \ - "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03ae\u03b4\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9.\n\n" + "Το αÏχείο \"%1\$s\" ήδη υπάÏχει.\n\n" ::msgcat::mcset el "File \"%1\$s\" does not exist." \ - "\u03a4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \"%1\$s\" \u03b4\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03b5\u03b9." - ::msgcat::mcset el "File &name:" "\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5:" - ::msgcat::mcset el "File &names:" "\u038c&\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd:" - ::msgcat::mcset el "Files of &type:" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u03c4\u03bf\u03c5 &\u03c4\u03cd\u03c0\u03bf\u03c5:" - ::msgcat::mcset el "Fi&les:" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1:" - ::msgcat::mcset el "&Filter" "\u03a6\u03af\u03bb\u03c4\u03c1\u03bf" - ::msgcat::mcset el "Fil&ter:" "\u03a6\u03af\u03bb\u03c4\u03c1\u03bf:" - ::msgcat::mcset el "&Green" "\u03a0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf" - ::msgcat::mcset el "Hi" "\u0393\u03b5\u03b9\u03b1" - ::msgcat::mcset el "Hide Console" "\u0391\u03c0\u03cc\u03ba\u03c1\u03c5\u03c8\u03b7 \u03ba\u03bf\u03bd\u03c3\u03cc\u03bb\u03b1\u03c2" - ::msgcat::mcset el "&Ignore" "\u0391\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7" + "Το αÏχείο \"%1\$s\" δεν υπάÏχει." + ::msgcat::mcset el "File &name:" "ÎŒ&νομα αÏχείου:" + ::msgcat::mcset el "File &names:" "ÎŒ&νομα αÏχείων:" + ::msgcat::mcset el "Files of &type:" "ΑÏχεία του &Ï„Ïπου:" + ::msgcat::mcset el "Fi&les:" "ΑÏχεία:" + ::msgcat::mcset el "&Filter" "ΦίλτÏο" + ::msgcat::mcset el "Fil&ter:" "ΦίλτÏο:" + ::msgcat::mcset el "&Green" "ΠÏάσινο" + ::msgcat::mcset el "Hi" "Γεια" + ::msgcat::mcset el "Hide Console" "ΑπόκÏυψη κονσόλας" + ::msgcat::mcset el "&Ignore" "Αγνόηση" ::msgcat::mcset el "Invalid file name \"%1\$s\"." \ - "\u0386\u03ba\u03c5\u03c1\u03bf \u03cc\u03bd\u03bf\u03bc\u03b1 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \"%1\$s\"." - ::msgcat::mcset el "Log Files" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2" - ::msgcat::mcset el "&No" "\u038c\u03c7\u03b9" - ::msgcat::mcset el "&OK" "\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9" - ::msgcat::mcset el "OK" "\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9" - ::msgcat::mcset el "Ok" "\u0395\u03bd\u03c4\u03ac\u03be\u03b5\u03b9" - ::msgcat::mcset el "Open" "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1" - ::msgcat::mcset el "&Open" "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1" + "ΆκυÏο όνομα αÏχείου \"%1\$s\"." + ::msgcat::mcset el "Log Files" "ΑÏχεία ΚαταγÏαφής" + ::msgcat::mcset el "&No" "Όχι" + ::msgcat::mcset el "&OK" "Εντάξει" + ::msgcat::mcset el "OK" "Εντάξει" + ::msgcat::mcset el "Ok" "Εντάξει" + ::msgcat::mcset el "Open" "Άνοιγμα" + ::msgcat::mcset el "&Open" "Άνοιγμα" ::msgcat::mcset el "Open Multiple Files" \ - "\u0386\u03bd\u03bf\u03b9\u03b3\u03bc\u03b1 \u03c0\u03bf\u03bb\u03bb\u03b1\u03c0\u03bb\u03ce\u03bd \u03b1\u03c1\u03c7\u03b5\u03af\u03c9\u03bd" - ::msgcat::mcset el "P&aste" "\u0395\u03c0\u03b9\u03ba\u03cc\u03bb\u03bb\u03b7\u03c3\u03b7" - ::msgcat::mcset el "Quit" "\u0388\u03be\u03bf\u03b4\u03bf\u03c2" - ::msgcat::mcset el "&Red" "\u039a\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf" + "Άνοιγμα πολλαπλών αÏχείων" + ::msgcat::mcset el "P&aste" "Επικόλληση" + ::msgcat::mcset el "Quit" "Έξοδος" + ::msgcat::mcset el "&Red" "Κόκκινο" ::msgcat::mcset el "Replace existing file?" \ - "\u0395\u03c0\u03b9\u03ba\u03ac\u03bb\u03c5\u03c8\u03b7 \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03bd\u03c4\u03bf\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5;" - ::msgcat::mcset el "&Retry" "\u03a0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac" - ::msgcat::mcset el "&Save" "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7" - ::msgcat::mcset el "Save As" "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03b1\u03bd" - ::msgcat::mcset el "Save To Log" "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7 \u03c3\u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2" - ::msgcat::mcset el "Select Log File" "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5 \u03ba\u03b1\u03c4\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae\u03c2" + "Επικάλυψη υπάÏχοντος αÏχείου;" + ::msgcat::mcset el "&Retry" "ΠÏοσπάθησε ξανά" + ::msgcat::mcset el "&Save" "Αποθήκευση" + ::msgcat::mcset el "Save As" "Αποθήκευση σαν" + ::msgcat::mcset el "Save To Log" "Αποθήκευση στο αÏχείο καταγÏαφής" + ::msgcat::mcset el "Select Log File" "Επιλογή αÏχείου καταγÏαφής" ::msgcat::mcset el "Select a file to source" \ - "\u0395\u03c0\u03b9\u03bb\u03ad\u03be\u03c4\u03b5 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf \u03b3\u03b9\u03b1 \u03b5\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7" - ::msgcat::mcset el "&Selection:" "\u0395\u03c0\u03b9\u03bb\u03bf\u03b3\u03ae:" - ::msgcat::mcset el "Skip Messages" "\u0391\u03c0\u03bf\u03c6\u03c5\u03b3\u03ae\u03bc\u03b7\u03bd\u03c5\u03bc\u03ac\u03c4\u03c9\u03bd" - ::msgcat::mcset el "&Source..." "\u0395\u03ba\u03c4\u03ad\u03bb\u03b5\u03c3\u03b7..." + "Επιλέξτε αÏχείο για εκτέλεση" + ::msgcat::mcset el "&Selection:" "Επιλογή:" + ::msgcat::mcset el "Skip Messages" "Αποφυγήμηνυμάτων" + ::msgcat::mcset el "&Source..." "Εκτέλεση..." ::msgcat::mcset el "Tcl Scripts" "Tcl Scripts" - ::msgcat::mcset el "Tcl for Windows" "Tcl \u03b3\u03b9\u03b1 Windows" - ::msgcat::mcset el "Text Files" "\u0391\u03c1\u03c7\u03b5\u03af\u03b1 \u039a\u03b5\u03b9\u03bc\u03ad\u03bd\u03bf\u03c5" - ::msgcat::mcset el "&Yes" "\u039d\u03b1\u03b9" - ::msgcat::mcset el "abort" "\u03c4\u03b5\u03c1\u03bc\u03b1\u03c4\u03b9\u03c3\u03bc\u03cc\u03c2" - ::msgcat::mcset el "blue" "\u03bc\u03c0\u03bb\u03b5" - ::msgcat::mcset el "cancel" "\u03b1\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7" - ::msgcat::mcset el "extension" "\u03b5\u03c0\u03ad\u03ba\u03c4\u03b1\u03c3\u03b7" - ::msgcat::mcset el "extensions" "\u03b5\u03c0\u03b5\u03ba\u03c4\u03ac\u03c3\u03b5\u03b9\u03c2" - ::msgcat::mcset el "green" "\u03c0\u03c1\u03ac\u03c3\u03b9\u03bd\u03bf" - ::msgcat::mcset el "ignore" "\u03b1\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7" - ::msgcat::mcset el "ok" "\u03b5\u03bd\u03c4\u03ac\u03be\u03b5\u03b9" - ::msgcat::mcset el "red" "\u03ba\u03cc\u03ba\u03ba\u03b9\u03bd\u03bf" - ::msgcat::mcset el "retry" "\u03c0\u03c1\u03bf\u03c3\u03c0\u03ac\u03b8\u03b7\u03c3\u03b5 \u03be\u03b1\u03bd\u03ac" - ::msgcat::mcset el "yes" "\u03bd\u03b1\u03b9" + ::msgcat::mcset el "Tcl for Windows" "Tcl για Windows" + ::msgcat::mcset el "Text Files" "ΑÏχεία Κειμένου" + ::msgcat::mcset el "&Yes" "Îαι" + ::msgcat::mcset el "abort" "τεÏματισμός" + ::msgcat::mcset el "blue" "μπλε" + ::msgcat::mcset el "cancel" "ακÏÏωση" + ::msgcat::mcset el "extension" "επέκταση" + ::msgcat::mcset el "extensions" "επεκτάσεις" + ::msgcat::mcset el "green" "Ï€Ïάσινο" + ::msgcat::mcset el "ignore" "αγνόηση" + ::msgcat::mcset el "ok" "εντάξει" + ::msgcat::mcset el "red" "κόκκινο" + ::msgcat::mcset el "retry" "Ï€Ïοσπάθησε ξανά" + ::msgcat::mcset el "yes" "ναι" } Index: library/msgs/eo.msg ================================================================== --- library/msgs/eo.msg +++ library/msgs/eo.msg @@ -1,30 +1,30 @@ namespace eval ::tk { - ::msgcat::mcset eo "&Abort" "&\u0108esigo" + ::msgcat::mcset eo "&Abort" "&Ĉesigo" ::msgcat::mcset eo "&About..." "Pri..." - ::msgcat::mcset eo "All Files" "\u0108ioj dosieroj" + ::msgcat::mcset eo "All Files" "Ĉioj dosieroj" ::msgcat::mcset eo "Application Error" "Aplikoerraro" ::msgcat::mcset eo "&Blue" "&Blua" ::msgcat::mcset eo "Cancel" "Rezignu" ::msgcat::mcset eo "&Cancel" "&Rezignu" - ::msgcat::mcset eo "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble \u0109angi al dosierulon \"%1\$s\".\nVi ne rajtas tion." + ::msgcat::mcset eo "Cannot change to the directory \"%1\$s\".\nPermission denied." "Neeble ĉangi al dosierulon \"%1\$s\".\nVi ne rajtas tion." ::msgcat::mcset eo "Choose Directory" "Elektu Dosierujo" ::msgcat::mcset eo "Cl&ear" "&Klaru" ::msgcat::mcset eo "&Clear Console" "&Klaru konzolon" ::msgcat::mcset eo "Color" "Farbo" ::msgcat::mcset eo "Console" "Konzolo" ::msgcat::mcset eo "&Copy" "&Kopiu" - ::msgcat::mcset eo "Cu&t" "&Enpo\u015digu" + ::msgcat::mcset eo "Cu&t" "&EnpoÅigu" ::msgcat::mcset eo "&Delete" "&Forprenu" ::msgcat::mcset eo "Details >>" "Detaloj >>" ::msgcat::mcset eo "Directory \"%1\$s\" does not exist." "La dosierujo \"%1\$s\" ne ekzistas." ::msgcat::mcset eo "&Directory:" "&Dosierujo:" ::msgcat::mcset eo "&Edit" "&Redaktu" ::msgcat::mcset eo "Error: %1\$s" "Eraro: %1\$s" ::msgcat::mcset eo "E&xit" "&Eliru" ::msgcat::mcset eo "&File" "&Dosiero" - ::msgcat::mcset eo "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\n\u0108u vi volas anstata\u00fbigi la dosieron?" + ::msgcat::mcset eo "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "La dosiero \"%1\$s\" jam ekzistas.\nĈu vi volas anstataûigi la dosieron?" ::msgcat::mcset eo "File \"%1\$s\" already exists.\n\n" "La dosiero \"%1\$s\" jam egzistas. \n\n" ::msgcat::mcset eo "File \"%1\$s\" does not exist." "La dosierp \"%1\$s\" ne estas." ::msgcat::mcset eo "File &name:" "Dosiero&nomo:" ::msgcat::mcset eo "File &names:" "Dosiero&nomoj:" ::msgcat::mcset eo "Files of &type:" "Dosieroj de &Typo:" @@ -32,11 +32,11 @@ ::msgcat::mcset eo "&Filter" "&Filtrilo" ::msgcat::mcset eo "Fil&ter:" "&Filtrilo:" ::msgcat::mcset eo "&Green" "&Verda" ::msgcat::mcset eo "&Help" "&Helpu" ::msgcat::mcset eo "Hi" "Saluton" - ::msgcat::mcset eo "&Hide Console" "&Ka\u015du konzolon" + ::msgcat::mcset eo "&Hide Console" "&KaÅu konzolon" ::msgcat::mcset eo "&Ignore" "&Ignoru" ::msgcat::mcset eo "Invalid file name \"%1\$s\"." "Malvalida dosieronomo \"%1\$s\"." ::msgcat::mcset eo "Log Files" "Protokolo" ::msgcat::mcset eo "&No" "&Ne" ::msgcat::mcset eo "&OK" @@ -43,33 +43,33 @@ ::msgcat::mcset eo "OK" ::msgcat::mcset eo "Ok" ::msgcat::mcset eo "Open" "Malfermu" ::msgcat::mcset eo "&Open" "&Malfermu" ::msgcat::mcset eo "Open Multiple Files" "Melfermu multan dosierojn" - ::msgcat::mcset eo "P&aste" "&Elpo\u015digi" + ::msgcat::mcset eo "P&aste" "&ElpoÅigi" ::msgcat::mcset eo "&Quit" "&Finigu" ::msgcat::mcset eo "&Red" "&Rosa" - ::msgcat::mcset eo "Replace existing file?" "\u0108u anstata\u00fbu ekzistantan dosieron?" + ::msgcat::mcset eo "Replace existing file?" "Ĉu anstataûu ekzistantan dosieron?" ::msgcat::mcset eo "&Retry" "&Ripetu" ::msgcat::mcset eo "&Save" "&Savu" ::msgcat::mcset eo "Save As" "Savu kiel" ::msgcat::mcset eo "Save To Log" "Savu en protokolon" ::msgcat::mcset eo "Select Log File" "Elektu prokolodosieron" ::msgcat::mcset eo "Select a file to source" "Elektu dosieron por interpreti" ::msgcat::mcset eo "&Selection:" "&Elekto:" - ::msgcat::mcset eo "Skip Messages" "transsaltu pluajn mesa\u011dojn" + ::msgcat::mcset eo "Skip Messages" "transsaltu pluajn mesaÄojn" ::msgcat::mcset eo "&Source..." "&Fontoprogramo..." ::msgcat::mcset eo "Tcl Scripts" "Tcl-skriptoj" ::msgcat::mcset eo "Tcl for Windows" "Tcl por vindoso" ::msgcat::mcset eo "Text Files" "Tekstodosierojn" ::msgcat::mcset eo "&Yes" "&Jes" - ::msgcat::mcset eo "abort" "\u0109esigo" + ::msgcat::mcset eo "abort" "ĉesigo" ::msgcat::mcset eo "blue" "blua" ::msgcat::mcset eo "cancel" "rezignu" ::msgcat::mcset eo "extension" "ekspansio" ::msgcat::mcset eo "extensions" "ekspansioj" ::msgcat::mcset eo "green" "verda" ::msgcat::mcset eo "ignore" "ignorieren" - ::msgcat::mcset eo "red" "ru\u011da" + ::msgcat::mcset eo "red" "ruÄa" ::msgcat::mcset eo "retry" "ripetu" ::msgcat::mcset eo "yes" "jes" } Index: library/msgs/es.msg ================================================================== --- library/msgs/es.msg +++ library/msgs/es.msg @@ -1,10 +1,10 @@ namespace eval ::tk { ::msgcat::mcset es "&Abort" "&Abortar" ::msgcat::mcset es "&About..." "&Acerca de ..." ::msgcat::mcset es "All Files" "Todos los archivos" - ::msgcat::mcset es "Application Error" "Error de la aplicaci\u00f3n" + ::msgcat::mcset es "Application Error" "Error de la aplicación" ::msgcat::mcset es "&Blue" "&Azul" ::msgcat::mcset es "Cancel" "Cancelar" ::msgcat::mcset es "&Cancel" "&Cancelar" ::msgcat::mcset es "Cannot change to the directory \"%1\$s\".\nPermission denied." "No es posible acceder al directorio \"%1\$s\".\nPermiso denegado." ::msgcat::mcset es "Choose Directory" "Elegir directorio" @@ -20,11 +20,11 @@ ::msgcat::mcset es "&Directory:" "&Directorio:" ::msgcat::mcset es "&Edit" "&Editar" ::msgcat::mcset es "Error: %1\$s" ::msgcat::mcset es "E&xit" "Salir" ::msgcat::mcset es "&File" "&Archivo" - ::msgcat::mcset es "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "El archivo \"%1\$s\" ya existe.\n\u00bfDesea sobreescribirlo?" + ::msgcat::mcset es "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "El archivo \"%1\$s\" ya existe.\n¿Desea sobreescribirlo?" ::msgcat::mcset es "File \"%1\$s\" already exists.\n\n" "El archivo \"%1\$s\" ya existe.\n\n" ::msgcat::mcset es "File \"%1\$s\" does not exist." "El archivo \"%1\$s\" no existe." ::msgcat::mcset es "File &name:" "&Nombre de archivo:" ::msgcat::mcset es "File &names:" "&Nombres de archivo:" ::msgcat::mcset es "Files of &type:" "Archivos de &tipo:" @@ -34,43 +34,43 @@ ::msgcat::mcset es "&Green" "&Verde" ::msgcat::mcset es "&Help" "&Ayuda" ::msgcat::mcset es "Hi" "Hola" ::msgcat::mcset es "&Hide Console" "&Esconder la consola" ::msgcat::mcset es "&Ignore" "&Ignorar" - ::msgcat::mcset es "Invalid file name \"%1\$s\"." "Nombre de archivo inv\u00e1lido \"%1\$s\"." + ::msgcat::mcset es "Invalid file name \"%1\$s\"." "Nombre de archivo inválido \"%1\$s\"." ::msgcat::mcset es "Log Files" "Ficheros de traza" ::msgcat::mcset es "&No" ::msgcat::mcset es "&OK" ::msgcat::mcset es "OK" ::msgcat::mcset es "Ok" ::msgcat::mcset es "Open" "Abrir" ::msgcat::mcset es "&Open" "&Abrir" - ::msgcat::mcset es "Open Multiple Files" "Abrir m\u00faltiples archivos" + ::msgcat::mcset es "Open Multiple Files" "Abrir múltiples archivos" ::msgcat::mcset es "P&aste" "Peg&ar" ::msgcat::mcset es "&Quit" "&Abandonar" ::msgcat::mcset es "&Red" "&Rojo" - ::msgcat::mcset es "Replace existing file?" "\u00bfReemplazar el archivo existente?" + ::msgcat::mcset es "Replace existing file?" "¿Reemplazar el archivo existente?" ::msgcat::mcset es "&Retry" "&Reintentar" ::msgcat::mcset es "&Save" "&Guardar" ::msgcat::mcset es "Save As" "Guardar como" ::msgcat::mcset es "Save To Log" "Guardar al archivo de traza" ::msgcat::mcset es "Select Log File" "Elegir un archivo de traza" ::msgcat::mcset es "Select a file to source" "Seleccionar un archivo a evaluar" - ::msgcat::mcset es "&Selection:" "&Selecci\u00f3n:" + ::msgcat::mcset es "&Selection:" "&Selección:" ::msgcat::mcset es "Skip Messages" "Omitir los mensajes" ::msgcat::mcset es "&Source..." "E&valuar..." ::msgcat::mcset es "Tcl Scripts" "Scripts Tcl" ::msgcat::mcset es "Tcl for Windows" "Tcl para Windows" ::msgcat::mcset es "Text Files" "Archivos de texto" - ::msgcat::mcset es "&Yes" "&S\u00ed" + ::msgcat::mcset es "&Yes" "&Sí" ::msgcat::mcset es "abort" "abortar" ::msgcat::mcset es "blue" "azul" ::msgcat::mcset es "cancel" "cancelar" - ::msgcat::mcset es "extension" "extensi\u00f3n" + ::msgcat::mcset es "extension" "extensión" ::msgcat::mcset es "extensions" "extensiones" ::msgcat::mcset es "green" "verde" ::msgcat::mcset es "ignore" "ignorar" ::msgcat::mcset es "ok" ::msgcat::mcset es "red" "rojo" ::msgcat::mcset es "retry" "reintentar" - ::msgcat::mcset es "yes" "s\u00ed" + ::msgcat::mcset es "yes" "sí" } Index: library/msgs/fr.msg ================================================================== --- library/msgs/fr.msg +++ library/msgs/fr.msg @@ -1,28 +1,28 @@ namespace eval ::tk { ::msgcat::mcset fr "&Abort" "&Annuler" - ::msgcat::mcset fr "About..." "\u00c0 propos..." + ::msgcat::mcset fr "About..." "À propos..." ::msgcat::mcset fr "All Files" "Tous les fichiers" ::msgcat::mcset fr "Application Error" "Erreur d'application" ::msgcat::mcset fr "&Blue" "&Bleu" ::msgcat::mcset fr "Cancel" "Annuler" ::msgcat::mcset fr "&Cancel" "&Annuler" - ::msgcat::mcset fr "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossible d'acc\u00e9der au r\u00e9pertoire \"%1\$s\".\nPermission refus\u00e9e." - ::msgcat::mcset fr "Choose Directory" "Choisir r\u00e9pertoire" + ::msgcat::mcset fr "Cannot change to the directory \"%1\$s\".\nPermission denied." "Impossible d'accéder au répertoire \"%1\$s\".\nPermission refusée." + ::msgcat::mcset fr "Choose Directory" "Choisir répertoire" ::msgcat::mcset fr "Cl&ear" "Effacer" ::msgcat::mcset fr "Color" "Couleur" ::msgcat::mcset fr "Console" ::msgcat::mcset fr "Copy" "Copier" ::msgcat::mcset fr "Cu&t" "Couper" ::msgcat::mcset fr "Delete" "Effacer" - ::msgcat::mcset fr "Details >>" "D\u00e9tails >>" - ::msgcat::mcset fr "Directory \"%1\$s\" does not exist." "Le r\u00e9pertoire \"%1\$s\" n'existe pas." - ::msgcat::mcset fr "&Directory:" "&R\u00e9pertoire:" + ::msgcat::mcset fr "Details >>" "Détails >>" + ::msgcat::mcset fr "Directory \"%1\$s\" does not exist." "Le répertoire \"%1\$s\" n'existe pas." + ::msgcat::mcset fr "&Directory:" "&Répertoire:" ::msgcat::mcset fr "Error: %1\$s" "Erreur: %1\$s" ::msgcat::mcset fr "E&xit" "Quitter" - ::msgcat::mcset fr "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Le fichier \"%1\$s\" existe d\u00e9j\u00e0.\nVoulez-vous l'\u00e9craser?" - ::msgcat::mcset fr "File \"%1\$s\" already exists.\n\n" "Le fichier \"%1\$s\" existe d\u00e9j\u00e0.\n\n" + ::msgcat::mcset fr "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Le fichier \"%1\$s\" existe déjà.\nVoulez-vous l'écraser?" + ::msgcat::mcset fr "File \"%1\$s\" already exists.\n\n" "Le fichier \"%1\$s\" existe déjà.\n\n" ::msgcat::mcset fr "File \"%1\$s\" does not exist." "Le fichier \"%1\$s\" n'existe pas." ::msgcat::mcset fr "File &name:" "&Nom de fichier:" ::msgcat::mcset fr "File &names:" "&Noms de fichiers:" ::msgcat::mcset fr "Files of &type:" "&Type de fichiers:" ::msgcat::mcset fr "Fi&les:" "Fich&iers:" @@ -43,19 +43,19 @@ ::msgcat::mcset fr "Open Multiple Files" "Ouvrir plusieurs fichiers" ::msgcat::mcset fr "P&aste" "Coller" ::msgcat::mcset fr "&Quit" "&Quitter" ::msgcat::mcset fr "&Red" "&Rouge" ::msgcat::mcset fr "Replace existing file?" "Remplacer le fichier existant?" - ::msgcat::mcset fr "&Retry" "&R\u00e9-essayer" + ::msgcat::mcset fr "&Retry" "&Ré-essayer" ::msgcat::mcset fr "&Save" "&Sauvegarder" ::msgcat::mcset fr "Save As" "Sauvegarder sous" ::msgcat::mcset fr "Save To Log" "Sauvegarde au fichier de trace" ::msgcat::mcset fr "Select Log File" "Choisir un fichier de trace" - ::msgcat::mcset fr "Select a file to source" "Choisir un fichier \u00e0 \u00e9valuer" - ::msgcat::mcset fr "&Selection:" "&S\u00e9lection:" + ::msgcat::mcset fr "Select a file to source" "Choisir un fichier à évaluer" + ::msgcat::mcset fr "&Selection:" "&Sélection:" ::msgcat::mcset fr "Skip Messages" "Omettre les messages" - ::msgcat::mcset fr "&Source..." "\u00c9valuer..." + ::msgcat::mcset fr "&Source..." "Évaluer..." ::msgcat::mcset fr "Tcl Scripts" "Scripts Tcl" ::msgcat::mcset fr "Tcl for Windows" "Tcl pour Windows" ::msgcat::mcset fr "Text Files" "Fichiers texte" ::msgcat::mcset fr "&Yes" "&Oui" ::msgcat::mcset fr "abort" "abandonner" @@ -65,8 +65,8 @@ ::msgcat::mcset fr "extensions" ::msgcat::mcset fr "green" "vert" ::msgcat::mcset fr "ignore" "ignorer" ::msgcat::mcset fr "ok" ::msgcat::mcset fr "red" "rouge" - ::msgcat::mcset fr "retry" "r\u00e9essayer" + ::msgcat::mcset fr "retry" "réessayer" ::msgcat::mcset fr "yes" "oui" } Index: library/msgs/hu.msg ================================================================== --- library/msgs/hu.msg +++ library/msgs/hu.msg @@ -1,78 +1,78 @@ namespace eval ::tk { - ::msgcat::mcset hu "&Abort" "&Megszak\u00edt\u00e1s" - ::msgcat::mcset hu "&About..." "N\u00e9vjegy..." - ::msgcat::mcset hu "All Files" "Minden f\u00e1jl" - ::msgcat::mcset hu "Application Error" "Alkalmaz\u00e1s hiba" - ::msgcat::mcset hu "&Blue" "&K\u00e9k" - ::msgcat::mcset hu "Cancel" "M\u00e9gsem" - ::msgcat::mcset hu "&Cancel" "M\u00e9g&sem" - ::msgcat::mcset hu "Cannot change to the directory \"%1\$s\".\nPermission denied." "A k\u00f6nyvt\u00e1rv\u00e1lt\u00e1s nem siker\u00fclt: \"%1\$s\".\nHozz\u00e1f\u00e9r\u00e9s megtagadva." - ::msgcat::mcset hu "Choose Directory" "K\u00f6nyvt\u00e1r kiv\u00e1laszt\u00e1sa" - ::msgcat::mcset hu "Cl&ear" "T\u00f6rl\u00e9s" - ::msgcat::mcset hu "&Clear Console" "&T\u00f6rl\u00e9s Konzol" - ::msgcat::mcset hu "Color" "Sz\u00edn" + ::msgcat::mcset hu "&Abort" "&Megszakítás" + ::msgcat::mcset hu "&About..." "Névjegy..." + ::msgcat::mcset hu "All Files" "Minden fájl" + ::msgcat::mcset hu "Application Error" "Alkalmazás hiba" + ::msgcat::mcset hu "&Blue" "&Kék" + ::msgcat::mcset hu "Cancel" "Mégsem" + ::msgcat::mcset hu "&Cancel" "Még&sem" + ::msgcat::mcset hu "Cannot change to the directory \"%1\$s\".\nPermission denied." "A könyvtárváltás nem sikerült: \"%1\$s\".\nHozzáférés megtagadva." + ::msgcat::mcset hu "Choose Directory" "Könyvtár kiválasztása" + ::msgcat::mcset hu "Cl&ear" "Törlés" + ::msgcat::mcset hu "&Clear Console" "&Törlés Konzol" + ::msgcat::mcset hu "Color" "Szín" ::msgcat::mcset hu "Console" "Konzol" - ::msgcat::mcset hu "&Copy" "&M\u00e1sol\u00e1s" - ::msgcat::mcset hu "Cu&t" "&Kiv\u00e1g\u00e1s" - ::msgcat::mcset hu "&Delete" "&T\u00f6rl\u00e9s" - ::msgcat::mcset hu "Details >>" "R\u00e9szletek >>" - ::msgcat::mcset hu "Directory \"%1\$s\" does not exist." "\"%1\$s\" k\u00f6nyvt\u00e1r nem l\u00e9tezik." - ::msgcat::mcset hu "&Directory:" "&K\u00f6nyvt\u00e1r:" + ::msgcat::mcset hu "&Copy" "&Másolás" + ::msgcat::mcset hu "Cu&t" "&Kivágás" + ::msgcat::mcset hu "&Delete" "&Törlés" + ::msgcat::mcset hu "Details >>" "Részletek >>" + ::msgcat::mcset hu "Directory \"%1\$s\" does not exist." "\"%1\$s\" könyvtár nem létezik." + ::msgcat::mcset hu "&Directory:" "&Könyvtár:" #::msgcat::mcset hu "&Edit" ::msgcat::mcset hu "Error: %1\$s" "Hiba: %1\$s" - ::msgcat::mcset hu "E&xit" "Kil\u00e9p\u00e9s" - ::msgcat::mcset hu "&File" "&F\u00e1jl" - ::msgcat::mcset hu "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "\"%1\$s\" f\u00e1jl m\u00e1r l\u00e9tezik.\nFel\u00fcl\u00edrjam?" - ::msgcat::mcset hu "File \"%1\$s\" already exists.\n\n" "\"%1\$s\" f\u00e1jl m\u00e1r l\u00e9tezik.\n\n" - ::msgcat::mcset hu "File \"%1\$s\" does not exist." "\"%1\$s\" f\u00e1jl nem l\u00e9tezik." - ::msgcat::mcset hu "File &name:" "F\u00e1jl &neve:" - ::msgcat::mcset hu "File &names:" "F\u00e1jlok &nevei:" - ::msgcat::mcset hu "Files of &type:" "F\u00e1jlok &t\u00edpusa:" - ::msgcat::mcset hu "Fi&les:" "F\u00e1j&lok:" - ::msgcat::mcset hu "&Filter" "&Sz\u0171r\u0151" - ::msgcat::mcset hu "Fil&ter:" "S&z\u0171r\u0151:" - ::msgcat::mcset hu "&Green" "&Z\u00f6ld" + ::msgcat::mcset hu "E&xit" "Kilépés" + ::msgcat::mcset hu "&File" "&Fájl" + ::msgcat::mcset hu "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "\"%1\$s\" fájl már létezik.\nFelülírjam?" + ::msgcat::mcset hu "File \"%1\$s\" already exists.\n\n" "\"%1\$s\" fájl már létezik.\n\n" + ::msgcat::mcset hu "File \"%1\$s\" does not exist." "\"%1\$s\" fájl nem létezik." + ::msgcat::mcset hu "File &name:" "Fájl &neve:" + ::msgcat::mcset hu "File &names:" "Fájlok &nevei:" + ::msgcat::mcset hu "Files of &type:" "Fájlok &típusa:" + ::msgcat::mcset hu "Fi&les:" "Fáj&lok:" + ::msgcat::mcset hu "&Filter" "&SzűrÅ‘" + ::msgcat::mcset hu "Fil&ter:" "S&zűrÅ‘:" + ::msgcat::mcset hu "&Green" "&Zöld" #::msgcat::mcset hu "&Help" - ::msgcat::mcset hu "Hi" "\u00dcdv" - ::msgcat::mcset hu "&Hide Console" "Konzol &elrejt\u00e9se" - ::msgcat::mcset hu "&Ignore" "K&ihagy\u00e1s" - ::msgcat::mcset hu "Invalid file name \"%1\$s\"." "\u00c9rv\u00e9nytelen f\u00e1jln\u00e9v: \"%1\$s\"." - ::msgcat::mcset hu "Log Files" "Log f\u00e1jlok" + ::msgcat::mcset hu "Hi" "Ãœdv" + ::msgcat::mcset hu "&Hide Console" "Konzol &elrejtése" + ::msgcat::mcset hu "&Ignore" "K&ihagyás" + ::msgcat::mcset hu "Invalid file name \"%1\$s\"." "Érvénytelen fájlnév: \"%1\$s\"." + ::msgcat::mcset hu "Log Files" "Log fájlok" ::msgcat::mcset hu "&No" "&Nem" ::msgcat::mcset hu "&OK" ::msgcat::mcset hu "OK" ::msgcat::mcset hu "Ok" - ::msgcat::mcset hu "Open" "Megnyit\u00e1s" - ::msgcat::mcset hu "&Open" "&Megnyit\u00e1s" - ::msgcat::mcset hu "Open Multiple Files" "T\u00f6bb f\u00e1jl megnyit\u00e1sa" - ::msgcat::mcset hu "P&aste" "&Beilleszt\u00e9s" - ::msgcat::mcset hu "&Quit" "&Kil\u00e9p\u00e9s" - ::msgcat::mcset hu "&Red" "&V\u00f6r\u00f6s" - ::msgcat::mcset hu "Replace existing file?" "Megl\u00e9v\u0151 f\u00e1jl cser\u00e9je?" - ::msgcat::mcset hu "&Retry" "\u00daj&ra" - ::msgcat::mcset hu "&Save" "&Ment\u00e9s" - ::msgcat::mcset hu "Save As" "Ment\u00e9s m\u00e1sk\u00e9nt" - ::msgcat::mcset hu "Save To Log" "Ment\u00e9s log f\u00e1jlba" - ::msgcat::mcset hu "Select Log File" "Log f\u00e1jl kiv\u00e1laszt\u00e1sa" - ::msgcat::mcset hu "Select a file to source" "Forr\u00e1sf\u00e1jl kiv\u00e1laszt\u00e1sa" - ::msgcat::mcset hu "&Selection:" "&Kijel\u00f6l\u00e9s:" - ::msgcat::mcset hu "Show &Hidden Directories" "&Rejtett k\u00f6nyvt\u00e1rak megjelen\u00edt\u00e9se" - ::msgcat::mcset hu "Show &Hidden Files and Directories" "&Rejtett f\u00e1jlok \u00e9s k\u00f6nyvt\u00e1rak megjelen\u00edt\u00e9se" - ::msgcat::mcset hu "Skip Messages" "\u00dczenetek kihagy\u00e1sa" - ::msgcat::mcset hu "&Source..." "&Forr\u00e1s..." + ::msgcat::mcset hu "Open" "Megnyitás" + ::msgcat::mcset hu "&Open" "&Megnyitás" + ::msgcat::mcset hu "Open Multiple Files" "Több fájl megnyitása" + ::msgcat::mcset hu "P&aste" "&Beillesztés" + ::msgcat::mcset hu "&Quit" "&Kilépés" + ::msgcat::mcset hu "&Red" "&Vörös" + ::msgcat::mcset hu "Replace existing file?" "MeglévÅ‘ fájl cseréje?" + ::msgcat::mcset hu "&Retry" "Új&ra" + ::msgcat::mcset hu "&Save" "&Mentés" + ::msgcat::mcset hu "Save As" "Mentés másként" + ::msgcat::mcset hu "Save To Log" "Mentés log fájlba" + ::msgcat::mcset hu "Select Log File" "Log fájl kiválasztása" + ::msgcat::mcset hu "Select a file to source" "Forrásfájl kiválasztása" + ::msgcat::mcset hu "&Selection:" "&Kijelölés:" + ::msgcat::mcset hu "Show &Hidden Directories" "&Rejtett könyvtárak megjelenítése" + ::msgcat::mcset hu "Show &Hidden Files and Directories" "&Rejtett fájlok és könyvtárak megjelenítése" + ::msgcat::mcset hu "Skip Messages" "Ãœzenetek kihagyása" + ::msgcat::mcset hu "&Source..." "&Forrás..." ::msgcat::mcset hu "Tcl Scripts" "Tcl scriptek" ::msgcat::mcset hu "Tcl for Windows" "Tcl Windows-hoz" - ::msgcat::mcset hu "Text Files" "Sz\u00f6vegf\u00e1jlok" + ::msgcat::mcset hu "Text Files" "Szövegfájlok" ::msgcat::mcset hu "&Yes" "&Igen" - ::msgcat::mcset hu "abort" "megszak\u00edt\u00e1s" - ::msgcat::mcset hu "blue" "k\u00e9k" - ::msgcat::mcset hu "cancel" "m\u00e9gsem" - ::msgcat::mcset hu "extension" "kiterjeszt\u00e9s" - ::msgcat::mcset hu "extensions" "kiterjeszt\u00e9sek" - ::msgcat::mcset hu "green" "z\u00f6ld" + ::msgcat::mcset hu "abort" "megszakítás" + ::msgcat::mcset hu "blue" "kék" + ::msgcat::mcset hu "cancel" "mégsem" + ::msgcat::mcset hu "extension" "kiterjesztés" + ::msgcat::mcset hu "extensions" "kiterjesztések" + ::msgcat::mcset hu "green" "zöld" ::msgcat::mcset hu "ignore" "ignorer" ::msgcat::mcset hu "ok" - ::msgcat::mcset hu "red" "v\u00f6r\u00f6s" - ::msgcat::mcset hu "retry" "\u00fajra" + ::msgcat::mcset hu "red" "vörös" + ::msgcat::mcset hu "retry" "újra" ::msgcat::mcset hu "yes" "igen" } Index: library/msgs/it.msg ================================================================== --- library/msgs/it.msg +++ library/msgs/it.msg @@ -18,12 +18,12 @@ ::msgcat::mcset it "Details >>" "Dettagli >>" ::msgcat::mcset it "Directory \"%1\$s\" does not exist." "La directory \"%1\$s\" non esiste." ::msgcat::mcset it "&Directory:" ::msgcat::mcset it "Error: %1\$s" "Errore: %1\$s" ::msgcat::mcset it "E&xit" "Esci" - ::msgcat::mcset it "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Il file \"%1\$s\" esiste gi\u00e0.\nVuoi sovrascriverlo?" - ::msgcat::mcset it "File \"%1\$s\" already exists.\n\n" "Il file \"%1\$s\" esiste gi\u00e0.\n\n" + ::msgcat::mcset it "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Il file \"%1\$s\" esiste già.\nVuoi sovrascriverlo?" + ::msgcat::mcset it "File \"%1\$s\" already exists.\n\n" "Il file \"%1\$s\" esiste già.\n\n" ::msgcat::mcset it "File \"%1\$s\" does not exist." "Il file \"%1\$s\" non esiste." ::msgcat::mcset it "File &name:" "&Nome del file:" ::msgcat::mcset it "File &names:" "&Nomi dei file:" ::msgcat::mcset it "Files of &type:" "File di &tipo:" ::msgcat::mcset it "Fi&les:" "Fi&le:" @@ -56,11 +56,11 @@ ::msgcat::mcset it "Skip Messages" "Salta i messaggi" ::msgcat::mcset it "Source..." "Esegui..." ::msgcat::mcset it "Tcl Scripts" "Script Tcl" ::msgcat::mcset it "Tcl for Windows" "Tcl per Windows" ::msgcat::mcset it "Text Files" "File di testo" - ::msgcat::mcset it "&Yes" "&S\u00ec" + ::msgcat::mcset it "&Yes" "&Sì" ::msgcat::mcset it "abort" "interrompi" ::msgcat::mcset it "blue" "blu" ::msgcat::mcset it "cancel" "annulla" ::msgcat::mcset it "extension" "estensione" ::msgcat::mcset it "extensions" "estensioni" @@ -67,7 +67,7 @@ ::msgcat::mcset it "green" "verde" ::msgcat::mcset it "ignore" "ignora" ::msgcat::mcset it "ok" ::msgcat::mcset it "red" "rosso" ::msgcat::mcset it "retry" "riprova" - ::msgcat::mcset it "yes" "s\u00ec" + ::msgcat::mcset it "yes" "sì" } Index: library/msgs/nl.msg ================================================================== --- library/msgs/nl.msg +++ library/msgs/nl.msg @@ -13,20 +13,20 @@ ::msgcat::mcset nl "Choose Directory" "Kies map" ::msgcat::mcset nl "Cl&ear" "Wissen" ::msgcat::mcset nl "&Clear Console" "&Wis Console" ::msgcat::mcset nl "Color" "Kleur" ::msgcat::mcset nl "Console" - ::msgcat::mcset nl "&Copy" "Kopi\u00ebren" + ::msgcat::mcset nl "&Copy" "Kopiëren" ::msgcat::mcset nl "Cu&t" "Knippen" ::msgcat::mcset nl "&Delete" "Wissen" ::msgcat::mcset nl "Details >>" ::msgcat::mcset nl "Directory \"%1\$s\" does not exist." "Map \"%1\$s\" bestaat niet." ::msgcat::mcset nl "&Directory:" "&Map:" ::msgcat::mcset nl "&Edit" "Bewerken" ::msgcat::mcset nl "Effects" "Effecten" ::msgcat::mcset nl "Error: %1\$s" "Fout: %1\$s" - ::msgcat::mcset nl "E&xit" "Be\u00ebindigen" + ::msgcat::mcset nl "E&xit" "Beëindigen" ::msgcat::mcset nl "&File" "Bestand" ::msgcat::mcset nl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Bestand \"%1\$s\" bestaat al.\nWilt u het overschrijven?" ::msgcat::mcset nl "File \"%1\$s\" already exists.\n\n" "Bestand \"%1\$s\" bestaat al.\n\n" ::msgcat::mcset nl "File \"%1\$s\" does not exist." "Bestand \"%1\$s\" bestaat niet." ::msgcat::mcset nl "File &name:" "Bestands&naam:" @@ -38,11 +38,11 @@ ::msgcat::mcset nl "Font" ::msgcat::mcset nl "&Font:" ::msgcat::mcset nl "Font st&yle:" "Font stijl:" ::msgcat::mcset nl "&Green" "&Groen" ::msgcat::mcset nl "&Help" - ::msgcat::mcset nl "Hi" "H\u00e9" + ::msgcat::mcset nl "Hi" "Hé" ::msgcat::mcset nl "&Hide Console" "Verberg Console" ::msgcat::mcset nl "&Ignore" "&Negeren" ::msgcat::mcset nl "Invalid file name \"%1\$s\"." "Ongeldige bestandsnaam \"%1\$s\"." ::msgcat::mcset nl "Italic" "Cursief" ::msgcat::mcset nl "Log Files" "Log Bestanden" Index: library/msgs/pl.msg ================================================================== --- library/msgs/pl.msg +++ library/msgs/pl.msg @@ -1,38 +1,38 @@ namespace eval ::tk { ::msgcat::mcset pl "&Abort" "&Przerwij" ::msgcat::mcset pl "&About..." "O programie..." ::msgcat::mcset pl "All Files" "Wszystkie pliki" - ::msgcat::mcset pl "Application Error" "B\u0142\u0105d w programie" + ::msgcat::mcset pl "Application Error" "BÅ‚Ä…d w programie" ::msgcat::mcset pl "&Apply" "Zastosuj" ::msgcat::mcset pl "Bold" "Pogrubienie" ::msgcat::mcset pl "Bold Italic" "Pogrubiona kursywa" ::msgcat::mcset pl "&Blue" "&Niebieski" ::msgcat::mcset pl "Cancel" "Anuluj" ::msgcat::mcset pl "&Cancel" "&Anuluj" - ::msgcat::mcset pl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nie mo\u017cna otworzy\u0107 katalogu \"%1\$s\".\nOdmowa dost\u0119pu." + ::msgcat::mcset pl "Cannot change to the directory \"%1\$s\".\nPermission denied." "Nie można otworzyć katalogu \"%1\$s\".\nOdmowa dostÄ™pu." ::msgcat::mcset pl "Choose Directory" "Wybierz katalog" - ::msgcat::mcset pl "Cl&ear" "&Wyczy\u015b\u0107" - ::msgcat::mcset pl "&Clear Console" "&Wyczy\u015b\u0107 konsol\u0119" + ::msgcat::mcset pl "Cl&ear" "&Wyczyść" + ::msgcat::mcset pl "&Clear Console" "&Wyczyść konsolÄ™" ::msgcat::mcset pl "Color" "Kolor" ::msgcat::mcset pl "Console" "Konsola" ::msgcat::mcset pl "&Copy" "&Kopiuj" ::msgcat::mcset pl "Cu&t" "&Wytnij" - ::msgcat::mcset pl "&Delete" "&Usu\u0144" - ::msgcat::mcset pl "Details >>" "Szczeg\u00f3\u0142y >>" + ::msgcat::mcset pl "&Delete" "&UsuÅ„" + ::msgcat::mcset pl "Details >>" "Szczegóły >>" ::msgcat::mcset pl "Directory \"%1\$s\" does not exist." "Katalog \"%1\$s\" nie istnieje." ::msgcat::mcset pl "&Directory:" "&Katalog:" ::msgcat::mcset pl "&Edit" "&Edytuj" ::msgcat::mcset pl "Effects" "Efekty" - ::msgcat::mcset pl "Error: %1\$s" "B\u0142\u0105d: %1\$s" - ::msgcat::mcset pl "E&xit" "&Wyjd\u017a" + ::msgcat::mcset pl "Error: %1\$s" "BÅ‚Ä…d: %1\$s" + ::msgcat::mcset pl "E&xit" "&Wyjdź" ::msgcat::mcset pl "&File" "&Plik" - ::msgcat::mcset pl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Plik \"%1\$s\" ju\u017c istnieje.\nCzy chcesz go nadpisa\u0107?" - ::msgcat::mcset pl "File \"%1\$s\" already exists.\n\n" "Plik \"%1\$s\" ju\u017c istnieje.\n\n" + ::msgcat::mcset pl "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Plik \"%1\$s\" już istnieje.\nCzy chcesz go nadpisać?" + ::msgcat::mcset pl "File \"%1\$s\" already exists.\n\n" "Plik \"%1\$s\" już istnieje.\n\n" ::msgcat::mcset pl "File \"%1\$s\" does not exist." "Plik \"%1\$s\" nie istnieje." ::msgcat::mcset pl "File &name:" "Nazwa &pliku:" - ::msgcat::mcset pl "File &names:" "Nazwy &plik\u00f3w:" + ::msgcat::mcset pl "File &names:" "Nazwy &plików:" ::msgcat::mcset pl "Files of &type:" "Pliki &typu:" ::msgcat::mcset pl "Fi&les:" "Pli&ki:" ::msgcat::mcset pl "&Filter" "&Filtr" ::msgcat::mcset pl "Fil&ter:" "&Filtr:" ::msgcat::mcset pl "Font" "Czcionka" @@ -39,45 +39,45 @@ ::msgcat::mcset pl "&Font:" "Czcio&nka:" ::msgcat::mcset pl "Font st&yle:" "&Styl czcionki:" ::msgcat::mcset pl "&Green" "&Zielony" ::msgcat::mcset pl "&Help" "&Pomoc" ::msgcat::mcset pl "Hi" "Witaj" - ::msgcat::mcset pl "&Hide Console" "&Ukryj konsol\u0119" + ::msgcat::mcset pl "&Hide Console" "&Ukryj konsolÄ™" ::msgcat::mcset pl "&Ignore" "&Ignoruj" - ::msgcat::mcset pl "Invalid file name \"%1\$s\"." "Niew\u0142a\u015bciwa nazwa pliku \"%1\$s\"." + ::msgcat::mcset pl "Invalid file name \"%1\$s\"." "NiewÅ‚aÅ›ciwa nazwa pliku \"%1\$s\"." ::msgcat::mcset pl "Italic" "Kursywa" ::msgcat::mcset pl "Log Files" "Pliki dziennika" ::msgcat::mcset pl "&No" "&Nie" ::msgcat::mcset pl "&OK" ::msgcat::mcset pl "OK" ::msgcat::mcset pl "Ok" - ::msgcat::mcset pl "Open" "Otw\u00f3rz" - ::msgcat::mcset pl "&Open" "&Otw\u00f3rz" - ::msgcat::mcset pl "Open Multiple Files" "Otw\u00f3rz wiele plik\u00f3w" + ::msgcat::mcset pl "Open" "Otwórz" + ::msgcat::mcset pl "&Open" "&Otwórz" + ::msgcat::mcset pl "Open Multiple Files" "Otwórz wiele plików" ::msgcat::mcset pl "P&aste" "&Wklej" - ::msgcat::mcset pl "&Quit" "&Zako\u0144cz" + ::msgcat::mcset pl "&Quit" "&ZakoÅ„cz" ::msgcat::mcset pl "&Red" "&Czerwony" ::msgcat::mcset pl "Regular" "Regularne" - ::msgcat::mcset pl "Replace existing file?" "Czy zast\u0105pi\u0107 istniej\u0105cy plik?" - ::msgcat::mcset pl "&Retry" "&Pon\u00f3w" - ::msgcat::mcset pl "Sample" "Przyk\u0142ad" + ::msgcat::mcset pl "Replace existing file?" "Czy zastÄ…pić istniejÄ…cy plik?" + ::msgcat::mcset pl "&Retry" "&Ponów" + ::msgcat::mcset pl "Sample" "PrzykÅ‚ad" ::msgcat::mcset pl "&Save" "&Zapisz" ::msgcat::mcset pl "Save As" "Zapisz jako" ::msgcat::mcset pl "Save To Log" "Wpisz do dziennika" ::msgcat::mcset pl "Select Log File" "Wybierz plik dziennika" ::msgcat::mcset pl "Select a file to source" "Wybierz plik do wykonania" - ::msgcat::mcset pl "&Selection:" "&Wyb\u00f3r:" + ::msgcat::mcset pl "&Selection:" "&Wybór:" ::msgcat::mcset pl "&Size:" "&Rozmiar:" - ::msgcat::mcset pl "Show &Hidden Directories" "Poka\u017c &ukryte katalogi" - ::msgcat::mcset pl "Show &Hidden Files and Directories" "Poka\u017c &ukryte pliki i katalogi" - ::msgcat::mcset pl "Skip Messages" "Pomi\u0144 pozosta\u0142e komunikaty" - ::msgcat::mcset pl "&Source..." "&Kod \u017ar\u00f3d\u0142owy..." - ::msgcat::mcset pl "Stri&keout" "&Przekre\u015blenie" + ::msgcat::mcset pl "Show &Hidden Directories" "Pokaż &ukryte katalogi" + ::msgcat::mcset pl "Show &Hidden Files and Directories" "Pokaż &ukryte pliki i katalogi" + ::msgcat::mcset pl "Skip Messages" "PomiÅ„ pozostaÅ‚e komunikaty" + ::msgcat::mcset pl "&Source..." "&Kod źródÅ‚owy..." + ::msgcat::mcset pl "Stri&keout" "&PrzekreÅ›lenie" ::msgcat::mcset pl "Tcl Scripts" "Skrypty Tcl" ::msgcat::mcset pl "Tcl for Windows" "Tcl dla Windows" ::msgcat::mcset pl "Text Files" "Pliki tekstowe" - ::msgcat::mcset pl "&Underline" "Po&dkre\u015blenie" + ::msgcat::mcset pl "&Underline" "Po&dkreÅ›lenie" ::msgcat::mcset pl "&Yes" "&Tak" ::msgcat::mcset pl "abort" "przerwij" ::msgcat::mcset pl "blue" "niebieski" ::msgcat::mcset pl "cancel" "anuluj" ::msgcat::mcset pl "extension" "rozszerzenie" @@ -84,8 +84,8 @@ ::msgcat::mcset pl "extensions" "rozszerzenia" ::msgcat::mcset pl "green" "zielony" ::msgcat::mcset pl "ignore" "ignoruj" ::msgcat::mcset pl "ok" ::msgcat::mcset pl "red" "czerwony" - ::msgcat::mcset pl "retry" "pon\u00f3w" + ::msgcat::mcset pl "retry" "ponów" ::msgcat::mcset pl "yes" "tak" } Index: library/msgs/pt.msg ================================================================== --- library/msgs/pt.msg +++ library/msgs/pt.msg @@ -1,31 +1,31 @@ namespace eval ::tk { ::msgcat::mcset pt "&Abort" "&Abortar" ::msgcat::mcset pt "About..." "Sobre ..." ::msgcat::mcset pt "All Files" "Todos os arquivos" - ::msgcat::mcset pt "Application Error" "Erro de aplica\u00e7\u00e3o" + ::msgcat::mcset pt "Application Error" "Erro de aplicação" ::msgcat::mcset pt "&Blue" "&Azul" ::msgcat::mcset pt "Cancel" "Cancelar" ::msgcat::mcset pt "&Cancel" "&Cancelar" - ::msgcat::mcset pt "Cannot change to the directory \"%1\$s\".\nPermission denied." "N\u00e3o foi poss\u00edvel mudar para o diret\u00f3rio \"%1\$s\".\nPermiss\u00e3o negada." - ::msgcat::mcset pt "Choose Directory" "Escolha um diret\u00f3rio" + ::msgcat::mcset pt "Cannot change to the directory \"%1\$s\".\nPermission denied." "Não foi possível mudar para o diretório \"%1\$s\".\nPermissão negada." + ::msgcat::mcset pt "Choose Directory" "Escolha um diretório" ::msgcat::mcset pt "Cl&ear" "Apagar" ::msgcat::mcset pt "&Clear Console" "Apagar Console" ::msgcat::mcset pt "Color" "Cor" ::msgcat::mcset pt "Console" ::msgcat::mcset pt "&Copy" "Copiar" ::msgcat::mcset pt "Cu&t" "Recortar" ::msgcat::mcset pt "&Delete" "Excluir" ::msgcat::mcset pt "Details >>" "Detalhes >>" - ::msgcat::mcset pt "Directory \"%1\$s\" does not exist." "O diret\u00f3rio \"%1\$s\" n\u00e3o existe." - ::msgcat::mcset pt "&Directory:" "&Diret\u00f3rio:" + ::msgcat::mcset pt "Directory \"%1\$s\" does not exist." "O diretório \"%1\$s\" não existe." + ::msgcat::mcset pt "&Directory:" "&Diretório:" ::msgcat::mcset pt "Error: %1\$s" "Erro: %1\$s" ::msgcat::mcset pt "E&xit" "Sair" ::msgcat::mcset pt "&File" "Arquivo" - ::msgcat::mcset pt "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "O arquivo \"%1\$s\" j\u00e1 existe.\nDeseja sobrescreve-lo?" - ::msgcat::mcset pt "File \"%1\$s\" already exists.\n\n" "O arquivo \"%1\$s\" j\u00e1 existe.\n\n" - ::msgcat::mcset pt "File \"%1\$s\" does not exist." "Arquivo \"%1\$s\" n\u00e3o existe." + ::msgcat::mcset pt "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "O arquivo \"%1\$s\" já existe.\nDeseja sobrescreve-lo?" + ::msgcat::mcset pt "File \"%1\$s\" already exists.\n\n" "O arquivo \"%1\$s\" já existe.\n\n" + ::msgcat::mcset pt "File \"%1\$s\" does not exist." "Arquivo \"%1\$s\" não existe." ::msgcat::mcset pt "File &name:" "&Nome do arquivo:" ::msgcat::mcset pt "File &names:" "&Nomes dos arquivos:" ::msgcat::mcset pt "Files of &type:" "Arquivos do &tipo:" ::msgcat::mcset pt "Fi&les:" "&Arquivos:" ::msgcat::mcset pt "&Filter" "&Filtro" @@ -32,19 +32,19 @@ ::msgcat::mcset pt "Fil&ter:" "Fil&tro:" ::msgcat::mcset pt "&Green" "&Verde" ::msgcat::mcset pt "Hi" "Oi" ::msgcat::mcset pt "&Hide Console" "Ocultar console" ::msgcat::mcset pt "&Ignore" "&Ignorar" - ::msgcat::mcset pt "Invalid file name \"%1\$s\"." "O nome do arquivo \u00e9 inv\u00e1lido \"%1\$s\"." + ::msgcat::mcset pt "Invalid file name \"%1\$s\"." "O nome do arquivo é inválido \"%1\$s\"." ::msgcat::mcset pt "Log Files" "Arquivos de log" - ::msgcat::mcset pt "&No" "&N\u00e3o" + ::msgcat::mcset pt "&No" "&Não" ::msgcat::mcset pt "&OK" ::msgcat::mcset pt "OK" ::msgcat::mcset pt "Ok" ::msgcat::mcset pt "Open" "Abrir" ::msgcat::mcset pt "&Open" "&Abrir" - ::msgcat::mcset pt "Open Multiple Files" "Abrir m\u00faltiplos arquivos" + ::msgcat::mcset pt "Open Multiple Files" "Abrir múltiplos arquivos" ::msgcat::mcset pt "P&aste" "Col&ar" ::msgcat::mcset pt "Quit" "Encerrar" ::msgcat::mcset pt "&Red" "&Vermelho" ::msgcat::mcset pt "Replace existing file?" "Substituir arquivo existente?" ::msgcat::mcset pt "&Retry" "Tenta&r novamente" @@ -51,24 +51,24 @@ ::msgcat::mcset pt "&Save" "&Salvar" ::msgcat::mcset pt "Save As" "Salvar como" ::msgcat::mcset pt "Save To Log" "Salvar arquivo de log" ::msgcat::mcset pt "Select Log File" "Selecionar arquivo de log" ::msgcat::mcset pt "Select a file to source" "Selecione um arquivo como fonte" - ::msgcat::mcset pt "&Selection:" "&Sele\u00e7\u00e3o:" + ::msgcat::mcset pt "&Selection:" "&Seleção:" ::msgcat::mcset pt "Skip Messages" "Omitir as mensagens" ::msgcat::mcset pt "&Source..." "&Fonte..." ::msgcat::mcset pt "Tcl Scripts" "Scripts Tcl" ::msgcat::mcset pt "Tcl for Windows" "Tcl para Windows" ::msgcat::mcset pt "Text Files" "Arquivos de texto" ::msgcat::mcset pt "&Yes" "&Sim" ::msgcat::mcset pt "abort" "abortar" ::msgcat::mcset pt "blue" "azul" ::msgcat::mcset pt "cancel" "cancelar" - ::msgcat::mcset pt "extension" "extens\u00e3o" - ::msgcat::mcset pt "extensions" "extens\u00f5es" + ::msgcat::mcset pt "extension" "extensão" + ::msgcat::mcset pt "extensions" "extensões" ::msgcat::mcset pt "green" "verde" ::msgcat::mcset pt "ignore" "ignorar" ::msgcat::mcset pt "ok" ::msgcat::mcset pt "red" "vermelho" ::msgcat::mcset pt "retry" "tentar novamente" ::msgcat::mcset pt "yes" "sim" } Index: library/msgs/ru.msg ================================================================== --- library/msgs/ru.msg +++ library/msgs/ru.msg @@ -1,75 +1,75 @@ namespace eval ::tk { - ::msgcat::mcset ru "&Abort" "&\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c" - ::msgcat::mcset ru "&About..." "\u041f\u0440\u043e..." - ::msgcat::mcset ru "All Files" "\u0412\u0441\u0435 \u0444\u0430\u0439\u043b\u044b" - ::msgcat::mcset ru "Application Error" "\u041e\u0448\u0438\u0431\u043a\u0430 \u0432 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0435" - ::msgcat::mcset ru "&Blue" " &\u0413\u043e\u043b\u0443\u0431\u043e\u0439" - ::msgcat::mcset ru "Cancel" "\u041e\u0442&\u043c\u0435\u043d\u0430" - ::msgcat::mcset ru "&Cancel" "\u041e\u0442&\u043c\u0435\u043d\u0430" + ::msgcat::mcset ru "&Abort" "&Отменить" + ::msgcat::mcset ru "&About..." "Про..." + ::msgcat::mcset ru "All Files" "Ð’Ñе файлы" + ::msgcat::mcset ru "Application Error" "Ошибка в программе" + ::msgcat::mcset ru "&Blue" " &Голубой" + ::msgcat::mcset ru "Cancel" "От&мена" + ::msgcat::mcset ru "&Cancel" "От&мена" ::msgcat::mcset ru "Cannot change to the directory \"%1\$s\".\nPermission denied." \ - "\u041d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0435\u0440\u0435\u0439\u0442\u0438 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433 \"%1\$s\".\n\u041d\u0435\u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u0430\u0432 \u0434\u043e\u0441\u0442\u0443\u043f\u0430" - ::msgcat::mcset ru "Choose Directory" "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u043a\u0430\u0442\u0430\u043b\u043e\u0433" - ::msgcat::mcset ru "Cl&ear" "\u041e\u0447\u0438\u0441\u0442\u0438\u0442\u044c" - ::msgcat::mcset ru "Color" "\u0426\u0432\u0435\u0442" - ::msgcat::mcset ru "Console" "\u041a\u043e\u043d\u0441\u043e\u043b\u044c" - ::msgcat::mcset ru "&Copy" "\u041a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c" - ::msgcat::mcset ru "Cu&t" "\u0412\u044b\u0440\u0435\u0437\u0430\u0442\u044c" - ::msgcat::mcset ru "&Delete" "\u0423\u0434\u0430\u043b\u0438\u0442\u044c" - ::msgcat::mcset ru "Details >>" "\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 >>" - ::msgcat::mcset ru "Directory \"%1\$s\" does not exist." "\u041a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \"%1\$s\" \u043d\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442." - ::msgcat::mcset ru "&Directory:" "&\u041a\u0430\u0442\u0430\u043b\u043e\u0433:" - ::msgcat::mcset ru "Error: %1\$s" "\u041e\u0448\u0438\u0431\u043a\u0430: %1\$s" - ::msgcat::mcset ru "E&xit" "\u0412\u044b\u0445\u043e\u0434" + "Ðе могу перейти в каталог \"%1\$s\".\nÐедоÑтаточно прав доÑтупа" + ::msgcat::mcset ru "Choose Directory" "Выберите каталог" + ::msgcat::mcset ru "Cl&ear" "ОчиÑтить" + ::msgcat::mcset ru "Color" "Цвет" + ::msgcat::mcset ru "Console" "КонÑоль" + ::msgcat::mcset ru "&Copy" "Копировать" + ::msgcat::mcset ru "Cu&t" "Вырезать" + ::msgcat::mcset ru "&Delete" "Удалить" + ::msgcat::mcset ru "Details >>" "Подробнее >>" + ::msgcat::mcset ru "Directory \"%1\$s\" does not exist." "Каталога \"%1\$s\" не ÑущеÑтвует." + ::msgcat::mcset ru "&Directory:" "&Каталог:" + ::msgcat::mcset ru "Error: %1\$s" "Ошибка: %1\$s" + ::msgcat::mcset ru "E&xit" "Выход" ::msgcat::mcset ru "File \"%1\$s\" already exists.\nDo you want to overwrite it?" \ - "\u0424\u0430\u0439\u043b \"%1\$s\" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0435\u0433\u043e?" - ::msgcat::mcset ru "File \"%1\$s\" already exists.\n\n" "\u0424\u0430\u0439\u043b \"%1\$s\" \u0443\u0436\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\n\n" - ::msgcat::mcset ru "File \"%1\$s\" does not exist." "\u0424\u0430\u0439\u043b \"%1\$s\" \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d." - ::msgcat::mcset ru "File &name:" "&\u0418\u043c\u044f \u0444\u0430\u0439\u043b\u0430:" - ::msgcat::mcset ru "File &names:" "&\u0418\u043c\u0435\u043d\u0430 \u0444\u0430\u0439\u043b\u043e\u0432:" - ::msgcat::mcset ru "Files of &type:" "&\u0422\u0438\u043f \u0444\u0430\u0439\u043b\u043e\u0432:" - ::msgcat::mcset ru "Fi&les:" "\u0424\u0430\u0439&\u043b\u044b:" - ::msgcat::mcset ru "&Filter" "&\u0424\u0438\u043b\u044c\u0442\u0440" - ::msgcat::mcset ru "Fil&ter:" "\u0424\u0438\u043b\u044c&\u0442\u0440:" - ::msgcat::mcset ru "&Green" " &\u0417\u0435\u043b\u0435\u043d\u044b\u0439" - ::msgcat::mcset ru "Hi" "\u041f\u0440\u0438\u0432\u0435\u0442" - ::msgcat::mcset ru "&Hide Console" "\u0421\u043f\u0440\u044f\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c" - ::msgcat::mcset ru "&Ignore" "&\u0418\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c" - ::msgcat::mcset ru "Invalid file name \"%1\$s\"." "\u041d\u0435\u0432\u0435\u0440\u043d\u043e\u0435 \u0438\u043c\u044f \u0444\u0430\u0439\u043b\u0430 \"%1\$s\"." - ::msgcat::mcset ru "Log Files" "\u0424\u0430\u0439\u043b\u044b \u0436\u0443\u0440\u043d\u0430\u043b\u0430" - ::msgcat::mcset ru "&No" "&\u041d\u0435\u0442" - ::msgcat::mcset ru "&OK" "&\u041e\u041a" - ::msgcat::mcset ru "OK" "\u041e\u041a" - ::msgcat::mcset ru "Ok" "\u0414\u0430" - ::msgcat::mcset ru "Open" "\u041e\u0442\u043a\u0440\u044b\u0442\u044c" - ::msgcat::mcset ru "&Open" "&\u041e\u0442\u043a\u0440\u044b\u0442\u044c" - ::msgcat::mcset ru "Open Multiple Files" "\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0444\u0430\u0439\u043b\u043e\u0432" - ::msgcat::mcset ru "P&aste" "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c" - ::msgcat::mcset ru "&Quit" "\u0412\u044b\u0445\u043e\u0434" - ::msgcat::mcset ru "&Red" " &\u041a\u0440\u0430\u0441\u043d\u044b\u0439" - ::msgcat::mcset ru "Replace existing file?" "\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 \u0444\u0430\u0439\u043b?" - ::msgcat::mcset ru "&Retry" "&\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c" - ::msgcat::mcset ru "&Save" "&\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c" - ::msgcat::mcset ru "Save As" "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a" - ::msgcat::mcset ru "Save To Log" "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432 \u0436\u0443\u0440\u043d\u0430\u043b" - ::msgcat::mcset ru "Select Log File" "\u0412\u044b\u0431\u0440\u0430\u0442\u044c \u0436\u0443\u0440\u043d\u0430\u043b" - ::msgcat::mcset ru "Select a file to source" "\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u0444\u0430\u0439\u043b \u0434\u043b\u044f \u0438\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0430\u0446\u0438\u0438" + "Файл \"%1\$s\" уже ÑущеÑтвует.\nЗаменить его?" + ::msgcat::mcset ru "File \"%1\$s\" already exists.\n\n" "Файл \"%1\$s\" уже ÑущеÑтвует.\n\n" + ::msgcat::mcset ru "File \"%1\$s\" does not exist." "Файл \"%1\$s\" не найден." + ::msgcat::mcset ru "File &name:" "&Ð˜Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð°:" + ::msgcat::mcset ru "File &names:" "&Имена файлов:" + ::msgcat::mcset ru "Files of &type:" "&Тип файлов:" + ::msgcat::mcset ru "Fi&les:" "Фай&лы:" + ::msgcat::mcset ru "&Filter" "&Фильтр" + ::msgcat::mcset ru "Fil&ter:" "Филь&Ñ‚Ñ€:" + ::msgcat::mcset ru "&Green" " &Зеленый" + ::msgcat::mcset ru "Hi" "Привет" + ::msgcat::mcset ru "&Hide Console" "СпрÑтать конÑоль" + ::msgcat::mcset ru "&Ignore" "&Игнорировать" + ::msgcat::mcset ru "Invalid file name \"%1\$s\"." "Ðеверное Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° \"%1\$s\"." + ::msgcat::mcset ru "Log Files" "Файлы журнала" + ::msgcat::mcset ru "&No" "&Ðет" + ::msgcat::mcset ru "&OK" "&ОК" + ::msgcat::mcset ru "OK" "ОК" + ::msgcat::mcset ru "Ok" "Да" + ::msgcat::mcset ru "Open" "Открыть" + ::msgcat::mcset ru "&Open" "&Открыть" + ::msgcat::mcset ru "Open Multiple Files" "Открыть неÑколько файлов" + ::msgcat::mcset ru "P&aste" "Ð’Ñтавить" + ::msgcat::mcset ru "&Quit" "Выход" + ::msgcat::mcset ru "&Red" " &КраÑный" + ::msgcat::mcset ru "Replace existing file?" "Заменить ÑущеÑтвующий файл?" + ::msgcat::mcset ru "&Retry" "&Повторить" + ::msgcat::mcset ru "&Save" "&Сохранить" + ::msgcat::mcset ru "Save As" "Сохранить как" + ::msgcat::mcset ru "Save To Log" "Сохранить в журнал" + ::msgcat::mcset ru "Select Log File" "Выбрать журнал" + ::msgcat::mcset ru "Select a file to source" "Выберите файл Ð´Ð»Ñ Ð¸Ð½Ñ‚ÐµÑ€Ð¿Ñ€ÐµÑ‚Ð°Ñ†Ð¸Ð¸" ::msgcat::mcset ru "&Selection:" - ::msgcat::mcset ru "Skip Messages" "\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f" - ::msgcat::mcset ru "&Source..." "\u0418\u043d\u0442\u0435\u0440\u043f\u0440\u0435\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b..." - ::msgcat::mcset ru "Tcl Scripts" "\u041f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0430 \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 TCL" - ::msgcat::mcset ru "Tcl for Windows" "TCL \u0434\u043b\u044f Windows" - ::msgcat::mcset ru "Text Files" "\u0422\u0435\u043a\u0441\u0442\u043e\u0432\u044b\u0435 \u0444\u0430\u0439\u043b\u044b" - ::msgcat::mcset ru "&Yes" "&\u0414\u0430" - ::msgcat::mcset ru "abort" "\u043e\u0442\u043c\u0435\u043d\u0430" - ::msgcat::mcset ru "blue" " \u0433\u043e\u043b\u0443\u0431\u043e\u0439" - ::msgcat::mcset ru "cancel" "\u043e\u0442\u043c\u0435\u043d\u0430" - ::msgcat::mcset ru "extension" "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0435" - ::msgcat::mcset ru "extensions" "\u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f" - ::msgcat::mcset ru "green" " \u0437\u0435\u043b\u0435\u043d\u044b\u0439" - ::msgcat::mcset ru "ignore" "\u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c" - ::msgcat::mcset ru "ok" "\u043e\u043a" - ::msgcat::mcset ru "red" " \u043a\u0440\u0430\u0441\u043d\u044b\u0439" - ::msgcat::mcset ru "retry" "\u043f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c" - ::msgcat::mcset ru "yes" "\u0434\u0430" + ::msgcat::mcset ru "Skip Messages" "ПропуÑтить ÑообщениÑ" + ::msgcat::mcset ru "&Source..." "Интерпретировать файл..." + ::msgcat::mcset ru "Tcl Scripts" "Программа на Ñзыке TCL" + ::msgcat::mcset ru "Tcl for Windows" "TCL Ð´Ð»Ñ Windows" + ::msgcat::mcset ru "Text Files" "ТекÑтовые файлы" + ::msgcat::mcset ru "&Yes" "&Да" + ::msgcat::mcset ru "abort" "отмена" + ::msgcat::mcset ru "blue" " голубой" + ::msgcat::mcset ru "cancel" "отмена" + ::msgcat::mcset ru "extension" "раÑширение" + ::msgcat::mcset ru "extensions" "раÑширениÑ" + ::msgcat::mcset ru "green" " зеленый" + ::msgcat::mcset ru "ignore" "пропуÑтить" + ::msgcat::mcset ru "ok" "ок" + ::msgcat::mcset ru "red" " краÑный" + ::msgcat::mcset ru "retry" "повторить" + ::msgcat::mcset ru "yes" "да" } Index: library/msgs/sv.msg ================================================================== --- library/msgs/sv.msg +++ library/msgs/sv.msg @@ -1,18 +1,18 @@ namespace eval ::tk { ::msgcat::mcset sv "&Abort" "&Avsluta" ::msgcat::mcset sv "&About..." "&Om..." ::msgcat::mcset sv "All Files" "Samtliga filer" ::msgcat::mcset sv "Application Error" "Programfel" - ::msgcat::mcset sv "&Blue" "&Bl\u00e5" + ::msgcat::mcset sv "&Blue" "&BlÃ¥" ::msgcat::mcset sv "Cancel" "Avbryt" ::msgcat::mcset sv "&Cancel" "&Avbryt" - ::msgcat::mcset sv "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan ej n\u00e5 mappen \"%1\$s\".\nSaknar r\u00e4ttigheter." - ::msgcat::mcset sv "Choose Directory" "V\u00e4lj mapp" + ::msgcat::mcset sv "Cannot change to the directory \"%1\$s\".\nPermission denied." "Kan ej nÃ¥ mappen \"%1\$s\".\nSaknar rättigheter." + ::msgcat::mcset sv "Choose Directory" "Välj mapp" ::msgcat::mcset sv "Cl&ear" "&Radera" ::msgcat::mcset sv "&Clear Console" "&Radera konsollen" - ::msgcat::mcset sv "Color" "F\u00e4rg" + ::msgcat::mcset sv "Color" "Färg" ::msgcat::mcset sv "Console" "Konsoll" ::msgcat::mcset sv "&Copy" "&Kopiera" ::msgcat::mcset sv "Cu&t" "Klipp u&t" ::msgcat::mcset sv "&Delete" "&Radera" ::msgcat::mcset sv "Details >>" "Detaljer >>" @@ -20,57 +20,57 @@ ::msgcat::mcset sv "&Directory:" "&Mapp:" ::msgcat::mcset sv "&Edit" "R&edigera" ::msgcat::mcset sv "Error: %1\$s" "Fel: %1\$s" ::msgcat::mcset sv "E&xit" "&Avsluta" ::msgcat::mcset sv "&File" "&Fil" - ::msgcat::mcset sv "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Filen \"%1\$s\" finns redan.\nVill du skriva \u00f6ver den?" + ::msgcat::mcset sv "File \"%1\$s\" already exists.\nDo you want to overwrite it?" "Filen \"%1\$s\" finns redan.\nVill du skriva över den?" ::msgcat::mcset sv "File \"%1\$s\" already exists.\n\n" "Filen \"%1\$s\" finns redan.\n\n" ::msgcat::mcset sv "File \"%1\$s\" does not exist." "Filen \"%1\$s\" finns ej." ::msgcat::mcset sv "File &name:" "Fil&namn:" ::msgcat::mcset sv "File &names:" "Fil&namn:" ::msgcat::mcset sv "Files of &type:" "Filer av &typ:" ::msgcat::mcset sv "Fi&les:" "Fi&ler:" ::msgcat::mcset sv "&Filter" ::msgcat::mcset sv "Fil&ter:" - ::msgcat::mcset sv "&Green" "&Gr\u00f6n" - ::msgcat::mcset sv "&Help" "&Hj\u00e4lp" + ::msgcat::mcset sv "&Green" "&Grön" + ::msgcat::mcset sv "&Help" "&Hjälp" ::msgcat::mcset sv "Hi" "Hej" - ::msgcat::mcset sv "&Hide Console" "&G\u00f6m konsollen" + ::msgcat::mcset sv "&Hide Console" "&Göm konsollen" ::msgcat::mcset sv "&Ignore" "&Ignorera" ::msgcat::mcset sv "Invalid file name \"%1\$s\"." "Ogiltigt filnamn \"%1\$s\"." ::msgcat::mcset sv "Log Files" "Loggfiler" ::msgcat::mcset sv "&No" "&Nej" ::msgcat::mcset sv "&OK" ::msgcat::mcset sv "OK" ::msgcat::mcset sv "Ok" - ::msgcat::mcset sv "Open" "\u00d6ppna" - ::msgcat::mcset sv "&Open" "&\u00d6ppna" - ::msgcat::mcset sv "Open Multiple Files" "\u00d6ppna flera filer" + ::msgcat::mcset sv "Open" "Öppna" + ::msgcat::mcset sv "&Open" "&Öppna" + ::msgcat::mcset sv "Open Multiple Files" "Öppna flera filer" ::msgcat::mcset sv "P&aste" "&Klistra in" ::msgcat::mcset sv "&Quit" "&Avsluta" - ::msgcat::mcset sv "&Red" "&R\u00f6d" - ::msgcat::mcset sv "Replace existing file?" "Ers\u00e4tt existerande fil?" - ::msgcat::mcset sv "&Retry" "&F\u00f6rs\u00f6k igen" + ::msgcat::mcset sv "&Red" "&Röd" + ::msgcat::mcset sv "Replace existing file?" "Ersätt existerande fil?" + ::msgcat::mcset sv "&Retry" "&Försök igen" ::msgcat::mcset sv "&Save" "&Spara" ::msgcat::mcset sv "Save As" "Spara som" ::msgcat::mcset sv "Save To Log" "Spara till logg" - ::msgcat::mcset sv "Select Log File" "V\u00e4lj loggfil" - ::msgcat::mcset sv "Select a file to source" "V\u00e4lj k\u00e4llfil" + ::msgcat::mcset sv "Select Log File" "Välj loggfil" + ::msgcat::mcset sv "Select a file to source" "Välj källfil" ::msgcat::mcset sv "&Selection:" "&Val:" - ::msgcat::mcset sv "Skip Messages" "Hoppa \u00f6ver meddelanden" - ::msgcat::mcset sv "&Source..." "&K\u00e4lla..." + ::msgcat::mcset sv "Skip Messages" "Hoppa över meddelanden" + ::msgcat::mcset sv "&Source..." "&Källa..." ::msgcat::mcset sv "Tcl Scripts" "Tcl skript" - ::msgcat::mcset sv "Tcl for Windows" "Tcl f\u00f6r Windows" + ::msgcat::mcset sv "Tcl for Windows" "Tcl för Windows" ::msgcat::mcset sv "Text Files" "Textfiler" ::msgcat::mcset sv "&Yes" "&Ja" ::msgcat::mcset sv "abort" "avbryt" - ::msgcat::mcset sv "blue" "bl\u00e5" + ::msgcat::mcset sv "blue" "blÃ¥" ::msgcat::mcset sv "cancel" "avbryt" ::msgcat::mcset sv "extension" "utvidgning" ::msgcat::mcset sv "extensions" "utvidgningar" - ::msgcat::mcset sv "green" "gr\u00f6n" + ::msgcat::mcset sv "green" "grön" ::msgcat::mcset sv "ignore" "ignorera" ::msgcat::mcset sv "ok" - ::msgcat::mcset sv "red" "r\u00f6d" - ::msgcat::mcset sv "retry" "f\u00f6rs\u00f6k igen" + ::msgcat::mcset sv "red" "röd" + ::msgcat::mcset sv "retry" "försök igen" ::msgcat::mcset sv "yes" "ja" } Index: library/palette.tcl ================================================================== --- library/palette.tcl +++ library/palette.tcl @@ -203,31 +203,31 @@ # Given a color name, computes a new color value that darkens (or # brightens) the given color by a given percent. # # Arguments: # color - Name of starting color. -# perecent - Integer telling how much to brighten or darken as a +# percent - Integer telling how much to brighten or darken as a # percent: 50 means darken by 50%, 110 means brighten # by 10%. proc ::tk::Darken {color percent} { - foreach {red green blue} [winfo rgb . $color] { - set red [expr {($red/256)*$percent/100}] - set green [expr {($green/256)*$percent/100}] - set blue [expr {($blue/256)*$percent/100}] - break - } - if {$red > 255} { - set red 255 - } - if {$green > 255} { - set green 255 - } - if {$blue > 255} { - set blue 255 - } - return [format "#%02x%02x%02x" $red $green $blue] + if {$percent < 0} { + return #000000 + } elseif {$percent > 200} { + return #ffffff + } elseif {$percent <= 100} { + lassign [winfo rgb . $color] r g b + set r [expr {($r/256)*$percent/100}] + set g [expr {($g/256)*$percent/100}] + set b [expr {($b/256)*$percent/100}] + } elseif {$percent > 100} { + lassign [winfo rgb . $color] r g b + set r [expr {255 - ((65535-$r)/256)*(200-$percent)/100}] + set g [expr {255 - ((65535-$g)/256)*(200-$percent)/100}] + set b [expr {255 - ((65535-$b)/256)*(200-$percent)/100}] + } + return [format #%02x%02x%02x $r $g $b] } # ::tk_bisque -- # Reset the Tk color palette to the old "bisque" colors. # Index: library/tclIndex ================================================================== --- library/tclIndex +++ library/tclIndex @@ -245,9 +245,8 @@ set auto_index(::tk::ListBoxKeyAccel_Set) [list source [file join $dir xmfbox.tcl]] set auto_index(::tk::ListBoxKeyAccel_Unset) [list source [file join $dir xmfbox.tcl]] set auto_index(::tk::ListBoxKeyAccel_Key) [list source [file join $dir xmfbox.tcl]] set auto_index(::tk::ListBoxKeyAccel_Goto) [list source [file join $dir xmfbox.tcl]] set auto_index(::tk::ListBoxKeyAccel_Reset) [list source [file join $dir xmfbox.tcl]] -set auto_index(tk_getFileType) [list source [file join $dir xmfbox.tcl]] set auto_index(::tk::unsupported::ExposePrivateCommand) [list source [file join $dir unsupported.tcl]] set auto_index(::tk::unsupported::ExposePrivateVariable) [list source [file join $dir unsupported.tcl]] set auto_index(::tk::fontchooser) [list source [file join $dir fontchooser.tcl]] Index: library/text.tcl ================================================================== --- library/text.tcl +++ library/text.tcl @@ -461,11 +461,11 @@ if {"x11" eq [tk windowingsystem]} { # Support for mousewheels on Linux/Unix commonly comes through mapping # the wheel to the extended buttons. If you have a mousewheel, find # Linux configuration info at: - # http://www.inria.fr/koala/colas/mouse-wheel-scroll/ + # http://linuxreviews.org/howtos/xfree/mouse/ bind Text <4> { if {!$tk_strictMotif} { %W yview scroll -50 pixels } } @@ -766,10 +766,13 @@ } else { $w tag add sel insert $new } $w mark set $anchorname insert } else { + if {[catch {$w index $anchorname}]} { + $w mark set $anchorname insert + } if {[$w compare $new < $anchorname]} { set first $new set last $anchorname } else { set first $anchorname @@ -1053,17 +1056,17 @@ proc ::tk_textCut w { if {![catch {set data [$w get sel.first sel.last]}]} { # make <> an atomic operation on the Undo stack, # i.e. separate it from other delete operations on either side set oldSeparator [$w cget -autoseparators] - if {$oldSeparator} { + if {([$w cget -state] eq "normal") && $oldSeparator} { $w edit separator } clipboard clear -displayof $w clipboard append -displayof $w $data $w delete sel.first sel.last - if {$oldSeparator} { + if {([$w cget -state] eq "normal") && $oldSeparator} { $w edit separator } } } @@ -1200,5 +1203,101 @@ } if {[info exists Priv(mouseMoved)] && $Priv(mouseMoved)} { $w scan dragto $x $y } } + +# ::tk::TextUndoRedoProcessMarks -- +# +# This proc is executed after an undo or redo action. +# It processes the list of undo/redo marks temporarily set in the +# text widget to positions delimiting where changes happened, and +# returns a flat list of ranges. The temporary marks are removed +# from the text widget. +# +# Arguments: +# w - The text widget + +proc ::tk::TextUndoRedoProcessMarks {w} { + set indices {} + set undoMarks {} + + # only consider the temporary marks set by an undo/redo action + foreach mark [$w mark names] { + if {[string range $mark 0 11] eq "tk::undoMark"} { + lappend undoMarks $mark + } + } + + # transform marks into indices + # the number of undo/redo marks is always even, each right mark + # completes a left mark to give a range + # this is true because: + # - undo/redo only deals with insertions and deletions of text + # - insertions may move marks but not delete them + # - when deleting text, marks located inside the deleted range + # are not erased but moved to the start of the deletion range + # . this is done in TkBTreeDeleteIndexRange ("This segment + # refuses to die...") + # . because MarkDeleteProc does nothing else than returning + # a value indicating that marks are not deleted by this + # deleteProc + # . mark deletion rather happen through [.text mark unset xxx] + # which was not used _up to this point of the code_ (it + # is a bit later just before exiting the present proc) + set nUndoMarks [llength $undoMarks] + set n [expr {$nUndoMarks / 2}] + set undoMarks [lsort -dictionary $undoMarks] + set Lmarks [lrange $undoMarks 0 [expr {$n - 1}]] + set Rmarks [lrange $undoMarks $n [llength $undoMarks]] + foreach Lmark $Lmarks Rmark $Rmarks { + lappend indices [$w index $Lmark] [$w index $Rmark] + $w mark unset $Lmark $Rmark + } + + # process ranges to: + # - remove those already fully included in another range + # - merge overlapping ranges + set ind [lsort -dictionary -stride 2 $indices] + set indices {} + + for {set i 0} {$i < $nUndoMarks} {incr i 2} { + set il1 [lindex $ind $i] + set ir1 [lindex $ind [expr {$i + 1}]] + lappend indices $il1 $ir1 + + for {set j [expr {$i + 2}]} {$j < $nUndoMarks} {incr j 2} { + set il2 [lindex $ind $j] + set ir2 [lindex $ind [expr {$j + 1}]] + + if {[$w compare $il2 > $ir1]} { + # second range starts after the end of first range + # -> further second ranges do not need to be considered + # because ranges were sorted by increasing first index + set j $nUndoMarks + + } else { + if {[$w compare $ir2 > $ir1]} { + # second range overlaps first range + # -> merge them into a single range + set indices [lreplace $indices end-1 end] + lappend indices $il1 $ir2 + + } else { + # second range is fully included in first range + # -> ignore it + + } + # in both cases above, the second range shall be + # trimmed out from the list of ranges + set ind [lreplace $ind $j [expr {$j + 1}]] + incr j -2 + incr nUndoMarks -2 + + } + + } + + } + + return $indices +} Index: library/tk.tcl ================================================================== --- library/tk.tcl +++ library/tk.tcl @@ -9,11 +9,11 @@ # # See the file "license.terms" for information on usage and redistribution of # this file, and for a DISCLAIMER OF ALL WARRANTIES. # Verify that we have Tk binary and script components from the same release -package require -exact Tk 8.6.6 +package require -exact Tk 8.7a2 # Create a ::tk namespace namespace eval ::tk { # Set up the msgcat commands namespace eval msgcat { @@ -598,22 +598,23 @@ } # ::tk::AmpMenuArgs -- # Processes arguments for a menu entry, turning -label option into # -label and -underline options, returned by ::tk::UnderlineAmpersand. +# The cmd argument is supposed to be either "add" or "entryconfigure" # -proc ::tk::AmpMenuArgs {widget add type args} { +proc ::tk::AmpMenuArgs {widget cmd type args} { set options {} foreach {opt val} $args { if {$opt eq "-label"} { lassign [UnderlineAmpersand $val] newlabel under lappend options -label $newlabel -underline $under } else { lappend options $opt $val } } - $widget add $type {*}$options + $widget $cmd $type {*}$options } # ::tk::FindAltKeyTarget -- # Search recursively through the hierarchy of visible widgets to find # button or label which has $char as underlined character. Index: library/tkfbox.tcl ================================================================== --- library/tkfbox.tcl +++ library/tkfbox.tcl @@ -308,10 +308,11 @@ } set data(selectFile) $data(-initialfile) # 5. Parse the -filetypes option # + set data(origfiletypes) $data(-filetypes) set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)] if {![winfo exists $data(-parent)]} { return -code error -errorcode [list TK LOOKUP WINDOW $data(-parent)] \ "bad window path name \"$data(-parent)\"" @@ -1117,11 +1118,13 @@ [info exists data(-typevariable)] && $data(-typevariable) ne "" && [info exists data(-filetypes)] && [llength $data(-filetypes)] && [info exists data(filterType)] && $data(filterType) ne "" } then { upvar #0 $data(-typevariable) typeVariable - set typeVariable [lindex $data(filterType) 0] + set typeVariable [lindex $data(origfiletypes) \ + [lsearch -exact $data(-filetypes) $data(filterType)] 0] + } } bind $data(okBtn) {} set Priv(selectFilePath) $selectFilePath } Index: library/ttk/altTheme.tcl ================================================================== --- library/ttk/altTheme.tcl +++ library/ttk/altTheme.tcl @@ -12,10 +12,11 @@ -border "#414141" -activebg "#ececec" -disabledfg "#a3a3a3" -selectbg "#4a6984" -selectfg "#ffffff" + -altindicator "#aaaaaa" } ttk::style theme settings alt { ttk::style configure "." \ @@ -44,23 +45,28 @@ } -highlightcolor {alternate black} ttk::style configure TCheckbutton -indicatorcolor "#ffffff" -padding 2 ttk::style configure TRadiobutton -indicatorcolor "#ffffff" -padding 2 ttk::style map TCheckbutton -indicatorcolor \ - [list disabled $colors(-frame) pressed $colors(-frame)] + [list pressed $colors(-frame) \ + alternate $colors(-altindicator) \ + disabled $colors(-frame)] ttk::style map TRadiobutton -indicatorcolor \ - [list disabled $colors(-frame) pressed $colors(-frame)] + [list pressed $colors(-frame) \ + alternate $colors(-altindicator) \ + disabled $colors(-frame)] ttk::style configure TMenubutton \ -width -11 -padding "3 3" -relief raised ttk::style configure TEntry -padding 1 ttk::style map TEntry -fieldbackground \ [list readonly $colors(-frame) disabled $colors(-frame)] ttk::style configure TCombobox -padding 1 ttk::style map TCombobox -fieldbackground \ - [list readonly $colors(-frame) disabled $colors(-frame)] + [list readonly $colors(-frame) disabled $colors(-frame)] \ + -arrowcolor [list disabled $colors(-disabledfg)] ttk::style configure ComboboxPopdownFrame \ -relief solid -borderwidth 1 ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} ttk::style map TSpinbox -fieldbackground \ @@ -87,15 +93,19 @@ # Treeview: ttk::style configure Heading -font TkHeadingFont -relief raised ttk::style configure Treeview -background $colors(-window) ttk::style map Treeview \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; + -background [list disabled $colors(-frame)\ + {!disabled !selected} $colors(-window) \ + selected $colors(-selectbg)] \ + -foreground [list disabled $colors(-disabledfg) \ + {!disabled !selected} black \ + selected $colors(-selectfg)] ttk::style configure TScale \ -groovewidth 4 -troughrelief sunken \ -sliderwidth raised -borderwidth 2 ttk::style configure TProgressbar \ -background $colors(-selectbg) -borderwidth 0 } } Index: library/ttk/aquaTheme.tcl ================================================================== --- library/ttk/aquaTheme.tcl +++ library/ttk/aquaTheme.tcl @@ -39,12 +39,17 @@ # Treeview: ttk::style configure Heading -font TkHeadingFont ttk::style configure Treeview -rowheight 18 -background White ttk::style map Treeview \ - -background {{selected background} systemHighlightSecondary - selected systemHighlight} + -background [list disabled systemDialogBackgroundInactive \ + {!disabled !selected} systemWindowBody \ + {selected background} systemHighlightSecondary \ + selected systemHighlight] \ + -foreground [list disabled systemModelessDialogInactiveText \ + {!disabled !selected} black \ + selected systemModelessDialogActiveText] # Enable animation for ttk::progressbar widget: ttk::style configure TProgressbar -period 100 -maxphase 255 # For Aqua, labelframe labels should appear outside the border, Index: library/ttk/button.tcl ================================================================== --- library/ttk/button.tcl +++ library/ttk/button.tcl @@ -6,11 +6,11 @@ # This doesn't seem to be conventional, but it's a nice way # to provide extra feedback while the grab is active. # (If the button is released off the widget, the grab deactivates and # we get a event then, which turns off the "active" state) # -# Normally, and events are +# Normally, and events are # delivered to the widget which received the initial # event. However, Tk [grab]s (#1223103) and menu interactions # (#1222605) can interfere with this. To guard against spurious # events, the binding only sets # the pressed state if the button is currently active. Index: library/ttk/clamTheme.tcl ================================================================== --- library/ttk/clamTheme.tcl +++ library/ttk/clamTheme.tcl @@ -3,22 +3,24 @@ # # Inspired by the XFCE family of Gnome themes. # namespace eval ttk::theme::clam { - variable colors + variable colors array set colors { - -disabledfg "#999999" - -frame "#dcdad5" - -window "#ffffff" - -dark "#cfcdc8" - -darker "#bab5ab" - -darkest "#9e9a91" - -lighter "#eeebe7" - -lightest "#ffffff" - -selectbg "#4a6984" - -selectfg "#ffffff" + -disabledfg "#999999" + -frame "#dcdad5" + -window "#ffffff" + -dark "#cfcdc8" + -darker "#bab5ab" + -darkest "#9e9a91" + -lighter "#eeebe7" + -lightest "#ffffff" + -selectbg "#4a6984" + -selectfg "#ffffff" + -altindicator "#5895bc" + -disabledaltindicator "#a0a0a0" } ttk::style theme settings clam { ttk::style configure "." \ @@ -78,13 +80,19 @@ ttk::style configure TRadiobutton \ -indicatorbackground "#ffffff" \ -indicatormargin {1 1 4 1} \ -padding 2 ; ttk::style map TCheckbutton -indicatorbackground \ - [list disabled $colors(-frame) pressed $colors(-frame)] + [list pressed $colors(-frame) \ + {!disabled alternate} $colors(-altindicator) \ + {disabled alternate} $colors(-disabledaltindicator) \ + disabled $colors(-frame)] ttk::style map TRadiobutton -indicatorbackground \ - [list disabled $colors(-frame) pressed $colors(-frame)] + [list pressed $colors(-frame) \ + {!disabled alternate} $colors(-altindicator) \ + {disabled alternate} $colors(-disabledaltindicator) \ + disabled $colors(-frame)] ttk::style configure TMenubutton \ -width -11 -padding 5 -relief raised ttk::style configure TEntry -padding 1 -insertwidth 1 @@ -100,11 +108,11 @@ -background [list active $colors(-lighter) \ pressed $colors(-lighter)] \ -fieldbackground [list {readonly focus} $colors(-selectbg) \ readonly $colors(-frame)] \ -foreground [list {readonly focus} $colors(-selectfg)] \ - ; + -arrowcolor [list disabled $colors(-disabledfg)] ttk::style configure ComboboxPopdownFrame \ -relief solid -borderwidth 1 ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} ttk::style map TSpinbox \ @@ -121,12 +129,16 @@ # Treeview: ttk::style configure Heading \ -font TkHeadingFont -relief raised -padding {3} ttk::style configure Treeview -background $colors(-window) ttk::style map Treeview \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; + -background [list disabled $colors(-frame)\ + {!disabled !selected} $colors(-window) \ + selected $colors(-selectbg)] \ + -foreground [list disabled $colors(-disabledfg) \ + {!disabled !selected} black \ + selected $colors(-selectfg)] ttk::style configure TLabelframe \ -labeloutside true -labelmargins {0 0 0 4} \ -borderwidth 2 -relief raised Index: library/ttk/classicTheme.tcl ================================================================== --- library/ttk/classicTheme.tcl +++ library/ttk/classicTheme.tcl @@ -13,10 +13,11 @@ -troughbg "#c3c3c3" -selectbg "#c3c3c3" -selectfg "#000000" -disabledfg "#a3a3a3" -indicator "#b03060" + -altindicator "#b05e5e" } ttk::style theme settings classic { ttk::style configure "." \ -font TkDefaultFont \ @@ -47,19 +48,23 @@ ttk::style map TButton -relief [list {!disabled pressed} sunken] ttk::style configure TCheckbutton -indicatorrelief raised ttk::style map TCheckbutton \ -indicatorcolor [list \ - pressed $colors(-frame) selected $colors(-indicator)] \ - -indicatorrelief {selected sunken pressed sunken} \ + pressed $colors(-frame) \ + alternate $colors(-altindicator) \ + selected $colors(-indicator)] \ + -indicatorrelief {alternate raised selected sunken pressed sunken} \ ; ttk::style configure TRadiobutton -indicatorrelief raised ttk::style map TRadiobutton \ -indicatorcolor [list \ - pressed $colors(-frame) selected $colors(-indicator)] \ - -indicatorrelief {selected sunken pressed sunken} \ + pressed $colors(-frame) \ + alternate $colors(-altindicator) \ + selected $colors(-indicator)] \ + -indicatorrelief {alternate raised selected sunken pressed sunken} \ ; ttk::style configure TMenubutton -relief raised -padding "3m 1m" ttk::style configure TEntry -relief sunken -padding 1 -font TkTextFont @@ -91,12 +96,16 @@ # Treeview: ttk::style configure Heading -font TkHeadingFont -relief raised ttk::style configure Treeview -background $colors(-window) ttk::style map Treeview \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; + -background [list disabled $colors(-frame)\ + {!disabled !selected} $colors(-window) \ + selected $colors(-selectbg)] \ + -foreground [list disabled $colors(-disabledfg) \ + {!disabled !selected} black \ + selected $colors(-selectfg)] # # Toolbar buttons: # ttk::style configure Toolbutton -padding 2 -relief flat -shiftrelief 2 Index: library/ttk/combobox.tcl ================================================================== --- library/ttk/combobox.tcl +++ library/ttk/combobox.tcl @@ -86,22 +86,22 @@ { ttk::combobox::Unpost [winfo parent %W] } ### Option database settings. # -option add *TCombobox*Listbox.font TkTextFont -option add *TCombobox*Listbox.relief flat -option add *TCombobox*Listbox.highlightThickness 0 +option add *TCombobox*Listbox.font TkTextFont widgetDefault +option add *TCombobox*Listbox.relief flat widgetDefault +option add *TCombobox*Listbox.highlightThickness 0 widgetDefault ## Platform-specific settings. # switch -- [tk windowingsystem] { x11 { - option add *TCombobox*Listbox.background white + option add *TCombobox*Listbox.background white widgetDefault } aqua { - option add *TCombobox*Listbox.borderWidth 0 + option add *TCombobox*Listbox.borderWidth 0 widgetDefault } } ### Binding procedures. # @@ -366,11 +366,12 @@ proc ttk::combobox::PlacePopdown {cb popdown} { set x [winfo rootx $cb] set y [winfo rooty $cb] set w [winfo width $cb] set h [winfo height $cb] - set postoffset [ttk::style lookup TCombobox -postoffset {} {0 0 0 0}] + set style [$cb cget -style] + set postoffset [ttk::style lookup $style -postoffset {} {0 0 0 0}] foreach var {x y w h} delta $postoffset { incr $var $delta } set H [winfo reqheight $popdown] Index: library/ttk/defaults.tcl ================================================================== --- library/ttk/defaults.tcl +++ library/ttk/defaults.tcl @@ -3,20 +3,23 @@ # namespace eval ttk::theme::default { variable colors array set colors { - -frame "#d9d9d9" - -foreground "#000000" - -window "#ffffff" - -text "#000000" - -activebg "#ececec" - -selectbg "#4a6984" - -selectfg "#ffffff" - -darker "#c3c3c3" - -disabledfg "#a3a3a3" - -indicator "#4a6984" + -frame "#d9d9d9" + -foreground "#000000" + -window "#ffffff" + -text "#000000" + -activebg "#ececec" + -selectbg "#4a6984" + -selectfg "#ffffff" + -darker "#c3c3c3" + -disabledfg "#a3a3a3" + -indicator "#4a6984" + -disabledindicator "#a3a3a3" + -altindicator "#9fbdd8" + -disabledaltindicator "#c0c0c0" } ttk::style theme settings default { ttk::style configure "." \ @@ -38,21 +41,33 @@ [list disabled $colors(-disabledfg)] ttk::style configure TButton \ -anchor center -padding "3 3" -width -9 \ -relief raised -shiftrelief 1 - ttk::style map TButton -relief [list {!disabled pressed} sunken] + ttk::style map TButton -relief [list {!disabled pressed} sunken] ttk::style configure TCheckbutton \ -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1 ttk::style map TCheckbutton -indicatorcolor \ - [list pressed $colors(-activebg) selected $colors(-indicator)] + [list pressed $colors(-activebg) \ + {!disabled alternate} $colors(-altindicator) \ + {disabled alternate} $colors(-disabledaltindicator) \ + {!disabled selected} $colors(-indicator) \ + {disabled selected} $colors(-disabledindicator)] + ttk::style map TCheckbutton -indicatorrelief \ + [list alternate raised] ttk::style configure TRadiobutton \ -indicatorcolor "#ffffff" -indicatorrelief sunken -padding 1 ttk::style map TRadiobutton -indicatorcolor \ - [list pressed $colors(-activebg) selected $colors(-indicator)] + [list pressed $colors(-activebg) \ + {!disabled alternate} $colors(-altindicator) \ + {disabled alternate} $colors(-disabledaltindicator) \ + {!disabled selected} $colors(-indicator) \ + {disabled selected} $colors(-disabledindicator)] + ttk::style map TRadiobutton -indicatorrelief \ + [list alternate raised] ttk::style configure TMenubutton \ -relief raised -padding "10 3" ttk::style configure TEntry \ @@ -60,11 +75,12 @@ ttk::style map TEntry -fieldbackground \ [list readonly $colors(-frame) disabled $colors(-frame)] ttk::style configure TCombobox -arrowsize 12 -padding 1 ttk::style map TCombobox -fieldbackground \ - [list readonly $colors(-frame) disabled $colors(-frame)] + [list readonly $colors(-frame) disabled $colors(-frame)] \ + -arrowcolor [list disabled $colors(-disabledfg)] ttk::style configure TSpinbox -arrowsize 10 -padding {2 0 10 0} ttk::style map TSpinbox -fieldbackground \ [list readonly $colors(-frame) disabled $colors(-frame)] \ -arrowcolor [list disabled $colors(-disabledfg)] @@ -92,12 +108,16 @@ ttk::style configure Heading -font TkHeadingFont -relief raised ttk::style configure Treeview \ -background $colors(-window) \ -foreground $colors(-text) ; ttk::style map Treeview \ - -background [list selected $colors(-selectbg)] \ - -foreground [list selected $colors(-selectfg)] ; + -background [list disabled $colors(-frame)\ + {!disabled !selected} $colors(-window) \ + selected $colors(-selectbg)] \ + -foreground [list disabled $colors(-disabledfg) \ + {!disabled !selected} black \ + selected $colors(-selectfg)] # Combobox popdown frame ttk::style layout ComboboxPopdownFrame { ComboboxPopdownFrame.border -sticky nswe } Index: library/ttk/entry.tcl ================================================================== --- library/ttk/entry.tcl +++ library/ttk/entry.tcl @@ -32,11 +32,11 @@ } } ### Option database settings. # -option add *TEntry.cursor [ttk::cursor text] +option add *TEntry.cursor [ttk::cursor text] widgetDefault ### Bindings. # # Removed the following standard Tk bindings: # @@ -416,11 +416,11 @@ ## binding # Suspend autoscroll. # proc ttk::entry::DragIn {w} { - ttk::CancelRepeat + ttk::CancelRepeat } ## binding # proc ttk::entry::Release {w} { @@ -430,11 +430,11 @@ } ## AutoScroll # Called repeatedly when the mouse is outside an entry window # with Button 1 down. Scroll the window left or right, -# depending on where the mouse left the window, and extend +# depending on where the mouse left the window, and extend # the selection according to the current selection mode. # # TODO: AutoScroll should repeat faster (50ms) than normal autorepeat. # TODO: Need a way for Repeat scripts to cancel themselves. # Index: library/ttk/menubutton.tcl ================================================================== --- library/ttk/menubutton.tcl +++ library/ttk/menubutton.tcl @@ -8,11 +8,11 @@ # Keyboard: or accelerator key to post menu # # (In addition, when menu system is active, "dropdown" -- menu posts # on mouse-over. Ttk menubuttons don't implement this). # -# For keyboard and popdown mode, we hand off to tk_popup and let +# For keyboard and popdown mode, we hand off to tk_popup and let # the built-in Tk bindings handle the rest of the interaction. # # ON X11: # # Standard Tk menubuttons use a global grab on the menubutton. @@ -20,17 +20,17 @@ # since we need to process the final event, # and this might be delivered to the menu. So instead we # rely on the passive grab that occurs on events, # and transition to popdown mode when the mouse is released # or dragged outside the menubutton. -# +# # ON WINDOWS: # -# I'm not sure what the hell is going on here. [$menu post] apparently +# I'm not sure what the hell is going on here. [$menu post] apparently # sets up some kind of internal grab for native menus. # On this platform, just use [tk_popup] for all menu actions. -# +# # ON MACOS: # # Same probably applies here. # @@ -59,11 +59,11 @@ bind TMenubutton \ { if {[winfo exists %W]} { %W state !pressed } } } # PostPosition -- -# Returns the x and y coordinates where the menu +# Returns the x and y coordinates where the menu # should be posted, based on the menubutton and menu size # and -direction option. # # TODO: adjust menu width to be at least as wide as the button # for -direction above, below. @@ -83,11 +83,11 @@ switch -- $dir { above { if {$y >= $mh} { incr y -$mh } { incr y $bh } } below { if {$y <= $sh} { incr y $bh } { incr y -$mh } } left { if {$x >= $mw} { incr x -$mw } { incr x $bw } } right { if {$x <= $sw} { incr x $bw } { incr x -$mw } } - flush { + flush { # post menu atop menubutton. # If there's a menu entry whose label matches the # menubutton -text, assume this is an optionmenu # and place that entry over the menubutton. set index [FindMenuEntry $menu [$mb cget -text]] @@ -111,11 +111,11 @@ tk_popup $menu $x $y } # Pulldown (X11 only) -- # Called when Button1 is pressed on a menubutton. -# Posts the menu; a subsequent ButtonRelease +# Posts the menu; a subsequent ButtonRelease # or Leave event will set a grab on the menu. # proc ttk::menubutton::Pulldown {mb} { variable State if {[$mb instate disabled] || [set menu [$mb cget -menu]] eq ""} { Index: library/ttk/notebook.tcl ================================================================== --- library/ttk/notebook.tcl +++ library/ttk/notebook.tcl @@ -68,11 +68,11 @@ } } } # MnemonicTab $nb $key -- -# Scan all tabs in the specified notebook for one with the +# Scan all tabs in the specified notebook for one with the # specified mnemonic. If found, returns path name of tab; # otherwise returns "" # proc ttk::notebook::MnemonicTab {nb key} { set key [string toupper $key] @@ -92,12 +92,12 @@ # enableTraversal -- # Enable keyboard traversal for a notebook widget # by adding bindings to the containing toplevel window. # -# TLNotebooks($top) keeps track of the list of all traversal-enabled -# notebooks contained in the toplevel +# TLNotebooks($top) keeps track of the list of all traversal-enabled +# notebooks contained in the toplevel # proc ttk::notebook::enableTraversal {nb} { variable TLNotebooks set top [winfo toplevel $nb] @@ -143,11 +143,11 @@ set index [lsearch -exact $TLNotebooks($top) $nb] set TLNotebooks($top) [lreplace $TLNotebooks($top) $index $index] } } -# EnclosingNotebook $w -- +# EnclosingNotebook $w -- # Return the nearest traversal-enabled notebook widget # that contains $w. # # BUGS: this only works properly for tabs that are direct children # of the notebook widget. This routine should follow the @@ -169,11 +169,11 @@ return "" } # TLCycleTab -- # toplevel binding procedure for Control-Tab / Control-Shift-Tab -# Select the next/previous tab in the nearest ancestor notebook. +# Select the next/previous tab in the nearest ancestor notebook. # proc ttk::notebook::TLCycleTab {w dir} { set nb [EnclosingNotebook $w] if {$nb ne ""} { CycleTab $nb $dir Index: library/ttk/scrollbar.tcl ================================================================== --- library/ttk/scrollbar.tcl +++ library/ttk/scrollbar.tcl @@ -84,11 +84,11 @@ } proc ttk::scrollbar::Drag {w x y} { variable State if {![info exists State(first)]} { - # Initial buttonpress was not on the thumb, + # Initial buttonpress was not on the thumb, # or something screwy has happened. In either case, ignore: return; } set xDelta [expr {$x - $State(xPress)}] set yDelta [expr {$y - $State(yPress)}] Index: library/ttk/sizegrip.tcl ================================================================== --- library/ttk/sizegrip.tcl +++ library/ttk/sizegrip.tcl @@ -7,11 +7,11 @@ # switch -- [tk windowingsystem] { x11 - win32 { - option add *TSizegrip.cursor [ttk::cursor seresize] + option add *TSizegrip.cursor [ttk::cursor seresize] widgetDefault } aqua { # Aqua sizegrips use default Arrow cursor. } } Index: library/ttk/treeview.tcl ================================================================== --- library/ttk/treeview.tcl +++ library/ttk/treeview.tcl @@ -44,11 +44,11 @@ bind Treeview \ { ttk::treeview::Select %W %x %y extend } bind Treeview <> \ { ttk::treeview::Select %W %x %y toggle } -ttk::copyBindings TtkScrollable Treeview +ttk::copyBindings TtkScrollable Treeview ### Binding procedures. # ## Keynav -- Keyboard navigation Index: library/ttk/ttk.tcl ================================================================== --- library/ttk/ttk.tcl +++ library/ttk/ttk.tcl @@ -120,11 +120,11 @@ # proc ttk::LoadThemes {} { variable library # "default" always present: - uplevel #0 [list source [file join $library defaults.tcl]] + uplevel #0 [list source [file join $library defaults.tcl]] set builtinThemes [style theme names] foreach {theme scripts} { classic classicTheme.tcl alt altTheme.tcl Index: library/ttk/vistaTheme.tcl ================================================================== --- library/ttk/vistaTheme.tcl +++ library/ttk/vistaTheme.tcl @@ -1,11 +1,11 @@ # # Settings for Microsoft Windows Vista and Server 2008 # # The Vista theme can only be defined on Windows Vista and above. The theme -# is created in C due to the need to assign a theme-enabled function for +# is created in C due to the need to assign a theme-enabled function for # detecting when themeing is disabled. On systems that cannot support the # Vista theme, there will be no such theme created and we must not # evaluate this script. if {"vista" ni [ttk::style theme names]} { @@ -19,10 +19,11 @@ ttk::style configure . \ -background SystemButtonFace \ -foreground SystemWindowText \ -selectforeground SystemHighlightText \ -selectbackground SystemHighlight \ + -insertcolor SystemWindowText \ -font TkDefaultFont \ ; ttk::style map "." \ -foreground [list disabled SystemGrayText] \ @@ -44,33 +45,39 @@ # Treeview: ttk::style configure Heading -font TkHeadingFont ttk::style configure Treeview -background SystemWindow ttk::style map Treeview \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; + -background [list disabled SystemButtonFace \ + {!disabled !selected} SystemWindow \ + selected SystemHighlight] \ + -foreground [list disabled SystemGrayText \ + {!disabled !selected} SystemWindowText \ + selected SystemHighlightText] # Label and Toolbutton - ttk::style configure TLabelframe.Label -foreground "#0046d5" + ttk::style configure TLabelframe.Label -foreground SystemButtonText ttk::style configure Toolbutton -padding {4 4} # Combobox ttk::style configure TCombobox -padding 2 - ttk::style element create Combobox.field vsapi \ - COMBOBOX 2 {{} 1} ttk::style element create Combobox.border vsapi \ COMBOBOX 4 {disabled 4 focus 3 active 2 hover 2 {} 1} + ttk::style element create Combobox.background vsapi \ + EDIT 3 {disabled 3 readonly 5 focus 4 hover 2 {} 1} ttk::style element create Combobox.rightdownarrow vsapi \ COMBOBOX 6 {disabled 4 pressed 3 active 2 {} 1} \ -syssize {SM_CXVSCROLL SM_CYVSCROLL} ttk::style layout TCombobox { Combobox.border -sticky nswe -border 0 -children { Combobox.rightdownarrow -side right -sticky ns Combobox.padding -expand 1 -sticky nswe -children { - Combobox.focus -expand 1 -sticky nswe -children { - Combobox.textarea -sticky nswe + Combobox.background -sticky nswe -children { + Combobox.focus -expand 1 -sticky nswe -children { + Combobox.textarea -sticky nswe + } } } } } # Vista.Combobox droplist frame @@ -131,11 +138,11 @@ ttk::style layout TSpinbox { Spinbox.field -sticky nswe -children { Spinbox.background -sticky news -children { Spinbox.padding -sticky news -children { Spinbox.innerbg -sticky news -children { - Spinbox.textarea -expand 1 -sticky {} + Spinbox.textarea -expand 1 } } Spinbox.uparrow -side top -sticky ens Spinbox.downarrow -side bottom -sticky ens } @@ -144,11 +151,11 @@ ttk::style map TSpinbox \ -selectbackground [list !focus SystemWindow] \ -selectforeground [list !focus SystemWindowText] \ ; - + # SCROLLBAR elements (Vista includes a state for 'hover') ttk::style element create Vertical.Scrollbar.uparrow vsapi \ SCROLLBAR 1 {disabled 4 pressed 3 active 2 hover 17 {} 1} \ -syssize {SM_CXVSCROLL SM_CYVSCROLL} ttk::style element create Vertical.Scrollbar.downarrow vsapi \ @@ -180,20 +187,21 @@ ttk::style element create Horizontal.Progressbar.pbar vsapi \ PROGRESS 3 {{} 1} -padding 8 ttk::style layout Horizontal.TProgressbar { Horizontal.Progressbar.trough -sticky nswe -children { Horizontal.Progressbar.pbar -side left -sticky ns + Horizontal.Progressbar.text -sticky nesw } } ttk::style element create Vertical.Progressbar.pbar vsapi \ PROGRESS 3 {{} 1} -padding 8 ttk::style layout Vertical.TProgressbar { Vertical.Progressbar.trough -sticky nswe -children { Vertical.Progressbar.pbar -side bottom -sticky we } } - + # Scale ttk::style element create Horizontal.Scale.slider vsapi \ TRACKBAR 3 {disabled 5 focus 4 pressed 3 active 2 {} 1} \ -width 6 -height 12 ttk::style layout Horizontal.TScale { @@ -213,12 +221,12 @@ Vertical.Scale.track -sticky ns Vertical.Scale.slider -side top -sticky {} } } } - + # Treeview ttk::style configure Item -padding {4 0 0 0} - + package provide ttk::theme::vista 1.0 } } Index: library/ttk/winTheme.tcl ================================================================== --- library/ttk/winTheme.tcl +++ library/ttk/winTheme.tcl @@ -8,10 +8,12 @@ ttk::style configure "." \ -background SystemButtonFace \ -foreground SystemWindowText \ -selectforeground SystemHighlightText \ -selectbackground SystemHighlight \ + -fieldbackground SystemWindow \ + -insertcolor SystemWindowText \ -troughcolor SystemScrollbar \ -font TkDefaultFont \ ; ttk::style map "." -foreground [list disabled SystemGrayText] ; @@ -69,12 +71,16 @@ # Treeview: ttk::style configure Heading -font TkHeadingFont -relief raised ttk::style configure Treeview -background SystemWindow ttk::style map Treeview \ - -background [list selected SystemHighlight] \ - -foreground [list selected SystemHighlightText] ; + -background [list disabled SystemButtonFace \ + {!disabled !selected} SystemWindow \ + selected SystemHighlight] \ + -foreground [list disabled SystemGrayText \ + {!disabled !selected} SystemWindowText \ + selected SystemHighlightText] ttk::style configure TProgressbar \ -background SystemHighlight -borderwidth 0 ; } } Index: library/ttk/xpTheme.tcl ================================================================== --- library/ttk/xpTheme.tcl +++ library/ttk/xpTheme.tcl @@ -9,10 +9,11 @@ ttk::style configure . \ -background SystemButtonFace \ -foreground SystemWindowText \ -selectforeground SystemHighlightText \ -selectbackground SystemHighlight \ + -insertcolor SystemWindowText \ -font TkDefaultFont \ ; ttk::style map "." \ -foreground [list disabled SystemGrayText] \ @@ -59,7 +60,17 @@ -selectforeground [list !focus SystemWindowText] \ ; ttk::style configure Toolbutton -padding {4 4} + # Treeview: + ttk::style configure Heading -font TkHeadingFont -relief raised + ttk::style configure Treeview -background SystemWindow + ttk::style map Treeview \ + -background [list disabled SystemButtonFace \ + {!disabled !selected} SystemWindow \ + selected SystemHighlight] \ + -foreground [list disabled SystemGrayText \ + {!disabled !selected} SystemWindowText \ + selected SystemHighlightText]; } } Index: library/xmfbox.tcl ================================================================== --- library/xmfbox.tcl +++ library/xmfbox.tcl @@ -154,20 +154,20 @@ } # The filetypes radiobuttons # set data(fileType) $data(-defaulttype) # Default type to first entry - set initialTypeName [lindex $data(-filetypes) 0 0] + set initialTypeName [lindex $data(origfiletypes) 0 0] if {$data(-typevariable) ne ""} { upvar #0 $data(-typevariable) typeVariable if {[info exists typeVariable]} { set initialTypeName $typeVariable } } set ix 0 set data(fileType) 0 - foreach fltr $data(-filetypes) { + foreach fltr $data(origfiletypes) { set fname [lindex $fltr 0] if {[string first $initialTypeName $fname] == 0} { set data(fileType) $ix break } @@ -183,11 +183,11 @@ frame $f set cnt 0 if {$data(-filetypes) ne {}} { foreach type $data(-filetypes) { - set title [lindex [lindex $type 0] 0] + set title [lindex $type 0] set filter [lindex $type 1] radiobutton $f.b$cnt \ -text $title \ -variable ::tk::dialog::file::[winfo name $w](fileType) \ -value $cnt \ @@ -208,11 +208,10 @@ proc ::tk::MotifFDialog_SetFilter {w type} { upvar ::tk::dialog::file::[winfo name $w] data variable ::tk::Priv set data(filter) [lindex $type 1] - set Priv(selectFileType) [lindex [lindex $type 0] 0] MotifFDialog_Update $w } # ::tk::MotifFDialog_Config -- @@ -297,10 +296,11 @@ # 5. Parse the -filetypes option. It is not used by the motif # file dialog, but we check for validity of the value to make sure # the application code also runs fine with the TK file dialog. # + set data(origfiletypes) $data(-filetypes) set data(-filetypes) [::tk::FDGetFileTypes $data(-filetypes)] if {![info exists data(filter)]} { set data(filter) * } @@ -868,11 +868,11 @@ # Return selected filter if {[info exists data(-typevariable)] && $data(-typevariable) ne "" && [info exists data(-filetypes)] && $data(-filetypes) ne ""} { upvar #0 $data(-typevariable) typeVariable - set typeVariable [lindex $data(-filetypes) $data(fileType) 0] + set typeVariable [lindex $data(origfiletypes) $data(fileType) 0] } if {$data(-multiple) != 0} { set Priv(selectFilePath) $newFileList } else { @@ -978,11 +978,5 @@ variable ::tk::Priv unset -nocomplain Priv(lbAccel,$w) } -proc ::tk_getFileType {} { - variable ::tk::Priv - - return $Priv(selectFileType) -} - Index: macosx/GNUmakefile ================================================================== --- macosx/GNUmakefile +++ macosx/GNUmakefile @@ -100,11 +100,11 @@ PROJECT := tk PRODUCT_NAME := Tk UNIX_DIR := ${CURDIR}/../unix -VERSION := $(shell awk -F= '/^TK_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.in) +VERSION := $(shell awk -F= '/^TK_VERSION/ {print $$2; nextfile}' ${UNIX_DIR}/configure.ac) TCL_VERSION := ${VERSION} wish := wish WISH = wish${VERSION} BUILD_TARGET := all tktest @@ -178,11 +178,11 @@ ${objdir}/Makefile: ${UNIX_DIR}/Makefile.in ${UNIX_DIR}/configure \ ${UNIX_DIR}/tkConfig.sh.in Tk-Info.plist.in Wish-Info.plist.in mkdir -p "${OBJ_DIR}" && cd "${OBJ_DIR}" && \ if [ ${UNIX_DIR}/configure -nt config.status ]; then ${UNIX_DIR}/configure -C \ --prefix="${PREFIX}" --bindir="${BINDIR}" --libdir="${LIBDIR}" \ - --mandir="${MANDIR}" --enable-threads --enable-framework \ + --mandir="${MANDIR}" --enable-framework \ --with-tcl="${TCL_DIR}" \ ${CONFIGURE_ARGS} ${EXTRA_CONFIGURE_ARGS}; else ./config.status; fi ifneq (${VERSION},${TCL_VERSION}) @cd "${OBJ_DIR}" && sed -e 's#/Versions/${TCL_VERSION}#/Versions/${VERSION}#' \ tkConfig.sh > tkConfig.sh.1 && mv -f tkConfig.sh.1 tkConfig.sh Index: macosx/README ================================================================== --- macosx/README +++ macosx/README @@ -1,42 +1,42 @@ -Tcl/Tk Mac OS X README +Tcl/Tk macOS README ---------------------- -This is the README file for the Mac OS X/Darwin version of Tcl/Tk. +This is the README file for the macOS/Darwin version of Tcl/Tk. 1. Where to go for support -------------------------- - The tcl-mac mailing list on sourceforge is the best place to ask questions -specific to Tcl & Tk on Mac OS X: +specific to Tcl & Tk on macOS: http://lists.sourceforge.net/lists/listinfo/tcl-mac (this page also has a link to searchable archives of the list, please check them before asking on the list, many questions have already been answered). - For general Tcl/Tk questions, the newsgroup comp.lang.tcl is your best bet: http://groups.google.com/group/comp.lang.tcl/ -- The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on Mac OS X, see +- The Tcl'ers Wiki also has many pages dealing with Tcl & Tk on macOS, see http://wiki.tcl.tk/_/ref?N=3753 http://wiki.tcl.tk/_/ref?N=8361 -- Please report bugs with Tk on Mac OS X to the tracker: +- Please report bugs with Tk on macOS to the tracker: http://core.tcl.tk/tk/reportlist -2. Using Tcl/Tk on Mac OS X +2. Using Tcl/Tk on macOS --------------------------- -- There are two versions of Tk available on Mac OS X: TkAqua using the native +- There are two versions of Tk available on macOS: TkAqua using the native aqua widgets and look&feel, and TkX11 using the traditional unix X11 wigets. TkX11 requires an X11 server to be installed, such as Apple's X11 (which is -available as an optional or default install on recent Mac OS X). +available as an optional or default install on recent macOS). TkAqua and TkX11 can be distinguished at runtime via [tk windowingsystem]. -- At a minimum, Mac OS X 10.3 is required to run Tcl and TkX11. -TkAqua requires Mac OS X 10.5 or later (starting with the Cocoa-based Tk 8.5.7). +- At a minimum, macOS 10.3 is required to run Tcl and TkX11. +TkAqua requires macOS 10.6 or later. -- Unless weak-linking is used, Tcl/Tk built on Mac OS X 10.x will not run on +- Unless weak-linking is used, Tcl/Tk built on macOS 10.x will not run on 10.y with y < x; on the other hand Tcl/Tk built on 10.y will always run on 10.x with y <= x (but without any of the fixes and optimizations that would be available in a binary built on 10.x). Weak-linking is available on OS X 10.2 or later, it additionally allows Tcl/Tk built on 10.x to run on any 10.y with x > y >= z (for a chosen z >= 2). @@ -60,12 +60,11 @@ the Resources/Scripts directory of the framework. - [load]able binary extensions can linked as either ordinary shared libraries (.dylib) or as MachO bundles (since 8.4.10/8.5a3); bundles have the advantage that they are [load]ed more efficiently from a tcl VFS (no temporary copy to the -native filesystem required), and prior to Mac OS X 10.5, only bundles can be -[unload]ed. +native filesystem required). - The 'deploy' target of macosx/GNUmakefile installs the html manpages into the standard documentation location in the Tcl/Tk frameworks: Tcl.framework/Resources/Documentation/Reference/Tcl Tk.framework/Resources/Documentation/Reference/Tk @@ -161,11 +160,11 @@ present, this procedure is invoked instead by the standard Help menu item. Support for the Window menu and [tk::mac::ShowHelp] was added with the Cocoa-based Tk 8.5.7. - The TkAqua-specific command [tk::unsupported::MacWindowStyle style] is used to -get and set Mac OS X-specific toplevel window class and attributes. Note that +get and set macOS-specific toplevel window class and attributes. Note that the window class and many attributes have to be set before the window is first mapped for the change to have any effect. The command has the following syntax: tk::unsupported::MacWindowStyle style window ?class? ?attributes? The 2 argument form returns a list of the current class and attributes for the @@ -177,80 +176,46 @@ Window attribute names: standardDocument, standardFloating, resizable, fullZoom, horizontalZoom, verticalZoom, closeBox, collapseBox, toolbarButton, sideTitlebar, noTitleBar, unifiedTitleAndToolbar, metal, hud, noShadow, doesNotCycle, noActivates, hideOnSuspend, inWindowMenu, ignoreClicks, doesNotHide, - canJoinAllSpaces, moveToActiveSpace, nonActivating, black, dark, light, - gray, red, green, blue, cyan, yellow, magenta, orange, purple, - brown, clear, opacity + canJoinAllSpaces, moveToActiveSpace, nonActivating Note that not all attributes are valid for all window classes. Support for the 3 argument form was added with the Cocoa-based Tk 8.5.7, at the same time support for some legacy Carbon-specific classes and attributes was removed (they are still accepted by the command but no longer have any effect). -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: - -toplevel .f -tk::unsupported::MacWindowStyle style .f document {metal light opaque closeBox collapseBox resizable standardDocument } - -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 - -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). - -Below are the corresponding hex and/or Tk-defined colors that can be used from Tk widgets to match the NSColor-based attributes: - -black #000000 -dark #545454 -light #ababab -white #ffffff -gray #7f7f7f -red #ff0000 -green #00ff00 -blue #0000ff -cyan #00ffff -yellow #ffff00 -magenta #ff00ff -orange #ff8000 -purple #800080 -brown #996633 -clear systemTransparent - -- The Cocoa-based TkAqua can be distinguished from the older Carbon-based -version via the [winfo server .] command, example output on Mac OS X 10.5.7: - Cocoa-based: CG409.3 Apple AppKit GC 949.46 Mac OS X 1057 - Carbon-based: QD10R30 Apple 1057 - -- If you want to use Remote Debugging with Xcode, you need to set the +If you want to use Remote Debugging with Xcode, you need to set the environment variable XCNOSTDIN to 1 in the Executable editor for Wish. That will cause us to force closing stdin & stdout. Otherwise, given how Xcode launches Wish remotely, they will be left open and then Wish & gdb will fight for stdin. -3. Building Tcl/Tk on Mac OS X +3. Building Tcl/Tk on macOS ------------------------------ -- At least Mac OS X 10.3 is required to build Tcl and TkX11, and Mac OS X 10.5 -is required to build TkAqua. -Apple's Xcode Developer Tools need to be installed (only the most recent version -matching your OS release is supported), the Xcode installer is available on Mac -OS X install media or may be present in /Applications/Installers on Macs that -came with OS X preinstalled. The most recent version can always be downloaded -from the ADC website http://connect.apple.com (free ADC membership required). - -- Tcl/Tk are most easily built as Mac OS X frameworks via GNUmakefile in +- At least macOS 10.3 is required to build Tcl and TkX11, and macOS 10.6 +is required to build TkAqua. The XCode application provides everything +needed to build Tk, but it is not necessary to install the full XCode. +It suffices to install the Command Line Tools package, which can be done +by running the command: +xcode-selecct --install + +- Tcl/Tk are most easily built as macOS frameworks via GNUmakefile in tcl/macosx and tk/macosx (see below for details), but can also be built with the standard unix configure and make buildsystem in tcl/unix resp. tk/unix as on any other unix platform (indeed, the GNUmakefiles are just wrappers around the unix buildsystem). -The Mac OS X specific configure flags are --enable-aqua, --enable-framework and +The macOS specific configure flags are --enable-aqua, --enable-framework and --disable-corefoundation (which disables CF and notably reverts to the standard select based notifier). Note that --enable-aqua is incompatible with --disable-corefoundation (for both Tcl and Tk configure). -- It is also possible to build with the Xcode IDE via the projects in -tk/macosx, take care to use the project matching your DevTools and OS version: +- It was once possible to build with the Xcode IDE via the projects in +tk/macosx, but this has not been tested recently. Take care to use the +project matching your DevTools and OS version: Tk.xcode: for Xcode 3.1 on 10.5 Tk.xcodeproj: for Xcode 3.2 on 10.6 These have the following targets: Tk: calls through to tk/macosx/GNUMakefile, requires a corresponding build of the Tcl @@ -290,11 +255,11 @@ ${USER}.pbxuser file (located inside the Tk.xcodeproj bundle directory) with a text editor. - To build universal binaries outside of the Xcode IDE, set CFLAGS as follows: export CFLAGS="-arch i386 -arch x86_64 -arch ppc" -This requires Mac OS X 10.4 and Xcode 2.4 (or Xcode 2.2 if -arch x86_64 is +This requires macOS 10.4 and Xcode 2.4 (or Xcode 2.2 if -arch x86_64 is omitted, but _not_ Xcode 2.1) and will work on any architecture (on PowerPC Tiger you need to add "-isysroot /Developer/SDKs/MacOSX10.4u.sdk"). Note that configure requires CFLAGS to contain a least one architecture that can be run on the build machine (i.e. ppc on G3/G4, ppc or ppc64 on G5, ppc or i386 on Core and ppc, i386 or x86_64 on Core2/Xeon). @@ -301,13 +266,13 @@ Universal builds of Tcl TEA extensions are also possible with CFLAGS set as above, they will be [load]able by universal as well as thin binaries of Tcl. - To enable weak-linking, set the MACOSX_DEPLOYMENT_TARGET environment variable to the minimal OS version the binaries should be able to run on, e.g: - export MACOSX_DEPLOYMENT_TARGET=10.4 + export MACOSX_DEPLOYMENT_TARGET=10.6 This requires at least gcc 3.1; with gcc 4 or later, set/add to CFLAGS instead: - export CFLAGS="-mmacosx-version-min=10.4" + export CFLAGS="-mmacosx-version-min=10.6" Support for weak-linking was added with 8.4.14/8.5a5. Detailed Instructions for building with macosx/GNUmakefile ---------------------------------------------------------- @@ -387,65 +352,221 @@ TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin sudo make -C tk${ver}/macosx install \ TCL_FRAMEWORK_DIR=$HOME/Library/Frameworks TCLSH_DIR=$HOME/usr/bin The Makefile variables TCL_FRAMEWORK_DIR and TCLSH_DIR were added with Tk 8.4.3. -4. About the event loop in Tk for Mac OSX ------------------------------------------ +4. Details regarding the macOS port of Tk. +------------------------------------------- + +4.1 About the event loop +~~~~~~~~~~~~~~~~~~~~~~~~ -The main program in a typical OSX application looks like this (see *) +The main program in a typical OSX application looks like this (see +https://developer.apple.com/library/mac/documentation/Cocoa/\ +Reference/ApplicationKit/Classes/NSApplication_Class) void NSApplicationMain(int argc, char *argv[]) { [NSApplication sharedApplication]; [NSBundle loadNibNamed:@"myMain" owner:NSApp]; [NSApp run]; } +Here NSApp is a standard global variable, initialized by the OS, which +points to an object in a subclass of NSApplication (called +TKApplication in the case of the macOS port of Tk). -The run method implements the event loop for the application. There -are three key steps in the run method. First it calls -[NSApp finishLaunching], which creates the bouncing application icon -and does other mysterious things. Second it creates an +The [NSApp run] method implements the event loop for a typical Mac +application. There are three key steps in the run method. First it +calls [NSApp finishLaunching], which creates the bouncing application +icon and does other mysterious things. Second it creates an NSAutoreleasePool. Third, it starts an event loop which drains the NSAutoreleasePool every time the queue is empty, and replaces the drained pool with a new one. This third step is essential to preventing memory leaks, since the internal methods of Appkit objects all assume that an autorelease pool is in scope and will be drained when the event processing cycle ends. -Mac OSX Tk does not call the [NSApp run] method at all. Instead it -uses the event loop built in to Tk. So we must take care to replicate -the important features of the method ourselves. Here is how this -works in outline. - -We add a private NSAUtoreleasePool* property to our subclass of -NSApplication. (The subclass is called TKApplication but can be -referenced with the global variable NSApp). The TkpInit -function calls [NSApp _setup] which initializes this property by -creating an NSAutoreleasePool. A bit later on, TkpInit calls -[NSAPP _setupEventLoop] which in turn calls the -[NSApp finishLaunching] method. - -Each time that Tcl processes an event in its queue, it calls a -platform specific function which, in the case of Mac OSX, is named -TkMacOSXEventsCheckProc. In the unix implementations of Tk, including -the Mac OSX version, this function collects events from an "event -source", and transfers them to the Tcl event queue. In Mac OSX the -event source is the NSApplication event queue. Each NSEvent is -converted to a Tcl event which is added to the Tcl event queue. The -NSEvent is also passed to [NSApp sendevent], which sends the event on -to the application's NSWindows, which send it to their NSViews, etc. +The macOS Tk application does not call the [NSApp run] method at +all. Instead it uses the event loop built in to Tk. So the +application must take care to replicate the important features of the +method ourselves. The way that autorelease pools are handled is +discussed in 4.2 below. Here we discuss the event handling itself. + +The Tcl event loop simply consists of repeated calls to TclDoOneEvent. +Each call to TclDoOneEvent begins by collecting all pending events from +an "event source", converting them to Tcl events and adding them +to the Tcl event queue. For macOS, the event source is the NSApp +object, which maintains an event queue even though its run method +will never be called to process them. The NSApp provides methods for +inspecting the queue and removing events from it as well as the +[NSApp sendevent] which sends an event to all of the application's +NSWindows which can then send it to subwindows, etc. + +The event collection process consists of first calling a platform +specific SetupProc and then a platform specific CheckProc. In +the macOS port, these are named TkMacOSXEventsSetupProc and +TkMacOSXEventsCheckProc. + +It is important to understand that the Apple window manager does not +have the concept of an expose event. Their replacement for an expose +event is to have the window manager call the [NSView drawRect] method +in any situation where an expose event for that NSView would be +generated in X11. The [NSView drawRect] method is a no-op which is +expected to be overridden by any application. In the case of Tcl, the +replacement [NSView drawRect] method creates a Tcl expose event +for each dirty rectangle of the NSView, and then adds the expose +event to the Tcl queue. + + +4.2 Autorelease pools +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +In order to carry out the job of managing autorelease pools, which +would normally be handled by the [NSApp run] method, a private +NSAUtoreleasePool* property is added to the TkApplication subclass of +NSApplication. The TkpInit function calls [NSApp _setup] which +initializes this property by creating an NSAutoreleasePool prior to +calling [NSApp finishLaunching]. This mimics the behavior of the +[NSApp run] method, which calls [NSApp finishLaunching] just before +starting the event loop. + Since the CheckProc function gets called for every Tk event, it is an appropriate place to drain the main NSAutoreleasePool and replace it -with a new pool. This is done by calling the method -[NSApp _resetAutoreleasePool], where _resetAutoreleasePool is a method -which we define for the subclass TKApplication. - -One minor caveat is that there are several steps of the Tk -initialization which precede the call to TkpInit. Notably, the font -package is initialized first. Since there is no NSAUtoreleasePool in -scope prior to calling TkpInit, the functions called in these -preliminary stages need to create and drain their own +with a new pool. This is done by calling the method [NSApp +_resetAutoreleasePool], where _resetAutoreleasePool is a method which +we define for the subclass. Unfortunately, by itself this is not +sufficient for safe memory managememt because, as was made painfully +evident with the release of OS X 10.13, it is possible for calls to +TclDoOneEvent, and hence to CheckProc, to be nested. Draining the +autorelease pool in a nested call leads to crashes as objects in use +by the outer call can get freed by the inner call and then reused later. +One particular situation where this happens is when a modal dialogue +gets posted by a Tk Application. To address this, the NSApp object +also implements a semaphore to prevent draining the autorelease pool +in nested calls to CheckProc. + +One additional minor caveat for developers is that there are several +steps of the Tk initialization which precede the call to TkpInit. +Notably, the font package is initialized first. Since there is no +NSAUtoreleasePool in scope prior to calling TkpInit, the functions +called in these preliminary stages need to create and drain their own NSAutoreleasePools whenever they call methods of Appkit objects (e.g. NSFont). -* https://developer.apple.com/library/mac/documentation/Cocoa/\ -Reference/ApplicationKit/Classes/NSApplication_Class +4.3 Clipping regions and "ghost windows" +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Another unusual aspect of the macOS port is its use of clipping +regions. It was part of Daniel Steffen's original design that the +TkWindowPrivate struct maintains three HIShapeRef regions, named +visRgn, aboveVisRgn and drawRgn. These regions are used as clipping +masks whenever drawing into an NSView. The visRgn is the bounding box +of the window with a rectangle removed for each subwindow and for each +sibling window at a higher stacking level. The drawRgn is the +intersection of the visRgn with the clipping rectangle of the +window. (Normally, the clipping rectangle is the same as the bounding +rectangle, but drawing can be clipped to a smaller rectangle by +calling TkpClipDrawableToRect.) The aboveVisRgn is the intersection of +the window's bounding rectangle with the bounding rectangle of the +parent window. Much of the code in tkMacOSXSubindows.c is devoted to +rebuilding these clipping regions whenever something changes in the +layout of the windows. This turns out to be a tricky thing to do and +it is extremely prone to errors which can be difficult to trace. + +It is not entirely clear what the original reason for using these +clipping regions was. But one benefit is that if they are correctly +maintained then it allows windows to be drawn in any order. You do +not have to draw them in the order of the window hierarchy. Each +window can draw its entire rectangle through its own mask and never +have to worry about drawing in the wrong place. It is likely that +the need for using clipping regions arose because, as Apple explicitly +states in the documentation for [NSView subviews], + + "The order of the subviews may be considered as being + back-to-front, but this does not imply invalidation and drawing + behavior." + +In the early versions of the macOS port, buttons were implemented as +subviews of class TkButton. This probably exacerbated the likelihood +that Tk windows would need to be drawn in arbitrary order. + +The most obvious side effect caused by not maintaining the clipping +regions is the appearance of so-called "ghost windows". A common +situation where these may arise is when a window containing buttons +is being scrolled. A user may see two images of the same button on +the screen, one in the pre-scroll location and one in the post-scroll +location. + +To see how these 'ghost windows' can arise, think about what happens if +the clipping regions are not maintained correctly. A window might +have a rectangle missing from its clipping region because that +rectangle is the bounding rectangle for a subwindow, say a button. +The parent should not draw in the missing rectangle since doing so +would trash the button. The button is responsible for drawing +there. Now imagine that the button gets moved, say by a scroll, but +the missing rectangle in the parent's clipping region does not get +moved correctly, or it gets moved later on, after the parent has +redrawn itself. The parent would still not be allowed to draw in the +old rectangle, so the user would continue to see the image of the +button in its old location, as well as another image in the new +location. This is a prototypical example of a "ghost window". +Anytime you see a "ghost window", you should suspect problems with the +updates to the clipping region visRgn. It is natural to look for +timing issues, race conditions, or other "event loop problems". But +in fact, the whole design of the code is to make those timing issues +irrelevant. As long as the clipping regions are correctly maintained +the timing does not matter. And if they are not correctly maintained +then you will see "ghost windows". + +It is worth including a detailed description of one specific place +where the failure to correctly maintain clipping regions caused "ghost +window" artifacts that plagued the macOS port for years. These +occurred when scrolling a Text widget which contained embedded +subwindows. It involved some specific differences between the +low-level behavior of Apple's window manager versus those of the other +platforms, and the fix ultimately required changes in the generic Tk +implementation (documented in the comments in the DisplayText +function). + +The Text widget attempts to improve perfomance when scrolling by +minimizing the number of text lines which need to be redisplayed. It +does this by calling the platform-specific TkScrollWindow function +which uses a low-level routine to map one rectangle of the window to +another. The TkScrollWindow function returns a damage region which is +then used by the Text widget's DisplayText function to determine which +text lines need to be redrawn. On the unix and win platforms, this +damage region includes bounding rectangles for all embedded windows +inside the Text widget. The way that this works is system dependent. +On unix, the low level scrolling is done by XCopyRegion, which +generates a GraphicsExpose event for each embedded window. These +GraphicsExposed events are processsed within TkScrollWindow, using a +special handler which adds the bounding rectangle of each subwindow to +the damage region. On the win platform the damage region is built by +the low level function ScrollWindowEx, and it also includes bounding +rectangles for all embedded windows. This is possible because on X11 +and Windows every Tk widget is also known to the window manager as a +window. The situation is different on macOS. The underlying object +for a top level window on macOS is the NSView. However, Apple +explicitly warns in its documentation that performance degradation +occurs when an NSView has more than about 100 subviews. A Text widget +with thousands of lines of text could easily contain more than 100 +embedded windows. In fact, while the original Cocoa port of Tk did +use the NSButton object, which is derived from NSView, as the basis +for its Tk Buttons, that was changed in order to improve performance. +Moreover, the low level routine used for scrolling on macOS, namely +[NSView scrollrect:by], does not provide any damage information. So +TkScrollWindow needs to work differently on macOS. Since it would be +inefficient to iterate through all embedded windows in a Text widget, +looking for those which meet the scrolling area, the damage region +constructed by TkScrollWindow contains only the difference between the +source and destination rectangles for the scrolling. The embedded +windows are redrawn within the DisplayText function by some +conditional code which is only used for macOS. + +5.0 Virtual events on 10.14 +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +10.14 supports system appearance changes, and has added a "Dark Mode" +that casts all window frames and menus as black. Tk 8.6.9 has added two +virtual events, <> and <>, to allow you to update +your Tk app's appearance when the system appearance changes. Just bind +your appearance-updating code to these virtual events and you will see +it triggered when the system appearance toggles between dark and light. Index: macosx/Tk-Common.xcconfig ================================================================== --- macosx/Tk-Common.xcconfig +++ macosx/Tk-Common.xcconfig @@ -34,13 +34,13 @@ LIBDIR = $(PREFIX)/lib MANDIR = $(PREFIX)/man PER_ARCH_CFLAGS_ppc = -mcpu=G3 -mtune=G4 $(PER_ARCH_CFLAGS_ppc) PREFIX = /usr/local TCL_BUILD_DIR = $(OBJROOT)/../tcl/Tcl.build/$(CONFIGURATION)/Tcl.build/Objects -TCL_CONFIGURE_ARGS = --enable-threads --enable-dtrace +TCL_CONFIGURE_ARGS = --enable-dtrace TCL_FRAMEWORK_DIR = $(SYMROOT)/../tcl/$(CONFIGURATION) TCL_LIBRARY = $(LIBDIR)/tcl$(VERSION) TCL_PACKAGE_PATH = "$(LIBDIR)" TCL_DEFS = HAVE_TCL_CONFIG_H TK_LIBRARY = $(LIBDIR)/tk$(VERSION) TK_DEFS = HAVE_TK_CONFIG_H TCL_NO_DEPRECATED -VERSION = 8.6 +VERSION = 8.7 Index: macosx/Tk.xcode/project.pbxproj ================================================================== --- macosx/Tk.xcode/project.pbxproj +++ macosx/Tk.xcode/project.pbxproj @@ -1170,11 +1170,11 @@ F966BC6808F27A3D005CB29B /* winWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winWm.test; sourceTree = ""; }; F966BC6908F27A3D005CB29B /* wm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = wm.test; sourceTree = ""; }; F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = ""; }; F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F966BC6E08F27A3D005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; + F966BC6E08F27A3D005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = ""; }; F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = ""; }; F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F966BC7208F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; F966BC7308F27A3D005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = ""; }; @@ -1209,21 +1209,18 @@ F966BC9008F27A3D005CB29B /* tkUnixWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixWm.c; sourceTree = ""; }; F966BC9108F27A3D005CB29B /* tkUnixXId.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixXId.c; sourceTree = ""; }; F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = ""; }; F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; - F966BC9808F27A3E005CB29B /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = ""; }; + F966BC9708F27A3E005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = ""; }; - F966BC9B08F27A3E005CB29B /* mkd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mkd.bat; sourceTree = ""; }; F966BC9C08F27A3E005CB29B /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = ""; }; F966BCEE08F27A3E005CB29B /* tk.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.rc; sourceTree = ""; }; F966BCEF08F27A3E005CB29B /* tk_base.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk_base.rc; sourceTree = ""; }; F966BCF208F27A3E005CB29B /* wish.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wish.rc; sourceTree = ""; }; F966BCF308F27A3E005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; - F966BCF408F27A3E005CB29B /* rmd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rmd.bat; sourceTree = ""; }; F966BCF508F27A3F005CB29B /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = ""; }; F966BCF608F27A3F005CB29B /* stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubs.c; sourceTree = ""; }; F966BCF708F27A3F005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = ""; }; F966BCF808F27A3F005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = ""; }; F966BCF908F27A3F005CB29B /* tkWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWin.h; sourceTree = ""; }; @@ -1914,11 +1911,11 @@ F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = ""; }; F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = ""; }; F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = ""; }; F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = ""; }; F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; + F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F96D442208F272B8004A47F5 /* eolFix.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eolFix.tcl; sourceTree = ""; }; F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = ""; }; F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = ""; }; F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = ""; }; F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = ""; }; @@ -1939,11 +1936,11 @@ F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = ""; }; F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = ""; }; F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = ""; }; F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; + F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = ""; }; F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = ""; }; F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = ""; }; F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = ""; }; @@ -1982,14 +1979,12 @@ F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = ""; }; F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = ""; }; F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = ""; }; F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = ""; }; - F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = ""; }; F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; - F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = ""; }; + F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = ""; }; F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = ""; }; F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = ""; }; @@ -2741,11 +2736,11 @@ F966BC6B08F27A3D005CB29B /* unix */ = { isa = PBXGroup; children = ( F966BC6C08F27A3D005CB29B /* aclocal.m4 */, F966BC6D08F27A3D005CB29B /* configure */, - F966BC6E08F27A3D005CB29B /* configure.in */, + F966BC6E08F27A3D005CB29B /* configure.ac */, F966BC6F08F27A3D005CB29B /* install-sh */, F966BC7008F27A3D005CB29B /* installManPage */, F966BC7108F27A3D005CB29B /* Makefile.in */, F966BC7208F27A3D005CB29B /* README */, F966BC7308F27A3D005CB29B /* tcl.m4 */, @@ -2788,15 +2783,13 @@ isa = PBXGroup; children = ( F966BC9408F27A3D005CB29B /* aclocal.m4 */, F966BC9508F27A3D005CB29B /* buildall.vc.bat */, F966BC9608F27A3E005CB29B /* configure */, - F966BC9708F27A3E005CB29B /* configure.in */, - F966BC9808F27A3E005CB29B /* makefile.bc */, + F966BC9708F27A3E005CB29B /* configure.ac */, F966BC9908F27A3E005CB29B /* Makefile.in */, F966BC9A08F27A3E005CB29B /* makefile.vc */, - F966BC9B08F27A3E005CB29B /* mkd.bat */, F966BC9C08F27A3E005CB29B /* nmakehlp.c */, F966BC9D08F27A3E005CB29B /* rc */, F966BCF308F27A3E005CB29B /* README */, F966BCF408F27A3E005CB29B /* rmd.bat */, F966BCF508F27A3F005CB29B /* rules.vc */, @@ -3724,11 +3717,11 @@ F96D43D008F272B8004A47F5 /* tools */ = { isa = PBXGroup; children = ( F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */, F96D43D208F272B8004A47F5 /* configure */, - F96D43D308F272B8004A47F5 /* configure.in */, + F96D43D308F272B8004A47F5 /* configure.ac */, F96D442208F272B8004A47F5 /* eolFix.tcl */, F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */, F96D442508F272B8004A47F5 /* genStubs.tcl */, F96D442708F272B8004A47F5 /* index.tcl */, F96D442808F272B8004A47F5 /* installData.tcl */, @@ -3757,11 +3750,11 @@ F96D443E08F272B9004A47F5 /* unix */ = { isa = PBXGroup; children = ( F96D444008F272B9004A47F5 /* aclocal.m4 */, F96D444108F272B9004A47F5 /* configure */, - F96D444208F272B9004A47F5 /* configure.in */, + F96D444208F272B9004A47F5 /* configure.ac */, F96D444308F272B9004A47F5 /* dltest */, F96D444D08F272B9004A47F5 /* install-sh */, F96D444E08F272B9004A47F5 /* installManPage */, F96D444F08F272B9004A47F5 /* ldAix */, F96D445008F272B9004A47F5 /* Makefile.in */, @@ -3817,14 +3810,12 @@ isa = PBXGroup; children = ( F96D447008F272BA004A47F5 /* aclocal.m4 */, F96D447108F272BA004A47F5 /* buildall.vc.bat */, F96D447208F272BA004A47F5 /* cat.c */, - F96D447308F272BA004A47F5 /* coffbase.txt */, F96D447408F272BA004A47F5 /* configure */, - F96D447508F272BA004A47F5 /* configure.in */, - F96D447608F272BA004A47F5 /* makefile.bc */, + F96D447508F272BA004A47F5 /* configure.ac */, F96D447708F272BA004A47F5 /* Makefile.in */, F96D447808F272BA004A47F5 /* makefile.vc */, F96D447908F272BA004A47F5 /* nmakehlp.c */, F96D447A08F272BA004A47F5 /* README */, F96D447C08F272BA004A47F5 /* rules.vc */, @@ -3972,11 +3963,11 @@ buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TCL_SRCROOT)/macosx/configure.ac", - "$(TCL_SRCROOT)/unix/configure.in", + "$(TCL_SRCROOT)/unix/configure.ac", "$(TCL_SRCROOT)/unix/tcl.m4", "$(TCL_SRCROOT)/unix/aclocal.m4", "$(TCL_SRCROOT)/unix/tclConfig.sh.in", "$(TCL_SRCROOT)/unix/Makefile.in", "$(TCL_SRCROOT)/unix/dltest/Makefile.in", @@ -3985,21 +3976,21 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tcl/tclConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; + shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; showEnvVarsInLog = 0; }; F9A5C5F608F651AB008AE941 /* Configure Tk */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TK_SRCROOT)/macosx/configure.ac", - "$(TK_SRCROOT)/unix/configure.in", + "$(TK_SRCROOT)/unix/configure.ac", "$(TK_SRCROOT)/unix/tcl.m4", "$(TK_SRCROOT)/unix/aclocal.m4", "$(TK_SRCROOT)/unix/tkConfig.sh.in", ); name = "Configure Tk"; @@ -4006,21 +3997,21 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tk/tkConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; + shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; showEnvVarsInLog = 0; }; F9FD30B40CC1AD070073837D /* Configure Tcl */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TCL_SRCROOT)/macosx/configure.ac", - "$(TCL_SRCROOT)/unix/configure.in", + "$(TCL_SRCROOT)/unix/configure.ac", "$(TCL_SRCROOT)/unix/tcl.m4", "$(TCL_SRCROOT)/unix/aclocal.m4", "$(TCL_SRCROOT)/unix/tclConfig.sh.in", "$(TCL_SRCROOT)/unix/Makefile.in", "$(TCL_SRCROOT)/unix/dltest/Makefile.in", @@ -4029,21 +4020,21 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tcl/tclConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; + shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; showEnvVarsInLog = 0; }; F9FD30B50CC1AD070073837D /* Configure Tk */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TK_SRCROOT)/macosx/configure.ac", - "$(TK_SRCROOT)/unix/configure.in", + "$(TK_SRCROOT)/unix/configure.ac", "$(TK_SRCROOT)/unix/tcl.m4", "$(TK_SRCROOT)/unix/aclocal.m4", "$(TK_SRCROOT)/unix/tkConfig.sh.in", ); name = "Configure Tk"; @@ -4050,11 +4041,11 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tk/tkConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi"; + shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ Index: macosx/Tk.xcodeproj/project.pbxproj ================================================================== --- macosx/Tk.xcodeproj/project.pbxproj +++ macosx/Tk.xcodeproj/project.pbxproj @@ -1170,11 +1170,11 @@ F966BC6808F27A3D005CB29B /* winWm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winWm.test; sourceTree = ""; }; F966BC6908F27A3D005CB29B /* wm.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = wm.test; sourceTree = ""; }; F966BC6A08F27A3D005CB29B /* xmfbox.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = xmfbox.test; sourceTree = ""; }; F966BC6C08F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F966BC6D08F27A3D005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F966BC6E08F27A3D005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; + F966BC6E08F27A3D005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F966BC6F08F27A3D005CB29B /* install-sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = "install-sh"; sourceTree = ""; }; F966BC7008F27A3D005CB29B /* installManPage */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = installManPage; sourceTree = ""; }; F966BC7108F27A3D005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F966BC7208F27A3D005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; F966BC7308F27A3D005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = ""; }; @@ -1209,21 +1209,18 @@ F966BC9008F27A3D005CB29B /* tkUnixWm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixWm.c; sourceTree = ""; }; F966BC9108F27A3D005CB29B /* tkUnixXId.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tkUnixXId.c; sourceTree = ""; }; F966BC9408F27A3D005CB29B /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F966BC9508F27A3D005CB29B /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = ""; }; F966BC9608F27A3E005CB29B /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F966BC9708F27A3E005CB29B /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; - F966BC9808F27A3E005CB29B /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = ""; }; + F966BC9708F27A3E005CB29B /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F966BC9908F27A3E005CB29B /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F966BC9A08F27A3E005CB29B /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = ""; }; - F966BC9B08F27A3E005CB29B /* mkd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = mkd.bat; sourceTree = ""; }; F966BC9C08F27A3E005CB29B /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = ""; }; F966BCEE08F27A3E005CB29B /* tk.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk.rc; sourceTree = ""; }; F966BCEF08F27A3E005CB29B /* tk_base.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = tk_base.rc; sourceTree = ""; }; F966BCF208F27A3E005CB29B /* wish.rc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = wish.rc; sourceTree = ""; }; F966BCF308F27A3E005CB29B /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; - F966BCF408F27A3E005CB29B /* rmd.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rmd.bat; sourceTree = ""; }; F966BCF508F27A3F005CB29B /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = ""; }; F966BCF608F27A3F005CB29B /* stubs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = stubs.c; sourceTree = ""; }; F966BCF708F27A3F005CB29B /* tcl.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tcl.m4; sourceTree = ""; }; F966BCF808F27A3F005CB29B /* tkConfig.sh.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = tkConfig.sh.in; sourceTree = ""; }; F966BCF908F27A3F005CB29B /* tkWin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tkWin.h; sourceTree = ""; }; @@ -1914,11 +1911,11 @@ F96D43CD08F272B7004A47F5 /* winNotify.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winNotify.test; sourceTree = ""; }; F96D43CE08F272B7004A47F5 /* winPipe.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winPipe.test; sourceTree = ""; }; F96D43CF08F272B7004A47F5 /* winTime.test */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = winTime.test; sourceTree = ""; }; F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = checkLibraryDoc.tcl; sourceTree = ""; }; F96D43D208F272B8004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F96D43D308F272B8004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; + F96D43D308F272B8004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F96D442208F272B8004A47F5 /* eolFix.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = eolFix.tcl; sourceTree = ""; }; F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = fix_tommath_h.tcl; sourceTree = ""; }; F96D442508F272B8004A47F5 /* genStubs.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = genStubs.tcl; sourceTree = ""; }; F96D442708F272B8004A47F5 /* index.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = index.tcl; sourceTree = ""; }; F96D442808F272B8004A47F5 /* installData.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = installData.tcl; sourceTree = ""; }; @@ -1939,11 +1936,11 @@ F96D443A08F272B9004A47F5 /* tclZIC.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = tclZIC.tcl; sourceTree = ""; }; F96D443B08F272B9004A47F5 /* uniClass.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniClass.tcl; sourceTree = ""; }; F96D443C08F272B9004A47F5 /* uniParse.tcl */ = {isa = PBXFileReference; explicitFileType = text.script; fileEncoding = 4; path = uniParse.tcl; sourceTree = ""; }; F96D444008F272B9004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F96D444108F272B9004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F96D444208F272B9004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; + F96D444208F272B9004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F96D444408F272B9004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F96D444508F272B9004A47F5 /* pkga.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkga.c; sourceTree = ""; }; F96D444608F272B9004A47F5 /* pkgb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgb.c; sourceTree = ""; }; F96D444708F272B9004A47F5 /* pkgc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgc.c; sourceTree = ""; }; F96D444808F272B9004A47F5 /* pkgd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pkgd.c; sourceTree = ""; }; @@ -1982,14 +1979,12 @@ F96D446C08F272B9004A47F5 /* tclXtNotify.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtNotify.c; sourceTree = ""; }; F96D446D08F272B9004A47F5 /* tclXtTest.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tclXtTest.c; sourceTree = ""; }; F96D447008F272BA004A47F5 /* aclocal.m4 */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = aclocal.m4; sourceTree = ""; }; F96D447108F272BA004A47F5 /* buildall.vc.bat */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = buildall.vc.bat; sourceTree = ""; }; F96D447208F272BA004A47F5 /* cat.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cat.c; sourceTree = ""; }; - F96D447308F272BA004A47F5 /* coffbase.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = coffbase.txt; sourceTree = ""; }; F96D447408F272BA004A47F5 /* configure */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = configure; sourceTree = ""; }; - F96D447508F272BA004A47F5 /* configure.in */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.in; sourceTree = ""; }; - F96D447608F272BA004A47F5 /* makefile.bc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.bc; sourceTree = ""; }; + F96D447508F272BA004A47F5 /* configure.ac */ = {isa = PBXFileReference; explicitFileType = text.script.sh; fileEncoding = 4; path = configure.ac; sourceTree = ""; }; F96D447708F272BA004A47F5 /* Makefile.in */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = Makefile.in; sourceTree = ""; }; F96D447808F272BA004A47F5 /* makefile.vc */ = {isa = PBXFileReference; explicitFileType = sourcecode.make; fileEncoding = 4; path = makefile.vc; sourceTree = ""; }; F96D447908F272BA004A47F5 /* nmakehlp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nmakehlp.c; sourceTree = ""; }; F96D447A08F272BA004A47F5 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; F96D447C08F272BA004A47F5 /* rules.vc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = rules.vc; sourceTree = ""; }; @@ -2741,11 +2736,11 @@ F966BC6B08F27A3D005CB29B /* unix */ = { isa = PBXGroup; children = ( F966BC6C08F27A3D005CB29B /* aclocal.m4 */, F966BC6D08F27A3D005CB29B /* configure */, - F966BC6E08F27A3D005CB29B /* configure.in */, + F966BC6E08F27A3D005CB29B /* configure.ac */, F966BC6F08F27A3D005CB29B /* install-sh */, F966BC7008F27A3D005CB29B /* installManPage */, F966BC7108F27A3D005CB29B /* Makefile.in */, F966BC7208F27A3D005CB29B /* README */, F966BC7308F27A3D005CB29B /* tcl.m4 */, @@ -2788,19 +2783,16 @@ isa = PBXGroup; children = ( F966BC9408F27A3D005CB29B /* aclocal.m4 */, F966BC9508F27A3D005CB29B /* buildall.vc.bat */, F966BC9608F27A3E005CB29B /* configure */, - F966BC9708F27A3E005CB29B /* configure.in */, - F966BC9808F27A3E005CB29B /* makefile.bc */, + F966BC9708F27A3E005CB29B /* configure.ac */, F966BC9908F27A3E005CB29B /* Makefile.in */, F966BC9A08F27A3E005CB29B /* makefile.vc */, - F966BC9B08F27A3E005CB29B /* mkd.bat */, F966BC9C08F27A3E005CB29B /* nmakehlp.c */, F966BC9D08F27A3E005CB29B /* rc */, F966BCF308F27A3E005CB29B /* README */, - F966BCF408F27A3E005CB29B /* rmd.bat */, F966BCF508F27A3F005CB29B /* rules.vc */, F966BCF608F27A3F005CB29B /* stubs.c */, F966BCF708F27A3F005CB29B /* tcl.m4 */, F966BCF808F27A3F005CB29B /* tkConfig.sh.in */, F966BCF908F27A3F005CB29B /* tkWin.h */, @@ -3724,11 +3716,11 @@ F96D43D008F272B8004A47F5 /* tools */ = { isa = PBXGroup; children = ( F96D43D108F272B8004A47F5 /* checkLibraryDoc.tcl */, F96D43D208F272B8004A47F5 /* configure */, - F96D43D308F272B8004A47F5 /* configure.in */, + F96D43D308F272B8004A47F5 /* configure.ac */, F96D442208F272B8004A47F5 /* eolFix.tcl */, F96D442408F272B8004A47F5 /* fix_tommath_h.tcl */, F96D442508F272B8004A47F5 /* genStubs.tcl */, F96D442708F272B8004A47F5 /* index.tcl */, F96D442808F272B8004A47F5 /* installData.tcl */, @@ -3757,11 +3749,11 @@ F96D443E08F272B9004A47F5 /* unix */ = { isa = PBXGroup; children = ( F96D444008F272B9004A47F5 /* aclocal.m4 */, F96D444108F272B9004A47F5 /* configure */, - F96D444208F272B9004A47F5 /* configure.in */, + F96D444208F272B9004A47F5 /* configure.ac */, F96D444308F272B9004A47F5 /* dltest */, F96D444D08F272B9004A47F5 /* install-sh */, F96D444E08F272B9004A47F5 /* installManPage */, F96D444F08F272B9004A47F5 /* ldAix */, F96D445008F272B9004A47F5 /* Makefile.in */, @@ -3817,14 +3809,12 @@ isa = PBXGroup; children = ( F96D447008F272BA004A47F5 /* aclocal.m4 */, F96D447108F272BA004A47F5 /* buildall.vc.bat */, F96D447208F272BA004A47F5 /* cat.c */, - F96D447308F272BA004A47F5 /* coffbase.txt */, F96D447408F272BA004A47F5 /* configure */, - F96D447508F272BA004A47F5 /* configure.in */, - F96D447608F272BA004A47F5 /* makefile.bc */, + F96D447508F272BA004A47F5 /* configure.ac */, F96D447708F272BA004A47F5 /* Makefile.in */, F96D447808F272BA004A47F5 /* makefile.vc */, F96D447908F272BA004A47F5 /* nmakehlp.c */, F96D447A08F272BA004A47F5 /* README */, F96D447C08F272BA004A47F5 /* rules.vc */, @@ -3975,11 +3965,11 @@ buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TCL_SRCROOT)/macosx/configure.ac", - "$(TCL_SRCROOT)/unix/configure.in", + "$(TCL_SRCROOT)/unix/configure.ac", "$(TCL_SRCROOT)/unix/tcl.m4", "$(TCL_SRCROOT)/unix/aclocal.m4", "$(TCL_SRCROOT)/unix/tclConfig.sh.in", "$(TCL_SRCROOT)/unix/Makefile.in", "$(TCL_SRCROOT)/unix/dltest/Makefile.in", @@ -3988,21 +3978,21 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tcl/tclConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; + shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; showEnvVarsInLog = 0; }; F9A5C5F608F651AB008AE941 /* Configure Tk */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TK_SRCROOT)/macosx/configure.ac", - "$(TK_SRCROOT)/unix/configure.in", + "$(TK_SRCROOT)/unix/configure.ac", "$(TK_SRCROOT)/unix/tcl.m4", "$(TK_SRCROOT)/unix/aclocal.m4", "$(TK_SRCROOT)/unix/tkConfig.sh.in", ); name = "Configure Tk"; @@ -4009,21 +3999,21 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tk/tkConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; + shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-aqua --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; showEnvVarsInLog = 0; }; F9FD30B40CC1AD070073837D /* Configure Tcl */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TCL_SRCROOT)/macosx/configure.ac", - "$(TCL_SRCROOT)/unix/configure.in", + "$(TCL_SRCROOT)/unix/configure.ac", "$(TCL_SRCROOT)/unix/tcl.m4", "$(TCL_SRCROOT)/unix/aclocal.m4", "$(TCL_SRCROOT)/unix/tclConfig.sh.in", "$(TCL_SRCROOT)/unix/Makefile.in", "$(TCL_SRCROOT)/unix/dltest/Makefile.in", @@ -4032,21 +4022,21 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tcl/tclConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; + shellScript = "## tcl configure shell script phase\n\ncd \"${TCL_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tcl/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tcl && cd tcl &&\nif [ \"${TCL_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tcl\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n \"${TCL_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi\n"; showEnvVarsInLog = 0; }; F9FD30B50CC1AD070073837D /* Configure Tk */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( "$(TK_SRCROOT)/macosx/configure.ac", - "$(TK_SRCROOT)/unix/configure.in", + "$(TK_SRCROOT)/unix/configure.ac", "$(TK_SRCROOT)/unix/tcl.m4", "$(TK_SRCROOT)/unix/aclocal.m4", "$(TK_SRCROOT)/unix/tkConfig.sh.in", ); name = "Configure Tk"; @@ -4053,11 +4043,11 @@ outputPaths = ( "$(DERIVED_FILE_DIR)/tk/tkConfig.sh", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/bash; - shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.in -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi"; + shellScript = "## tk configure shell script phase\n\ncd \"${TK_SRCROOT}\"/macosx &&\nif [ configure.ac -nt configure -o ../unix/configure.ac -nt configure -o ../unix/tcl.m4 -nt configure -o ../unix/aclocal.m4 -nt configure ]; then\n echo \"Running autoconf & autoheader in tk/macosx\"\n rm -rf autom4te.cache\n ${AUTOCONF:-${DEVELOPER_DIR}/usr/bin/autoconf} && ${AUTOHEADER:-${DEVELOPER_DIR}/usr/bin/autoheader} || exit $?\n rm -rf autom4te.cache\nfi\n\ncd \"${DERIVED_FILE_DIR}\" && mkdir -p tk && cd tk &&\nif [ \"${TK_SRCROOT}\"/macosx/configure -nt config.status ]; then\n echo \"Configuring Tk\"\n CC=$(xcrun -find ${GCC} || echo ${GCC})\n PATH=\"${PATH}:/usr/X11R6/bin\" \"${TK_SRCROOT}\"/macosx/configure --cache-file=../config.cache --prefix=${PREFIX} --bindir=${BINDIR} --libdir=${LIBDIR} --mandir=${MANDIR} --includedir=${INCLUDEDIR} --disable-shared --enable-xft --with-tcl=../tcl CC=${CC} LD=${CC} ${CONFIGURE_ARGS}\nelse\n ./config.status\nfi"; showEnvVarsInLog = 0; }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ Index: macosx/Wish-Info.plist.in ================================================================== --- macosx/Wish-Info.plist.in +++ macosx/Wish-Info.plist.in @@ -67,11 +67,11 @@ CFBundleSignature WiSH CFBundleVersion @TK_VERSION@@TK_PATCH_LEVEL@ LSMinimumSystemVersion - 10.5.0 + 10.6.0 LSRequiresCarbon NSAppleScriptEnabled OSAScriptingDefinition Index: macosx/configure.ac ================================================================== --- macosx/configure.ac +++ macosx/configure.ac @@ -6,6 +6,6 @@ dnl Ensure that the config (auto)headers support is used, then just dnl include the configure sources from ../unix: m4_include(../unix/aclocal.m4) m4_define(SC_USE_CONFIG_HEADERS) -m4_include(../unix/configure.in) +m4_include(../unix/configure.ac) Index: macosx/tkMacOSXBitmap.c ================================================================== --- macosx/tkMacOSXBitmap.c +++ macosx/tkMacOSXBitmap.c @@ -10,11 +10,11 @@ * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" - +#include "tkMacOSXConstants.h" /* * This structure holds information about native bitmaps. */ typedef struct { @@ -171,11 +171,11 @@ Pixmap pixmap; IconRef icon; OSErr err; err = ChkErr(GetIconRef, kOnSystemDisk, kSystemIconsCreator, - PTR2UINT(source), &icon); + (unsigned int)PTR2UINT(source), &icon); if (err == noErr) { pixmap = GetBitmapForIcon(display, icon, CGSizeMake(builtInIconSize, builtInIconSize)); ReleaseIconRef(icon); } else { @@ -208,11 +208,11 @@ Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman"); Tcl_UtfToExternalDString(encoding, s, -1, &ds); if (Tcl_DStringLength(&ds) <= 4) { char string[4] = {}; - memcpy(string, Tcl_DStringValue(&ds), (size_t) Tcl_DStringLength(&ds)); + memcpy(string, Tcl_DStringValue(&ds), Tcl_DStringLength(&ds)); *t = (OSType) string[0] << 24 | (OSType) string[1] << 16 | (OSType) string[2] << 8 | (OSType) string[3]; result = TCL_OK; } Tcl_DStringFree(&ds); @@ -296,11 +296,11 @@ } } else { string = [NSString stringWithUTF8String:name]; image = [NSImage imageNamed:string]; if (!image) { - NSURL *url = [NSURL URLWithString:string]; + NSURL *url = [NSURL fileURLWithPath:string]; if (url) { image = [[[NSImage alloc] initWithContentsOfURL:url] autorelease]; } } Index: macosx/tkMacOSXButton.c ================================================================== --- macosx/tkMacOSXButton.c +++ macosx/tkMacOSXButton.c @@ -19,23 +19,20 @@ #include "tkMacOSXPrivate.h" #include "tkButton.h" #include "tkMacOSXFont.h" #include "tkMacOSXDebug.h" - #define FIRST_DRAW 2 #define ACTIVE 4 - /* - * Default insets for controls + * Extra padding used for computing the content size that should + * be allowed when drawing the HITheme button. */ -#define DEF_INSET_LEFT 12 -#define DEF_INSET_RIGHT 12 -#define DEF_INSET_TOP 1 -#define DEF_INSET_BOTTOM 1 +#define HI_PADX 2 +#define HI_PADY 1 /* * Some defines used to control what type of control is drawn. */ @@ -316,13 +313,12 @@ Tk_FreeTextLayout(butPtr->textLayout); butPtr->textLayout = Tk_ComputeTextLayout(butPtr->tkfont, Tcl_GetString(butPtr->textPtr), -1, butPtr->wrapLength, butPtr->justify, 0, &butPtr->textWidth, &butPtr->textHeight); - /*Remove extraneous padding around label widgets.*/ txtWidth = butPtr->textWidth; - txtHeight = butPtr->textHeight + DEF_INSET_BOTTOM + DEF_INSET_TOP; + txtHeight = butPtr->textHeight; charWidth = Tk_TextWidth(butPtr->tkfont, "0", 1); Tk_GetFontMetrics(butPtr->tkfont, &fm); haveText = (txtWidth != 0 && txtHeight != 0); } @@ -393,11 +389,11 @@ HIRect tmpRect; HIRect contBounds; int paddingx = 0; int paddingy = 0; - tmpRect = CGRectMake(0, 0, width, height); + tmpRect = CGRectMake(0, 0, width + 2*HI_PADX, height + 2*HI_PADY); HIThemeGetButtonContentBounds(&tmpRect, &mbPtr->drawinfo, &contBounds); /* If the content region has a minimum height, match it. */ if (height < contBounds.size.height) { height = contBounds.size.height; @@ -646,11 +642,11 @@ TkComputeAnchor(butPtr->anchor, tkwin, butPtr->padX, butPtr->padY, butPtr->textWidth + butPtr->indicatorSpace, butPtr->textHeight, &x, &y); x += butPtr->indicatorSpace; Tk_DrawTextLayout(butPtr->display, pixmap, dpPtr->gc, butPtr->textLayout, - x, y - DEF_INSET_BOTTOM, 0, -1); + x, y, 0, -1); } /* * If the button is disabled with a stipple rather than a special * foreground color, generate the stippled effect. If the widget @@ -783,23 +779,10 @@ if (!TkMacOSXSetupDrawingContext(pixmap, dpPtr->gc, 1, &dc)) { return; } - - if (mbPtr->btnkind == kThemePushButton) { - /* - * For some reason, pushbuttons get drawn a bit - * too low, normally. Correct for this. - */ - if (cntrRect.size.height < 22) { - cntrRect.origin.y -= 1; - } else if (cntrRect.size.height < 23) { - cntrRect.origin.y -= 2; - } - } - hiinfo.version = 0; hiinfo.state = mbPtr->drawinfo.state; hiinfo.kind = mbPtr->btnkind; hiinfo.value = mbPtr->drawinfo.value; hiinfo.adornment = mbPtr->drawinfo.adornment; @@ -907,11 +890,14 @@ if (tkwin == NULL || !Tk_IsMapped(tkwin)) { return; } - /*Overlay Tk elements over button native region: drawing elements within button boundaries/native region causes unpredictable metrics.*/ + /* + * Overlay Tk elements over button native region: drawing elements + * within button boundaries/native region causes unpredictable metrics. + */ DrawButtonImageAndText( butPtr); } /* *-------------------------------------------------------------- Index: macosx/tkMacOSXClipboard.c ================================================================== --- macosx/tkMacOSXClipboard.c +++ macosx/tkMacOSXClipboard.c @@ -68,14 +68,12 @@ - (void) tkCheckPasteboard { if (clipboardOwner && [[NSPasteboard generalPasteboard] changeCount] != changeCount) { TkDisplay *dispPtr = TkGetDisplayList(); - if (dispPtr) { XEvent event; - event.xany.type = SelectionClear; event.xany.serial = NextRequest(Tk_Display(clipboardOwner)); event.xany.send_event = False; event.xany.window = Tk_WindowId(clipboardOwner); event.xany.display = Tk_Display(clipboardOwner); @@ -123,12 +121,14 @@ ClientData clientData) /* Arbitrary value to pass to proc. */ { int result = TCL_ERROR; TkDisplay *dispPtr = ((TkWindow *) tkwin)->dispPtr; - if (dispPtr && selection == dispPtr->clipboardAtom && (target == XA_STRING - || target == dispPtr->utf8Atom)) { + int haveExternalClip = ([[NSPasteboard generalPasteboard] changeCount] != changeCount); + if (dispPtr && (haveExternalClip || dispPtr->clipboardActive) + && selection == dispPtr->clipboardAtom + && (target == XA_STRING || target == dispPtr->utf8Atom)) { NSString *string = nil; NSPasteboard *pb = [NSPasteboard generalPasteboard]; NSString *type = [pb availableTypeFromArray:[NSArray arrayWithObject: NSStringPboardType]]; @@ -174,11 +174,10 @@ if (dispPtr && selection == dispPtr->clipboardAtom) { clipboardOwner = owner ? Tk_IdToWindow(display, owner) : NULL; if (!dispPtr->clipboardActive) { NSPasteboard *pb = [NSPasteboard generalPasteboard]; - changeCount = [pb declareTypes:[NSArray array] owner:NSApp]; } } return Success; } @@ -286,36 +285,14 @@ void TkSelPropProc( register XEvent *eventPtr) /* X PropertyChange event. */ { } - -/* - *---------------------------------------------------------------------- - * - * TkSuspendClipboard -- - * - * Handle clipboard conversion as required by the suppend event. - * - * Results: - * None. - * - * Side effects: - * The local scrap is moved to the global scrap. - * - *---------------------------------------------------------------------- - */ - -void -TkSuspendClipboard(void) -{ - changeCount = [[NSPasteboard generalPasteboard] changeCount]; -} /* * Local Variables: * mode: objc * c-basic-offset: 4 * fill-column: 79 * coding: utf-8 * End: */ Index: macosx/tkMacOSXColor.c ================================================================== --- macosx/tkMacOSXColor.c +++ macosx/tkMacOSXColor.c @@ -264,17 +264,13 @@ case TRANSPARENT_PIXEL: rgba[3] = 0.0; break; } - // this attempts to find something roughly fitting for any display -// *c = CGColorCreateGenericRGB(rgba[0], rgba[1], rgba[2], rgba[3]); - - // may be off for non-main display but in most cases better than prev static CGColorSpaceRef deviceRGBSpace = NULL; if (!deviceRGBSpace) { - deviceRGBSpace = CGDisplayCopyColorSpace(CGMainDisplayID()); + deviceRGBSpace = CGColorSpaceCreateDeviceRGB(); } *c = CGColorCreate(deviceRGBSpace, rgba ); } return err; } ADDED macosx/tkMacOSXConstants.h Index: macosx/tkMacOSXConstants.h ================================================================== --- /dev/null +++ macosx/tkMacOSXConstants.h @@ -0,0 +1,96 @@ +/* + * tkMacOSXConstants.h -- + * + * Macros which map the names of NS constants used in the Tk code to + * the new name that Apple came up with for subsequent versions of the + * operating system. (Each new OS release seems to come with a new + * naming convention for the same old constants.) + * + * Copyright (c) 2017 Marc Culler + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#ifndef _TKMACCONSTANTS +#define _TKMACCONSTANTS + +/* + * Let's raise a glass for the project manager who improves our lives by + * generating deprecation warnings about pointless changes of the names + * of constants. + */ + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101000 +#define NSOKButton NSModalResponseOK +#endif + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 +#define NSAppKitDefined NSEventTypeAppKitDefined +#define NSApplicationActivatedEventType NSEventSubtypeApplicationActivated +#define NSApplicationDeactivatedEventType NSEventSubtypeApplicationDeactivated +#define NSWindowExposedEventType NSEventSubtypeWindowExposed +#define NSScreenChangedEventType NSEventSubtypeScreenChanged +#define NSWindowMovedEventType NSEventSubtypeWindowMoved +#define NSKeyUp NSEventTypeKeyUp +#define NSKeyDown NSEventTypeKeyDown +#define NSFlagsChanged NSEventTypeFlagsChanged +#define NSLeftMouseDown NSEventTypeLeftMouseDown +#define NSLeftMouseUp NSEventTypeLeftMouseUp +#define NSRightMouseDown NSEventTypeRightMouseDown +#define NSRightMouseUp NSEventTypeRightMouseUp +#define NSLeftMouseDragged NSEventTypeLeftMouseDragged +#define NSRightMouseDragged NSEventTypeRightMouseDragged +#define NSMouseMoved NSEventTypeMouseMoved +#define NSMouseEntered NSEventTypeMouseEntered +#define NSMouseExited NSEventTypeMouseExited +#define NSScrollWheel NSEventTypeScrollWheel +#define NSOtherMouseDown NSEventTypeOtherMouseDown +#define NSOtherMouseUp NSEventTypeOtherMouseUp +#define NSOtherMouseDragged NSEventTypeOtherMouseDragged +#define NSTabletPoint NSEventTypeTabletPoint +#define NSTabletProximity NSEventTypeTabletProximity +#define NSDeviceIndependentModifierFlagsMask NSEventModifierFlagDeviceIndependentFlagsMask +#define NSCommandKeyMask NSEventModifierFlagCommand +#define NSShiftKeyMask NSEventModifierFlagShift +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock +#define NSAlternateKeyMask NSEventModifierFlagOption +#define NSControlKeyMask NSEventModifierFlagControl +#define NSNumericPadKeyMask NSEventModifierFlagNumericPad +#define NSFunctionKeyMask NSEventModifierFlagFunction +#define NSCursorUpdate NSEventTypeCursorUpdate +#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground +#define NSCompositeCopy NSCompositingOperationCopy +#define NSWarningAlertStyle NSAlertStyleWarning +#define NSInformationalAlertStyle NSAlertStyleInformational +#define NSCriticalAlertStyle NSAlertStyleCritical +#define NSCenterTextAlignment NSTextAlignmentCenter +#define NSDeviceIndependentModifierFlagsMask NSEventModifierFlagDeviceIndependentFlagsMask +#define NSCommandKeyMask NSEventModifierFlagCommand +#define NSShiftKeyMask NSEventModifierFlagShift +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock +#define NSAlternateKeyMask NSEventModifierFlagOption +#define NSControlKeyMask NSEventModifierFlagControl +#define NSNumericPadKeyMask NSEventModifierFlagNumericPad +#define NSFunctionKeyMask NSEventModifierFlagFunction +#define NSKeyUp NSEventTypeKeyUp +#define NSKeyDown NSEventTypeKeyDown +#define NSFlagsChanged NSEventTypeFlagsChanged +#define NSAlphaShiftKeyMask NSEventModifierFlagCapsLock +#define NSShiftKeyMask NSEventModifierFlagShift +#define NSAnyEventMask NSEventMaskAny +#define NSTexturedBackgroundWindowMask NSWindowStyleMaskTexturedBackground +#define NSUtilityWindowMask NSWindowStyleMaskUtilityWindow +#define NSNonactivatingPanelMask NSWindowStyleMaskNonactivatingPanel +#define NSDocModalWindowMask NSWindowStyleMaskDocModalWindow +#define NSHUDWindowMask NSWindowStyleMaskHUDWindow +#define NSTitledWindowMask NSWindowStyleMaskTitled +#define NSClosableWindowMask NSWindowStyleMaskClosable +#define NSResizableWindowMask NSWindowStyleMaskResizable +#define NSUnifiedTitleAndToolbarWindowMask NSWindowStyleMaskUnifiedTitleAndToolbar +#define NSMiniaturizableWindowMask NSWindowStyleMaskMiniaturizable +#define NSBorderlessWindowMask NSWindowStyleMaskBorderless +#define NSFullScreenWindowMask NSWindowStyleMaskFullScreen +#endif + +#endif Index: macosx/tkMacOSXDefault.h ================================================================== --- macosx/tkMacOSXDefault.h +++ macosx/tkMacOSXDefault.h @@ -189,10 +189,12 @@ #define DEF_ENTRY_INSERT_OFF_TIME "300" #define DEF_ENTRY_INSERT_ON_TIME "600" /* #define DEF_ENTRY_INSERT_WIDTH "2" */ #define DEF_ENTRY_INSERT_WIDTH "1" #define DEF_ENTRY_JUSTIFY "left" +#define DEF_ENTRY_PLACEHOLDER "" +#define DEF_ENTRY_PLACEHOLDERFG "#b3b3b3" #define DEF_ENTRY_READONLY_BG_COLOR NORMAL_BG #define DEF_ENTRY_READONLY_BG_MONO WHITE #define DEF_ENTRY_RELIEF "sunken" /* #define DEF_ENTRY_RELIEF "solid" */ #define DEF_ENTRY_SCROLL_COMMAND "" @@ -310,10 +312,11 @@ #define DEF_MENU_ACTIVE_BG_COLOR "systemMenuActive" #define DEF_MENU_ACTIVE_BG_MONO BLACK #define DEF_MENU_ACTIVE_BORDER_WIDTH "0" #define DEF_MENU_ACTIVE_FG_COLOR "systemMenuActiveText" #define DEF_MENU_ACTIVE_FG_MONO WHITE +#define DEF_MENU_ACTIVE_RELIEF "flat" #define DEF_MENU_BG_COLOR "systemMenu" #define DEF_MENU_BG_MONO WHITE #define DEF_MENU_BORDER_WIDTH "0" #define DEF_MENU_CURSOR "arrow" #define DEF_MENU_DISABLED_FG_COLOR "systemMenuDisabled" @@ -323,15 +326,10 @@ #define DEF_MENU_POST_COMMAND "" #define DEF_MENU_RELIEF "flat" #define DEF_MENU_SELECT_COLOR "systemMenuActive" #define DEF_MENU_SELECT_MONO BLACK #define DEF_MENU_TAKE_FOCUS "0" - -/* - * FIXME: Turn the default back to 1 when we make tearoff menus work again. - */ - #define DEF_MENU_TEAROFF "0" #define DEF_MENU_TEAROFF_CMD ((char *) NULL) #define DEF_MENU_TITLE "" #define DEF_MENU_TYPE "normal" Index: macosx/tkMacOSXDialog.c ================================================================== --- macosx/tkMacOSXDialog.c +++ macosx/tkMacOSXDialog.c @@ -4,17 +4,19 @@ * Contains the Mac implementation of the common dialog boxes. * * Copyright (c) 1996-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen + * Copyright (c) 2017 Christian Gollwitzer. * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkFileFilter.h" +#include "tkMacOSXConstants.h" #if MAC_OS_X_VERSION_MIN_REQUIRED < 1090 #define modalOK NSOKButton #define modalCancel NSCancelButton #else @@ -22,10 +24,31 @@ #define modalCancel NSModalResponseCancel #endif #define modalOther -1 #define modalError -2 +/*Vars for filtering in "open file" and "save file" dialogs.*/ +typedef struct { + bool doFileTypes; // show the accessory view which displays the filter menu + bool preselectFilter; // a filter was selected by the typevariable + bool userHasSelectedFilter; // The user has changed the filter in the accessory view + + NSMutableArray *fileTypeNames; // array of names, e.g. "Text document" + NSMutableArray *fileTypeExtensions; // array of allowed extensions per name, e.g. "txt", "doc" + NSMutableArray *fileTypeLabels; // displayed string, e.g. "Text document (.txt, .doc)" + NSMutableArray *fileTypeAllowsAll; // boolean if the all pattern (*.*) is included + + NSMutableArray *allowedExtensions; // set of all allowed extensions + bool allowedExtensionsAllowAll; // set of all allowed extensions includes *.* + + NSUInteger fileTypeIndex; // index of currently selected filter +} filepanelFilterInfo; + +filepanelFilterInfo filterInfo; + +NSOpenPanel *openpanel; +NSSavePanel *savepanel; static const char *const colorOptionStrings[] = { "-initialcolor", "-parent", "-title", NULL }; enum colorOptions { @@ -92,11 +115,11 @@ }; enum alertIconOptions { ICON_ERROR, ICON_INFO, ICON_QUESTION, ICON_WARNING }; static const char *const alertButtonStrings[] = { - "abort", "retry", "ignore", "ok", "cancel", "yes", "no", NULL + "abort", "retry", "ignore", "ok", "cancel", "no", "yes", NULL }; static const NSString *const alertButtonNames[][3] = { [TYPE_ABORTRETRYIGNORE] = {@"Abort", @"Retry", @"Ignore"}, [TYPE_OK] = {@"OK"}, @@ -122,12 +145,12 @@ /* abort retry ignore ok cancel yes no */ [TYPE_ABORTRETRYIGNORE] = {1, 2, 3, 0, 0, 0, 0}, [TYPE_OK] = {0, 0, 0, 1, 0, 0, 0}, [TYPE_OKCANCEL] = {0, 0, 0, 1, 2, 0, 0}, [TYPE_RETRYCANCEL] = {0, 1, 0, 0, 2, 0, 0}, - [TYPE_YESNO] = {0, 0, 0, 0, 0, 1, 2}, - [TYPE_YESNOCANCEL] = {0, 0, 0, 0, 3, 1, 2}, + [TYPE_YESNO] = {0, 0, 0, 0, 0, 2, 1}, + [TYPE_YESNOCANCEL] = {0, 0, 0, 0, 3, 2, 1}, }; /* * Need also the inverse mapping, from NSAlertFirstButtonReturn etc to the * descriptive button text string index. @@ -136,30 +159,28 @@ static const short alertNativeButtonIndexAndTypeToButtonIndex[][3] = { [TYPE_ABORTRETRYIGNORE] = {0, 1, 2}, [TYPE_OK] = {3, 0, 0}, [TYPE_OKCANCEL] = {3, 4, 0}, [TYPE_RETRYCANCEL] = {1, 4, 0}, - [TYPE_YESNO] = {5, 6, 0}, - [TYPE_YESNOCANCEL] = {5, 6, 4}, + [TYPE_YESNO] = {6, 5, 0}, + [TYPE_YESNOCANCEL] = {6, 5, 4}, }; /* * Construct a file URL from directory and filename. Either may * be nil. If both are nil, returns nil. */ -#if MAC_OS_X_VERSION_MIN_REQUIRED > 1050 static NSURL *getFileURL(NSString *directory, NSString *filename) { NSURL *url = nil; if (directory) { - url = [NSURL fileURLWithPath:directory]; + url = [NSURL fileURLWithPath:directory isDirectory:YES]; } if (filename) { url = [NSURL URLWithString:filename relativeToURL:url]; } return url; } -#endif #pragma mark TKApplication(TKDialog) @interface NSColorPanel(TKDialog) - (void) _setUseModalAppearance: (BOOL) flag; @@ -170,11 +191,11 @@ - (void) tkFilePanelDidEnd: (NSSavePanel *) panel returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo { FilePanelCallbackInfo *callbackInfo = contextInfo; - if (returnCode == NSFileHandlingPanelOKButton) { + if (returnCode == modalOK) { Tcl_Obj *resultObj; if (callbackInfo->multiple) { resultObj = Tcl_NewListObj(0, NULL); for (NSURL *url in [(NSOpenPanel*)panel URLs]) { @@ -198,11 +219,11 @@ ckfree(tmpv); } } else { Tcl_SetObjResult(callbackInfo->interp, resultObj); } - } else if (returnCode == NSFileHandlingPanelCancelButton) { + } else if (returnCode == modalCancel) { Tcl_ResetResult(callbackInfo->interp); } if (panel == [NSApp modalWindow]) { [NSApp stopModalWithCode:returnCode]; } @@ -209,10 +230,11 @@ if (callbackInfo->cmdObj) { Tcl_DecrRefCount(callbackInfo->cmdObj); ckfree(callbackInfo); } } + - (void) tkAlertDidEnd: (NSAlert *) alert returnCode: (NSInteger) returnCode contextInfo: (void *) contextInfo { AlertCallbackInfo *callbackInfo = contextInfo; @@ -245,10 +267,46 @@ if (callbackInfo->cmdObj) { Tcl_DecrRefCount(callbackInfo->cmdObj); ckfree(callbackInfo); } } + +- (void)selectFormat:(id)sender { + NSPopUpButton *button = (NSPopUpButton *)sender; + filterInfo.fileTypeIndex = [button indexOfSelectedItem]; + + if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) { + [openpanel setAllowsOtherFileTypes:YES]; + /* setAllowsOtherFileTypes might have no effect; it's inherited from the + * NSSavePanel, where it has the effect that it does not append an extension + * Setting the allowed file types to nil allows selecting any file */ + [openpanel setAllowedFileTypes:nil]; + } else { + NSMutableArray *allowedtypes = [filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]; + [openpanel setAllowedFileTypes:allowedtypes]; + [openpanel setAllowsOtherFileTypes:NO]; + } + + filterInfo.userHasSelectedFilter = true; +} + +- (void)saveFormat:(id)sender { + NSPopUpButton *button = (NSPopUpButton *)sender; + filterInfo.fileTypeIndex = [button indexOfSelectedItem]; + + if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterInfo.fileTypeIndex] boolValue]) { + [savepanel setAllowsOtherFileTypes:YES]; + [savepanel setAllowedFileTypes:nil]; + } else { + NSMutableArray *allowedtypes = [filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]; + [savepanel setAllowedFileTypes:allowedtypes]; + [savepanel setAllowsOtherFileTypes:NO]; + } + + filterInfo.userHasSelectedFilter = true; +} + @end #pragma mark - /* @@ -337,11 +395,11 @@ [colorPanel setColor:initialColor]; } returnCode = [NSApp runModalForWindow:colorPanel]; if (returnCode == modalOK) { color = [[colorPanel color] colorUsingColorSpace: - [NSColorSpace genericRGBColorSpace]]; + [NSColorSpace deviceRGBColorSpace]]; numberOfComponents = [color numberOfComponents]; } if (color && numberOfComponents >= 3 && numberOfComponents <= 4) { CGFloat components[4]; char colorstr[8]; @@ -358,10 +416,124 @@ result = TCL_OK; end: return result; } + +/* dissect the -filetype nested lists and store the information + * in the filterInfo structure */ +int parseFileFilters(Tcl_Interp *interp, Tcl_Obj *fileTypesPtr, Tcl_Obj *typeVariablePtr) { + + if (!fileTypesPtr) { + filterInfo.doFileTypes = false; + return TCL_OK; + } + + FileFilterList fl; + TkInitFileFilters(&fl); + if (TkGetFileFilters(interp, &fl, fileTypesPtr, 0) != TCL_OK) { + TkFreeFileFilters(&fl); + return TCL_ERROR; + } + + filterInfo.doFileTypes = (fl.filters != NULL); + + filterInfo.fileTypeIndex = 0; + filterInfo.fileTypeExtensions = [NSMutableArray array]; + filterInfo.fileTypeNames = [NSMutableArray array]; + filterInfo.fileTypeLabels = [NSMutableArray array]; + filterInfo.fileTypeAllowsAll = [NSMutableArray array]; + + filterInfo.allowedExtensions = [NSMutableArray array]; + filterInfo.allowedExtensionsAllowAll = NO; + + if (filterInfo.doFileTypes) { + for (FileFilter *filterPtr = fl.filters; filterPtr; + filterPtr = filterPtr->next) { + NSString * name = [[NSString alloc] initWithUTF8String: filterPtr -> name]; + [filterInfo.fileTypeNames addObject:name]; + [name release]; + NSMutableArray * clauseextensions = [NSMutableArray array]; + NSMutableArray * displayextensions = [NSMutableArray array]; + bool allowsAll = NO; + + for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; + clausePtr = clausePtr->next) { + + for (GlobPattern *globPtr = clausePtr->patterns; globPtr; + globPtr = globPtr->next) { + const char *str = globPtr->pattern; + while (*str && (*str == '*' || *str == '.')) { + str++; + } + if (*str) { + NSString *extension = [[NSString alloc] initWithUTF8String:str]; + if (![filterInfo.allowedExtensions containsObject:extension]) { + [filterInfo.allowedExtensions addObject:extension]; + } + + [clauseextensions addObject:extension]; + [displayextensions addObject:[@"." stringByAppendingString:extension]]; + + [extension release]; + } else { + // it is the all pattern (*, .* or *.*) + allowsAll = YES; + filterInfo.allowedExtensionsAllowAll = YES; + [displayextensions addObject:@"*"]; + } + } + } + [filterInfo.fileTypeExtensions addObject:clauseextensions]; + [filterInfo.fileTypeAllowsAll addObject:[NSNumber numberWithBool:allowsAll]]; + + NSMutableString * label = [[NSMutableString alloc] initWithString:name]; + [label appendString:@" ("]; + [label appendString:[displayextensions componentsJoinedByString:@", "]]; + [label appendString:@")"]; + [filterInfo.fileTypeLabels addObject:label]; + [label release]; + + } + + /* Check if the typevariable exists and matches one of the names */ + filterInfo.preselectFilter = false; + filterInfo.userHasSelectedFilter = false; + if (typeVariablePtr) { + /* extract the variable content as a NSString */ + Tcl_Obj *selectedFileTypeObj = Tcl_ObjGetVar2(interp, typeVariablePtr, NULL, TCL_GLOBAL_ONLY); + + /* check that the typevariable exists */ + if (selectedFileTypeObj != NULL) { + const char *selectedFileType = Tcl_GetString(selectedFileTypeObj); + NSString *selectedFileTypeStr = [[NSString alloc] initWithUTF8String:selectedFileType]; + NSUInteger index = [filterInfo.fileTypeNames indexOfObject:selectedFileTypeStr]; + + if (index != NSNotFound) { + filterInfo.fileTypeIndex = index; + filterInfo.preselectFilter = true; + } + } + } + + } + + TkFreeFileFilters(&fl); + return TCL_OK; +} + +bool filterCompatible(NSString *extension, int filterIndex) { + NSMutableArray *allowedExtensions = [filterInfo.fileTypeExtensions objectAtIndex: filterIndex]; + + /* If this contains the all pattern, accept any extension */ + if ([[filterInfo.fileTypeAllowsAll objectAtIndex:filterIndex] boolValue]) { + return true; + } + + return [allowedExtensions containsObject: extension]; +} + /* *---------------------------------------------------------------------- * * Tk_GetOpenFileObjCmd -- @@ -386,23 +558,20 @@ { Tk_Window tkwin = clientData; char *str; int i, result = TCL_ERROR, haveParentOption = 0; int index, len, multiple = 0; - FileFilterList fl; - Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL; + Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; NSString *directory = nil, *filename = nil; - NSString *message, *title, *type; + NSString *message = nil, *title = nil; NSWindow *parent; - NSMutableArray *fileTypes = nil; - NSOpenPanel *panel = [NSOpenPanel openPanel]; + openpanel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - TkInitFileFilters(&fl); for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], openOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { goto end; } @@ -414,13 +583,11 @@ } switch (index) { case OPEN_DEFAULT: break; case OPEN_FILETYPES: - if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) { - goto end; - } + fileTypesPtr = objv[i + 1]; break; case OPEN_INITDIR: str = Tcl_GetStringFromObj(objv[i + 1], &len); if (len) { directory = [[[NSString alloc] initWithUTF8String:str] @@ -435,12 +602,10 @@ } break; case OPEN_MESSAGE: message = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; - [message release]; break; case OPEN_MULTIPLE: if (Tcl_GetBooleanFromObj(interp, objv[i + 1], &multiple) != TCL_OK) { goto end; @@ -455,115 +620,185 @@ haveParentOption = 1; break; case OPEN_TITLE: title = [[NSString alloc] initWithUTF8String: Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; - [title release]; break; case OPEN_TYPEVARIABLE: typeVariablePtr = objv[i + 1]; break; case OPEN_COMMAND: cmdObj = objv[i+1]; break; } } - [panel setAllowsMultipleSelection:multiple]; - if (fl.filters) { - fileTypes = [NSMutableArray array]; - for (FileFilter *filterPtr = fl.filters; filterPtr; - filterPtr = filterPtr->next) { - for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; - clausePtr = clausePtr->next) { - for (GlobPattern *globPtr = clausePtr->patterns; globPtr; - globPtr = globPtr->next) { - str = globPtr->pattern; - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - type = [[NSString alloc] initWithUTF8String:str]; - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; - } - [type release]; - } - } - for (MacFileType *mfPtr = clausePtr->macTypes; mfPtr; - mfPtr = mfPtr->next) { - if (mfPtr->type) { - type = NSFileTypeForHFSTypeCode(mfPtr->type); - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; - } - } - } - } - } - } - [panel setAllowedFileTypes:fileTypes]; + + if (title) { + [openpanel setTitle:title]; + + /* From OSX 10.11, the title string is silently ignored in the open panel. + * Prepend the title to the message in this case + * NOTE should be conditional on OSX version, but + * -mmacosx-version-min does not revert this behaviour*/ + + if (message) { + NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; + [message release]; + [title release]; + message = fullmessage; + } else { + message = title; + } + } + + if (message) { + [openpanel setMessage:message]; + [message release]; + } + + [openpanel setAllowsMultipleSelection:multiple]; + + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { + goto end; + } + + if (filterInfo.doFileTypes) { + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:@"Filter:"]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 240, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:filterInfo.fileTypeLabels]; + [popupButton setAction:@selector(selectFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + + if (filterInfo.preselectFilter) { + /* A specific filter was selected from the typevariable. Select it and + * open the accessory view */ + [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; + /* on OSX > 10.11, the optons are not visible by default. Ergo allow all file types + [openpanel setAllowedFileTypes:filterInfo.fileTypeExtensions[filterInfo.fileTypeIndex]]; + */ + [openpanel setAllowedFileTypes:filterInfo.allowedExtensions]; + } else { + [openpanel setAllowedFileTypes:filterInfo.allowedExtensions]; + } + + if (filterInfo.allowedExtensionsAllowAll) { + [openpanel setAllowsOtherFileTypes:YES]; + } else { + [openpanel setAllowsOtherFileTypes:NO]; + } + + [openpanel setAccessoryView:accessoryView]; + } else { + /* No filters are given. Allow picking all files */ + [openpanel setAllowsOtherFileTypes:YES]; + } + if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { cmdObj = Tcl_DuplicateObj(cmdObj); } Tcl_IncrRefCount(cmdObj); } + callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = multiple; parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); if (haveParentOption && parent && ![parent attachedSheet]) { - parentIsKey = [parent isKeyWindow]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory - file:filename - types:fileTypes - modalForWindow:parent - modalDelegate:NSApp - didEndSelector: - @selector(tkFilePanelDidEnd:returnCode:contextInfo:) - contextInfo:callbackInfo]; -#else - [panel setAllowedFileTypes:fileTypes]; - [panel setDirectoryURL:getFileURL(directory, filename)]; - [panel beginSheetModalForWindow:parent + parentIsKey = [parent isKeyWindow]; + if (directory || filename ) { + NSURL * fileURL = getFileURL(directory, filename); + [openpanel setDirectoryURL:fileURL]; + } + + [openpanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel + { [NSApp tkFilePanelDidEnd:openpanel returnCode:returnCode contextInfo:callbackInfo ]; } ]; -#endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; + modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:openpanel]; } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory - file:filename]; -#else - [panel setDirectoryURL:getFileURL(directory, filename)]; - modalReturnCode = [panel runModal]; -#endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode + if (directory || filename ) { + NSURL * fileURL = getFileURL(directory, filename); + [openpanel setDirectoryURL:fileURL]; + } + + modalReturnCode = [openpanel runModal]; + [NSApp tkFilePanelDidEnd:openpanel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; if (parentIsKey) { [parent makeKeyWindow]; } - if (typeVariablePtr && result == TCL_OK) { + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && + filterInfo.doFileTypes) { /* - * The -typevariable option is not really supported. + * The -typevariable must be set to the selected file type, if the dialog was not cancelled */ + NSUInteger selectedFilterIndex = filterInfo.fileTypeIndex; + NSString *selectedFilter = NULL; + if (filterInfo.userHasSelectedFilter) { + selectedFilterIndex = filterInfo.fileTypeIndex; + selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex]; + } else { + /* Difficult case: the user has not touched the filter settings, but we must + * return something in the typevariable. First check if the preselected type is compatible + * with the selected file, otherwise choose the first compatible type from the list, + * finally fall back to the empty string */ + NSURL *selectedFile; + if (multiple) { + // Use the first file in the case of multiple selection + // Anyway it is not overly useful here + selectedFile = [[openpanel URLs] objectAtIndex:0]; + } else { + selectedFile = [openpanel URL]; + } - Tcl_SetVar2(interp, Tcl_GetString(typeVariablePtr), NULL, - "", TCL_GLOBAL_ONLY); + NSString *extension = [selectedFile pathExtension]; + if (filterInfo.preselectFilter && + filterCompatible(extension, filterInfo.fileTypeIndex)) { + selectedFilterIndex = filterInfo.fileTypeIndex; // The preselection from the typevariable + selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex]; + } else { + // scan the list + NSUInteger i; + for (i = 0; i < [filterInfo.fileTypeNames count]; i++) { + if (filterCompatible(extension, i)) { + selectedFilterIndex = i; + break; + } + } + if (i == selectedFilterIndex) { + selectedFilter = [filterInfo.fileTypeNames objectAtIndex:selectedFilterIndex]; + } else { + selectedFilter = @""; + } + + } + } + + Tcl_ObjSetVar2(interp, typeVariablePtr, NULL, + Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); } + end: - TkFreeFileFilters(&fl); return result; } + /* *---------------------------------------------------------------------- * * Tk_GetSaveFileObjCmd -- @@ -589,23 +824,20 @@ Tk_Window tkwin = clientData; char *str; int i, result = TCL_ERROR, haveParentOption = 0; int confirmOverwrite = 1; int index, len; - FileFilterList fl; - Tcl_Obj *cmdObj = NULL; + Tcl_Obj *cmdObj = NULL, *typeVariablePtr = NULL, *fileTypesPtr = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; NSString *directory = nil, *filename = nil, *defaultType = nil; - NSString *message, *title, *type; + NSString *message = nil, *title = nil; NSWindow *parent; - NSMutableArray *fileTypes = nil; - NSSavePanel *panel = [NSSavePanel savePanel]; + savepanel = [NSSavePanel savePanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; - TkInitFileFilters(&fl); for (i = 1; i < objc; i += 2) { if (Tcl_GetIndexFromObjStruct(interp, objv[i], saveOptionStrings, sizeof(char *), "option", TCL_EXACT, &index) != TCL_OK) { goto end; } @@ -614,100 +846,131 @@ "value for \"%s\" missing", Tcl_GetString(objv[i]))); Tcl_SetErrorCode(interp, "TK", "FILEDIALOG", "VALUE", NULL); goto end; } switch (index) { - case SAVE_DEFAULT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - defaultType = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case SAVE_FILETYPES: - if (TkGetFileFilters(interp, &fl, objv[i + 1], 0) != TCL_OK) { - goto end; - } - break; - case SAVE_INITDIR: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - directory = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case SAVE_INITFILE: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - if (len) { - filename = [[[NSString alloc] initWithUTF8String:str] - autorelease]; - } - break; - case SAVE_MESSAGE: - message = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [panel setMessage:message]; - [message release]; - break; - case SAVE_PARENT: - str = Tcl_GetStringFromObj(objv[i + 1], &len); - tkwin = Tk_NameToWindow(interp, str, tkwin); - if (!tkwin) { - goto end; - } - haveParentOption = 1; - break; - case SAVE_TITLE: - title = [[NSString alloc] initWithUTF8String: - Tcl_GetString(objv[i + 1])]; - [panel setTitle:title]; - [title release]; - break; - case SAVE_TYPEVARIABLE: - break; - case SAVE_COMMAND: - cmdObj = objv[i+1]; - break; - case SAVE_CONFIRMOW: - if (Tcl_GetBooleanFromObj(interp, objv[i + 1], - &confirmOverwrite) != TCL_OK) { - goto end; - } - break; - } - } - if (fl.filters || defaultType) { - fileTypes = [NSMutableArray array]; - [fileTypes addObject:defaultType ? defaultType : (id)kUTTypeContent]; - for (FileFilter *filterPtr = fl.filters; filterPtr; - filterPtr = filterPtr->next) { - for (FileFilterClause *clausePtr = filterPtr->clauses; clausePtr; - clausePtr = clausePtr->next) { - for (GlobPattern *globPtr = clausePtr->patterns; globPtr; - globPtr = globPtr->next) { - str = globPtr->pattern; - while (*str && (*str == '*' || *str == '.')) { - str++; - } - if (*str) { - type = [[NSString alloc] initWithUTF8String:str]; - if (![fileTypes containsObject:type]) { - [fileTypes addObject:type]; - } - [type release]; - } - } - } - } - [panel setAllowedFileTypes:fileTypes]; - [panel setAllowsOtherFileTypes:YES]; - } - [panel setCanSelectHiddenExtension:YES]; - [panel setExtensionHidden:NO]; + case SAVE_DEFAULT: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + while (*str && (*str == '*' || *str == '.')) { + str++; + } + if (*str) { + defaultType = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + } + break; + case SAVE_FILETYPES: + fileTypesPtr = objv[i + 1]; + break; + case SAVE_INITDIR: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + if (len) { + directory = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + } + break; + case SAVE_INITFILE: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + if (len) { + filename = [[[NSString alloc] initWithUTF8String:str] + autorelease]; + [savepanel setNameFieldStringValue:filename]; + } + break; + case SAVE_MESSAGE: + message = [[NSString alloc] initWithUTF8String: + Tcl_GetString(objv[i + 1])]; + break; + case SAVE_PARENT: + str = Tcl_GetStringFromObj(objv[i + 1], &len); + tkwin = Tk_NameToWindow(interp, str, tkwin); + if (!tkwin) { + goto end; + } + haveParentOption = 1; + break; + case SAVE_TITLE: + title = [[NSString alloc] initWithUTF8String: + Tcl_GetString(objv[i + 1])]; + break; + case SAVE_TYPEVARIABLE: + typeVariablePtr = objv[i + 1]; + break; + case SAVE_COMMAND: + cmdObj = objv[i+1]; + break; + case SAVE_CONFIRMOW: + if (Tcl_GetBooleanFromObj(interp, objv[i + 1], + &confirmOverwrite) != TCL_OK) { + goto end; + } + break; + } + } + + if (title) { + [savepanel setTitle:title]; + + /* From OSX 10.11, the title string is silently ignored, if the save panel is a sheet. + * Prepend the title to the message in this case + * NOTE should be conditional on OSX version, but + * -mmacosx-version-min does not revert this behaviour*/ + if (haveParentOption) { + if (message) { + NSString *fullmessage = [[NSString alloc] initWithFormat:@"%@\n%@",title,message]; + [message release]; + [title release]; + message = fullmessage; + } else { + message = title; + } + } + } + + if (message) { + [savepanel setMessage:message]; + [message release]; + } + + if (parseFileFilters(interp, fileTypesPtr, typeVariablePtr) != TCL_OK) { + goto end; + } + + if (filterInfo.doFileTypes) { + NSView *accessoryView = [[NSView alloc] initWithFrame:NSMakeRect(0.0, 0.0, 300, 32.0)]; + NSTextField *label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 60, 22)]; + [label setEditable:NO]; + [label setStringValue:NSLocalizedString(@"Format:", nil)]; + [label setBordered:NO]; + [label setBezeled:NO]; + [label setDrawsBackground:NO]; + + NSPopUpButton *popupButton = [[NSPopUpButton alloc] initWithFrame:NSMakeRect(50.0, 2, 340, 22.0) pullsDown:NO]; + [popupButton addItemsWithTitles:filterInfo.fileTypeLabels]; + [popupButton selectItemAtIndex:filterInfo.fileTypeIndex]; + [popupButton setAction:@selector(saveFormat:)]; + + [accessoryView addSubview:label]; + [accessoryView addSubview:popupButton]; + + [savepanel setAccessoryView:accessoryView]; + + [savepanel setAllowedFileTypes:[filterInfo.fileTypeExtensions objectAtIndex:filterInfo.fileTypeIndex]]; + [savepanel setAllowsOtherFileTypes:filterInfo.allowedExtensionsAllowAll]; + } else if (defaultType) { + /* If no filetypes are given, defaultextension is an alternative way + * to specify the attached extension. Just propose this extension, + * but don't display an accessory view */ + NSMutableArray *AllowedFileTypes = [NSMutableArray array]; + [AllowedFileTypes addObject:defaultType]; + [savepanel setAllowedFileTypes:AllowedFileTypes]; + [savepanel setAllowsOtherFileTypes:YES]; + } + + [savepanel setCanSelectHiddenExtension:YES]; + [savepanel setExtensionHidden:NO]; + if (cmdObj) { callbackInfo = ckalloc(sizeof(FilePanelCallbackInfo)); if (Tcl_IsShared(cmdObj)) { cmdObj = Tcl_DuplicateObj(cmdObj); } @@ -714,46 +977,59 @@ Tcl_IncrRefCount(cmdObj); } callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = 0; + parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); if (haveParentOption && parent && ![parent attachedSheet]) { parentIsKey = [parent isKeyWindow]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory - file:filename - modalForWindow:parent - modalDelegate:NSApp - didEndSelector: - @selector(tkFilePanelDidEnd:returnCode:contextInfo:) - contextInfo:callbackInfo]; -#else - [panel setDirectoryURL:getFileURL(directory, filename)]; - [panel beginSheetModalForWindow:parent + if (directory) { + [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + /*check for file name, otherwise set to empty string; crashes with uncaught exception if set to nil*/ + if (filename) { + [savepanel setNameFieldStringValue:filename]; + } else { + [savepanel setNameFieldStringValue:@""]; + } + [savepanel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) - { [NSApp tkFilePanelDidEnd:panel + { [NSApp tkFilePanelDidEnd:savepanel returnCode:returnCode contextInfo:callbackInfo ]; } ]; -#endif - modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; + modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:savepanel]; } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory file:filename]; -#else - [panel setDirectoryURL:getFileURL(directory, filename)]; - modalReturnCode = [panel runModal]; -#endif - [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode + if (directory) { + [savepanel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; + } + /*check for file name, otherwise set to empty string; crashes with uncaught exception if set to nil*/ + if (filename) { + [savepanel setNameFieldStringValue:filename]; + } else { + [savepanel setNameFieldStringValue:@""]; + } + modalReturnCode = [savepanel runModal]; + [NSApp tkFilePanelDidEnd:savepanel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; if (parentIsKey) { [parent makeKeyWindow]; } + + if ((typeVariablePtr && (modalReturnCode == NSOKButton)) && filterInfo.doFileTypes) { + /* + * The -typevariable must be set to the selected file type, if the dialog was not cancelled + */ + NSString * selectedFilter = [filterInfo.fileTypeNames objectAtIndex:filterInfo.fileTypeIndex]; + Tcl_ObjSetVar2(interp, typeVariablePtr, NULL, + Tcl_NewStringObj([selectedFilter UTF8String], -1), TCL_GLOBAL_ONLY); + } + + end: - TkFreeFileFilters(&fl); return result; } /* *---------------------------------------------------------------------- @@ -785,11 +1061,11 @@ int i, result = TCL_ERROR, haveParentOption = 0; int index, len, mustexist = 0; Tcl_Obj *cmdObj = NULL; FilePanelCallbackInfo callbackInfoStruct; FilePanelCallbackInfo *callbackInfo = &callbackInfoStruct; - NSString *directory = nil, *filename = nil; + NSString *directory = nil; NSString *message, *title; NSWindow *parent; NSOpenPanel *panel = [NSOpenPanel openPanel]; NSInteger modalReturnCode = modalError; BOOL parentIsKey = NO; @@ -856,36 +1132,27 @@ Tcl_IncrRefCount(cmdObj); } callbackInfo->cmdObj = cmdObj; callbackInfo->interp = interp; callbackInfo->multiple = 0; + /*check for directory value, set to root if not specified; otherwise crashes with exception because of nil string parameter*/ + if (!directory) { + directory = @"/"; + } parent = TkMacOSXDrawableWindow(((TkWindow *) tkwin)->window); if (haveParentOption && parent && ![parent attachedSheet]) { - parentIsKey = [parent isKeyWindow]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - [panel beginSheetForDirectory:directory - file:filename - modalForWindow:parent - modalDelegate:NSApp - didEndSelector: @selector(tkFilePanelDidEnd:returnCode:contextInfo:) - contextInfo:callbackInfo]; -#else - [panel setDirectoryURL:getFileURL(directory, filename)]; + parentIsKey = [parent isKeyWindow]; + [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; [panel beginSheetModalForWindow:parent completionHandler:^(NSInteger returnCode) { [NSApp tkFilePanelDidEnd:panel returnCode:returnCode contextInfo:callbackInfo ]; } ]; -#endif modalReturnCode = cmdObj ? modalOther : [NSApp runModalForWindow:panel]; } else { -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - modalReturnCode = [panel runModalForDirectory:directory file:nil]; -#else - [panel setDirectoryURL:getFileURL(directory, filename)]; + [panel setDirectoryURL:[NSURL fileURLWithPath:directory isDirectory:YES]]; modalReturnCode = [panel runModal]; -#endif [NSApp tkFilePanelDidEnd:panel returnCode:modalReturnCode contextInfo:callbackInfo]; } result = (modalReturnCode != modalError) ? TCL_OK : TCL_ERROR; if (parentIsKey) { @@ -1061,11 +1328,11 @@ [message release]; break; case ALERT_ICON: if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertIconStrings, - sizeof(char *), "value", TCL_EXACT, &iconIndex) != TCL_OK) { + sizeof(char *), "-icon value", TCL_EXACT, &iconIndex) != TCL_OK) { goto end; } break; case ALERT_MESSAGE: @@ -1091,11 +1358,11 @@ [title release]; break; case ALERT_TYPE: if (Tcl_GetIndexFromObjStruct(interp, objv[i + 1], alertTypeStrings, - sizeof(char *), "value", TCL_EXACT, &typeIndex) != TCL_OK) { + sizeof(char *), "-type value", TCL_EXACT, &typeIndex) != TCL_OK) { goto end; } break; case ALERT_COMMAND: cmdObj = objv[i+1]; @@ -1107,11 +1374,11 @@ * Any '-default' option needs to know the '-type' option, which is * why we do this here. */ if (Tcl_GetIndexFromObjStruct(interp, objv[indexDefaultOption + 1], - alertButtonStrings, sizeof(char *), "value", TCL_EXACT, &index) != TCL_OK) { + alertButtonStrings, sizeof(char *), "-default value", TCL_EXACT, &index) != TCL_OK) { goto end; } /* * Need to map from "ok" etc. to 1, 2, 3, right to left. Index: macosx/tkMacOSXDraw.c ================================================================== --- macosx/tkMacOSXDraw.c +++ macosx/tkMacOSXDraw.c @@ -14,11 +14,10 @@ * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXDebug.h" -#include "xbytes.h" #include "tkButton.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_DRAWING @@ -43,16 +42,10 @@ /* * Prototypes for functions used only in this file. */ static void ClipToGC(Drawable d, GC gc, HIShapeRef *clipRgnPtr); -static CGImageRef CreateCGImageWithXImage(XImage *ximage); -static CGContextRef GetCGContextForDrawable(Drawable d); -static void DrawCGImage(Drawable d, GC gc, CGContextRef context, CGImageRef image, - unsigned long imageForeground, unsigned long imageBackground, - CGRect imageBounds, CGRect srcBounds, CGRect dstBounds); - /* *---------------------------------------------------------------------- * * TkMacOSXInitCGDrawing -- @@ -106,17 +99,18 @@ } /* *---------------------------------------------------------------------- * - * BitmapRepFromDrawableRect + * TkMacOSXBitmapRepFromDrawableRect * * Extract bitmap data from a MacOSX drawable as an NSBitmapImageRep. * * Results: - * Returns an autoreleased NSBitmapRep representing the image of the given - * rectangle of the given drawable. + * Returns an NSBitmapRep representing the image of the given + * rectangle of the given drawable. This object is retained. + * The caller is responsible for releasing it. * * NOTE: The x,y coordinates should be relative to a coordinate system with * origin at the top left, as used by XImage and CGImage, not bottom * left as used by NSView. * @@ -124,11 +118,11 @@ * None * *---------------------------------------------------------------------- */ NSBitmapImageRep* -BitmapRepFromDrawableRect( +TkMacOSXBitmapRepFromDrawableRect( Drawable drawable, int x, int y, unsigned int width, unsigned int height) @@ -138,34 +132,34 @@ CGImageRef cg_image=NULL, sub_cg_image=NULL; NSBitmapImageRep *bitmap_rep=NULL; NSView *view=NULL; if ( mac_drawable->flags & TK_IS_PIXMAP ) { /* - This means that the MacDrawable is functioning as a Tk Pixmap, so its view - field is NULL. + * This means that the MacDrawable is functioning as a + * Tk Pixmap, so its view field is NULL. */ - cg_context = GetCGContextForDrawable(drawable); + cg_context = TkMacOSXGetCGContextForDrawable(drawable); CGRect image_rect = CGRectMake(x, y, width, height); cg_image = CGBitmapContextCreateImage( (CGContextRef) cg_context); sub_cg_image = CGImageCreateWithImageInRect(cg_image, image_rect); if ( sub_cg_image ) { - /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/ bitmap_rep = [NSBitmapImageRep alloc]; [bitmap_rep initWithCGImage:sub_cg_image]; } if ( cg_image ) { CGImageRelease(cg_image); } } else if ( (view = TkMacOSXDrawableView(mac_drawable)) ) { - /* convert top-left coordinates to NSView coordinates */ + /* + * Convert Tk top-left to NSView bottom-left coordinates. + */ int view_height = [view bounds].size.height; NSRect view_rect = NSMakeRect(x + mac_drawable->xOff, - view_height - height - y - mac_drawable->yOff, - width,height); + view_height - height - y - mac_drawable->yOff, + width, height); if ( [view lockFocusIfCanDraw] ) { - /*This can be dealloc'ed prematurely if set for autorelease, causing crashes.*/ bitmap_rep = [NSBitmapImageRep alloc]; bitmap_rep = [bitmap_rep initWithFocusedViewRect:view_rect]; [view unlockFocus]; } else { TkMacOSXDbgMsg("Could not lock focus on view."); @@ -228,20 +222,20 @@ if ( dc.context ) { if (srcDraw->flags & TK_IS_PIXMAP) { img = TkMacOSXCreateCGImageWithDrawable(src); }else if (TkMacOSXDrawableWindow(src)) { - bitmap_rep = BitmapRepFromDrawableRect(src, src_x, src_y, width, height); + bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(src, src_x, src_y, width, height); if ( bitmap_rep ) { img = [bitmap_rep CGImage]; } } else { TkMacOSXDbgMsg("Invalid source drawable - neither window nor pixmap."); } if (img) { - DrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background, + TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, gc->background, CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), CGRectMake(src_x, src_y, width, height), CGRectMake(dest_x, dest_y, width, height)); CFRelease(img); @@ -337,11 +331,11 @@ CGImageRelease(img); CGImageRelease(mask); CGImageRelease(submask); CGImageRelease(subimage); } else { - DrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground, + TkMacOSXDrawCGImage(dst, gc, dc.context, img, gc->foreground, imageBackground, CGRectMake(0, 0, srcDraw->size.width, srcDraw->size.height), CGRectMake(src_x, src_y, width, height), CGRectMake(dest_x, dest_y, width, height)); CGImageRelease(img); } @@ -354,162 +348,10 @@ TkMacOSXRestoreDrawingContext(&dc); } else { /* source drawable is a window, not a Pixmap */ XCopyArea(display, src, dst, gc, src_x, src_y, width, height, dest_x, dest_y); } } - -/* - *---------------------------------------------------------------------- - * - * TkPutImage -- - * - * Copies a subimage from an in-memory image to a rectangle of - * of the specified drawable. - * - * Results: - * None. - * - * Side effects: - * Draws the image on the specified drawable. - * - *---------------------------------------------------------------------- - */ - -int -TkPutImage( - unsigned long *colors, /* Unused on Macintosh. */ - int ncolors, /* Unused on Macintosh. */ - Display* display, /* Display. */ - Drawable d, /* Drawable to place image on. */ - GC gc, /* GC to use. */ - XImage* image, /* Image to place. */ - int src_x, /* Source X & Y. */ - int src_y, - int dest_x, /* Destination X & Y. */ - int dest_y, - unsigned int width, /* Same width & height for both */ - unsigned int height) /* distination and source. */ -{ - TkMacOSXDrawingContext dc; - - display->request++; - if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return BadDrawable; - } - if (dc.context) { - CGImageRef img = CreateCGImageWithXImage(image); - - if (img) { - /* If the XImage has big pixels, rescale the source dimensions.*/ - int pp = image->pixelpower; - DrawCGImage(d, gc, dc.context, img, gc->foreground, gc->background, - CGRectMake(0, 0, image->width<height<bytes_per_line * image->height; - const CGFloat *decode = NULL; - CGBitmapInfo bitmapInfo; - CGDataProviderRef provider = NULL; - char *data = NULL; - CGDataProviderReleaseDataCallback releaseData = ReleaseData; - - if (image->bits_per_pixel == 1) { - /* - * BW image - */ - - /* Reverses the sense of the bits */ - static const CGFloat decodeWB[2] = {1, 0}; - decode = decodeWB; - - bitsPerComponent = 1; - bitsPerPixel = 1; - if (image->bitmap_bit_order != MSBFirst) { - char *srcPtr = image->data + image->xoffset; - char *endPtr = srcPtr + len; - char *destPtr = (data = ckalloc(len)); - - while (srcPtr < endPtr) { - *destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))]; - } - } else { - data = memcpy(ckalloc(len), image->data + image->xoffset, len); - } - if (data) { - provider = CGDataProviderCreateWithData(data, data, len, releaseData); - } - if (provider) { - img = CGImageMaskCreate(image->width, image->height, bitsPerComponent, - bitsPerPixel, image->bytes_per_line, provider, decode, 0); - } - } else if (image->format == ZPixmap && image->bits_per_pixel == 32) { - /* - * Color image - */ - - CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); - - bitsPerComponent = 8; - bitsPerPixel = 32; - bitmapInfo = (image->byte_order == MSBFirst ? - kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little) | - kCGImageAlphaNoneSkipFirst; - data = memcpy(ckalloc(len), image->data + image->xoffset, len); - if (data) { - provider = CGDataProviderCreateWithData(data, data, len, releaseData); - } - if (provider) { - img = CGImageCreate(image->width, image->height, bitsPerComponent, - bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo, - provider, decode, 0, kCGRenderingIntentDefault); - CFRelease(provider); - } - if (colorspace) { - CFRelease(colorspace); - } - } else { - TkMacOSXDbgMsg("Unsupported image type"); - } - return img; -} /* *---------------------------------------------------------------------- * * TkMacOSXCreateCGImageWithDrawable -- @@ -528,11 +370,11 @@ CGImageRef TkMacOSXCreateCGImageWithDrawable( Drawable drawable) { CGImageRef img = NULL; - CGContextRef context = GetCGContextForDrawable(drawable); + CGContextRef context = TkMacOSXGetCGContextForDrawable(drawable); if (context) { img = CGBitmapContextCreateImage(context); } return img; @@ -596,12 +438,14 @@ Tk_Image image, int width, int height) { Pixmap pixmap = Tk_GetPixmap(display, None, width, height, 0); + MacDrawable *macDraw = (MacDrawable *) pixmap; NSImage *nsImage; + macDraw->flags |= TK_USE_XIMAGE_ALPHA; Tk_RedrawImage(image, 0, 0, width, height, pixmap, 0, 0); nsImage = CreateNSImageWithPixmap(pixmap, width, height); Tk_FreePixmap(display, pixmap); return [nsImage autorelease]; @@ -647,11 +491,11 @@ } /* *---------------------------------------------------------------------- * - * GetCGContextForDrawable -- + * TkMacOSXGetCGContextForDrawable -- * * Get CGContext for given Drawable, creating one if necessary. * * Results: * CGContext. @@ -661,14 +505,14 @@ * *---------------------------------------------------------------------- */ CGContextRef -GetCGContextForDrawable( - Drawable d) +TkMacOSXGetCGContextForDrawable( + Drawable drawable) { - MacDrawable *macDraw = (MacDrawable *) d; + MacDrawable *macDraw = (MacDrawable *) drawable; if (macDraw && (macDraw->flags & TK_IS_PIXMAP) && !macDraw->context) { const size_t bitsPerComponent = 8; size_t bitsPerPixel, bytesPerRow, len; CGColorSpaceRef colorspace = NULL; @@ -683,11 +527,11 @@ if (macDraw->flags & TK_IS_BW_PIXMAP) { bitsPerPixel = 8; bitmapInfo = (CGBitmapInfo)kCGImageAlphaOnly; } else { - colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + colorspace = CGColorSpaceCreateDeviceRGB(); bitsPerPixel = 32; bitmapInfo |= kCGImageAlphaPremultipliedFirst; } bytesPerRow = ((size_t) macDraw->size.width * bitsPerPixel + 127) >> 3 & ~15; @@ -709,11 +553,11 @@ } /* *---------------------------------------------------------------------- * - * DrawCGImage -- + * TkMacOSXDrawCGImage -- * * Draw CG image into drawable. * * Results: * None. @@ -723,11 +567,11 @@ * *---------------------------------------------------------------------- */ void -DrawCGImage( +TkMacOSXDrawCGImage( Drawable d, GC gc, CGContextRef context, CGImageRef image, unsigned long imageForeground, @@ -856,10 +700,20 @@ prevx += points[i].x; prevy += points[i].y; CGContextAddLineToPoint(dc.context, prevx, prevy); } } + /* + * In the case of closed polylines, the first and last points + * are the same. We want miter or bevel join be rendered also + * at this point, this needs telling CoreGraphics that the + * path is closed. + */ + if ((points[0].x == points[npoints-1].x) && + (points[0].y == points[npoints-1].y)) { + CGContextClosePath(dc.context); + } CGContextStrokePath(dc.context); } TkMacOSXRestoreDrawingContext(&dc); return Success; } @@ -878,11 +732,11 @@ * Renders a series of unconnected lines. * *---------------------------------------------------------------------- */ -void +int XDrawSegments( Display *display, Drawable d, GC gc, XSegment *segments, @@ -892,11 +746,11 @@ TkMacOSXDrawingContext dc; int i, lw = gc->line_width; display->request++; if (!TkMacOSXSetupDrawingContext(d, gc, 1, &dc)) { - return; + return BadDrawable; } if (dc.context) { double o = (lw % 2) ? .5 : 0; for (i = 0; i < nsegments; i++) { @@ -909,10 +763,11 @@ macWin->yOff + segments[i].y2 + o); CGContextStrokePath(dc.context); } } TkMacOSXRestoreDrawingContext(&dc); + return Success; } /* *---------------------------------------------------------------------- * @@ -1473,11 +1328,11 @@ * * Scroll a rectangle of the specified window and accumulate * a damage region. * * Results: - * Returns 0 if the scroll genereated no additional damage. + * Returns 0 if the scroll generated no additional damage. * Otherwise, sets the region that needs to be repainted after * scrolling and returns 1. * * Side effects: * Scrolls the bits in the window. @@ -1503,78 +1358,43 @@ int result = 0; if ( view ) { /* Get the scroll area in NSView coordinates (origin at bottom left). */ bounds = [view bounds]; - scrollSrc = NSMakeRect( - macDraw->xOff + x, + scrollSrc = NSMakeRect(macDraw->xOff + x, bounds.size.height - height - (macDraw->yOff + y), width, height); scrollDst = NSOffsetRect(scrollSrc, dx, -dy); /* Limit scrolling to the window content area. */ visRect = [view visibleRect]; scrollSrc = NSIntersectionRect(scrollSrc, visRect); scrollDst = NSIntersectionRect(scrollDst, visRect); if ( !NSIsEmptyRect(scrollSrc) && !NSIsEmptyRect(scrollDst) ) { - /* * Mark the difference between source and destination as damaged. * This region is described in NSView coordinates (y=0 at the bottom) * and converted to Tk coordinates later. */ srcRect = CGRectMake(x, y, width, height); dstRect = CGRectOffset(srcRect, dx, dy); - /* Expand the rectangles slightly to avoid degeneracies. */ - srcRect.origin.y -= 1; - srcRect.size.height += 2; - dstRect.origin.y += 1; - dstRect.size.height -= 2; - /* Compute the damage. */ dmgRgn = HIShapeCreateMutableWithRect(&srcRect); extraRgn = HIShapeCreateWithRect(&dstRect); ChkErr(HIShapeDifference, dmgRgn, extraRgn, (HIMutableShapeRef) dmgRgn); result = HIShapeIsEmpty(dmgRgn) ? 0 : 1; - /* Convert to Tk coordinates. */ + /* Convert to Tk coordinates, offset by the window origin. */ TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); if (extraRgn) { CFRelease(extraRgn); } /* Scroll the rectangle. */ [view scrollRect:scrollSrc by:NSMakeSize(dx, -dy)]; - - /* Shift the Tk children which meet the source rectangle. */ - TkWindow *winPtr = (TkWindow *)tkwin; - TkWindow *childPtr; - CGRect childBounds; - for (childPtr = winPtr->childList; childPtr != NULL; childPtr = childPtr->nextPtr) { - if (Tk_IsMapped(childPtr) && !Tk_IsTopLevel(childPtr)) { - TkMacOSXWinCGBounds(childPtr, &childBounds); - if (CGRectIntersectsRect(srcRect, childBounds)) { - MacDrawable *macChild = childPtr->privatePtr; - if (macChild) { - macChild->yOff += dy; - macChild->xOff += dx; - childPtr->changes.y = macChild->yOff; - childPtr->changes.x = macChild->xOff; - } - } - } - } - - /* Queue up Expose events for the damage region. */ - int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); - [view generateExposeEvents:dmgRgn childrenOnly:1]; - Tcl_SetServiceMode(oldMode); - - /* Belt and suspenders: make the AppKit request a redraw - when it gets control again. */ } } else { dmgRgn = HIShapeCreateEmpty(); TkMacOSXSetWithNativeRegion(damageRgn, dmgRgn); } @@ -1647,11 +1467,11 @@ } if (dontDraw) { goto end; } if (useCG) { - dc.context = GetCGContextForDrawable(d); + dc.context = TkMacOSXGetCGContextForDrawable(d); } if (!dc.context || !(macDraw->flags & TK_IS_PIXMAP)) { isWin = (TkMacOSXDrawableWindow(d) != nil); } if (dc.context) { @@ -1666,11 +1486,10 @@ dontDraw = ![view canDraw]; } if (dontDraw) { goto end; } - [[view window] disableFlushWindow]; dc.view = view; dc.context = [[NSGraphicsContext currentContext] graphicsPort]; dc.portBounds = NSRectToCGRect([view bounds]); if (dc.clipRgn) { clipBounds = CGContextGetClipBoundingBox(dc.context); @@ -1692,17 +1511,17 @@ CGContextSaveGState(dc.context); } CGContextSetTextDrawingMode(dc.context, kCGTextFill); CGContextConcatCTM(dc.context, t); if (dc.clipRgn) { - #ifdef TK_MAC_DEBUG_DRAWING +#ifdef TK_MAC_DEBUG_DRAWING CGContextSaveGState(dc.context); ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); CGContextSetRGBFillColor(dc.context, 1.0, 0.0, 0.0, 0.1); CGContextEOFillPath(dc.context); CGContextRestoreGState(dc.context); - #endif /* TK_MAC_DEBUG_DRAWING */ +#endif /* TK_MAC_DEBUG_DRAWING */ CGRect r; if (!HIShapeIsRectangular(dc.clipRgn) || !CGRectContainsRect( *HIShapeGetBounds(dc.clipRgn, &r), CGRectApplyAffineTransform(clipBounds, t))) { ChkErr(HIShapeReplacePathInCGContext, dc.clipRgn, dc.context); @@ -1793,11 +1612,10 @@ TkMacOSXDrawingContext *dcPtr) { if (dcPtr->context) { CGContextSynchronize(dcPtr->context); [[dcPtr->view window] setViewsNeedDisplay:YES]; - [[dcPtr->view window] enableFlushWindow]; if (dcPtr->focusLocked) { [dcPtr->view unlockFocus]; } else { CGContextRestoreGState(dcPtr->context); } Index: macosx/tkMacOSXEmbed.c ================================================================== --- macosx/tkMacOSXEmbed.c +++ macosx/tkMacOSXEmbed.c @@ -191,11 +191,11 @@ */ int TkpScanWindowId( Tcl_Interp *interp, - CONST char * string, + const char * string, Window *idPtr) { int code; Tcl_Obj obj; @@ -625,11 +625,11 @@ containerPtr = containerPtr->nextPtr) { Tcl_DStringStartSublist(&dString); if (containerPtr->parent == None) { Tcl_DStringAppendElement(&dString, ""); } else if (all) { - sprintf(buffer, "0x%x", (int) containerPtr->parent); + sprintf(buffer, "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->parent); Tcl_DStringAppendElement(&dString, buffer); } else { Tcl_DStringAppendElement(&dString, "XXX"); } if (containerPtr->parentPtr == NULL) { @@ -639,11 +639,11 @@ containerPtr->parentPtr->pathName); } if (containerPtr->embedded == None) { Tcl_DStringAppendElement(&dString, ""); } else if (all) { - sprintf(buffer, "0x%x", (int) containerPtr->embedded); + sprintf(buffer, "0x%" TCL_Z_MODIFIER "x", (size_t) containerPtr->embedded); Tcl_DStringAppendElement(&dString, buffer); } else { Tcl_DStringAppendElement(&dString, "XXX"); } if (containerPtr->embeddedPtr == NULL) { @@ -796,10 +796,17 @@ XEvent *eventPtr) /* ResizeRequest event. */ { TkWindow *winPtr = clientData; Container *containerPtr; Tk_ErrorHandler errHandler; + + if (!firstContainerPtr) { + /* + * When the interpreter is being dismantled this can be nil. + */ + return; + } /* * Ignore any X protocol errors that happen in this procedure (almost any * operation could fail, for example, if the embedded application has * deleted its window). Index: macosx/tkMacOSXEvent.c ================================================================== --- macosx/tkMacOSXEvent.c +++ macosx/tkMacOSXEvent.c @@ -12,10 +12,11 @@ */ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" #pragma mark TKApplication(TKEvent) enum { NSWindowWillMoveEventType = 20 @@ -86,19 +87,17 @@ win = [theEvent window]; break; } case NSCursorUpdate: break; -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 case NSEventTypeGesture: case NSEventTypeMagnify: case NSEventTypeRotate: case NSEventTypeSwipe: case NSEventTypeBeginGesture: case NSEventTypeEndGesture: break; -#endif #endif default: break; /* return theEvent */ } @@ -130,11 +129,11 @@ { NSArray *macWindows = [NSApp orderedWindows]; for (NSWindow *w in macWindows) { if (TkMacOSXGetXWindow(w)) { - [w flushWindow]; + [w displayIfNeeded]; } } } Index: macosx/tkMacOSXFont.c ================================================================== --- macosx/tkMacOSXFont.c +++ macosx/tkMacOSXFont.c @@ -257,11 +257,11 @@ } else { TkInitFontAttributes(faPtr); } fontPtr->nsFont = nsFont; // some don't like antialiasing on fixed-width even if bigger than limit -// dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10; + // dontAA = [nsFont isFixedPitch] && fontPtr->font.fa.size <= 10; if (antialiasedTextEnabled >= 0/* || dontAA*/) { renderingMode = (antialiasedTextEnabled == 0/* || dontAA*/) ? NSFontIntegerAdvancementsRenderingMode : NSFontAntialiasedRenderingMode; } @@ -513,11 +513,11 @@ Tk_Window tkwin, /* For display where font will be used. */ const TkFontAttributes *faPtr) /* Set of attributes to match. */ { MacFont *fontPtr; - int points = TkFontGetPoints(tkwin, faPtr->size); + int points = (int)(TkFontGetPoints(tkwin, faPtr->size) + 0.5); NSFontTraitMask traits = GetNSFontTraitsFromTkFontAttributes(faPtr); NSInteger weight = (faPtr->weight == TK_FW_BOLD ? 9 : 5); NSFont *nsFont; nsFont = FindNSFont(faPtr->family, traits, weight, points, 0); @@ -670,18 +670,18 @@ void TkpGetFontAttrsForChar( Tk_Window tkwin, /* Window on the font's display */ Tk_Font tkfont, /* Font to query */ - Tcl_UniChar c, /* Character of interest */ + int c, /* Character of interest */ TkFontAttributes* faPtr) /* Output: Font attributes */ { MacFont *fontPtr = (MacFont *) tkfont; NSFont *nsFont = fontPtr->nsFont; *faPtr = fontPtr->font.fa; if (nsFont && ![[nsFont coveredCharacterSet] characterIsMember:c]) { - UTF16Char ch = c; + UTF16Char ch = (UTF16Char) c; nsFont = [nsFont bestMatchingFontForCharacters:&ch length:1 attributes:nil actualCoveredLength:NULL]; if (nsFont) { GetTkFontAttributesForNSFont(nsFont, faPtr); @@ -817,19 +817,10 @@ rangeStart + rangeLength > numBytes || (maxLength == 0 && !(flags & TK_AT_LEAST_ONE))) { *lengthPtr = 0; return 0; } -#if 0 - /* Back-compatibility with ATSUI renderer, appears not to be needed */ - if (rangeStart == 0 && maxLength == 1 && (flags & TK_ISOLATE_END) && - !(flags & TK_AT_LEAST_ONE)) { - length = 0; - fit = 0; - goto done; - } -#endif if (maxLength > 32767) { maxLength = 32767; } string = [[NSString alloc] initWithBytesNoCopy:(void*)source length:numBytes encoding:NSUTF8StringEncoding freeWhenDone:NO]; @@ -858,10 +849,14 @@ CFRelease(line); } else { double maxWidth = maxLength + offset; NSCharacterSet *cs; + /* + * Get a line breakpoint in the source string. + */ + index = start; if (flags & TK_WHOLE_WORDS) { index = CTTypesetterSuggestLineBreak(typesetter, start, maxWidth); if (index <= start && (flags & TK_AT_LEAST_ONE)) { flags &= ~TK_WHOLE_WORDS; @@ -868,19 +863,47 @@ } } if (index <= start && !(flags & TK_WHOLE_WORDS)) { index = CTTypesetterSuggestClusterBreak(typesetter, start, maxWidth); } - cs = (index < len || (flags & TK_WHOLE_WORDS)) ? + + /* + * Trim right whitespace/lineending characters. + */ + + cs = (index <= len && (flags & TK_WHOLE_WORDS)) ? whitespaceCharacterSet : lineendingCharacterSet; while (index > start && [cs characterIsMember:[string characterAtIndex:(index - 1)]]) { index--; } + + /* + * If there is no line breakpoint in the source string between + * its start and the index position that fits in maxWidth, then + * CTTypesetterSuggestLineBreak() returns that very last index. + * However if the TK_WHOLE_WORDS flag is set, we want to break + * at a word boundary. In this situation, unless TK_AT_LEAST_ONE + * is set, we must report that zero chars actually fit (in other + * words the smallest word of the source string is still larger + * than maxWidth). + */ + + if ((index >= start) && (index < len) && + (flags & TK_WHOLE_WORDS) && !(flags & TK_AT_LEAST_ONE) && + ![cs characterIsMember:[string characterAtIndex:index]]) { + index = start; + } + if (index <= start && (flags & TK_AT_LEAST_ONE)) { index = start + 1; } + + /* + * Now measure the string width in pixels. + */ + if (index > 0) { range.length = index; line = CTTypesetterCreateLine(typesetter, range); width = CTLineGetTypographicBounds(line, NULL, NULL, NULL); CFRelease(line); @@ -919,11 +942,10 @@ flags & TK_PARTIAL_OK ? "partialOk " : "", flags & TK_WHOLE_WORDS ? "wholeWords " : "", flags & TK_AT_LEAST_ONE ? "atLeastOne " : "", flags & TK_ISOLATE_END ? "isolateEnd " : "", length, fit); -//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); #endif *lengthPtr = length; return fit; } Index: macosx/tkMacOSXHLEvents.c ================================================================== --- macosx/tkMacOSXHLEvents.c +++ macosx/tkMacOSXHLEvents.c @@ -34,11 +34,11 @@ */ static void tkMacOSXProcessFiles(NSAppleEventDescriptor* event, NSAppleEventDescriptor* replyEvent, Tcl_Interp *interp, - char* procedure); + const char* procedure); static int MissedAnyParameters(const AppleEvent *theEvent); static int ReallyKillMe(Tcl_Event *eventPtr, int flags); #pragma mark TKApplication(TKHLEvents) @@ -275,13 +275,13 @@ static void tkMacOSXProcessFiles( NSAppleEventDescriptor* event, NSAppleEventDescriptor* replyEvent, Tcl_Interp *interp, - char* procedure) + const char* procedure) { - Tcl_Encoding utf8 = Tcl_GetEncoding(NULL, "utf-8"); + Tcl_Encoding utf8; const AEDesc *fileSpecDesc = nil; AEDesc contents; char URLString[1 + URL_MAX_LENGTH]; NSURL *fileURL; DescType type; @@ -329,10 +329,11 @@ * paths contained in the AppleEvent as arguments. */ Tcl_DStringInit(&command); Tcl_DStringAppend(&command, procedure, -1); + utf8 = Tcl_GetEncoding(NULL, "utf-8"); for (index = 1; index <= count; index++) { if (noErr != AEGetNthPtr(fileSpecDesc, index, typeFileURL, &keyword, &type, (Ptr) URLString, URL_MAX_LENGTH, &actual)) { continue; @@ -347,10 +348,12 @@ } Tcl_ExternalToUtfDString(utf8, [[fileURL path] UTF8String], -1, &pathName); Tcl_DStringAppendElement(&command, Tcl_DStringValue(&pathName)); Tcl_DStringFree(&pathName); } + + Tcl_FreeEncoding(utf8); AEDisposeDesc(&contents); /* * Handle the event by evaluating the Tcl expression we constructed. */ @@ -359,11 +362,10 @@ Tcl_DStringLength(&command), TCL_EVAL_GLOBAL); if (code != TCL_OK) { Tcl_BackgroundException(interp, code); } Tcl_DStringFree(&command); - return; } /* *---------------------------------------------------------------------- * ADDED macosx/tkMacOSXImage.c Index: macosx/tkMacOSXImage.c ================================================================== --- /dev/null +++ macosx/tkMacOSXImage.c @@ -0,0 +1,580 @@ +/* + * tkMacOSXImage.c -- + * + * The code in this file provides an interface for XImages, + * + * Copyright (c) 1995-1997 Sun Microsystems, Inc. + * Copyright 2001-2009, Apple Inc. + * Copyright (c) 2005-2009 Daniel A. Steffen + * Copyright 2017 Marc Culler. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + */ + +#include "tkMacOSXPrivate.h" +#include "xbytes.h" + +#pragma mark XImage handling + +int +_XInitImageFuncPtrs( + XImage *image) +{ + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * TkMacOSXCreateCGImageWithXImage -- + * + * Create CGImage from XImage, copying the image data. + * + * Results: + * CGImage, release after use. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static void ReleaseData(void *info, const void *data, size_t size) { + ckfree(info); +} + +CGImageRef +TkMacOSXCreateCGImageWithXImage( + XImage *image, + int use_ximage_alpha) +{ + CGImageRef img = NULL; + size_t bitsPerComponent, bitsPerPixel; + size_t len = image->bytes_per_line * image->height; + const CGFloat *decode = NULL; + CGBitmapInfo bitmapInfo; + CGDataProviderRef provider = NULL; + char *data = NULL; + CGDataProviderReleaseDataCallback releaseData = ReleaseData; + + if (image->bits_per_pixel == 1) { + /* + * BW image + */ + + /* Reverses the sense of the bits */ + static const CGFloat decodeWB[2] = {1, 0}; + decode = decodeWB; + + bitsPerComponent = 1; + bitsPerPixel = 1; + if (image->bitmap_bit_order != MSBFirst) { + char *srcPtr = image->data + image->xoffset; + char *endPtr = srcPtr + len; + char *destPtr = (data = ckalloc(len)); + + while (srcPtr < endPtr) { + *destPtr++ = xBitReverseTable[(unsigned char)(*(srcPtr++))]; + } + } else { + data = memcpy(ckalloc(len), image->data + image->xoffset, len); + } + if (data) { + provider = CGDataProviderCreateWithData(data, data, len, releaseData); + } + if (provider) { + img = CGImageMaskCreate(image->width, image->height, bitsPerComponent, + bitsPerPixel, image->bytes_per_line, provider, decode, 0); + } + } else if (image->format == ZPixmap && image->bits_per_pixel == 32) { + /* + * Color image + */ + + CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); + + bitsPerComponent = 8; + bitsPerPixel = 32; + bitmapInfo = (image->byte_order == MSBFirst ? + kCGBitmapByteOrder32Big : kCGBitmapByteOrder32Little); + if (use_ximage_alpha) { + bitmapInfo |= kCGImageAlphaPremultipliedFirst; + } else { + bitmapInfo |= kCGImageAlphaNoneSkipFirst; + } + data = memcpy(ckalloc(len), image->data + image->xoffset, len); + if (data) { + provider = CGDataProviderCreateWithData(data, data, len, releaseData); + } + if (provider) { + img = CGImageCreate(image->width, image->height, bitsPerComponent, + bitsPerPixel, image->bytes_per_line, colorspace, bitmapInfo, + provider, decode, 0, kCGRenderingIntentDefault); + CFRelease(provider); + } + if (colorspace) { + CFRelease(colorspace); + } + } else { + TkMacOSXDbgMsg("Unsupported image type"); + } + return img; +} + + +/* + *---------------------------------------------------------------------- + * + * XGetImage -- + * + * This function copies data from a pixmap or window into an XImage. + * + * Results: + * Returns a newly allocated XImage containing the data from the given + * rectangle of the given drawable, or NULL if the XImage could not be + * constructed. NOTE: If we are copying from a window on a Retina + * display, the dimensions of the XImage will be 2*width x 2*height. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ +struct pixel_fmt {int r; int g; int b; int a;}; +static struct pixel_fmt bgra = {2, 1, 0, 3}; +static struct pixel_fmt abgr = {3, 2, 1, 0}; + +XImage * +XGetImage( + Display *display, + Drawable drawable, + int x, + int y, + unsigned int width, + unsigned int height, + unsigned long plane_mask, + int format) +{ + NSBitmapImageRep* bitmap_rep = NULL; + NSUInteger bitmap_fmt = 0; + XImage* imagePtr = NULL; + char* bitmap = NULL; + char R, G, B, A; + int depth = 32, offset = 0, bitmap_pad = 0; + unsigned int bytes_per_row, size, row, n, m; + unsigned int scalefactor=1, scaled_height=height, scaled_width=width; + NSWindow *win = TkMacOSXDrawableWindow(drawable); + MacDrawable *macDraw = ((MacDrawable*)drawable); + static enum {unknown, no, yes} has_retina = unknown; + + if (win && has_retina == unknown) { +#ifdef __clang__ + has_retina = [win respondsToSelector:@selector(backingScaleFactor)]? + yes : no; +#else + has_retina = no; +#endif + } + + if (has_retina == yes) { + /* + * We only allow scale factors 1 or 2, as Apple currently does. + */ +#ifdef __clang__ + scalefactor = [win backingScaleFactor] == 2.0 ? 2 : 1; +#endif + scaled_height *= scalefactor; + scaled_width *= scalefactor; + } + + if (format == ZPixmap) { + if (width == 0 || height == 0) { + return NULL; + } + bitmap_rep = TkMacOSXBitmapRepFromDrawableRect(drawable, + x, y, width, height); + if (!bitmap_rep) { + TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep"); + return NULL; + } + bitmap_fmt = [bitmap_rep bitmapFormat]; + size = [bitmap_rep bytesPerPlane]; + bytes_per_row = [bitmap_rep bytesPerRow]; + bitmap = ckalloc(size); + if (!bitmap || + (bitmap_fmt != 0 && bitmap_fmt != 1) || + [bitmap_rep samplesPerPixel] != 4 || + [bitmap_rep isPlanar] != 0 || + bytes_per_row != 4 * scaled_width || + size != bytes_per_row*scaled_height ) { + TkMacOSXDbgMsg("XGetImage: Unrecognized bitmap format"); + CFRelease(bitmap_rep); + return NULL; + } + + if (macDraw->flags & TK_USE_XIMAGE_ALPHA) { + /* + * When called by TkImgPhotoDisplay we are being asked to return a + * background image to be blended with the photoimage using its + * alpha channel, if it has one. Returning a black pixmap here + * makes TkImgPhotoDisplay create an XImage with a premultiplied + * alpha channel, as favored by Apple. When TkImgPhotoDisplay + * passes this XImage to TkPutImage, targeting a pixmap, it creates + * an image with correct transparency. This is used, for example, + * when creating an iconphoto or a menu image from a PNG + * photoimage. + */ + bzero(bitmap, size); + } else { + memcpy(bitmap, (char *)[bitmap_rep bitmapData], size); + } + CFRelease(bitmap_rep); + + /* + * When Apple extracts a bitmap from an NSView, it may be in + * either BGRA or ABGR format. For an XImage we need RGBA. + */ + struct pixel_fmt pixel = bitmap_fmt == 0 ? bgra : abgr; + + for (row=0, n=0; rowpixelpower = 1; + } + } else { + /* + * There are some calls to XGetImage in the generic Tk + * code which pass an XYPixmap rather than a ZPixmap. + * XYPixmaps should be handled here. + */ + TkMacOSXDbgMsg("XGetImage does not handle XYPixmaps at the moment."); + } + return imagePtr; +} + +/* + *---------------------------------------------------------------------- + * + * DestroyImage -- + * + * Destroys storage associated with an image. + * + * Results: + * None. + * + * Side effects: + * Deallocates the image. + * + *---------------------------------------------------------------------- + */ + +static int +DestroyImage( + XImage *image) +{ + if (image) { + if (image->data) { + ckfree(image->data); + } + ckfree(image); + } + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * ImageGetPixel -- + * + * Get a single pixel from an image. + * + * Results: + * Returns the 32 bit pixel value. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static unsigned long +ImageGetPixel( + XImage *image, + int x, + int y) +{ + unsigned char r = 0, g = 0, b = 0; + + if (image && image->data) { + unsigned char *srcPtr = ((unsigned char*) image->data) + + (y * image->bytes_per_line) + + (((image->xoffset + x) * image->bits_per_pixel) / NBBY); + + switch (image->bits_per_pixel) { + case 32: { + r = (*((unsigned int*) srcPtr) >> 16) & 0xff; + g = (*((unsigned int*) srcPtr) >> 8) & 0xff; + b = (*((unsigned int*) srcPtr) ) & 0xff; + /*if (image->byte_order == LSBFirst) { + r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0]; + } else { + r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3]; + }*/ + break; + } + case 16: + r = (*((unsigned short*) srcPtr) >> 7) & 0xf8; + g = (*((unsigned short*) srcPtr) >> 2) & 0xf8; + b = (*((unsigned short*) srcPtr) << 3) & 0xf8; + break; + case 8: + r = (*srcPtr << 2) & 0xc0; + g = (*srcPtr << 4) & 0xc0; + b = (*srcPtr << 6) & 0xc0; + r |= r >> 2 | r >> 4 | r >> 6; + g |= g >> 2 | g >> 4 | g >> 6; + b |= b >> 2 | b >> 4 | b >> 6; + break; + case 4: { + unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4); + r = (c & 0x04) ? 0xff : 0; + g = (c & 0x02) ? 0xff : 0; + b = (c & 0x01) ? 0xff : 0; + break; + } + case 1: + r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0; + break; + } + } + return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b; +} + +/* + *---------------------------------------------------------------------- + * + * ImagePutPixel -- + * + * Set a single pixel in an image. + * + * Results: + * None. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +static int +ImagePutPixel( + XImage *image, + int x, + int y, + unsigned long pixel) +{ + if (image && image->data) { + unsigned char *dstPtr = ((unsigned char*) image->data) + + (y * image->bytes_per_line) + + (((image->xoffset + x) * image->bits_per_pixel) / NBBY); + if (image->bits_per_pixel == 32) { + *((unsigned int*) dstPtr) = pixel; + } else { + unsigned char r = ((pixel & image->red_mask) >> 16) & 0xff; + unsigned char g = ((pixel & image->green_mask) >> 8) & 0xff; + unsigned char b = ((pixel & image->blue_mask) ) & 0xff; + switch (image->bits_per_pixel) { + case 16: + *((unsigned short*) dstPtr) = ((r & 0xf8) << 7) | + ((g & 0xf8) << 2) | ((b & 0xf8) >> 3); + break; + case 8: + *dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) | + ((b & 0xc0) >> 6); + break; + case 4: { + unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) | + ((b & 0x80) >> 7); + *dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) : + ((*dstPtr & 0x0f) | ((c << 4) & 0xf0)); + break; + } + case 1: + *dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) : + (*dstPtr & ~(0x80 >> (x % 8))); + break; + } + } + } + return 0; +} + +/* + *---------------------------------------------------------------------- + * + * XCreateImage -- + * + * Allocates storage for a new XImage. + * + * Results: + * Returns a newly allocated XImage. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +XImage * +XCreateImage( + Display* display, + Visual* visual, + unsigned int depth, + int format, + int offset, + char* data, + unsigned int width, + unsigned int height, + int bitmap_pad, + int bytes_per_line) +{ + XImage *ximage; + display->request++; + ximage = ckalloc(sizeof(XImage)); + + ximage->height = height; + ximage->width = width; + ximage->depth = depth; + ximage->xoffset = offset; + ximage->format = format; + ximage->data = data; + ximage->obdata = NULL; + /* The default pixelpower is 0. This must be explicitly set to 1 in the + * case of an XImage extracted from a Retina display. + */ + ximage->pixelpower = 0; + + if (format == ZPixmap) { + ximage->bits_per_pixel = 32; + ximage->bitmap_unit = 32; + } else { + ximage->bits_per_pixel = 1; + ximage->bitmap_unit = 8; + } + if (bitmap_pad) { + ximage->bitmap_pad = bitmap_pad; + } else { + /* Use 16 byte alignment for best Quartz perfomance */ + ximage->bitmap_pad = 128; + } + if (bytes_per_line) { + ximage->bytes_per_line = bytes_per_line; + } else { + ximage->bytes_per_line = ((width * ximage->bits_per_pixel + + (ximage->bitmap_pad - 1)) >> 3) & + ~((ximage->bitmap_pad >> 3) - 1); + } +#ifdef WORDS_BIGENDIAN + ximage->byte_order = MSBFirst; + ximage->bitmap_bit_order = MSBFirst; +#else + ximage->byte_order = LSBFirst; + ximage->bitmap_bit_order = LSBFirst; +#endif + ximage->red_mask = 0x00FF0000; + ximage->green_mask = 0x0000FF00; + ximage->blue_mask = 0x000000FF; + ximage->f.create_image = NULL; + ximage->f.destroy_image = DestroyImage; + ximage->f.get_pixel = ImageGetPixel; + ximage->f.put_pixel = ImagePutPixel; + ximage->f.sub_image = NULL; + ximage->f.add_pixel = NULL; + + return ximage; +} + +/* + *---------------------------------------------------------------------- + * + * TkPutImage -- + * + * Copies a subimage from an in-memory image to a rectangle of + * of the specified drawable. + * + * Results: + * None. + * + * Side effects: + * Draws the image on the specified drawable. + * + *---------------------------------------------------------------------- + */ + +int +TkPutImage( + unsigned long *colors, /* Unused on Macintosh. */ + int ncolors, /* Unused on Macintosh. */ + Display* display, /* Display. */ + Drawable drawable, /* Drawable to place image on. */ + GC gc, /* GC to use. */ + XImage* image, /* Image to place. */ + int src_x, /* Source X & Y. */ + int src_y, + int dest_x, /* Destination X & Y. */ + int dest_y, + unsigned int width, /* Same width & height for both */ + unsigned int height) /* distination and source. */ +{ + TkMacOSXDrawingContext dc; + MacDrawable *macDraw = ((MacDrawable*)drawable); + + display->request++; + if (!TkMacOSXSetupDrawingContext(drawable, gc, 1, &dc)) { + return BadDrawable; + } + if (dc.context) { + CGImageRef img = TkMacOSXCreateCGImageWithXImage(image, + macDraw->flags & TK_USE_XIMAGE_ALPHA); + if (img) { + /* If the XImage has big pixels, rescale the source dimensions.*/ + int pp = image->pixelpower; + TkMacOSXDrawCGImage(drawable, gc, dc.context, + img, gc->foreground, gc->background, + CGRectMake(0, 0, image->width<height< + * Copyright (c) 2017 Marc Culler * * See the file "license.terms" for information on usage and redistribution of * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ @@ -30,46 +31,53 @@ long tkMacOSXMacOSXVersion = 0; #pragma mark TKApplication(TKInit) -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -#define NSTextInputContextKeyboardSelectionDidChangeNotification @"NSTextInputContextKeyboardSelectionDidChangeNotification" -static void keyboardChanged(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo) { - [[NSNotificationCenter defaultCenter] postNotificationName:NSTextInputContextKeyboardSelectionDidChangeNotification object:nil userInfo:nil]; -} -#endif - @interface TKApplication(TKKeyboard) - (void) keyboardChanged: (NSNotification *) notification; @end -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 #define TKApplication_NSApplicationDelegate -#else -#define TKApplication_NSApplicationDelegate -#endif @interface TKApplication(TKWindowEvent) TKApplication_NSApplicationDelegate - (void) _setupWindowNotifications; @end @interface TKApplication(TKMenus) - (void) _setupMenus; @end @implementation TKApplication -@synthesize poolProtected = _poolProtected; +@synthesize poolLock = _poolLock; @end +/* + * #define this to see a message on stderr whenever _resetAutoreleasePool is + * called while the pool is locked. + */ +#undef DEBUG_LOCK + @implementation TKApplication(TKInit) - (void) _resetAutoreleasePool { - if(![self poolProtected]) { + if([self poolLock] == 0) { [_mainPool drain]; _mainPool = [NSAutoreleasePool new]; + } else { +#ifdef DEBUG_LOCK + fprintf(stderr, "Pool is locked with count %d!!!!\n", [self poolLock]); +#endif } } +- (void) _lockAutoreleasePool +{ + [self setPoolLock:[self poolLock] + 1]; +} +- (void) _unlockAutoreleasePool +{ + [self setPoolLock:[self poolLock] - 1]; +} #ifdef TK_MAC_DEBUG_NOTIFICATIONS - (void) _postedNotification: (NSNotification *) notification { TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); } @@ -85,37 +93,92 @@ observe(NSApplicationDidUnhideNotification, applicationShowHide:); observe(NSApplicationDidHideNotification, applicationShowHide:); observe(NSApplicationDidChangeScreenParametersNotification, displayChanged:); observe(NSTextInputContextKeyboardSelectionDidChangeNotification, keyboardChanged:); #undef observe -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - CFNotificationCenterAddObserver(CFNotificationCenterGetDistributedCenter(), NULL, &keyboardChanged, kTISNotifySelectedKeyboardInputSourceChanged, NULL, CFNotificationSuspensionBehaviorCoalesce); -#endif -} - -- (void) _setupEventLoop -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [self finishLaunching]; - [self setWindowsNeedUpdate:YES]; - [pool drain]; -} - -- (void) _setup: (Tcl_Interp *) interp -{ - _eventInterp = interp; - _mainPool = [NSAutoreleasePool new]; - [NSApp setPoolProtected:NO]; - _defaultMainMenu = nil; - [self _setupMenus]; - [self setDelegate:self]; +} + +-(void)applicationWillFinishLaunching:(NSNotification *)aNotification +{ + + /* + * Initialize notifications. + */ #ifdef TK_MAC_DEBUG_NOTIFICATIONS [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_postedNotification:) name:nil object:nil]; #endif [self _setupWindowNotifications]; [self _setupApplicationNotifications]; + + /* + * Construct the menu bar. + */ + _defaultMainMenu = nil; + [self _setupMenus]; + + /* + * Initialize event processing. + */ + TkMacOSXInitAppleEvents(_eventInterp); + + /* + * Initialize the graphics context. + */ + TkMacOSXUseAntialiasedText(_eventInterp, -1); + TkMacOSXInitCGDrawing(_eventInterp, TRUE, 0); +} + +-(void)applicationDidFinishLaunching:(NSNotification *)notification +{ + /* + * It is not safe to force activation of the NSApp until this + * method is called. Activating too early can cause the menu + * bar to be unresponsive. + */ + [NSApp activateIgnoringOtherApps: YES]; +} + +- (void) _setup: (Tcl_Interp *) interp +{ + /* + * Remember our interpreter. + */ + _eventInterp = interp; + + /* + * Install the global autoreleasePool. + */ + _mainPool = [NSAutoreleasePool new]; + [NSApp setPoolLock:0]; + + /* + * Be our own delegate. + */ + [self setDelegate:self]; + + /* + * Make sure we are allowed to open windows. + */ + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + + /* + * If no icon has been set from an Info.plist file, use the Wish icon from + * the Tk framework. + */ + NSString *iconFile = [[NSBundle mainBundle] objectForInfoDictionaryKey: + @"CFBundleIconFile"]; + if (!iconFile) { + NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"]; + if (path) { + NSImage *image = [[NSImage alloc] initWithContentsOfFile:path]; + if (image) { + [NSApp setApplicationIconImage:image]; + [image release]; + } + } + } } - (NSString *) tkFrameworkImagePath: (NSString *) image { NSString *path = nil; @@ -161,42 +224,10 @@ #pragma mark - /* *---------------------------------------------------------------------- * - * DoWindowActivate -- - * - * Idle handler that sets the application icon to the generic Tk icon. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static void -SetApplicationIcon( - ClientData clientData) -{ - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - NSString *path = [NSApp tkFrameworkImagePath:@"Tk.icns"]; - if (path) { - NSImage *image = [[NSImage alloc] initWithContentsOfFile:path]; - if (image) { - [NSApp setApplicationIconImage:image]; - [image release]; - } - } - [pool drain]; -} - -/* - *---------------------------------------------------------------------- - * * TkpInit -- * * Performs Mac-specific interpreter initialization related to the * tk_library variable. * @@ -221,24 +252,21 @@ * don't want to do the following initialization multiple times we protect * against doing it more than once. */ if (!initialized) { - int bundledExecutable = 0; - CFBundleRef bundleRef; - CFURLRef bundleUrl = NULL; struct utsname name; struct stat st; initialized = 1; /* * Initialize/check OS version variable for runtime checks. */ -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1050 -# error Mac OS X 10.5 required +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 +# error Mac OS X 10.6 required #endif if (!uname(&name)) { tkMacOSXMacOSXVersion = (strtod(name.release, NULL) + 96) * 10; } @@ -261,92 +289,16 @@ */ if (Tcl_MacOSXOpenVersionedBundleResources(interp, "com.tcltk.tklibrary", TK_FRAMEWORK_VERSION, 0, PATH_MAX, tkLibPath) != TCL_OK) { + # if 0 /* This is not really an error. Wish still runs fine. */ TkMacOSXDbgMsg("Tcl_MacOSXOpenVersionedBundleResources failed"); + # endif } #endif - { - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [[NSUserDefaults standardUserDefaults] registerDefaults: - [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithBool:YES], - @"_NSCanWrapButtonTitles", - [NSNumber numberWithInt:-1], - @"NSStringDrawingTypesetterBehavior", - nil]]; - [TKApplication sharedApplication]; - [pool drain]; - [NSApp _setup:interp]; - } - - /* Check whether we are a bundled executable: */ - bundleRef = CFBundleGetMainBundle(); - if (bundleRef) { - bundleUrl = CFBundleCopyBundleURL(bundleRef); - } - if (bundleUrl) { - /* - * A bundled executable is two levels down from its main bundle - * directory (e.g. Wish.app/Contents/MacOS/Wish), whereas an - * unbundled executable's main bundle directory is just the - * directory containing the executable. So to check whether we are - * bundled, we delete the last three path components of the - * executable's url and compare the resulting url with the main - * bundle url. - */ - - int j = 3; - CFURLRef url = CFBundleCopyExecutableURL(bundleRef); - - while (url && j--) { - CFURLRef parent = - CFURLCreateCopyDeletingLastPathComponent(NULL, url); - - CFRelease(url); - url = parent; - } - if (url) { - bundledExecutable = CFEqual(bundleUrl, url); - CFRelease(url); - } - CFRelease(bundleUrl); - } - - if (!bundledExecutable) { - /* - * If we are loaded into an executable that is not a bundled - * application, the window server does not let us come to the - * foreground. For such an executable, notify the window server - * that we are now a full GUI application. - */ - - OSStatus err = procNotFound; - ProcessSerialNumber psn = { 0, kCurrentProcess }; - - err = ChkErr(TransformProcessType, &psn, - kProcessTransformToForegroundApplication); - - /* - * Set application icon to generic Tk icon, do it at idle time - * instead of now to ensure tk_library is setup. - */ - - Tcl_DoWhenIdle(SetApplicationIcon, NULL); - } - - { - NSAutoreleasePool *pool = [NSAutoreleasePool new]; - [NSApp _setupEventLoop]; - TkMacOSXInitAppleEvents(interp); - TkMacOSXUseAntialiasedText(interp, -1); - TkMacOSXInitCGDrawing(interp, TRUE, 0); - [pool drain]; - } - /* * FIXME: Close stdin & stdout for remote debugging otherwise we will * fight with gdb for stdin & stdout */ @@ -353,10 +305,28 @@ if (getenv("XCNOSTDIN") != NULL) { close(0); close(1); } + /* + * Instantiate our NSApplication object. This needs to be + * done before we check whether to open a console window. + */ + + NSAutoreleasePool *pool = [NSAutoreleasePool new]; + [[NSUserDefaults standardUserDefaults] registerDefaults: + [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithBool:YES], + @"_NSCanWrapButtonTitles", + [NSNumber numberWithInt:-1], + @"NSStringDrawingTypesetterBehavior", + nil]]; + [TKApplication sharedApplication]; + [pool drain]; + [NSApp _setup:interp]; + [NSApp finishLaunching]; + /* * If we don't have a TTY and stdin is a special character file of * length 0, (e.g. /dev/null, which is what Finder sets when double * clicking Wish) then use the Tk based console interpreter. */ @@ -385,10 +355,11 @@ } if (Tk_CreateConsoleWindow(interp) == TCL_ERROR) { return TCL_ERROR; } } + } Tk_MacOSXSetupTkNotifier(); if (tkLibPath[0] != '\0') { Index: macosx/tkMacOSXInt.h ================================================================== --- macosx/tkMacOSXInt.h +++ macosx/tkMacOSXInt.h @@ -85,10 +85,11 @@ #define TK_DRAWN_UNDER_MENU 0x08 #define TK_FOCUSED_VIEW 0x10 #define TK_IS_PIXMAP 0x20 #define TK_IS_BW_PIXMAP 0x40 #define TK_DO_NOT_DRAW 0x80 +#define TK_USE_XIMAGE_ALPHA 0x100 /* * I am reserving TK_EMBEDDED = 0x100 in the MacDrawable flags * This is defined in tk.h. We need to duplicate the TK_EMBEDDED flag in the * TkWindow structure for the window, but in the MacWin. This way we can * still tell what the correct port is after the TKWindow structure has been Index: macosx/tkMacOSXKeyEvent.c ================================================================== --- macosx/tkMacOSXKeyEvent.c +++ macosx/tkMacOSXKeyEvent.c @@ -13,10 +13,11 @@ * this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" +#include "tkMacOSXConstants.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_KEYBOARD #endif @@ -37,10 +38,12 @@ static int caret_x = 0, caret_y = 0, caret_height = 0; static void setupXEvent(XEvent *xEvent, NSWindow *w, unsigned int state); static unsigned isFunctionKey(unsigned int code); + +unsigned short releaseCode; #pragma mark TKApplication(TKKeyEvent) @implementation TKApplication(TKKeyEvent) @@ -65,16 +68,20 @@ processingCompose = NO; } switch (type) { case NSKeyUp: - if (finishedCompose) - { - // if we were composing, swallow the last release since we already sent - finishedCompose = NO; - return theEvent; - } + + /*Fix for bug #1ba71a86bb: key release firing on key press.*/ + w = [theEvent window]; + XEvent xEvent; + setupXEvent(&xEvent, w, 0); + TkWindow *winPtr = TkMacOSXGetTkWindow(w); + Tk_Window tkwin = (Tk_Window) winPtr; + xEvent.xany.type = KeyRelease; + xEvent.xkey.keycode = releaseCode; + xEvent.xany.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); case NSKeyDown: repeat = [theEvent isARepeat]; characters = [theEvent characters]; charactersIgnoringModifiers = [theEvent charactersIgnoringModifiers]; len = [charactersIgnoringModifiers length]; @@ -168,11 +175,11 @@ */ xEvent.xkey.keycode = (modifiers ^ savedModifiers); } else { if (type == NSKeyUp || repeat) { - xEvent.xany.type = KeyRelease; + xEvent.xany.type = KeyRelease; } else { xEvent.xany.type = KeyPress; } /* For command key, take input manager's word so things @@ -235,12 +242,10 @@ by doCommandBySelector: deleteBackward: */ - (void)insertText: (id)aString { int i, len = [(NSString *)aString length]; XEvent xEvent; - TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); - Tk_Window tkwin = (Tk_Window) winPtr; if (NS_KEYLOG) NSLog (@"insertText '%@'\tlen = %d", aString, len); processingCompose = NO; finishedCompose = YES; @@ -252,24 +257,21 @@ /* now insert the string as keystrokes */ setupXEvent(&xEvent, [self window], 0); xEvent.xany.type = KeyPress; for (i =0; i: inserts display of composing characters */ - (void)setMarkedText: (id)aString selectedRange: (NSRange)selRange Index: macosx/tkMacOSXKeyboard.c ================================================================== --- macosx/tkMacOSXKeyboard.c +++ macosx/tkMacOSXKeyboard.c @@ -11,11 +11,11 @@ * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" - +#include "tkMacOSXConstants.h" /* * A couple of simple definitions to make code a bit more self-explaining. * * For the assignments of Mod1==meta==command and Mod2==alt==option, see also * tkMacOSXMouseEvent.c. @@ -93,10 +93,28 @@ {105, XK_F13}, {107, XK_F14}, {113, XK_F15}, {0, 0} }; + +#define NUM_MOD_KEYCODES 14 +static KeyCode modKeyArray[NUM_MOD_KEYCODES] = { + XK_Shift_L, + XK_Shift_R, + XK_Control_L, + XK_Control_R, + XK_Caps_Lock, + XK_Shift_Lock, + XK_Meta_L, + XK_Meta_R, + XK_Alt_L, + XK_Alt_R, + XK_Super_L, + XK_Super_R, + XK_Hyper_L, + XK_Hyper_R, +}; static int initialized = 0; static Tcl_HashTable keycodeTable; /* keyArray hashed by keycode value. */ static Tcl_HashTable vkeyTable; /* virtualkeyArray hashed by virtual * keycode value. */ @@ -160,17 +178,17 @@ Tcl_InitHashTable(&keycodeTable, TCL_ONE_WORD_KEYS); for (kPtr = keyArray; kPtr->keycode != 0; kPtr++) { hPtr = Tcl_CreateHashEntry(&keycodeTable, INT2PTR(kPtr->keycode), &dummy); - Tcl_SetHashValue(hPtr, kPtr->keysym); + Tcl_SetHashValue(hPtr, INT2PTR(kPtr->keysym)); } Tcl_InitHashTable(&vkeyTable, TCL_ONE_WORD_KEYS); for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) { hPtr = Tcl_CreateHashEntry(&vkeyTable, INT2PTR(kPtr->keycode), &dummy); - Tcl_SetHashValue(hPtr, kPtr->keysym); + Tcl_SetHashValue(hPtr, INT2PTR(kPtr->keysym)); } initialized = 1; } /* @@ -455,11 +473,10 @@ /* * MacOSX doesn't use the key codes for the modifiers for anything, and we * don't generate them either. So there is no modifier map. */ - modmap = ckalloc(sizeof(XModifierKeymap)); modmap->max_keypermod = 0; modmap->modifiermap = NULL; return modmap; } @@ -546,11 +563,10 @@ XKeysymToMacKeycode( Display *display, KeySym keysym) { KeyInfo *kPtr; - if (keysym <= LATIN1_MAX) { /* * Handle keysyms in the Latin-1 range where keysym and Unicode * character code point are the same. */ @@ -576,10 +592,21 @@ for (kPtr = virtualkeyArray; kPtr->keycode != 0; kPtr++) { if (kPtr->keysym == keysym) { return kPtr->keycode; } } + + /* + * Modifier keycodes only come from generated events. No translation + * is needed. + */ + + for (int i=0; i < NUM_MOD_KEYCODES; i++) { + if (keysym == modKeyArray[i]) { + return keysym; + } + } /* * For other keysyms (not Latin-1 and not special keys), we'd need a * generic keysym-to-unicode table. We don't have that, so we give up here. */ @@ -659,18 +686,24 @@ KeySym keysym, XEvent *eventPtr) { if (keysym == NoSymbol) { eventPtr->xkey.keycode = 0; + } else if ( modKeyArray[0] <= keysym && + keysym <= modKeyArray[NUM_MOD_KEYCODES - 1]) { + /* + * Keysyms for pure modifiers only arise in generated events. + * We should just copy them to the keycode. + */ + eventPtr->xkey.keycode = keysym; } else { Display *display = Tk_Display(tkwin); int macKeycode = XKeysymToMacKeycode(display, keysym); /* * See also XKeysymToKeycode. */ - if ((keysym >= XK_F1) && (keysym <= XK_F35)) { eventPtr->xkey.keycode = 0x0010; } else { eventPtr->xkey.keycode = 0x00FF & keysym; } @@ -732,11 +765,10 @@ * Handle pure modifier keys specially. We use -1 as a signal for * this. */ if (eventPtr->xany.send_event == -1) { - int modifier = eventPtr->xkey.keycode & NSDeviceIndependentModifierFlagsMask; if (modifier == NSCommandKeyMask) { return XK_Meta_L; } else if (modifier == NSShiftKeyMask) { @@ -889,22 +921,24 @@ dispPtr->altModMask = 0; dispPtr->metaModMask = 0; #endif /* - * MacOSX doesn't use the keycodes for the modifiers for anything, and we - * don't generate them either (the keycodes actually given in the simulated - * modifier events are bogus). So there is no modifier map. If we ever want - * to simulate real modifier keycodes, the list will be constant in the - * Carbon implementation. + * MacOSX doesn't create a key event when a modifier key is pressed or + * released. However, it is possible to generate key events for + * modifier keys, and this is done in the tests. So we construct an array + * containing the keycodes of the standard modifier keys from static data. */ if (dispPtr->modKeyCodes != NULL) { ckfree(dispPtr->modKeyCodes); } - dispPtr->numModKeyCodes = 0; - dispPtr->modKeyCodes = NULL; + dispPtr->numModKeyCodes = NUM_MOD_KEYCODES; + dispPtr->modKeyCodes = (KeyCode *)ckalloc(NUM_MOD_KEYCODES * sizeof(KeyCode)); + for (int i = 0; i < NUM_MOD_KEYCODES; i++) { + dispPtr->modKeyCodes[i] = modKeyArray[i]; + } } /* * Local Variables: * mode: objc Index: macosx/tkMacOSXMenu.c ================================================================== --- macosx/tkMacOSXMenu.c +++ macosx/tkMacOSXMenu.c @@ -17,10 +17,11 @@ #include "tkMenu.h" #include "tkColor.h" #include "tkFont.h" #include "tkMacOSXWm.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_MENUS #endif @@ -114,15 +115,11 @@ - (TkMenu *) tkMenu; - (int) tkIndexOfItem: (NSMenuItem *) menuItem; - (void) insertItem: (NSMenuItem *) newItem atTkIndex: (NSInteger) index; @end -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 #define TKMenu_NSMenuDelegate -#else -#define TKMenu_NSMenuDelegate -#endif @interface TKMenu(TKMenuDelegate) TKMenu_NSMenuDelegate @end @implementation TKMenu - (void) setSpecial: (NSUInteger) special @@ -771,12 +768,19 @@ } Drawable d = Tk_WindowId(root); NSView *rootview = TkMacOSXGetRootControl(d); NSWindow *win = [rootview window]; + int result; inPostMenu = 1; + + result = TkPreprocessMenu(menuPtr); + if (result != TCL_OK) { + inPostMenu = 0; + return result; + } int oldMode = Tcl_SetServiceMode(TCL_SERVICE_NONE); NSView *view = [win contentView]; NSRect frame = NSMakeRect(x + 9, tkMacOSXZeroScreenHeight - y - 9, 1, 1); @@ -1133,11 +1137,11 @@ columnEntryPtr->width = maxIndicatorSpace + maxWidth + 2 * activeBorderWidth; columnEntryPtr->x = x; columnEntryPtr->entryFlags &= ~ENTRY_LAST_COLUMN; } - x += maxIndicatorSpace + maxWidth + 2 * borderWidth; + x += maxIndicatorSpace + maxWidth + 2 * activeBorderWidth; maxWidth = maxIndicatorSpace = 0; lastColumnBreak = i; y = borderWidth; } accelWidth = modifierWidth = indicatorSpace = 0; @@ -1619,12 +1623,11 @@ int y, /* Y-coordinate of topleft of entry */ int width, /* Width of the entry rectangle */ int height, /* Height of the current rectangle */ int strictMotif, /* Boolean flag */ int drawArrow) /* Whether or not to draw the cascade arrow - * for cascade items. Only applies to - * Windows. */ + * for cascade items. */ { } #pragma mark Obsolete Index: macosx/tkMacOSXMenus.c ================================================================== --- macosx/tkMacOSXMenus.c +++ macosx/tkMacOSXMenus.c @@ -11,10 +11,11 @@ * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMenu.h" +#include "tkMacOSXConstants.h" static void GenerateEditEvent(const char *name); static Tcl_Obj * GetWidgetDemoPath(Tcl_Interp *interp); #pragma mark TKApplication(TKMenus) Index: macosx/tkMacOSXMouseEvent.c ================================================================== --- macosx/tkMacOSXMouseEvent.c +++ macosx/tkMacOSXMouseEvent.c @@ -13,10 +13,11 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" typedef struct { unsigned int state; long delta; Window window; Index: macosx/tkMacOSXNotify.c ================================================================== --- macosx/tkMacOSXNotify.c +++ macosx/tkMacOSXNotify.c @@ -13,12 +13,12 @@ * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ #include "tkMacOSXPrivate.h" #include "tkMacOSXEvent.h" +#include "tkMacOSXConstants.h" #include -#include #import /* This is not used for anything at the moment. */ typedef struct ThreadSpecificData { int initialized; @@ -138,21 +138,21 @@ /* * Install TkAqua event source in main event loop thread. */ if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) { - if (!pthread_main_np()) { + if (![NSThread isMainThread]) { /* * Panic if main runloop is not on the main application thread. */ Tcl_Panic("Tk_MacOSXSetupTkNotifier: %s", "first [load] of TkAqua has to occur in the main thread!"); } Tcl_CreateEventSource(TkMacOSXEventsSetupProc, TkMacOSXEventsCheckProc, - GetMainEventQueue()); + NULL); TkCreateExitHandler(TkMacOSXNotifyExitHandler, NULL); Tcl_SetServiceMode(TCL_SERVICE_ALL); TclMacOSXNotifierAddRunLoopMode(NSEventTrackingRunLoopMode); TclMacOSXNotifierAddRunLoopMode(NSModalPanelRunLoopMode); } @@ -182,11 +182,11 @@ { TSD_INIT(); Tcl_DeleteEventSource(TkMacOSXEventsSetupProc, TkMacOSXEventsCheckProc, - GetMainEventQueue()); + NULL); tsdPtr->initialized = 0; } /* *---------------------------------------------------------------------- @@ -214,13 +214,14 @@ TkMacOSXEventsSetupProc( ClientData clientData, int flags) { NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode]; - /* runloopMode will be nil if we are in the Tcl event loop. */ + /* runloopMode will be nil if we are in a Tcl event loop. */ if (flags & TCL_WINDOW_EVENTS && !runloopMode) { static const Tcl_Time zeroBlockTime = { 0, 0 }; + [NSApp _resetAutoreleasePool]; /* Call this with dequeue=NO -- just checking if the queue is empty. */ NSEvent *currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:GetRunLoopMode(TkMacOSXGetModalSession()) dequeue:NO]; @@ -254,33 +255,32 @@ TkMacOSXEventsCheckProc( ClientData clientData, int flags) { NSString *runloopMode = [[NSRunLoop currentRunLoop] currentMode]; - /* runloopMode will be nil if we are in the Tcl event loop. */ + /* runloopMode will be nil if we are in a Tcl event loop. */ if (flags & TCL_WINDOW_EVENTS && !runloopMode) { NSEvent *currentEvent = nil; NSEvent *testEvent = nil; NSModalSession modalSession; - + /* It is possible for the SetupProc to be called before this function + * returns. This happens, for example, when we process an event which + * opens a modal window. To prevent premature release of our + * application-wide autorelease pool by a nested call to the SetupProc, + * we must lock it here. + */ + [NSApp _lockAutoreleasePool]; do { - [NSApp _resetAutoreleasePool]; modalSession = TkMacOSXGetModalSession(); - testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask + testEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:GetRunLoopMode(modalSession) dequeue:NO]; /* We must not steal any events during LiveResize. */ -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 if (testEvent && [[testEvent window] inLiveResize]) { break; } -#else - if (testEvent && [[[testEvent window] contentView] inLiveResize]) { - break; - } -#endif currentEvent = [NSApp nextEventMatchingMask:NSAnyEventMask untilDate:[NSDate distantPast] inMode:GetRunLoopMode(modalSession) dequeue:YES]; if (currentEvent) { @@ -301,10 +301,12 @@ [currentEvent release]; } else { break; } } while (1); + /* Now we can unlock the pool. */ + [NSApp _unlockAutoreleasePool]; } } /* Index: macosx/tkMacOSXPort.h ================================================================== --- macosx/tkMacOSXPort.h +++ macosx/tkMacOSXPort.h @@ -51,11 +51,10 @@ #include #include #include #include #include -#include "tkIntXlibDecls.h" /* * The following macro defines the type of the mask arguments to * select: */ Index: macosx/tkMacOSXPrivate.h ================================================================== --- macosx/tkMacOSXPrivate.h +++ macosx/tkMacOSXPrivate.h @@ -57,31 +57,10 @@ } else { __VA_ARGS__ #define tk_if_mac_os_x_no(chk, cond, ...) \ if (0) { #define tk_else_mac_os_x_no(...) \ } else { __VA_ARGS__ -/* Private mapping macros defined according to Mac OS X version requirements */ -/* 10.5 Leopard */ -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1050 -#define tk_if_mac_os_x_min_10_5 tk_if_mac_os_x_yes -#define tk_else_mac_os_x_min_10_5 tk_else_mac_os_x_yes -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 -#define tk_if_mac_os_x_10_5 tk_if_mac_os_x_yes -#define tk_else_mac_os_x_10_5 tk_else_mac_os_x_yes -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ -#else /* MAC_OS_X_VERSION_MIN_REQUIRED */ -#define tk_if_mac_os_x_min_10_5 tk_if_mac_os_x_chk -#define tk_else_mac_os_x_min_10_5 tk_else_mac_os_x_chk -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1050 -#define tk_if_mac_os_x_10_5 tk_if_mac_os_x_chk -#define tk_else_mac_os_x_10_5 tk_else_mac_os_x_chk -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ -#endif /* MAC_OS_X_VERSION_MIN_REQUIRED */ -#if MAC_OS_X_VERSION_MAX_ALLOWED < 1050 -#define tk_if_mac_os_x_10_5 tk_if_mac_os_x_no -#define tk_else_mac_os_x_10_5 tk_else_mac_os_x_no -#endif /* MAC_OS_X_VERSION_MAX_ALLOWED */ /* * Macros for DEBUG_ASSERT_MESSAGE et al from Debugging.h. */ @@ -207,12 +186,18 @@ int activeFlag); MODULE_SCOPE WindowClass TkMacOSXWindowClass(TkWindow *winPtr); MODULE_SCOPE int TkMacOSXIsWindowZoomed(TkWindow *winPtr); MODULE_SCOPE int TkGenerateButtonEventForXPointer(Window window); MODULE_SCOPE EventModifiers TkMacOSXModifierState(void); -MODULE_SCOPE NSBitmapImageRep* BitmapRepFromDrawableRect(Drawable drawable, +MODULE_SCOPE NSBitmapImageRep* TkMacOSXBitmapRepFromDrawableRect(Drawable drawable, int x, int y, unsigned int width, unsigned int height); +MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithXImage(XImage *image, + int use_ximage_alpha); +MODULE_SCOPE void TkMacOSXDrawCGImage(Drawable d, GC gc, CGContextRef context, + CGImageRef image, unsigned long imageForeground, + unsigned long imageBackground, CGRect imageBounds, + CGRect srcBounds, CGRect dstBounds); MODULE_SCOPE int TkMacOSXSetupDrawingContext(Drawable d, GC gc, int useCG, TkMacOSXDrawingContext *dcPtr); MODULE_SCOPE void TkMacOSXRestoreDrawingContext( TkMacOSXDrawingContext *dcPtr); MODULE_SCOPE void TkMacOSXSetColorInContext(GC gc, unsigned long pixel, @@ -226,10 +211,11 @@ MODULE_SCOPE NSView* TkMacOSXDrawableView(MacDrawable *macWin); MODULE_SCOPE void TkMacOSXWinCGBounds(TkWindow *winPtr, CGRect *bounds); MODULE_SCOPE HIShapeRef TkMacOSXGetClipRgn(Drawable drawable); MODULE_SCOPE void TkMacOSXInvalidateViewRegion(NSView *view, HIShapeRef rgn); +MODULE_SCOPE CGContextRef TkMacOSXGetCGContextForDrawable(Drawable drawable); MODULE_SCOPE CGImageRef TkMacOSXCreateCGImageWithDrawable(Drawable drawable); MODULE_SCOPE NSImage* TkMacOSXGetNSImageWithTkImage(Display *display, Tk_Image image, int width, int height); MODULE_SCOPE NSImage* TkMacOSXGetNSImageWithBitmap(Display *display, Pixmap bitmap, GC gc, int width, int height); @@ -276,18 +262,21 @@ NSArray *_defaultHelpMenuItems; NSWindow *_windowWithMouse; NSAutoreleasePool *_mainPool; #ifdef __i386__ /* The Objective C runtime used on i386 requires this. */ - BOOL _poolProtected; + int _poolLock; #endif } -@property BOOL poolProtected; +@property int poolLock; + @end @interface TKApplication(TKInit) - (NSString *)tkFrameworkImagePath:(NSString*)image; - (void)_resetAutoreleasePool; +- (void)_lockAutoreleasePool; +- (void)_unlockAutoreleasePool; @end @interface TKApplication(TKEvent) - (NSEvent *)tkProcessEvent:(NSEvent *)theEvent; @end @interface TKApplication(TKMouseEvent) @@ -339,12 +328,12 @@ @end @interface TKContentView(TKWindowEvent) - (void) drawRect: (NSRect) rect; - (void) generateExposeEvents: (HIShapeRef) shape; -- (void) generateExposeEvents: (HIShapeRef) shape childrenOnly: (int) childrenOnly; -- (void) viewDidEndLiveResize; +- (void) viewDidChangeEffectiveAppearance; +- (void) updateAppearanceEvent; - (void) tkToolbarButton: (id) sender; - (BOOL) isOpaque; - (BOOL) wantsDefaultClipping; - (BOOL) acceptsFirstResponder; - (void) keyDown: (NSEvent *) theEvent; Index: macosx/tkMacOSXScale.c ================================================================== --- macosx/tkMacOSXScale.c +++ macosx/tkMacOSXScale.c @@ -169,11 +169,14 @@ */ Tcl_Preserve((ClientData) scalePtr); if ((scalePtr->flags & INVOKE_COMMAND) && (scalePtr->command != NULL)) { Tcl_Preserve((ClientData) interp); - sprintf(string, scalePtr->format, scalePtr->value); + if (snprintf(string, TCL_DOUBLE_SPACE, scalePtr->format, + scalePtr->value) < 0) { + string[TCL_DOUBLE_SPACE - 1] = '\0'; + } Tcl_DStringInit(&buf); Tcl_DStringAppend(&buf, scalePtr->command, -1); Tcl_DStringAppend(&buf, " ", -1); Tcl_DStringAppend(&buf, string, -1); result = Tcl_EvalEx(interp, Tcl_DStringValue(&buf), -1, 0); Index: macosx/tkMacOSXScrlbr.c ================================================================== --- macosx/tkMacOSXScrlbr.c +++ macosx/tkMacOSXScrlbr.c @@ -17,10 +17,17 @@ #include "tkMacOSXPrivate.h" #define MIN_SCROLLBAR_VALUE 0 +/* + * Minimum slider length, in pixels (designed to make sure that the slider is + * always easy to grab with the mouse). + */ + +#define MIN_SLIDER_LENGTH 5 + /*Borrowed from ttkMacOSXTheme.c to provide appropriate scaling of scrollbar values.*/ #ifdef __LP64__ #define RangeToFactor(maximum) (((double) (INT_MAX >> 1)) / (maximum)) #else #define RangeToFactor(maximum) (((double) (LONG_MAX >> 1)) / (maximum)) @@ -57,21 +64,20 @@ SInt32 width, minThumbHeight; int minHeight, topArrowHeight, bottomArrowHeight; NSControlSize controlSize; } ScrollbarMetrics; -static ScrollbarMetrics metrics[2] = { - {15, 54, 26, 14, 14, NSRegularControlSize}, /* kThemeScrollBarMedium */ - {11, 40, 20, 10, 10, NSSmallControlSize}, /* kThemeScrollBarSmall */ + +static ScrollbarMetrics metrics = { + 15, 54, 26, 14, 14, kControlSizeNormal /* kThemeScrollBarMedium */ }; HIThemeTrackDrawInfo info = { .version = 0, .min = 0.0, .max = 100.0, .attributes = kThemeTrackShowThumb, - .kind = kThemeScrollBarMedium, }; /* * Forward declarations for procedures defined later in this file: @@ -105,11 +111,11 @@ MacScrollbar *scrollPtr = (MacScrollbar *)ckalloc(sizeof(MacScrollbar)); scrollPtr->troughGC = None; scrollPtr->copyGC = None; - Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); + Tk_CreateEventHandler(tkwin,ExposureMask|StructureNotifyMask|FocusChangeMask|ButtonPressMask|ButtonReleaseMask|EnterWindowMask|LeaveWindowMask|VisibilityChangeMask, ScrollbarEventProc, scrollPtr); return (TkScrollbar *) scrollPtr; } /* @@ -209,78 +215,84 @@ * Side effects: * The scrollbar will be displayed differently. * *---------------------------------------------------------------------- */ + + extern void TkpComputeScrollbarGeometry( - register TkScrollbar *scrollPtr) -/* Scrollbar whose geometry may have - * changed. */ + register TkScrollbar *scrollPtr) + /* Scrollbar whose geometry may have + * changed. */ { - int variant, fieldLength; + /* + * Using code from tkUnixScrlbr.c because Unix scroll bindings are + * driving the display at the script level. All the Mac scrollbar + * has to do is re-draw itself. + * There is a difference with Unix however: on macOS later than 10.6 + * (Snow Leopard) the scrollbars have no arrows at all. This is + * handled by having scrollPtr->arrowLength set to zero. + */ + + int fieldLength; if (scrollPtr->highlightWidth < 0) { - scrollPtr->highlightWidth = 0; + scrollPtr->highlightWidth = 0; } scrollPtr->inset = scrollPtr->highlightWidth + scrollPtr->borderWidth; - variant = ((scrollPtr->vertical ? Tk_Width(scrollPtr->tkwin) : - Tk_Height(scrollPtr->tkwin)) - 2 * scrollPtr->inset - < metrics[0].width) ? 1 : 0; - scrollPtr->arrowLength = (metrics[variant].topArrowHeight + - metrics[variant].bottomArrowHeight) / 2; + scrollPtr->arrowLength = 0; fieldLength = (scrollPtr->vertical ? Tk_Height(scrollPtr->tkwin) - : Tk_Width(scrollPtr->tkwin)) - - 2 * (scrollPtr->arrowLength + scrollPtr->inset); + : Tk_Width(scrollPtr->tkwin)) + - 2*(scrollPtr->arrowLength + scrollPtr->inset); if (fieldLength < 0) { - fieldLength = 0; + fieldLength = 0; } - scrollPtr->sliderFirst = fieldLength * scrollPtr->firstFraction; - scrollPtr->sliderLast = fieldLength * scrollPtr->lastFraction; + scrollPtr->sliderFirst = fieldLength*scrollPtr->firstFraction; + scrollPtr->sliderLast = fieldLength*scrollPtr->lastFraction; /* - * Adjust the slider so that some piece of it is always - * displayed in the scrollbar and so that it has at least - * a minimal width (so it can be grabbed with the mouse). + * Adjust the slider so that some piece of it is always displayed in the + * scrollbar and so that it has at least a minimal width (so it can be + * grabbed with the mouse). */ - if (scrollPtr->sliderFirst > (fieldLength - 2*scrollPtr->borderWidth)) { - scrollPtr->sliderFirst = fieldLength - 2*scrollPtr->borderWidth; + if (scrollPtr->sliderFirst > fieldLength - MIN_SLIDER_LENGTH) { + scrollPtr->sliderFirst = fieldLength - MIN_SLIDER_LENGTH; } if (scrollPtr->sliderFirst < 0) { - scrollPtr->sliderFirst = 0; + scrollPtr->sliderFirst = 0; } - if (scrollPtr->sliderLast < (scrollPtr->sliderFirst + - metrics[variant].minThumbHeight)) { - scrollPtr->sliderLast = scrollPtr->sliderFirst + - metrics[variant].minThumbHeight; + if (scrollPtr->sliderLast < scrollPtr->sliderFirst + MIN_SLIDER_LENGTH) { + scrollPtr->sliderLast = scrollPtr->sliderFirst + MIN_SLIDER_LENGTH; } if (scrollPtr->sliderLast > fieldLength) { - scrollPtr->sliderLast = fieldLength; - } - if (!(MOUNTAIN_LION_STYLE)) { - scrollPtr->sliderFirst += scrollPtr->inset + - metrics[variant].topArrowHeight; - scrollPtr->sliderLast += scrollPtr->inset + - metrics[variant].bottomArrowHeight; - } + scrollPtr->sliderLast = fieldLength; + } + scrollPtr->sliderFirst += scrollPtr->arrowLength + scrollPtr->inset; + scrollPtr->sliderLast += scrollPtr->arrowLength + scrollPtr->inset; + /* - * Register the desired geometry for the window (leave enough space - * for the two arrows plus a minimum-size slider, plus border around - * the whole window, if any). Then arrange for the window to be - * redisplayed. + * Register the desired geometry for the window (leave enough space for + * the two arrows plus a minimum-size slider, plus border around the whole + * window, if any). Then arrange for the window to be redisplayed. */ - if (scrollPtr->vertical) { - Tk_GeometryRequest(scrollPtr->tkwin, scrollPtr->width + 2 * scrollPtr->inset, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) + metrics[variant].minThumbHeight); + if (scrollPtr->vertical) { + Tk_GeometryRequest(scrollPtr->tkwin, + scrollPtr->width + 2*scrollPtr->inset, + 2*(scrollPtr->arrowLength + scrollPtr->borderWidth + + scrollPtr->inset) + metrics.minThumbHeight); } else { - Tk_GeometryRequest(scrollPtr->tkwin, 2 * (scrollPtr->arrowLength + scrollPtr->borderWidth + scrollPtr->inset) + metrics[variant].minThumbHeight, scrollPtr->width + 2 * scrollPtr->inset); + Tk_GeometryRequest(scrollPtr->tkwin, + 2*(scrollPtr->arrowLength + scrollPtr->borderWidth + + scrollPtr->inset) + metrics.minThumbHeight, + scrollPtr->width + 2*scrollPtr->inset); } Tk_SetInternalBorder(scrollPtr->tkwin, scrollPtr->inset); - } /* *---------------------------------------------------------------------- * @@ -363,66 +375,64 @@ register TkScrollbar *scrollPtr, /* Scrollbar widget record. */ int x, int y) /* Coordinates within scrollPtr's window. */ { - /* + /* * Using code from tkUnixScrlbr.c because Unix scroll bindings are * driving the display at the script level. All the Mac scrollbar * has to do is re-draw itself. */ - int length, fieldlength, width, tmp; + int length, width, tmp; register const int inset = scrollPtr->inset; - register const int arrowSize = scrollPtr->arrowLength + inset; if (scrollPtr->vertical) { - length = Tk_Height(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Width(scrollPtr->tkwin); + length = Tk_Height(scrollPtr->tkwin); + width = Tk_Width(scrollPtr->tkwin); } else { - tmp = x; - x = y; - y = tmp; - length = Tk_Width(scrollPtr->tkwin); - fieldlength = length - 2 * arrowSize; - width = Tk_Height(scrollPtr->tkwin); - } - fieldlength = fieldlength < 0 ? 0 : fieldlength; + tmp = x; + x = y; + y = tmp; + length = Tk_Width(scrollPtr->tkwin); + width = Tk_Height(scrollPtr->tkwin); + } if (x=width-inset || y=length-inset) { - return OUTSIDE; + return OUTSIDE; } /* * All of the calculations in this procedure mirror those in * TkpDisplayScrollbar. Be sure to keep the two consistent. */ + if (y < inset + scrollPtr->arrowLength) { + return TOP_ARROW; + } if (y < scrollPtr->sliderFirst) { - return TOP_GAP; + return TOP_GAP; } if (y < scrollPtr->sliderLast) { - return SLIDER; - } - if (y < fieldlength){ - return BOTTOM_GAP; - } - if (y < fieldlength + arrowSize) { - return TOP_ARROW; - } - return BOTTOM_ARROW; + return SLIDER; + } + if (y >= length - (scrollPtr->arrowLength + inset)) { + return BOTTOM_ARROW; + } + + return BOTTOM_GAP; + } /* *-------------------------------------------------------------- * * UpdateControlValues -- * * This procedure updates the Macintosh scrollbar control to * display the values defined by the Tk scrollbar. This is the - * key interface to the Mac-native * scrollbar; the Unix bindings + * key interface to the Mac-native scrollbar; the Unix bindings * drive scrolling in the Tk window and all the Mac scrollbar has * to do is redraw itself. * * Results: * None. @@ -439,11 +449,10 @@ { Tk_Window tkwin = scrollPtr->tkwin; MacDrawable *macWin = (MacDrawable *) Tk_WindowId(scrollPtr->tkwin); double dViewSize; HIRect contrlRect; - int variant; short width, height; NSView *view = TkMacOSXDrawableView(macWin); CGFloat viewHeight = [view bounds].size.height; NSRect frame; @@ -456,12 +465,10 @@ info.bounds = contrlRect; width = contrlRect.size.width; height = contrlRect.size.height; - variant = contrlRect.size.width < metrics[0].width ? 1 : 0; - /* * Ensure we set scrollbar control bounds only once all size adjustments * have been computed. */ @@ -498,11 +505,11 @@ } else { info.value = MIN_SCROLLBAR_VALUE + factor * scrollPtr->firstFraction; } if((scrollPtr->firstFraction <= 0.0 && scrollPtr->lastFraction >= 1.0) - || height <= metrics[variant].minHeight) { + || height <= metrics.minHeight) { info.enableState = kThemeTrackHideTrack; } else { info.enableState = kThemeTrackActive; info.attributes = kThemeTrackShowThumb | kThemeTrackThumbRgnIsNotGhost; } @@ -512,12 +519,12 @@ /* *-------------------------------------------------------------- * * ScrollbarPress -- * - * This procedure is invoked in response to events. - * Enters a modal loop to handle scrollbar interactions. + * This procedure is invoked in response to , , + * , and events. Scrollbar appearance is modified. * *-------------------------------------------------------------- */ static int @@ -524,10 +531,17 @@ ScrollbarPress(TkScrollbar *scrollPtr, XEvent *eventPtr) { if (eventPtr->type == ButtonPress) { UpdateControlValues(scrollPtr); + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == EnterNotify) { + info.trackInfo.scrollbar.pressState = 1; + } + if (eventPtr->type == ButtonRelease || eventPtr->type == LeaveNotify) { + info.trackInfo.scrollbar.pressState = 0; } return TCL_OK; } @@ -564,11 +578,14 @@ case ActivateNotify: case DeactivateNotify: TkScrollbarEventuallyRedraw(scrollPtr); break; case ButtonPress: + case ButtonRelease: + case EnterNotify: + case LeaveNotify: ScrollbarPress(clientData, eventPtr); break; default: TkScrollbarEventProc(clientData, eventPtr); } } Index: macosx/tkMacOSXSubwindows.c ================================================================== --- macosx/tkMacOSXSubwindows.c +++ macosx/tkMacOSXSubwindows.c @@ -147,15 +147,31 @@ display->request++; macWin->winPtr->flags |= TK_MAPPED; if (Tk_IsTopLevel(macWin->winPtr)) { if (!Tk_IsEmbedded(macWin->winPtr)) { NSWindow *win = TkMacOSXDrawableWindow(window); - [NSApp activateIgnoringOtherApps:YES]; + /* + * We want to activate Tk when a toplevel is mapped + * but we must not supply YES here. This is because + * during Tk initialization the root window is mapped + * before applicationDidFinishLaunching returns. Forcing + * the app to activate too early can make the menu bar + * unresponsive. + */ + [NSApp activateIgnoringOtherApps:NO]; if ( [win canBecomeKeyWindow] ) { [win makeKeyAndOrderFront:NSApp]; } TkMacOSXApplyWindowAttributes(macWin->winPtr, win); + } else { + /* + * Rebuild the container's clipping region and display + * the window. + */ + TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr); + TkMacOSXInvalClipRgns((Tk_Window)contWinPtr); + TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); } TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); /* * We only need to send the MapNotify event for toplevel windows. @@ -170,11 +186,12 @@ event.xmap.event = window; event.xmap.override_redirect = macWin->winPtr->atts.override_redirect; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } else { /* - * Generate damage for that area of the window. + * Rebuild the parent's clipping region and display the window. + * */ TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr); TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); } @@ -186,10 +203,17 @@ event.xany.send_event = False; event.xany.display = display; event.xvisibility.type = VisibilityNotify; event.xvisibility.state = VisibilityUnobscured; NotifyVisibility(macWin->winPtr, &event); + + /* + * Make sure that subwindows get displayed. + */ + + GenerateConfigureNotify(macWin->winPtr, 1); + } /* *---------------------------------------------------------------------- * @@ -245,25 +269,26 @@ XUnmapWindow( Display *display, /* Display. */ Window window) /* Window. */ { MacDrawable *macWin = (MacDrawable *) window; + TkWindow *winPtr = macWin->winPtr; + TkWindow *parentPtr = winPtr->parentPtr; XEvent event; display->request++; - macWin->winPtr->flags &= ~TK_MAPPED; - if (Tk_IsTopLevel(macWin->winPtr)) { - if (!Tk_IsEmbedded(macWin->winPtr) && - macWin->winPtr->wmInfoPtr->hints.initial_state!=IconicState) { + if (Tk_IsTopLevel(winPtr)) { + if (!Tk_IsEmbedded(winPtr) && + winPtr->wmInfoPtr->hints.initial_state!=IconicState) { NSWindow *win = TkMacOSXDrawableWindow(window); if ([win isVisible]) { [[win parentWindow] removeChildWindow:win]; [win orderOut:NSApp]; } } - TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr); + TkMacOSXInvalClipRgns((Tk_Window) winPtr); /* * We only need to send the UnmapNotify event for toplevel windows. */ @@ -275,17 +300,24 @@ event.xunmap.window = window; event.xunmap.event = window; event.xunmap.from_configure = false; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); } else { + /* - * Generate damage for that area of the window. + * Rebuild the visRgn clip region for the parent so it will be allowed + * to draw in the space from which this subwindow was removed. */ - TkMacOSXInvalidateWindow(macWin, TK_PARENT_WINDOW); - TkMacOSXInvalClipRgns((Tk_Window) macWin->winPtr->parentPtr); + if (parentPtr && parentPtr->privatePtr->visRgn) { + TkMacOSXInvalidateViewRegion(TkMacOSXDrawableView(parentPtr->privatePtr), + parentPtr->privatePtr->visRgn); + } + TkMacOSXInvalClipRgns((Tk_Window) parentPtr); + TkMacOSXUpdateClipRgn(parentPtr); } + winPtr->flags &= ~TK_MAPPED; } /* *---------------------------------------------------------------------- * @@ -355,19 +387,21 @@ display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { NSWindow *w = macWin->winPtr->wmInfoPtr->window; if (w) { + /* We explicitly convert everything to doubles so we don't get * surprised (again) by what happens when you do arithmetic with * unsigned ints. */ + CGFloat X = (CGFloat)x; CGFloat Y = (CGFloat)y; CGFloat Width = (CGFloat)width; CGFloat Height = (CGFloat)height; - CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent; + CGFloat XOff = (CGFloat)macWin->winPtr->wmInfoPtr->xInParent; CGFloat YOff = (CGFloat)macWin->winPtr->wmInfoPtr->yInParent; NSRect r = NSMakeRect(X + XOff, tkMacOSXZeroScreenHeight - Y - YOff - Height, Width, Height); [w setFrame:[w frameRectForContentRect:r] display:YES]; @@ -445,18 +479,20 @@ TkWindow *contWinPtr = TkpGetOtherWindow(macWin->winPtr); if (contWinPtr) { macParent = contWinPtr->privatePtr; } else { + /* * Here we should handle out of process embedding. At this point, * we are assuming that the changes.x,y is not maintained, if you * need the info get it from Tk_GetRootCoords, and that the * toplevel sits at 0,0 when it is drawn. */ } } else { + /* * TODO: update all xOff & yOffs */ macParent = macWin->winPtr->parentPtr->privatePtr; @@ -544,10 +580,11 @@ display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { TkWmRestackToplevel(macWin->winPtr, Above, NULL); } else { + /* * TODO: this should generate damage */ } } @@ -578,11 +615,12 @@ display->request++; if (Tk_IsTopLevel(macWin->winPtr) && !Tk_IsEmbedded(macWin->winPtr)) { TkWmRestackToplevel(macWin->winPtr, Below, NULL); } else { - /* + + /* * TODO: this should generate damage */ } } #endif @@ -767,12 +805,12 @@ * contained window in a frame, and don't support any other widgets * in the frame either. This is not currently enforced, however. */ if (!Tk_IsTopLevel(winPtr)) { - TkMacOSXUpdateClipRgn(winPtr->parentPtr); if (winPtr->parentPtr) { + TkMacOSXUpdateClipRgn(winPtr->parentPtr); ChkErr(HIShapeIntersect, winPtr->parentPtr->privatePtr->aboveVisRgn, rgn, rgn); } win2Ptr = winPtr; @@ -849,10 +887,11 @@ } CFRelease(diffRgn); } CFRelease(rgn); } else { + /* * An unmapped window has empty clip regions to prevent any * (erroneous) drawing into it or its children from becoming * visible. [Bug 940117] */ @@ -1109,10 +1148,11 @@ void * TkMacOSXGetRootControl( Drawable drawable) { + /* * will probably need to fix this up for embedding */ return TkMacOSXDrawableView((MacDrawable *) drawable); @@ -1289,10 +1329,11 @@ int deltaY) { TkWindow *childPtr; if (winPtr->privatePtr == NULL) { + /* * We haven't called Tk_MakeWindowExist for this window yet. The offset * information will be postponed and calulated at that time. (This will * usually only happen when a mapped parent is being moved but has * child windows that have yet to be mapped.) Index: macosx/tkMacOSXWindowEvent.c ================================================================== --- macosx/tkMacOSXWindowEvent.c +++ macosx/tkMacOSXWindowEvent.c @@ -15,10 +15,11 @@ #include "tkMacOSXPrivate.h" #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" /* #ifdef TK_MAC_DEBUG #define TK_MAC_DEBUG_EVENTS #define TK_MAC_DEBUG_DRAWING @@ -39,18 +40,12 @@ #ifdef TK_MAC_DEBUG_NOTIFICATIONS extern NSString *NSWindowWillOrderOnScreenNotification; extern NSString *NSWindowDidOrderOnScreenNotification; extern NSString *NSWindowDidOrderOffScreenNotification; - -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -#define NSWindowWillStartLiveResizeNotification @"NSWindowWillStartLiveResizeNotification" -#define NSWindowDidEndLiveResizeNotification @"NSWindowDidEndLiveResizeNotification" -#endif -#endif - -extern BOOL opaqueTag; +#endif + @implementation TKApplication(TKWindowEvent) - (void) windowActivation: (NSNotification *) notification { @@ -71,15 +66,11 @@ { #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif BOOL movedOnly = [[notification name] - isEqualToString:NSWindowDidMoveNotification]; - - if (movedOnly) { - /* constraining to screen after move not needed with AppKit */ - } + isEqualToString:NSWindowDidMoveNotification]; NSWindow *w = [notification object]; TkWindow *winPtr = TkMacOSXGetTkWindow(w); if (winPtr) { @@ -99,10 +90,11 @@ width = bounds.size.width - wmPtr->xInParent; height = bounds.size.height - wmPtr->yInParent; flags |= TK_SIZE_CHANGED; } if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) { + /* * Propagate geometry changes immediately. */ flags |= TK_MACOSX_HANDLE_EVENT_IMMEDIATELY; @@ -122,10 +114,11 @@ if (winPtr) { winPtr->wmInfoPtr->hints.initial_state = TkMacOSXIsWindowZoomed(winPtr) ? ZoomState : NormalState; Tk_MapWindow((Tk_Window) winPtr); if (Tcl_GetServiceMode() != TCL_SERVICE_NONE) { + /* * Process all Tk events generated by Tk_MapWindow(). */ while (Tcl_ServiceEvent(0)) {} @@ -176,10 +169,11 @@ * so can always return NO from -windowShouldClose: for a Tk window. */ return (winPtr ? NO : YES); } + #ifdef TK_MAC_DEBUG_NOTIFICATIONS - (void) windowDragStart: (NSNotification *) notification { @@ -216,10 +210,12 @@ if (winPtr) { //Tk_UnmapWindow((Tk_Window) winPtr); } } + + #endif /* TK_MAC_DEBUG_NOTIFICATIONS */ - (void) _setupWindowNotifications { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; @@ -239,10 +235,11 @@ observe(NSWindowWillOrderOnScreenNotification, windowMapped:); observe(NSWindowDidOrderOnScreenNotification, windowBecameVisible:); observe(NSWindowDidOrderOffScreenNotification, windowUnmapped:); #endif #undef observe + } @end #pragma mark TKApplication(TKApplicationEvent) @@ -259,11 +256,10 @@ - (void) applicationDeactivate: (NSNotification *) notification { #ifdef TK_MAC_DEBUG_NOTIFICATIONS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd, notification); #endif - TkSuspendClipboard(); } - (void) applicationShowHide: (NSNotification *) notification { #ifdef TK_MAC_DEBUG_NOTIFICATIONS @@ -302,11 +298,11 @@ *---------------------------------------------------------------------- * * GenerateUpdates -- * * Given a Macintosh update region and a Tk window this function geneates - * a X Expose event for the window if it is within the update region. The + * an X Expose event for the window if it meets the update region. The * function will then recursivly have each damaged window generate Expose * events for its child windows. * * Results: * True if event(s) are generated - false otherwise. @@ -335,11 +331,11 @@ if (!HIShapeIntersectsRect(updateRgn, &bounds)) { return 0; } /* - * Compute the bounding box of the area that the damage occured in. + * Compute the bounding box of the area that the damage occurred in. */ boundsRgn = HIShapeCreateWithRect(&bounds); damageRgn = HIShapeCreateIntersection(updateRgn, boundsRgn); if (HIShapeIsEmpty(damageRgn)) { @@ -360,16 +356,16 @@ event.xexpose.x = damageBounds.origin.x - bounds.origin.x; event.xexpose.y = damageBounds.origin.y - bounds.origin.y; event.xexpose.width = damageBounds.size.width; event.xexpose.height = damageBounds.size.height; event.xexpose.count = 0; - Tk_HandleEvent(&event); + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); - #ifdef TK_MAC_DEBUG_DRAWING +#ifdef TK_MAC_DEBUG_DRAWING NSLog(@"Expose %p {{%d, %d}, {%d, %d}}", event.xany.window, event.xexpose.x, event.xexpose.y, event.xexpose.width, event.xexpose.height); - #endif +#endif /* * Generate updates for the children of this window */ @@ -582,14 +578,16 @@ wmPtr->flags &= ~(WM_NEGATIVE_X | WM_NEGATIVE_Y); } if ((flags & TK_SIZE_CHANGED) && !(wmPtr->flags & WM_SYNC_PENDING) && ((width != Tk_Width(tkwin)) || (height != Tk_Height(tkwin)))) { if ((wmPtr->width == -1) && (width == winPtr->reqWidth)) { + /* * Don't set external width, since the user didn't change it * from what the widgets asked for. */ + } else if (wmPtr->gridWin != NULL) { wmPtr->width = wmPtr->reqGridWidth + (width - winPtr->reqWidth)/wmPtr->widthInc; if (wmPtr->width < 0) { wmPtr->width = 0; @@ -597,14 +595,16 @@ } else { wmPtr->width = width; } if ((wmPtr->height == -1) && (height == winPtr->reqHeight)) { + /* * Don't set external height, since the user didn't change it * from what the widgets asked for. */ + } else if (wmPtr->gridWin != NULL) { wmPtr->height = wmPtr->reqGridHeight + (height - winPtr->reqHeight)/wmPtr->heightInc; if (wmPtr->height < 0) { wmPtr->height = 0; @@ -747,21 +747,11 @@ */ int Tk_MacOSXIsAppInFront(void) { - Boolean isFrontProcess = true; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - ProcessSerialNumber frontPsn, ourPsn = {0, kCurrentProcess}; - - if (noErr == GetFrontProcess(&frontPsn)){ - SameProcess(&frontPsn, &ourPsn, &isFrontProcess); - } -#else - isFrontProcess = [NSRunningApplication currentApplication].active; -#endif - return (isFrontProcess == true); + return ([NSRunningApplication currentApplication].active == true); } #pragma mark TKContentView #import @@ -826,21 +816,11 @@ while (rectsBeingDrawnCount--) { CGRect r = NSRectToCGRect(*rectsBeingDrawn++); r.origin.y = height - (r.origin.y + r.size.height); HIShapeUnionWithRect(drawShape, &r); } - if (CFRunLoopGetMain() == CFRunLoopGetCurrent()) { - [self generateExposeEvents:(HIShapeRef)drawShape]; - } else { - [self performSelectorOnMainThread:@selector(generateExposeEvents:) - withObject:(id)drawShape waitUntilDone:NO - modes:[NSArray arrayWithObjects:NSRunLoopCommonModes, - - NSEventTrackingRunLoopMode, NSModalPanelRunLoopMode, - nil]]; - } - + [self generateExposeEvents:(HIShapeRef)drawShape]; CFRelease(drawShape); } -(void) setFrameSize: (NSSize)newsize { @@ -852,105 +832,162 @@ unsigned int width = (unsigned int)newsize.width; unsigned int height=(unsigned int)newsize.height; ClientData oldArg; Tk_RestrictProc *oldProc; - /* This can be called from outside the Tk event loop. - * Since it calls Tcl_DoOneEvent, we need to make sure we - * don't clobber the AutoreleasePool set up by the caller. - */ - [NSApp setPoolProtected:YES]; - - /* - * Try to prevent flickers and flashes. - */ - [w disableFlushWindow]; - NSDisableScreenUpdates(); - - /* Disable Tk drawing until the window has been completely configured.*/ - TkMacOSXSetDrawingEnabled(winPtr, 0); - - /* Generate and handle a ConfigureNotify event for the new size.*/ - TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height, - TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY); - oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg); - while (Tk_DoOneEvent(TK_X_EVENTS|TK_DONT_WAIT)) {} - Tk_RestrictEvents(oldProc, oldArg, &oldArg); - - /* Now that Tk has configured all subwindows we can create the clip regions. */ - TkMacOSXSetDrawingEnabled(winPtr, 1); - TkMacOSXInvalClipRgns(tkwin); - TkMacOSXUpdateClipRgn(winPtr); - - /* Finally, generate and process expose events to redraw the window. */ - HIRect bounds = NSRectToCGRect([self bounds]); - HIShapeRef shape = HIShapeCreateWithRect(&bounds); - [self generateExposeEvents: shape]; - while (Tk_DoOneEvent(TK_ALL_EVENTS|TK_DONT_WAIT)) {} - [w enableFlushWindow]; - [w flushWindowIfNeeded]; - NSEnableScreenUpdates(); - [NSApp setPoolProtected:NO]; - } -} - -/* - * As insurance against bugs that might cause layout glitches during a live - * resize, we redraw the window one more time at the end of the resize - * operation. - */ - -- (void)viewDidEndLiveResize -{ - HIRect bounds = NSRectToCGRect([self bounds]); - HIShapeRef shape = HIShapeCreateWithRect(&bounds); - [super viewDidEndLiveResize]; - [self generateExposeEvents: shape]; -} - -/* Core method of this class: generates expose events for redrawing. If the - * Tcl_ServiceMode is set to TCL_SERVICE_ALL then the expose events will be - * immediately removed from the Tcl event loop and processed. Typically, they - * should be queued, however. - */ -- (void) generateExposeEvents: (HIShapeRef) shape -{ - [self generateExposeEvents:shape childrenOnly:0]; -} - -- (void) generateExposeEvents: (HIShapeRef) shape - childrenOnly: (int) childrenOnly -{ - TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); - unsigned long serial; - CGRect updateBounds; - int updatesNeeded; + /* + * This can be called from outside the Tk event loop. + * Since it calls Tcl_DoOneEvent, we need to make sure we + * don't clobber the AutoreleasePool set up by the caller. + */ + + [NSApp _lockAutoreleasePool]; + + /* + * Disable Tk drawing until the window has been completely configured. + */ + + TkMacOSXSetDrawingEnabled(winPtr, 0); + + /* + * Generate and handle a ConfigureNotify event for the new size. + */ + + TkGenWMConfigureEvent(tkwin, Tk_X(tkwin), Tk_Y(tkwin), width, height, + TK_SIZE_CHANGED | TK_MACOSX_HANDLE_EVENT_IMMEDIATELY); + oldProc = Tk_RestrictEvents(ConfigureRestrictProc, NULL, &oldArg); + Tk_RestrictEvents(oldProc, oldArg, &oldArg); + + /* + * Now that Tk has configured all subwindows, create the clip regions. + */ + + TkMacOSXSetDrawingEnabled(winPtr, 1); + TkMacOSXInvalClipRgns(tkwin); + TkMacOSXUpdateClipRgn(winPtr); + + /* + * Finally, generate and process expose events to redraw the window. + */ + + HIRect bounds = NSRectToCGRect([self bounds]); + HIShapeRef shape = HIShapeCreateWithRect(&bounds); + [self generateExposeEvents: shape]; + [w displayIfNeeded]; + [NSApp _unlockAutoreleasePool]; + } +} + +/* + * Core method of this class: generates expose events for redrawing. The + * expose events are immediately removed from the Tcl event loop and processed. + * This causes drawing procedures to be scheduled as idle events. Then all + * pending idle events are processed so the drawing will actually take place. + */ + +- (void) generateExposeEvents: (HIShapeRef) shape +{ + unsigned long serial; + CGRect updateBounds; + int updatesNeeded; + TkWindow *winPtr = TkMacOSXGetTkWindow([self window]); if (!winPtr) { return; } - /* Generate Tk Expose events. */ + /* + * Generate Tk Expose events. + */ + HIShapeGetBounds(shape, &updateBounds); - /* All of these events will share the same serial number. */ + + /* + * All of these events will share the same serial number. + */ + serial = LastKnownRequestProcessed(Tk_Display(winPtr)); updatesNeeded = GenerateUpdates(shape, &updateBounds, winPtr); - /* Process the Expose events if the service mode is TCL_SERVICE_ALL */ - if (updatesNeeded && Tcl_GetServiceMode() == TCL_SERVICE_ALL) { + if (updatesNeeded) { + + /* + * First process all of the Expose events. + */ + ClientData oldArg; Tk_RestrictProc *oldProc = Tk_RestrictEvents(ExposeRestrictProc, UINT2PTR(serial), &oldArg); - while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {} + while (Tcl_ServiceEvent(TCL_WINDOW_EVENTS)) {}; Tk_RestrictEvents(oldProc, oldArg, &oldArg); + + /* + * Starting with OSX 10.14, which uses Core Animation to draw windows, + * all drawing must be done within the drawRect method. (The CGContext + * which draws to the backing CALayer is created by the NSView before + * calling drawRect, and destroyed when drawRect returns. Drawing done + * with the current CGContext outside of the drawRect method has no + * effect.) + * + * Fortunately, Tk schedules all drawing to be done while Tcl is idle. + * So we can do the drawing by processing all of the idle events that + * were created when the expose events were processed. + */ + + while (Tcl_DoOneEvent(TCL_IDLE_EVENTS)) {} + } +} + + +/* + * These two methods allow Tk to register a virtual event which fires when the + * appearance changes on 10.14. + */ + +- (void) viewDidChangeEffectiveAppearance +{ + [self updateAppearanceEvent]; +} + +- (void) updateAppearanceEvent +{ + NSString *osxMode = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; + NSWindow *w = [self window]; + TkWindow *winPtr = TkMacOSXGetTkWindow(w); + XVirtualEvent event; + int x, y; + Tk_Window tkwin = (Tk_Window) winPtr; + bzero(&event, sizeof(XVirtualEvent)); + event.type = VirtualEvent; + event.serial = LastKnownRequestProcessed(Tk_Display(tkwin)); + event.send_event = false; + event.display = Tk_Display(tkwin); + event.event = Tk_WindowId(tkwin); + event.root = XRootWindow(Tk_Display(tkwin), 0); + event.subwindow = None; + event.time = TkpGetMS(); + XQueryPointer(NULL, winPtr->window, NULL, NULL, + &event.x_root, &event.y_root, &x, &y, &event.state); + Tk_TopCoordsToWindow(tkwin, x, y, &event.x, &event.y); + event.same_screen = true; + if (osxMode == nil) { + event.name = Tk_GetUid("LightAqua"); + Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); + return; + } + if ([osxMode isEqual:@"Dark"]) { + event.name = Tk_GetUid("DarkAqua"); + Tk_QueueWindowEvent((XEvent *) &event, TCL_QUEUE_TAIL); + return; } } /* * This is no-op on 10.7 and up because Apple has removed this widget, * but we are leaving it here for backwards compatibility. */ + - (void) tkToolbarButton: (id) sender { #ifdef TK_MAC_DEBUG_EVENTS TKLog(@"-[%@(%p) %s] %@", [self class], self, _cmd); #endif @@ -976,18 +1013,12 @@ } - (BOOL) isOpaque { NSWindow *w = [self window]; - - if (opaqueTag) { - return YES; - } else { - - return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) || + return (w && (([w styleMask] & NSTexturedBackgroundWindowMask) || ![w isOpaque]) ? NO : YES); - } } - (BOOL) wantsDefaultClipping { return NO; Index: macosx/tkMacOSXWm.c ================================================================== --- macosx/tkMacOSXWm.c +++ macosx/tkMacOSXWm.c @@ -8,10 +8,11 @@ * * Copyright (c) 1994-1997 Sun Microsystems, Inc. * Copyright 2001-2009, Apple Inc. * Copyright (c) 2006-2009 Daniel A. Steffen * Copyright (c) 2010 Kevin Walzer/WordTech Communications LLC. + * Copyright (c) 2017 Marc Culler. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. */ @@ -18,10 +19,11 @@ #include "tkMacOSXPrivate.h" #include "tkScrollbar.h" #include "tkMacOSXWm.h" #include "tkMacOSXEvent.h" #include "tkMacOSXDebug.h" +#include "tkMacOSXConstants.h" #define DEBUG_ZOMBIES 0 /* #ifdef TK_MAC_DEBUG @@ -51,13 +53,10 @@ | kWindowOpaqueForEventsAttribute | kWindowIgnoreClicksAttribute \ | kWindowDoesNotCycleAttribute | tkWindowDoesNotHideAttribute \ | tkCanJoinAllSpacesAttribute | tkMoveToActiveSpaceAttribute \ | tkNonactivatingPanelAttribute | tkHUDWindowAttribute) -/*Objects for use in setting background color and opacity of window.*/ -NSColor *colorName = NULL; -BOOL opaqueTag = FALSE; static const struct { const UInt64 validAttrs, defaultAttrs, forceOnAttrs, forceOffAttrs; int flags; NSUInteger styleMask; } macClassAttrs[] = { @@ -195,11 +194,10 @@ static Tcl_HashTable windowTable; static int windowHashInit = false; - #pragma mark NSWindow(TKWm) /* * Conversion of coordinates between window and screen. */ @@ -212,11 +210,10 @@ } - (NSPoint) convertPointFromScreen: (NSPoint)point { return [self convertScreenToBase:point]; } -@end #else - (NSPoint) convertPointToScreen: (NSPoint) point { NSRect pointrect; pointrect.origin = point; @@ -230,12 +227,28 @@ pointrect.origin = point; pointrect.size.width = 0; pointrect.size.height = 0; return [self convertRectFromScreen:pointrect].origin; } -@end #endif + +- (NSSize)windowWillResize:(NSWindow *)sender + toSize:(NSSize)frameSize +{ + NSRect currentFrame = [sender frame]; + TkWindow *winPtr = TkMacOSXGetTkWindow(sender); + if (winPtr) { + if (winPtr->wmInfoPtr->flags & WM_WIDTH_NOT_RESIZABLE) { + frameSize.width = currentFrame.size.width; + } + if (winPtr->wmInfoPtr->flags & WM_HEIGHT_NOT_RESIZABLE) { + frameSize.height = currentFrame.size.height; + } + } + return frameSize; +} +@end #pragma mark - /* @@ -362,29 +375,51 @@ static void GetMaxSize(TkWindow *winPtr, int *maxWidthPtr, int *maxHeightPtr); static void RemapWindows(TkWindow *winPtr, MacDrawable *parentWin); -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 -#define TK_GOT_AT_LEAST_SNOW_LEOPARD 1 -#endif - #pragma mark TKWindow(TKWm) -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 -@interface NSWindow(TkWm) -- (void) setCanCycle: (BOOL) canCycleFlag; -@end -#endif - @interface NSDrawerWindow : NSWindow { id _i1, _i2; } @end -@implementation TKWindow + +@implementation TKWindow: NSWindow +#if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12 +/* + * Override automatic fullscreen button on >10.12 because system fullscreen API + * confuses Tk window geometry. Custom implementation setting fullscreen status using + * Tk API and NSStatusItem in menubar to exit fullscreen status. + */ + +NSStatusItem *exitFullScreen; + +- (void)toggleFullScreen:(id)sender +{ + TkWindow *winPtr = TkMacOSXGetTkWindow(self); + Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr); + + if (([self styleMask] & NSFullScreenWindowMask) == NSFullScreenWindowMask) { + TkMacOSXMakeFullscreen(winPtr, self, 0, interp); + } else { + TkMacOSXMakeFullscreen(winPtr, self, 1, interp); + } +} + +-(void)restoreOldScreen:(id)sender { + + TkWindow *winPtr = TkMacOSXGetTkWindow(self); + Tcl_Interp *interp = Tk_Interp((Tk_Window)winPtr); + + TkMacOSXMakeFullscreen(winPtr, self, 0, interp); + [[NSStatusBar systemStatusBar] removeStatusItem: exitFullScreen]; +} + +#endif @end @implementation TKWindow(TKWm) - (BOOL) canBecomeKeyWindow @@ -393,10 +428,12 @@ return (winPtr && winPtr->wmInfoPtr && (winPtr->wmInfoPtr->macClass == kHelpWindowClass || winPtr->wmInfoPtr->attributes & kWindowNoActivatesAttribute)) ? NO : YES; } + + #if DEBUG_ZOMBIES - (id) retain { id result = [super retain]; @@ -410,11 +447,10 @@ return result; } - (id) autorelease { - static int xcount = 0; id result = [super autorelease]; const char *title = [[self title] UTF8String]; if (title == nil) { title = "unnamed window"; } @@ -765,10 +801,14 @@ * Map the window. */ XMapWindow(winPtr->display, winPtr->window); + /*Add window to Window menu.*/ + NSWindow *win = TkMacOSXDrawableWindow(winPtr->window); + [win setExcludedFromWindowsMenu:NO]; + } /* *---------------------------------------------------------------------- * @@ -875,35 +915,55 @@ if (window && !Tk_IsEmbedded(winPtr) ) { NSWindow *parent = [window parentWindow]; if (parent) { [parent removeChildWindow:window]; } - [window close]; - TkMacOSXUnregisterMacWindow(window); - if (winPtr->window) { - ((MacDrawable *) winPtr->window)->view = nil; - } #if DEBUG_ZOMBIES > 0 { const char *title = [[window title] UTF8String]; if (title == nil) { title = "unnamed window"; } printf(">>>> Closing <%s>. Count is: %lu\n", title, [window retainCount]); } #endif - [window release]; + [window close]; + TkMacOSXUnregisterMacWindow(window); + if (winPtr->window) { + ((MacDrawable *) winPtr->window)->view = nil; + } wmPtr->window = NULL; + [window release]; /* Activate the highest window left on the screen. */ NSArray *windows = [NSApp orderedWindows]; - if ( [windows count] > 0 ) { - NSWindow *front = [windows objectAtIndex:0]; - if ( front && [front canBecomeKeyWindow] ) { - [front makeKeyAndOrderFront:NSApp]; + for (id nswindow in windows) { + TkWindow *winPtr2 = TkMacOSXGetTkWindow(nswindow); + if (winPtr2 && nswindow != window) { + WmInfo *wmPtr = winPtr2->wmInfoPtr; + BOOL minimized = (wmPtr->hints.initial_state == IconicState || + wmPtr->hints.initial_state == WithdrawnState); + /* + * If no windows are left on the screen and the next + * window is iconified or withdrawn, we don't want to + * make it be the KeyWindow because that would cause + * it to be displayed on the screen. + */ + if ([nswindow canBecomeKeyWindow] && !minimized) { + [nswindow makeKeyAndOrderFront:NSApp]; + break; + } } } + /* + * Process all window events immediately to force the closed window to + * be deallocated. But don't do this for the root window as that is + * unnecessary and can lead to segfaults. + */ + if (winPtr->parentPtr) { + while (Tk_DoOneEvent(TK_WINDOW_EVENTS|TK_DONT_WAIT)) {} + } [NSApp _resetAutoreleasePool]; #if DEBUG_ZOMBIES > 0 fprintf(stderr, "================= Pool dump ===================\n"); [NSAutoreleasePool showPools]; @@ -1933,11 +1993,11 @@ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { register WmInfo *wmPtr = winPtr->wmInfoPtr; int reqWidth, reqHeight, widthInc, heightInc; - char *errorMsg; + const char *errorMsg; if ((objc != 3) && (objc != 7)) { Tcl_WrongNumArgs(interp, 2, objv, "window ?baseWidth baseHeight widthInc heightInc?"); return TCL_ERROR; @@ -2312,18 +2372,18 @@ *---------------------------------------------------------------------- * * WmIconphotoCmd -- * * This procedure is invoked to process the "wm iconphoto" Tcl command. - * See the user documentation for details on what it does. Not yet - * implemented for OS X. + * See the user documentation for details on what it does. * * Results: * A standard Tcl result. * * Side effects: * See the user documentation. + * * *---------------------------------------------------------------------- */ static int @@ -2332,49 +2392,56 @@ TkWindow *winPtr, /* Toplevel to work with */ Tcl_Interp *interp, /* Current interpreter. */ int objc, /* Number of arguments. */ Tcl_Obj *const objv[]) /* Argument objects. */ { - Tk_PhotoHandle photo; - int i, width, height, isDefault = 0; + Tk_Image tk_icon; + int width, height, isDefault = 0; if (objc < 4) { Tcl_WrongNumArgs(interp, 2, objv, - "window ?-default? image1 ?image2 ...?"); + "window ?-default? image1 ?image2 ...?"); return TCL_ERROR; } + + /*Parse args.*/ if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) { isDefault = 1; if (objc == 4) { Tcl_WrongNumArgs(interp, 2, objv, - "window ?-default? image1 ?image2 ...?"); + "window ?-default? image1 ?image2 ...?"); return TCL_ERROR; } } - /* - * Iterate over all images to retrieve their sizes, in order to allocate a - * buffer large enough to hold all images. - */ - - for (i = 3 + isDefault; i < objc; i++) { - photo = Tk_FindPhoto(interp, Tcl_GetString(objv[i])); - if (photo == NULL) { - Tcl_SetObjResult(interp, Tcl_ObjPrintf( - "can't use \"%s\" as iconphoto: not a photo image", - Tcl_GetString(objv[i]))); - Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL); - return TCL_ERROR; - } - Tk_PhotoGetSize(photo, &width, &height); - } - - /* - * TODO: This requires implementation for OS X, but we silently return for - * now. - */ - + /*Get icon name. We only use the first icon name because macOS does not + support multiple images in Tk photos.*/ + char *icon; + if (strcmp(Tcl_GetString(objv[3]), "-default") == 0) { + icon = Tcl_GetString(objv[4]); + } else { + icon = Tcl_GetString(objv[3]); + } + + /*Get image and convert to NSImage that can be displayed as icon.*/ + tk_icon = Tk_GetImage(interp, tkwin, icon, NULL, NULL); + if (tk_icon == NULL) { + Tcl_SetObjResult(interp, Tcl_ObjPrintf( + "can't use \"%s\" as iconphoto: not a photo image", + icon)); + Tcl_SetErrorCode(interp, "TK", "WM", "ICONPHOTO", "PHOTO", NULL); + return TCL_ERROR; + } + + NSImage *newIcon; + Tk_SizeOfImage(tk_icon, &width, &height); + newIcon = TkMacOSXGetNSImageWithTkImage(winPtr->display, tk_icon, width, height); + Tk_FreeImage(tk_icon); + if (newIcon == NULL) { + return TCL_ERROR; + } + [NSApp setApplicationIconImage: newIcon]; return TCL_OK; } /* *---------------------------------------------------------------------- @@ -2891,21 +2958,24 @@ if (prevPtr == NULL) { wmPtr->protPtr = protPtr->nextPtr; } else { prevPtr->nextPtr = protPtr->nextPtr; } + if (protPtr->command) + ckfree(protPtr->command); Tcl_EventuallyFree(protPtr, TCL_DYNAMIC); break; } } cmd = Tcl_GetStringFromObj(objv[4], &cmdLength); if (cmdLength > 0) { - protPtr = ckalloc(HANDLER_SIZE(cmdLength)); + protPtr = ckalloc(sizeof(ProtocolHandler)); protPtr->protocol = protocol; protPtr->nextPtr = wmPtr->protPtr; wmPtr->protPtr = protPtr; protPtr->interp = interp; + protPtr->command = ckalloc(cmdLength+1); strcpy(protPtr->command, cmd); } return TCL_OK; } @@ -3390,40 +3460,48 @@ wmPtr->masterWindowName = NULL; } else { if (TkGetWindowFromObj(interp, tkwin, objv[3], &master) != TCL_OK) { return TCL_ERROR; } - Tk_MakeWindowExist(master); + TkWindow* masterPtr = (TkWindow*) master; + while (!Tk_TopWinHierarchy(masterPtr)) { + /* + * Ensure that the master window is actually a Tk toplevel. + */ + + masterPtr = masterPtr->parentPtr; + } + Tk_MakeWindowExist((Tk_Window)masterPtr); if (wmPtr->iconFor != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't make \"%s\" a transient: it is an icon for %s", Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL); return TCL_ERROR; } - wmPtr2 = ((TkWindow *) master)->wmInfoPtr; - + wmPtr2 = masterPtr->wmInfoPtr; /* Under some circumstances, wmPtr2 is NULL here */ if (wmPtr2 != NULL && wmPtr2->iconFor != NULL) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't make \"%s\" a master: it is an icon for %s", Tcl_GetString(objv[3]), Tk_PathName(wmPtr2->iconFor))); Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "ICON", NULL); return TCL_ERROR; } - if ((TkWindow *) master == winPtr) { + if (masterPtr == winPtr) { Tcl_SetObjResult(interp, Tcl_ObjPrintf( "can't make \"%s\" its own master", Tk_PathName(winPtr))); Tcl_SetErrorCode(interp, "TK", "WM", "TRANSIENT", "SELF", NULL); return TCL_ERROR; } - wmPtr->master = Tk_WindowId(master); - masterWindowName = Tcl_GetStringFromObj(objv[3], &length); + wmPtr->master = Tk_WindowId(masterPtr); + masterWindowName = masterPtr->pathName; + length = strlen(masterWindowName); if (wmPtr->masterWindowName != NULL) { ckfree(wmPtr->masterWindowName); } wmPtr->masterWindowName = ckalloc(length+1); strcpy(wmPtr->masterWindowName, masterWindowName); @@ -3470,10 +3548,14 @@ Tcl_GetString(objv[2]), Tk_PathName(wmPtr->iconFor))); Tcl_SetErrorCode(interp, "TK", "WM", "WITHDRAW", "ICON", NULL); return TCL_ERROR; } TkpWmSetState(winPtr, WithdrawnState); + /*Remove window from Window menu.*/ + NSWindow *win = TkMacOSXDrawableWindow(winPtr->window); + [win setExcludedFromWindowsMenu:YES]; + return TCL_OK; } /* * Invoked by those wm subcommands that affect geometry. @@ -4207,19 +4289,11 @@ * The container window is in the same application. Query its * coordinates. */ winPtr = otherPtr; - - /* - * Remember to offset by the container window here, since at the - * end of this if branch, we will pop out to the container's - * parent... - */ - - x += winPtr->changes.x + winPtr->changes.border_width; - y += winPtr->changes.y + winPtr->changes.border_width; + continue; } winPtr = winPtr->parentPtr; } *xPtr = x; *yPtr = y; @@ -4630,48 +4704,54 @@ TkWindow *otherPtr) /* Window relative to which to restack; if * NULL, then winPtr gets restacked above or * below *all* siblings. */ { NSWindow *macWindow; - NSInteger otherMacWindowNumber; - - /* - * Get the mac window. Make sure it exists & is mapped. - */ - - if (winPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) winPtr); - } - if (winPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - /* - * Can't set stacking order properly until the window is on the screen - * (mapping it may give it a reparent window), so make sure it's on - * the screen. - */ - - TkWmMapWindow(winPtr); + NSWindow *otherMacWindow; + WmInfo *wmPtr = winPtr->wmInfoPtr; + int macAboveBelow = (aboveBelow == Above ? NSWindowAbove : NSWindowBelow); + int otherNumber = 0; /* 0 will be used when otherPtr is NULL. */ + + /* + * If the Tk windows has no drawable, or is withdrawn do nothing. + */ + if (winPtr->window == None || + wmPtr == NULL || + wmPtr->hints.initial_state == WithdrawnState) { + return; } macWindow = TkMacOSXDrawableWindow(winPtr->window); + if (macWindow == nil) { + return; + } + if (otherPtr) { + /* + * When otherPtr is non-NULL, if the other window has no + * drawable or is withdrawn, do nothing. + */ + WmInfo *otherWmPtr = otherPtr->wmInfoPtr; + if (winPtr->window == None || + otherWmPtr == NULL || + otherWmPtr->hints.initial_state == WithdrawnState) { + return; + } + otherMacWindow = TkMacOSXDrawableWindow(otherPtr->window); + if (otherMacWindow == nil) { + return; + } else { + /* + * If the other window is OK, get its number. + */ + otherNumber = [otherMacWindow windowNumber]; + } + } /* - * Get the window in which a raise or lower is in relation to. + * Just let the Mac window manager deal with all the subtleties + * of keeping track of off-screen windows, etc. */ - - if (otherPtr != NULL) { - if (otherPtr->window == None) { - Tk_MakeWindowExist((Tk_Window) otherPtr); - } - if (otherPtr->wmInfoPtr->flags & WM_NEVER_MAPPED) { - TkWmMapWindow(otherPtr); - } - otherMacWindowNumber = [TkMacOSXDrawableWindow(otherPtr->window) - windowNumber]; - } else { - otherMacWindowNumber = 0; - } - [macWindow orderWindow:(aboveBelow == Above ? NSWindowAbove : NSWindowBelow) - relativeTo:otherMacWindowNumber]; + [macWindow orderWindow:macAboveBelow relativeTo:otherNumber]; } /* *---------------------------------------------------------------------- * @@ -5087,12 +5167,12 @@ /* *---------------------------------------------------------------------- * * TkMacOSXIsWindowZoomed -- * - * Ask Carbon if the given window is in the zoomed out state. Because - * dragging & growing a window can change the Carbon zoom state, we + * Ask Cocoa if the given window is in the zoomed out state. Because + * dragging & growing a window can change the Cocoa zoom state, we * cannot rely on wmInfoPtr->hints.initial_state for this information. * * Results: * True if window is zoomed out, false otherwise. * @@ -5106,10 +5186,11 @@ TkMacOSXIsWindowZoomed( TkWindow *winPtr) { return [TkMacOSXDrawableWindow(winPtr->window) isZoomed]; } + /* *---------------------------------------------------------------------- * * TkMacOSXZoomToplevel -- @@ -5148,16 +5229,17 @@ /* * Do nothing if already in desired zoom state. */ - if (![window isZoomed] == (zoomPart == inZoomIn)) { + if ((![window isZoomed] == (zoomPart == inZoomIn))) { return false; } - [window zoom:NSApp]; - wmPtr->hints.initial_state = - (zoomPart == inZoomIn ? NormalState : ZoomState); + [window zoom:NSApp]; + + wmPtr->hints.initial_state = + (zoomPart == inZoomIn ? NormalState : ZoomState); return true; } /* *---------------------------------------------------------------------- @@ -5191,58 +5273,17 @@ enum SubCmds { TKMWS_STYLE }; Tk_Window tkwin = clientData; TkWindow *winPtr; - int index, i; + int index; if (objc < 3) { Tcl_WrongNumArgs(interp, 1, objv, "option window ?arg ...?"); return TCL_ERROR; } - /* - * Iterate through objc/objv to set correct background color and toggle - * opacity of window. - */ - - for (i= 0; i < objc; i++) { - if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*black*")) { - colorName = [NSColor blackColor]; // use #000000 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*dark*")) { - colorName = [NSColor darkGrayColor]; //use #545454 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*light*")) { - colorName = [NSColor lightGrayColor]; //use #ababab in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*white*")) { - colorName = [NSColor whiteColor]; //use #ffffff in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "gray*")) { - colorName = [NSColor grayColor]; //use #7f7f7f in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*red*")) { - colorName = [NSColor redColor]; //use #ff0000 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*green*")) { - colorName = [NSColor greenColor]; //use #00ff00 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*blue*")) { - colorName = [NSColor blueColor]; //use #0000ff in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*cyan*")) { - colorName = [NSColor cyanColor]; //use #00ffff in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*yellow*")) { - colorName = [NSColor yellowColor]; //use #ffff00 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*magenta*")) { - colorName = [NSColor magentaColor]; //use #ff00ff in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*orange*")) { - colorName = [NSColor orangeColor]; //use #ff8000 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*purple*")) { - colorName = [NSColor purpleColor]; //use #800080 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*brown*")){ - colorName = [NSColor brownColor]; //use #996633 in Tk scripts to match - } else if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*clear*")) { - colorName = [NSColor clearColor]; //use systemTransparent in Tk scripts to match - } - if (Tcl_StringMatch(Tcl_GetString(objv[i]), "*opacity*")) { - opaqueTag = YES; - } - } winPtr = (TkWindow *) Tk_NameToWindow(interp, Tcl_GetString(objv[2]), tkwin); if (winPtr == NULL) { return TCL_ERROR; @@ -5613,30 +5654,16 @@ [(NSPanel*)window setFloatingPanel:YES]; } if ((styleMask & (NSTexturedBackgroundWindowMask|NSHUDWindowMask)) && !(styleMask & NSDocModalWindowMask)) { /* - * Workaround for [Bug 2824538]: Texured windows are draggable + * Workaround for [Bug 2824538]: Textured windows are draggable * from opaque content. */ [window setMovableByWindowBackground:NO]; } - - /* Set background color and opacity of window if those flags are set. */ - if (colorName != NULL) { - [window setBackgroundColor: colorName]; - } - - if (opaqueTag) { -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD - [window setOpaque: opaqueTag]; -#else - [window setOpaque: YES]; -#endif - } - [window setDocumentEdited:NO]; wmPtr->window = window; macWin->view = window.contentView; TkMacOSXApplyWindowAttributes(winPtr, window); @@ -6270,16 +6297,19 @@ [macWindow setShowsResizeIndicator: !!(newAttributes & kWindowResizableAttribute)]; [[macWindow standardWindowButton:NSWindowZoomButton] setEnabled:(newAttributes & kWindowResizableAttribute) && (newAttributes & kWindowFullZoomAttribute)]; - if (newAttributes & kWindowResizableAttribute) { - wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE | - WM_HEIGHT_NOT_RESIZABLE); + if (newAttributes & kWindowHorizontalZoomAttribute) { + wmPtr->flags &= ~(WM_WIDTH_NOT_RESIZABLE); + } else { + wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE); + } + if (newAttributes & kWindowVerticalZoomAttribute) { + wmPtr->flags &= ~(WM_HEIGHT_NOT_RESIZABLE); } else { - wmPtr->flags |= (WM_WIDTH_NOT_RESIZABLE | - WM_HEIGHT_NOT_RESIZABLE); + wmPtr->flags |= (WM_HEIGHT_NOT_RESIZABLE); } WmUpdateGeom(wmPtr, winPtr); } if ((changedAttributes & kWindowToolbarButtonAttribute) || initial) { [macWindow setShowsToolbarButton: @@ -6323,28 +6353,16 @@ if (newAttributes & tkCanJoinAllSpacesAttribute) { b |= NSWindowCollectionBehaviorCanJoinAllSpaces; } else if (newAttributes & tkMoveToActiveSpaceAttribute) { b |= NSWindowCollectionBehaviorMoveToActiveSpace; } -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 if (newAttributes & kWindowDoesNotCycleAttribute) { b |= NSWindowCollectionBehaviorIgnoresCycle; } else { b |= NSWindowCollectionBehaviorParticipatesInCycle; } -#endif [macWindow setCollectionBehavior:b]; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 1060 - if (((changedAttributes & kWindowDoesNotCycleAttribute) || initial) -#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1060 - && tkMacOSXMacOSXVersion < 1060 -#endif - ) { - [macWindow setCanCycle: - !(newAttributes & kWindowDoesNotCycleAttribute)]; - } -#endif } if ((wmPtr->flags & WM_TOPMOST) != (oldFlags & WM_TOPMOST)) { [macWindow setLevel:(wmPtr->flags & WM_TOPMOST) ? kCGUtilityWindowLevel : ([macWindow isKindOfClass: [NSPanel class]] && [macWindow isFloatingPanel] ? @@ -6472,13 +6490,12 @@ int fullscreen, Tcl_Interp *interp) { WmInfo *wmPtr = winPtr->wmInfoPtr; int result = TCL_OK, wasFullscreen = (wmPtr->flags & WM_FULLSCREEN); -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD static unsigned long prevMask = 0, prevPres = 0; -#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/ + if (fullscreen) { int screenWidth = WidthOfScreen(Tk_Screen(winPtr)); int screenHeight = HeightOfScreen(Tk_Screen(winPtr)); @@ -6496,10 +6513,11 @@ "CONSTRAINT_FAILURE", NULL); } result = TCL_ERROR; wmPtr->flags &= ~WM_FULLSCREEN; } else { + Tk_UnmapWindow((Tk_Window) winPtr); NSRect bounds = [window contentRectForFrameRect:[window frame]]; NSRect screenBounds = NSMakeRect(0, 0, screenWidth, screenHeight); if (!NSEqualRects(bounds, screenBounds) && !wasFullscreen) { wmPtr->configX = wmPtr->x; @@ -6508,40 +6526,42 @@ wmPtr->attributes &= ~kWindowResizableAttribute; ApplyWindowAttributeFlagChanges(winPtr, window, wmPtr->configAttributes, wmPtr->flags, 1, 0); wmPtr->flags |= WM_SYNC_PENDING; [window setFrame:[window frameRectForContentRect: - screenBounds] display:YES]; + screenBounds] display:YES]; wmPtr->flags &= ~WM_SYNC_PENDING; } wmPtr->flags |= WM_FULLSCREEN; } -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD - /* - * We can't set these features on Leopard or earlier, as they don't - * exist (neither options nor API that uses them). This formally means - * that there's a bug with full-screen windows with Tk on old OSX, but - * it isn't worth blocking a build just for this. - */ - prevMask = [window styleMask]; prevPres = [NSApp presentationOptions]; - [window setStyleMask: NSBorderlessWindowMask]; - [NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock - | NSApplicationPresentationAutoHideMenuBar]; -#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/ + [window setStyleMask: NSFullScreenWindowMask]; + [NSApp setPresentationOptions: NSApplicationPresentationAutoHideDock | NSApplicationPresentationAutoHideMenuBar]; + + /*Fullscreen implementation for 10.13 and later.*/ + #if MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_12 + exitFullScreen = [[[NSStatusBar systemStatusBar] + statusItemWithLength:NSVariableStatusItemLength] retain]; + NSImage *exitIcon = [NSImage imageNamed:@"NSExitFullScreenTemplate"]; + [exitFullScreen setImage:exitIcon]; + [exitFullScreen setHighlightMode:YES]; + [exitFullScreen setToolTip:@"Exit Full Screen"]; + [exitFullScreen setTarget:window]; + [exitFullScreen setAction:@selector(restoreOldScreen:)]; + #endif + + Tk_MapWindow((Tk_Window) winPtr); } else { wmPtr->flags &= ~WM_FULLSCREEN; - -#ifdef TK_GOT_AT_LEAST_SNOW_LEOPARD [NSApp setPresentationOptions: prevPres]; [window setStyleMask: prevMask]; -#endif /*TK_GOT_AT_LEAST_SNOW_LEOPARD*/ } if (wasFullscreen && !(wmPtr->flags & WM_FULLSCREEN)) { + Tk_UnmapWindow((Tk_Window) winPtr); UInt64 oldAttributes = wmPtr->attributes; NSRect bounds = NSMakeRect(wmPtr->configX, tkMacOSXZeroScreenHeight - (wmPtr->configY + wmPtr->yInParent + wmPtr->configHeight), wmPtr->xInParent + wmPtr->configWidth, wmPtr->yInParent + wmPtr->configHeight); @@ -6551,10 +6571,11 @@ ApplyWindowAttributeFlagChanges(winPtr, window, oldAttributes, wmPtr->flags, 1, 0); wmPtr->flags |= WM_SYNC_PENDING; [window setFrame:[window frameRectForContentRect:bounds] display:YES]; wmPtr->flags &= ~WM_SYNC_PENDING; + Tk_MapWindow((Tk_Window) winPtr); } return result; } /* Index: macosx/tkMacOSXWm.h ================================================================== --- macosx/tkMacOSXWm.h +++ macosx/tkMacOSXWm.h @@ -27,19 +27,17 @@ struct ProtocolHandler *nextPtr; /* Next in list of protocol handlers for the * same top-level window, or NULL for end of * list. */ Tcl_Interp *interp; /* Interpreter in which to invoke command. */ - char command[4]; /* Tcl command to invoke when a client message + char* command; /* Tcl command to invoke when a client message * for this protocol arrives. The actual size * of the structure varies to accommodate the * needs of the actual command. THIS MUST BE * THE LAST FIELD OF THE STRUCTURE. */ } ProtocolHandler; -#define HANDLER_SIZE(cmdLength) \ -((unsigned) (sizeof(ProtocolHandler) - 3 + cmdLength)) /* * A data structure of the following type holds window-manager-related * information for each top-level window in an application. */ Index: macosx/tkMacOSXXStubs.c ================================================================== --- macosx/tkMacOSXXStubs.c +++ macosx/tkMacOSXXStubs.c @@ -38,31 +38,26 @@ /* * Declarations of static variables used in this file. */ +/* The unique Macintosh display. */ static TkDisplay *gMacDisplay = NULL; - /* Macintosh display. */ +/* The default name of the Macintosh display. */ static const char *macScreenName = ":0"; - /* Default name of macintosh display. */ +/* Timestamp showing the last reset of the inactivity timer. */ +static Time lastInactivityReset = 0; + /* * Forward declarations of procedures used in this file. */ static XID MacXIdAlloc(Display *display); static int DefaultErrorHandler(Display *display, XErrorEvent *err_evt); -/* - * Other declarations - */ - -static int DestroyImage(XImage *image); -static unsigned long ImageGetPixel(XImage *image, int x, int y); -static int ImagePutPixel(XImage *image, int x, int y, - unsigned long pixel); /* *---------------------------------------------------------------------- * * TkMacOSXDisplayChanged -- @@ -181,11 +176,11 @@ } display->vendor = vendor; { int major, minor, patch; -#if MAC_OS_X_VERSION_MIN_REQUIRED < 10100 +#if MAC_OS_X_VERSION_MIN_REQUIRED < 1080 Gestalt(gestaltSystemVersionMajor, (SInt32*)&major); Gestalt(gestaltSystemVersionMinor, (SInt32*)&minor); Gestalt(gestaltSystemVersionBugFix, (SInt32*)&patch); #else NSOperatingSystemVersion systemVersion = [[NSProcessInfo processInfo] operatingSystemVersion]; @@ -206,10 +201,11 @@ screen->ext_data = (XExtData *) &maxBounds; screen->root_visual = ckalloc(sizeof(Visual)); screen->root_visual->visualid = 0; screen->root_visual->class = TrueColor; + screen->root_visual->alpha_mask = 0xFF000000; screen->root_visual->red_mask = 0x00FF0000; screen->root_visual->green_mask = 0x0000FF00; screen->root_visual->blue_mask = 0x000000FF; screen->root_visual->bits_per_rgb = 24; screen->root_visual->map_entries = 256; @@ -381,17 +377,10 @@ { display->request++; return NULL; } -int -_XInitImageFuncPtrs( - XImage *image) -{ - return 0; -} - XErrorHandler XSetErrorHandler( XErrorHandler handler) { return DefaultErrorHandler; @@ -526,21 +515,21 @@ Window w) { } /* -void +int XDrawPoint( Display* display, Drawable d, GC gc, int x, int y) { } -void +int XDrawPoints( Display* display, Drawable d, GC gc, XPoint* points, @@ -679,18 +668,10 @@ */ display->request++; } -void -Tk_FreeXId( - Display *display, - XID xid) -{ - /* no-op function needed for stubs implementation. */ -} - int XSync( Display *display, Bool flag) { @@ -760,390 +741,10 @@ snprintf(buffer2, sizeof(buffer2), " Mac OS X %x", VendorRelease(Tk_Display(tkwin))); Tcl_AppendResult(interp, buffer, ServerVendor(Tk_Display(tkwin)), buffer2, NULL); } - -#pragma mark XImage handling - -/* - *---------------------------------------------------------------------- - * - * XCreateImage -- - * - * Allocates storage for a new XImage. - * - * Results: - * Returns a newly allocated XImage. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -XImage * -XCreateImage( - Display* display, - Visual* visual, - unsigned int depth, - int format, - int offset, - char* data, - unsigned int width, - unsigned int height, - int bitmap_pad, - int bytes_per_line) -{ - XImage *ximage; - display->request++; - ximage = ckalloc(sizeof(XImage)); - - ximage->height = height; - ximage->width = width; - ximage->depth = depth; - ximage->xoffset = offset; - ximage->format = format; - ximage->data = data; - ximage->obdata = NULL; - /* The default pixelpower is 0. This must be explicitly set to 1 in the - * case of an XImage extracted from a Retina display. - */ - ximage->pixelpower = 0; - - if (format == ZPixmap) { - ximage->bits_per_pixel = 32; - ximage->bitmap_unit = 32; - } else { - ximage->bits_per_pixel = 1; - ximage->bitmap_unit = 8; - } - if (bitmap_pad) { - ximage->bitmap_pad = bitmap_pad; - } else { - /* Use 16 byte alignment for best Quartz perfomance */ - ximage->bitmap_pad = 128; - } - if (bytes_per_line) { - ximage->bytes_per_line = bytes_per_line; - } else { - ximage->bytes_per_line = ((width * ximage->bits_per_pixel + - (ximage->bitmap_pad - 1)) >> 3) & - ~((ximage->bitmap_pad >> 3) - 1); - } -#ifdef WORDS_BIGENDIAN - ximage->byte_order = MSBFirst; - ximage->bitmap_bit_order = MSBFirst; -#else - ximage->byte_order = LSBFirst; - ximage->bitmap_bit_order = LSBFirst; -#endif - ximage->red_mask = 0x00FF0000; - ximage->green_mask = 0x0000FF00; - ximage->blue_mask = 0x000000FF; - ximage->f.create_image = NULL; - ximage->f.destroy_image = DestroyImage; - ximage->f.get_pixel = ImageGetPixel; - ximage->f.put_pixel = ImagePutPixel; - ximage->f.sub_image = NULL; - ximage->f.add_pixel = NULL; - - return ximage; -} - -/* - *---------------------------------------------------------------------- - * - * XGetImage -- - * - * This function copies data from a pixmap or window into an XImage. - * - * Results: - * Returns a newly allocated XImage containing the data from the given - * rectangle of the given drawable, or NULL if the XImage could not be - * constructed. NOTE: If we are copying from a window on a Retina - * display, the dimensions of the XImage will be 2*width x 2*height. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -XImage * -XGetImage( - Display *display, - Drawable d, - int x, - int y, - unsigned int width, - unsigned int height, - unsigned long plane_mask, - int format) -{ - NSBitmapImageRep *bitmap_rep; - NSUInteger bitmap_fmt; - XImage * imagePtr = NULL; - char * bitmap = NULL; - char * image_data=NULL; - int depth = 32; - int offset = 0; - int bitmap_pad = 0; - int bytes_per_row = 4*width; - int size; - MacDrawable *macDraw = (MacDrawable *) d; - NSWindow *win = TkMacOSXDrawableWindow(d); - /* This code assumes that backing scale factors are integers. Currently - * Retina displays use a scale factor of 2.0 and normal displays use 1.0. - * We do not support any other values here. - */ - int scalefactor = 1; - if (win && [win respondsToSelector:@selector(backingScaleFactor)]) { - scalefactor = ([win backingScaleFactor] == 2.0) ? 2 : 1; - } - int scaled_height = height * scalefactor; - int scaled_width = width * scalefactor; - - if (format == ZPixmap) { - if (width == 0 || height == 0) { - /* This happens all the time. - TkMacOSXDbgMsg("XGetImage: empty image requested"); - */ - return NULL; - } - - bitmap_rep = BitmapRepFromDrawableRect(d, x, y, width, height); - bitmap_fmt = [bitmap_rep bitmapFormat]; - - if ( bitmap_rep == Nil || - (bitmap_fmt != 0 && bitmap_fmt != 1) || - [bitmap_rep samplesPerPixel] != 4 || - [bitmap_rep isPlanar] != 0 ) { - TkMacOSXDbgMsg("XGetImage: Failed to construct NSBitmapRep"); - return NULL; - } - - NSSize image_size = NSMakeSize(width, height); - NSImage* ns_image = [[NSImage alloc]initWithSize:image_size]; - [ns_image addRepresentation:bitmap_rep]; - - /* Assume premultiplied nonplanar data with 4 bytes per pixel.*/ - if ( [bitmap_rep isPlanar ] == 0 && - [bitmap_rep samplesPerPixel] == 4 ) { - bytes_per_row = [bitmap_rep bytesPerRow]; - assert(bytes_per_row == 4 * scaled_width); - assert([bitmap_rep bytesPerPlane] == bytes_per_row * scaled_height); - size = bytes_per_row*scaled_height; - image_data = (char*)[bitmap_rep bitmapData]; - if ( image_data ) { - int row, n, m; - bitmap = ckalloc(size); - /* - Oddly enough, the bitmap has the top row at the beginning, - and the pixels are in BGRA or ABGR format. - */ - if (bitmap_fmt == 0) { - /* BGRA */ - for (row=0, n=0; rowpixelpower = 1; - } - [ns_image removeRepresentation:bitmap_rep]; /*releases the rep*/ - [ns_image release]; - } - } else { - TkMacOSXDbgMsg("Could not extract image from drawable."); - } - return imagePtr; -} - -/* - *---------------------------------------------------------------------- - * - * DestroyImage -- - * - * Destroys storage associated with an image. - * - * Results: - * None. - * - * Side effects: - * Deallocates the image. - * - *---------------------------------------------------------------------- - */ - -static int -DestroyImage( - XImage *image) -{ - if (image) { - if (image->data) { - ckfree(image->data); - } - ckfree(image); - } - return 0; -} - -/* - *---------------------------------------------------------------------- - * - * ImageGetPixel -- - * - * Get a single pixel from an image. - * - * Results: - * Returns the 32 bit pixel value. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static unsigned long -ImageGetPixel( - XImage *image, - int x, - int y) -{ - unsigned char r = 0, g = 0, b = 0; - - if (image && image->data) { - unsigned char *srcPtr = ((unsigned char*) image->data) - + (y * image->bytes_per_line) - + (((image->xoffset + x) * image->bits_per_pixel) / NBBY); - - switch (image->bits_per_pixel) { - case 32: { - r = (*((unsigned int*) srcPtr) >> 16) & 0xff; - g = (*((unsigned int*) srcPtr) >> 8) & 0xff; - b = (*((unsigned int*) srcPtr) ) & 0xff; - /*if (image->byte_order == LSBFirst) { - r = srcPtr[2]; g = srcPtr[1]; b = srcPtr[0]; - } else { - r = srcPtr[1]; g = srcPtr[2]; b = srcPtr[3]; - }*/ - break; - } - case 16: - r = (*((unsigned short*) srcPtr) >> 7) & 0xf8; - g = (*((unsigned short*) srcPtr) >> 2) & 0xf8; - b = (*((unsigned short*) srcPtr) << 3) & 0xf8; - break; - case 8: - r = (*srcPtr << 2) & 0xc0; - g = (*srcPtr << 4) & 0xc0; - b = (*srcPtr << 6) & 0xc0; - r |= r >> 2 | r >> 4 | r >> 6; - g |= g >> 2 | g >> 4 | g >> 6; - b |= b >> 2 | b >> 4 | b >> 6; - break; - case 4: { - unsigned char c = (x % 2) ? *srcPtr : (*srcPtr >> 4); - r = (c & 0x04) ? 0xff : 0; - g = (c & 0x02) ? 0xff : 0; - b = (c & 0x01) ? 0xff : 0; - break; - } - case 1: - r = g = b = ((*srcPtr) & (0x80 >> (x % 8))) ? 0xff : 0; - break; - } - } - return (PIXEL_MAGIC << 24) | (r << 16) | (g << 8) | b; -} - -/* - *---------------------------------------------------------------------- - * - * ImagePutPixel -- - * - * Set a single pixel in an image. - * - * Results: - * None. - * - * Side effects: - * None. - * - *---------------------------------------------------------------------- - */ - -static int -ImagePutPixel( - XImage *image, - int x, - int y, - unsigned long pixel) -{ - if (image && image->data) { - unsigned char r = ((pixel & image->red_mask) >> 16) & 0xff; - unsigned char g = ((pixel & image->green_mask) >> 8) & 0xff; - unsigned char b = ((pixel & image->blue_mask) ) & 0xff; - unsigned char *dstPtr = ((unsigned char*) image->data) - + (y * image->bytes_per_line) - + (((image->xoffset + x) * image->bits_per_pixel) / NBBY); - - switch (image->bits_per_pixel) { - case 32: - *((unsigned int*) dstPtr) = (0xff << 24) | (r << 16) | - (g << 8) | b; - /*if (image->byte_order == LSBFirst) { - dstPtr[3] = 0xff; dstPtr[2] = r; dstPtr[1] = g; dstPtr[0] = b; - } else { - dstPtr[0] = 0xff; dstPtr[1] = r; dstPtr[2] = g; dstPtr[3] = b; - }*/ - break; - case 16: - *((unsigned short*) dstPtr) = ((r & 0xf8) << 7) | - ((g & 0xf8) << 2) | ((b & 0xf8) >> 3); - break; - case 8: - *dstPtr = ((r & 0xc0) >> 2) | ((g & 0xc0) >> 4) | - ((b & 0xc0) >> 6); - break; - case 4: { - unsigned char c = ((r & 0x80) >> 5) | ((g & 0x80) >> 6) | - ((b & 0x80) >> 7); - *dstPtr = (x % 2) ? ((*dstPtr & 0xf0) | (c & 0x0f)) : - ((*dstPtr & 0x0f) | ((c << 4) & 0xf0)); - break; - } - case 1: - *dstPtr = ((r|g|b) & 0x80) ? (*dstPtr | (0x80 >> (x % 8))) : - (*dstPtr & ~(0x80 >> (x % 8))); - break; - } - } - return 0; -} /* *---------------------------------------------------------------------- * * XChangeWindowAttributes, XSetWindowBackground, @@ -1266,17 +867,14 @@ const char * TkGetDefaultScreenName( Tcl_Interp *interp, /* Not used. */ const char *screenName) /* If NULL, use default string. */ { -#if 0 if ((screenName == NULL) || (screenName[0] == '\0')) { screenName = macScreenName; } return screenName; -#endif - return macScreenName; } /* *---------------------------------------------------------------------- * @@ -1320,30 +918,26 @@ } timeObj = CFDictionaryGetValue(props, CFSTR("HIDIdleTime")); if (timeObj) { - CFTypeID type = CFGetTypeID(timeObj); - - if (type == CFDataGetTypeID()) { /* Jaguar */ - CFDataGetBytes((CFDataRef) timeObj, - CFRangeMake(0, sizeof(time)), (UInt8 *) &time); - /* Convert nanoseconds to milliseconds. */ - /* ret /= kMillisecondScale; */ - ret = (long) (time/kMillisecondScale); - } else if (type == CFNumberGetTypeID()) { /* Panther+ */ CFNumberGetValue((CFNumberRef)timeObj, kCFNumberSInt64Type, &time); /* Convert nanoseconds to milliseconds. */ - /* ret /= kMillisecondScale; */ ret = (long) (time/kMillisecondScale); - } else { - ret = -1l; - } } /* Cleanup */ CFRelease(props); + + /* + * If the idle time reported by the system is larger than the elapsed + * time since the last reset, return the elapsed time. + */ + long elapsed = (long)(TkpGetMS() - lastInactivityReset); + if (ret > elapsed) { + ret = elapsed; + } return ret; } /* @@ -1365,32 +959,11 @@ void Tk_ResetUserInactiveTime( Display *dpy) { - IOGPoint loc; - kern_return_t kr; - NXEvent nullEvent = {NX_NULLEVENT, {0, 0}, 0, -1, 0}; - enum { kNULLEventPostThrottle = 10 }; - static io_connect_t io_connection = MACH_PORT_NULL; - - if (io_connection == MACH_PORT_NULL) { - io_service_t service = IOServiceGetMatchingService( - kIOMasterPortDefault, IOServiceMatching(kIOHIDSystemClass)); - - if (service == MACH_PORT_NULL) { - return; - } - kr = IOServiceOpen(service, mach_task_self(), kIOHIDParamConnectType, - &io_connection); - IOObjectRelease(service); - if (kr != KERN_SUCCESS) { - return; - } - } - kr = IOHIDPostEvent(io_connection, NX_NULLEVENT, loc, &nullEvent.data, - FALSE, 0, FALSE); + lastInactivityReset = TkpGetMS(); } /* * Local Variables: * mode: objc Index: tests/bell.test ================================================================== --- tests/bell.test +++ tests/bell.test @@ -13,11 +13,11 @@ test bell-1.1 {bell command} -body { bell a } -returnCodes {error} -result {bad option "a": must be -displayof or -nice} test bell-1.2 {bell command} -body { - bell a b + bell a b } -returnCodes {error} -result {bad option "a": must be -displayof or -nice} test bell-1.3 {bell command} -body { bell -displayof gorp } -returnCodes {error} -result {bad window path name "gorp"} Index: tests/bind.test ================================================================== --- tests/bind.test +++ tests/bind.test @@ -31,10 +31,23 @@ bind Toplevel {} bind xyz {} bind {a b} {} bind .t {} } + +# This function fills the pattern matcher's ring buffer with events of +# the specified type. This can be used when testing with generated +# events to make sure that there are no stray events in the ring +# buffer which might cause the pattern matcher to find unintended +# matches. The size of the ring buffer is EVENT_BUFFER_SIZE, which is +# currently set to 30. If this changes, the code below will need to +# change. +proc clearRingBuffer {{event}} { + for {set i 0} {$i < 30} {incr i} { + event generate . $event + } +} # move the mouse pointer away of the testing area # otherwise some spurious events may pollute the tests toplevel .top wm geometry .top 50x50-50-50 @@ -75,14 +88,14 @@ } -cleanup { destroy .t.f } -result {test script more text} test bind-1.8 {bind command} -body { - bind .t {test script} + bind .t {test script} } -returnCodes error -result {bad event type or keysym "gorp"} test bind-1.9 {bind command} -body { - catch {bind .t {test script}} + catch {bind .t {test script}} bind .t } -result {} test bind-1.10 {bind command} -body { bind .t } -returnCodes ok -result {} @@ -139,14 +152,14 @@ destroy .t.f } -result {a b c d} test bind-2.9 {bindtags command} -body { frame .t.f bindtags .t.f {a b c} - bindtags .t.f "\{" + bindtags .t.f "\{" } -cleanup { destroy .t.f -} -returnCodes error -result {unmatched open brace in list} +} -returnCodes error -result {unmatched open brace in list} test bind-2.10 {bindtags command} -body { frame .t.f bindtags .t.f {a b c} catch {bindtags .t.f "\{"} bindtags .t.f @@ -154,14 +167,14 @@ destroy .t.f } -result {.t.f Frame .t all} test bind-2.11 {bindtags command} -body { frame .t.f bindtags .t.f {a b c} - bindtags .t.f "a .gorp b" + bindtags .t.f "a .gorp b" } -cleanup { destroy .t.f -} -returnCodes ok +} -returnCodes ok test bind-2.12 {bindtags command} -body { frame .t.f bindtags .t.f {a b c} catch {bindtags .t.f "a .gorp b"} bindtags .t.f @@ -197,11 +210,11 @@ bind Toplevel {lappend x "%W enter toplevel"} bind xyz {lappend x "%W enter xyz"} bind {a b} {lappend x "%W enter {a b}"} bind .t {lappend x "%W enter .t"} bind .t.f {lappend x "%W enter .t.f"} - + event generate .t.f return $x } -cleanup { destroy .t.f unsetBindings @@ -217,13 +230,13 @@ bind Toplevel {lappend x "%W enter toplevel"} bind xyz {lappend x "%W enter xyz"} bind {a b} {lappend x "%W enter {a b}"} bind .t {lappend x "%W enter .t"} bind .t.f {lappend x "%W enter .t.f"} - + bindtags .t.f {.t.f {a b} xyz} - event generate .t.f + event generate .t.f return $x } -cleanup { destroy .t.f unsetBindings } -result {{.t.f enter .t.f} {.t.f enter {a b}} {.t.f enter xyz}} @@ -233,11 +246,11 @@ bind Test {lappend x "%W enter frame"} bind Toplevel {lappend x "%W enter toplevel"} bind xyz {lappend x "%W enter xyz"} bind {a b} {lappend x "%W enter {a b}"} bind .t {lappend x "%W enter .t"} - + event generate .t return $x } -cleanup { unsetBindings } -result {{.t enter .t} {.t enter toplevel} {.t enter all}} @@ -253,11 +266,11 @@ bind Test {lappend x "%W enter frame"} bind Toplevel {lappend x "%W enter toplevel"} bind xyz {lappend x "%W enter xyz"} bind {a b} {lappend x "%W enter {a b}"} bind .t {lappend x "%W enter .t"} - + bindtags .t.f {.t.f .t.f2 .t.f3} bind .t.f {lappend x "%W enter .t.f"} bind .t.f3 {lappend x "%W enter .t.f3"} event generate .t.f return $x @@ -277,11 +290,11 @@ bind Toplevel {lappend x "%W enter toplevel"} bind xyz {lappend x "%W enter xyz"} bind {a b} {lappend x "%W enter {a b}"} bind .t {lappend x "%W enter .t"} bindtags .t.f {a b c d e f g h i j k l m n o p q r s t u v w x y z} - + event generate .t.f } -cleanup { destroy .t.f unsetBindings } -result {} @@ -381,29 +394,29 @@ } -cleanup { destroy .t.c } -result {Test} test bind-11.1 {Tk_GetAllBindings procedure} -body { - frame .t.f + frame .t.f foreach i "! a \\\{ ~ <> " { bind .t.f $i Test } lsort [bind .t.f] } -cleanup { destroy .t.f } -result {! <> a \{ ~} test bind-11.2 {Tk_GetAllBindings procedure} -body { - frame .t.f + frame .t.f foreach i " <1>" { bind .t.f $i Test } lsort [bind .t.f] } -cleanup { destroy .t.f } -result { } test bind-11.3 {Tk_GetAllBindings procedure} -body { - frame .t.f + frame .t.f foreach i " abcd ab" { bind .t.f $i Test } lsort [bind .t.f] } -cleanup { @@ -433,11 +446,11 @@ bind Test {lappend x "%W %K Test KeyPress"} bind all {lappend x "%W %K all KeyPress"} bind Test : {lappend x "%W %K Test :"} bind all _ {lappend x "%W %K all _"} bind .t.f : {lappend x "%W %K .t.f :"} - + event generate .t.f event generate .t.f event generate .t.f return $x } -cleanup { @@ -456,11 +469,11 @@ set x {} } -body { bind Test {lappend x "%W %K Test press any"; break} bind all {continue; lappend x "%W %K all press any"} bind .t.f : {lappend x "%W %K .t.f pressed colon"} - + event generate .t.f return $x } -cleanup { destroy .t.f bind all {} @@ -512,15 +525,15 @@ bind all {lappend x "%W destroyed"} set x {} frame .t.g -gorp foo } -cleanup { bind all {} -} -returnCodes error -result {unknown option "-gorp"} +} -returnCodes error -result {unknown option "-gorp"} test bind-13.6 {Tk_BindEvent procedure} -body { bind all {lappend x "%W destroyed"} set x {} - catch {frame .t.g -gorp foo} + catch {frame .t.g -gorp foo} return $x } -cleanup { bind all {} } -result {{.t.g destroyed}} @@ -597,14 +610,14 @@ focus -force .t.f update set x {} } -body { bind .t.f "lappend x Motion%#(%x,%y)" - event generate .t.f -serial 100 -x 100 -y 200 -when tail + event generate .t.f -serial 100 -x 100 -y 200 -when tail update event generate .t.f -serial 101 -x 200 -y 300 -when tail - event generate .t.f -serial 102 -x 300 -y 400 -when tail + event generate .t.f -serial 102 -x 300 -y 400 -when tail update return $x } -cleanup { destroy .t.f } -result {Motion100(100,200) Motion102(300,400)} @@ -614,14 +627,14 @@ focus -force .t.f update } -body { bind .t.f "lappend x %K%#" bind .t.f "lappend x %K%#" - event generate .t.f -serial 100 -when tail - event generate .t.f -serial 101 -when tail - event generate .t.f -serial 102 -when tail - event generate .t.f -serial 103 -when tail + event generate .t.f -serial 100 -when tail + event generate .t.f -serial 101 -when tail + event generate .t.f -serial 102 -when tail + event generate .t.f -serial 103 -when tail update } -cleanup { destroy .t.f } -result {} test bind-13.13 {Tk_BindEvent procedure: valid key detail} -setup { @@ -646,12 +659,12 @@ update set x {} } -body { bind .t.f "lappend x Key%K" bind .t.f "lappend x Release%K" - event generate .t.f -keycode 0 - event generate .t.f -keycode 0 + event generate .t.f -keycode -1 + event generate .t.f -keycode -1 return $x } -cleanup { destroy .t.f } -result {Key?? Release??} test bind-13.15 {Tk_BindEvent procedure: button detail} -setup { @@ -853,11 +866,11 @@ focus -force .t.f update set x {} } -body { bind .t.f {set x Button-2} - event generate .t.f + event generate .t.f return $x } -cleanup { destroy .t.f } -result {Button-2} test bind-13.28 {Tk_BindEvent procedure: detail virtual pattern list} -setup { @@ -1017,11 +1030,11 @@ destroy .t.f bind Test {} } -result {b1} test bind-13.45 {Tk_BindEvent procedure: error in script} -setup { proc bgerror msg { - global x + global x lappend x $msg } frame .t.f -class Test -width 150 -height 100 pack .t.f focus -force .t.f @@ -1206,11 +1219,11 @@ event generate .t.f -state 0x8 return $x } -cleanup { destroy .t.f } -result {0} -test bind-15.12 {MatchPatterns procedure, ignore modifier presses and releases} -constraints { +test bind-15.12 {MatchPatterns procedure, ignore modifier presses and releases} -constraints { nonPortable } -setup { frame .t.f -class Test -width 150 -height 100 pack .t.f focus -force .t.f @@ -1247,11 +1260,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -x 30 -y 40 event generate .t.f -x 31 -y 39 event generate .t.f return $x @@ -1264,11 +1277,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -x 30 -y 40 event generate .t.f -x 29 -y 41 event generate .t.f return $x @@ -1281,11 +1294,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -x 30 -y 40 event generate .t.f -x 40 -y 40 event generate .t.f return $x @@ -1298,11 +1311,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -x 30 -y 40 event generate .t.f -x 20 -y 40 event generate .t.f return $x @@ -1315,11 +1328,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -x 30 -y 40 event generate .t.f -x 30 -y 30 event generate .t.f return $x @@ -1332,11 +1345,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -x 30 -y 40 event generate .t.f -x 30 -y 50 event generate .t.f return $x @@ -1349,11 +1362,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -time 300 event generate .t.f -time 700 event generate .t.f return $x @@ -1366,11 +1379,11 @@ focus -force .t.f update } -body { bind .t.f {set x 1} set x 0 - event generate .t.f + event generate .t.f event generate .t.f event generate .t.f -time 300 event generate .t.f -time 900 event generate .t.f return $x @@ -1380,14 +1393,15 @@ test bind-15.22 {MatchPatterns procedure, time wrap-around} -setup { frame .t.f -class Test -width 150 -height 100 pack .t.f focus -force .t.f update + clearRingBuffer } -body { bind .t.f {set x 1} set x 0 - event generate .t.f -time [expr -100] + event generate .t.f -time -100 event generate .t.f -time 200 event generate .t.f return $x } -cleanup { destroy .t.f @@ -1395,10 +1409,11 @@ test bind-15.23 {MatchPatterns procedure, time wrap-around} -setup { frame .t.f -class Test -width 150 -height 100 pack .t.f focus -force .t.f update + clearRingBuffer } -body { bind .t.f {set x 1} set x 0 event generate .t.f -time -100 event generate .t.f -time 500 @@ -1405,17 +1420,17 @@ event generate .t.f return $x } -cleanup { destroy .t.f } -result {0} - test bind-15.24 {MatchPatterns procedure, virtual event} -setup { frame .t.f -class Test -width 150 -height 100 pack .t.f focus -force .t.f update set x {} + clearRingBuffer } -body { event add <> bind .t.f <> {lappend x paste} event generate .t.f event generate .t.f @@ -1428,10 +1443,11 @@ frame .t.f -class Test -width 150 -height 100 pack .t.f focus -force .t.f update set x {} + clearRingBuffer } -body { event add <> bind .t.f <> {lappend x paste} event generate .t.f event generate .t.f @@ -1444,10 +1460,11 @@ frame .t.f -class Test -width 150 -height 100 pack .t.f focus -force .t.f update set x {} + clearRingBuffer } -body { event add <>