no display name and no $DISPLAY environment variable
    while executing
"load /enadisk/commun/linux/local/ActiveTcl-8.6.11/lib/libtk8.6.so Tk"
    ("package ifneeded Tk 8.6.11" script)
    invoked from within
"package require Tk 8"
    (in namespace eval "::request" script line 11)
    invoked from within
"namespace eval ::request $script"
    ("::try" body line 12)

OUTPUT BUFFER:

#============================================================================== # Contains utility procedures for mega-widgets. # # Structure of the module: # - Namespace initialization # - Public utility procedures # # Copyright (c) 2000-2020 Csaba Nemethi (E-mail: csaba.nemethi@t-online.de) #============================================================================== package require Tk 8 # # Namespace initialization # ======================== # namespace eval mwutil { # # Public variables: # variable version 2.16 variable library if {$::tcl_version >= 8.4} { set library [file dirname [file normalize [info script]]] } else { set library [file dirname [info script]] ;# no "file normalize" yet } # # Public procedures: # namespace export wrongNumArgs getAncestorByClass convEventFields \ defineKeyNav processTraversal focusNext focusPrev \ configureWidget fullConfigOpt fullOpt enumOpts \ configureSubCmd attribSubCmd hasattribSubCmd \ unsetattribSubCmd getScrollInfo getScrollInfo2 \ isScrollable hasFocus genMouseWheelEvent \ windowingSystem currentTheme # # Make modified versions of the procedures tk_focusNext and # tk_focusPrev, to be invoked in the processTraversal command # proc makeFocusProcs {} { # # Enforce the evaluation of the Tk library file "focus.tcl" # tk_focusNext . # # Build the procedures focusNext and focusPrev # foreach dir {Next Prev} { set procBody [info body tk_focus$dir] regsub -all {winfo children} $procBody {getChildren $class} procBody proc focus$dir {w class} $procBody } } makeFocusProcs # # Invoked in the procedures focusNext and focusPrev defined above: # proc getChildren {class w} { if {[string compare [winfo class $w] $class] == 0} { return {} } else { return [winfo children $w] } } } # # Public utility procedures # ========================= # #------------------------------------------------------------------------------ # mwutil::wrongNumArgs # # Generates a "wrong # args" error message. #------------------------------------------------------------------------------ proc mwutil::wrongNumArgs args { set optList {} foreach arg $args { lappend optList \"$arg\" } return -code error "wrong # args: should be [enumOpts $optList]" } #------------------------------------------------------------------------------ # mwutil::getAncestorByClass # # Gets the path name of the widget of the specified class from the path name w # of one of its descendants. It is assumed that all of the ancestors of w # exist (but w itself needn't exist). #------------------------------------------------------------------------------ proc mwutil::getAncestorByClass {w class} { regexp {^(\..+)\..+$} $w dummy win while {[string compare [winfo class $win] $class] != 0} { set win [winfo parent $win] } return $win } #------------------------------------------------------------------------------ # mwutil::convEventFields # # Gets the path name of the widget of the specified class and the x and y # coordinates relative to the latter from the path name w of one of its # descendants and from the x and y coordinates relative to the latter. #------------------------------------------------------------------------------ proc mwutil::convEventFields {w x y class} { set win [getAncestorByClass $w $class] set _x [expr {$x + [winfo rootx $w] - [winfo rootx $win]}] set _y [expr {$y + [winfo rooty $w] - [winfo rooty $win]}] return [list $win $_x $_y] } #------------------------------------------------------------------------------ # mwutil::defineKeyNav # # For a given mega-widget class, the procedure defines the binding tag # ${class}KeyNav as a partial replacement for "all", by substituting the # scripts bound to the events , , and <> with new # ones which propagate these events to the mega-widget of the given class # containing the widget to which the event was reported. (The event # was replaced with <> in Tk 8.3.0.) This tag is # designed to be inserted before "all" in the list of binding tags of a # descendant of a mega-widget of the specified class. #------------------------------------------------------------------------------ proc mwutil::defineKeyNav class { foreach event { <>} { bind ${class}KeyNav $event \ [list mwutil::processTraversal %W $class $event] } bind Entry <> { %W selection range 0 end; %W icursor end } bind Spinbox <> { %W selection range 0 end; %W icursor end } } #------------------------------------------------------------------------------ # mwutil::processTraversal # # Processes the given traversal event for the mega-widget of the specified # class containing the widget w if that mega-widget is not the only widget # receiving the focus during keyboard traversal within its toplevel widget. #------------------------------------------------------------------------------ proc mwutil::processTraversal {w class event} { set win [getAncestorByClass $w $class] if {[string compare $event ""] == 0} { set target [focusNext $win $class] } else { set target [focusPrev $win $class] } if {[string compare $target $win] != 0} { set focusWin [focus -displayof $win] if {[string length $focusWin] != 0} { event generate $focusWin <> } focus $target event generate $target <> } return -code break "" } #------------------------------------------------------------------------------ # mwutil::configureWidget # # Configures the widget win by processing the command-line arguments specified # in optValPairs and, if the value of initialize is true, also those database # options that don't match any command-line arguments. #------------------------------------------------------------------------------ proc mwutil::configureWidget {win configSpecsName configCmd cgetCmd \ optValPairs initialize} { upvar $configSpecsName configSpecs # # Process the command-line arguments # set cmdLineOpts {} set savedOptValPairs {} set failed 0 set count [llength $optValPairs] foreach {opt val} $optValPairs { if {[catch {fullConfigOpt $opt configSpecs} result] != 0} { set failed 1 break } if {$count == 1} { set result "value for \"$opt\" missing" set failed 1 break } set opt $result lappend cmdLineOpts $opt lappend savedOptValPairs $opt [eval $cgetCmd [list $win $opt]] if {[catch {eval $configCmd [list $win $opt $val]} result] != 0} { set failed 1 break } incr count -2 } if {$failed} { # # Restore the saved values # foreach {opt val} $savedOptValPairs { eval $configCmd [list $win $opt $val] } return -code error $result } if {$initialize} { # # Process those configuration options that were not # given as command-line arguments; use the corresponding # values from the option database if available # foreach opt [lsort [array names configSpecs]] { if {[llength $configSpecs($opt)] == 1 || [lsearch -exact $cmdLineOpts $opt] >= 0} { continue } set dbName [lindex $configSpecs($opt) 0] set dbClass [lindex $configSpecs($opt) 1] set dbValue [option get $win $dbName $dbClass] if {[string length $dbValue] == 0} { set default [lindex $configSpecs($opt) 3] eval $configCmd [list $win $opt $default] } else { if {[catch { eval $configCmd [list $win $opt $dbValue] } result] != 0} { return -code error $result } } } } return "" } #------------------------------------------------------------------------------ # mwutil::fullConfigOpt # # Returns the full configuration option corresponding to the possibly # abbreviated option opt. #------------------------------------------------------------------------------ proc mwutil::fullConfigOpt {opt configSpecsName} { upvar $configSpecsName configSpecs if {[info exists configSpecs($opt)]} { if {[llength $configSpecs($opt)] == 1} { return $configSpecs($opt) } else { return $opt } } set optList [lsort [array names configSpecs]] set count 0 foreach elem $optList { if {[string first $opt $elem] == 0} { incr count if {$count == 1} { set option $elem } else { break } } } if {$count == 1} { if {[llength $configSpecs($option)] == 1} { return $configSpecs($option) } else { return $option } } elseif {$count == 0} { ### return -code error "unknown option \"$opt\"" return -code error \ "bad option \"$opt\": must be [enumOpts $optList]" } else { ### return -code error "unknown option \"$opt\"" return -code error \ "ambiguous option \"$opt\": must be [enumOpts $optList]" } } #------------------------------------------------------------------------------ # mwutil::fullOpt # # Returns the full option corresponding to the possibly abbreviated option opt. #------------------------------------------------------------------------------ proc mwutil::fullOpt {kind opt optList} { if {[lsearch -exact $optList $opt] >= 0} { return $opt } set count 0 foreach elem $optList { if {[string first $opt $elem] == 0} { incr count if {$count == 1} { set option $elem } else { break } } } if {$count == 1} { return $option } elseif {$count == 0} { return -code error \ "bad $kind \"$opt\": must be [enumOpts $optList]" } else { return -code error \ "ambiguous $kind \"$opt\": must be [enumOpts $optList]" } } #------------------------------------------------------------------------------ # mwutil::enumOpts # # Returns a string consisting of the elements of the given list, separated by # commas and spaces. #------------------------------------------------------------------------------ proc mwutil::enumOpts optList { set optCount [llength $optList] set n 1 foreach opt $optList { if {$n == 1} { set str $opt } elseif {$n < $optCount} { append str ", $opt" } else { if {$optCount > 2} { append str "," } append str " or $opt" } incr n } return $str } #------------------------------------------------------------------------------ # mwutil::configureSubCmd # # This procedure is invoked to process configuration subcommands. #------------------------------------------------------------------------------ proc mwutil::configureSubCmd {win configSpecsName configCmd cgetCmd argList} { upvar $configSpecsName configSpecs set argCount [llength $argList] if {$argCount > 1} { # # Set the specified configuration options to the given values # return [configureWidget $win configSpecs $configCmd $cgetCmd $argList 0] } elseif {$argCount == 1} { # # Return the description of the specified configuration option # set opt [fullConfigOpt [lindex $argList 0] configSpecs] set dbName [lindex $configSpecs($opt) 0] set dbClass [lindex $configSpecs($opt) 1] set default [lindex $configSpecs($opt) 3] return [list $opt $dbName $dbClass $default \ [eval $cgetCmd [list $win $opt]]] } else { # # Return a list describing all available configuration options # foreach opt [lsort [array names configSpecs]] { if {[llength $configSpecs($opt)] == 1} { set alias $configSpecs($opt) if {$::tk_version >= 8.1} { lappend result [list $opt $alias] } else { set dbName [lindex $configSpecs($alias) 0] lappend result [list $opt $dbName] } } else { set dbName [lindex $configSpecs($opt) 0] set dbClass [lindex $configSpecs($opt) 1] set default [lindex $configSpecs($opt) 3] lappend result [list $opt $dbName $dbClass $default \ [eval $cgetCmd [list $win $opt]]] } } return $result } } #------------------------------------------------------------------------------ # mwutil::attribSubCmd # # This procedure is invoked to process *attrib subcommands. #------------------------------------------------------------------------------ proc mwutil::attribSubCmd {win prefix argList} { set classNs [string tolower [winfo class $win]] upvar ::${classNs}::ns${win}::attribs attribs set argCount [llength $argList] if {$argCount > 1} { # # Set the specified attributes to the given values # if {$argCount % 2 != 0} { return -code error "value for \"[lindex $argList end]\" missing" } foreach {attr val} $argList { set attribs($prefix-$attr) $val } return "" } elseif {$argCount == 1} { # # Return the value of the specified attribute # set attr [lindex $argList 0] set name $prefix-$attr if {[info exists attribs($name)]} { return $attribs($name) } else { return "" } } else { # # Return the current list of attribute names and values # set len [string length "$prefix-"] set result {} foreach name [lsort [array names attribs "$prefix-*"]] { set attr [string range $name $len end] lappend result [list $attr $attribs($name)] } return $result } } #------------------------------------------------------------------------------ # mwutil::hasattribSubCmd # # This procedure is invoked to process has*attrib subcommands. #------------------------------------------------------------------------------ proc mwutil::hasattribSubCmd {win prefix attr} { set classNs [string tolower [winfo class $win]] upvar ::${classNs}::ns${win}::attribs attribs return [info exists attribs($prefix-$attr)] } #------------------------------------------------------------------------------ # mwutil::unsetattribSubCmd # # This procedure is invoked to process unset*attrib subcommands. #------------------------------------------------------------------------------ proc mwutil::unsetattribSubCmd {win prefix attr} { set classNs [string tolower [winfo class $win]] upvar ::${classNs}::ns${win}::attribs attribs set name $prefix-$attr if {[info exists attribs($name)]} { unset attribs($name) } return "" } #------------------------------------------------------------------------------ # mwutil::getScrollInfo # # Parses a list of arguments of the form "moveto " or "scroll # units|pages" and returns the corresponding list consisting of two or # three properly formatted elements. #------------------------------------------------------------------------------ proc mwutil::getScrollInfo argList { set argCount [llength $argList] set opt [lindex $argList 0] if {[string first $opt "moveto"] == 0} { if {$argCount != 2} { wrongNumArgs "moveto fraction" } set fraction [lindex $argList 1] format "%f" $fraction ;# floating-point number check with error message return [list moveto $fraction] } elseif {[string first $opt "scroll"] == 0} { if {$argCount != 3} { wrongNumArgs "scroll number units|pages" } set number [format "%d" [lindex $argList 1]] set what [lindex $argList 2] if {[string first $what "units"] == 0} { return [list scroll $number units] } elseif {[string first $what "pages"] == 0} { return [list scroll $number pages] } else { return -code error "bad argument \"$what\": must be units or pages" } } else { return -code error "unknown option \"$opt\": must be moveto or scroll" } } #------------------------------------------------------------------------------ # mwutil::getScrollInfo2 # # Parses a list of arguments of the form "moveto " or "scroll # units|pages" and returns the corresponding list consisting of two or # three properly formatted elements. #------------------------------------------------------------------------------ proc mwutil::getScrollInfo2 {cmd argList} { set argCount [llength $argList] set opt [lindex $argList 0] if {[string first $opt "moveto"] == 0} { if {$argCount != 2} { wrongNumArgs "$cmd moveto fraction" } set fraction [lindex $argList 1] format "%f" $fraction ;# floating-point number check with error message return [list moveto $fraction] } elseif {[string first $opt "scroll"] == 0} { if {$argCount != 3} { wrongNumArgs "$cmd scroll number units|pages" } set number [format "%d" [lindex $argList 1]] set what [lindex $argList 2] if {[string first $what "units"] == 0} { return [list scroll $number units] } elseif {[string first $what "pages"] == 0} { return [list scroll $number pages] } else { return -code error "bad argument \"$what\": must be units or pages" } } else { return -code error "unknown option \"$opt\": must be moveto or scroll" } } #------------------------------------------------------------------------------ # mwutil::isScrollable # # Returns a boolean value indicating whether the widget w is scrollable along a # given axis (x or y). #------------------------------------------------------------------------------ proc mwutil::isScrollable {w axis} { set viewCmd ${axis}view return [expr { [catch {$w cget -${axis}scrollcommand}] == 0 && [catch {$w $viewCmd} view] == 0 && [catch {$w $viewCmd moveto [lindex $view 0]}] == 0 && [catch {$w $viewCmd scroll 0 units}] == 0 && [catch {$w $viewCmd scroll 0 pages}] == 0 }] } #------------------------------------------------------------------------------ # mwutil::hasFocus # # Returns a boolean value indicating whether the focus window is (a descendant # of) the widget w and has the same toplevel. #------------------------------------------------------------------------------ proc mwutil::hasFocus w { set focusWin [focus -displayof $w] return [expr { [string first $w. $focusWin.] == 0 && [string compare [winfo toplevel $w] [winfo toplevel $focusWin]] == 0 }] } #------------------------------------------------------------------------------ # mwutil::genMouseWheelEvent # # Generates a mouse wheel event with the given root coordinates and delta on # the widget w. #------------------------------------------------------------------------------ proc mwutil::genMouseWheelEvent {w event rootX rootY delta} { set needsFocus [expr {[package vcompare $::tk_patchLevel "8.6b2"] < 0 && [string compare $::tcl_platform(platform) "windows"] == 0}] if {$needsFocus} { set focusWin [focus -displayof $w] focus $w } event generate $w $event -rootx $rootX -rooty $rootY -delta $delta if {$needsFocus} { focus $focusWin } } #------------------------------------------------------------------------------ # mwutil::windowingSystem # # Returns the windowing system ("x11", "win32", "classic", or "aqua"). #------------------------------------------------------------------------------ proc mwutil::windowingSystem {} { if {[catch {tk windowingsystem} winSys] != 0} { switch $::tcl_platform(platform) { unix { set winSys x11 } windows { set winSys win32 } macintosh { set winSys classic } } } return $winSys } #------------------------------------------------------------------------------ # mwutil::currentTheme # # Returns the current tile theme. #------------------------------------------------------------------------------ proc mwutil::currentTheme {} { if {[info exists ::ttk::currentTheme]} { return $::ttk::currentTheme } elseif {[info exists ::tile::currentTheme]} { return $::tile::currentTheme } else { return "" } }