Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / tools / src / nas,5.n2.os.2 / lib / python / lib / tk8.4 / tk.tcl
CommitLineData
86530b38
AT
1# tk.tcl --
2#
3# Initialization script normally executed in the interpreter for each
4# Tk-based application. Arranges class bindings for widgets.
5#
6# RCS: @(#) $Id: tk.tcl,v 1.46.2.2 2004/10/29 11:16:37 patthoyts Exp $
7#
8# Copyright (c) 1992-1994 The Regents of the University of California.
9# Copyright (c) 1994-1996 Sun Microsystems, Inc.
10# Copyright (c) 1998-2000 Ajuba Solutions.
11#
12# See the file "license.terms" for information on usage and redistribution
13# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
14
15# Insist on running with compatible versions of Tcl and Tk.
16package require -exact Tk 8.4
17package require -exact Tcl 8.4
18
19# Create a ::tk namespace
20namespace eval ::tk {
21 # Set up the msgcat commands
22 namespace eval msgcat {
23 namespace export mc mcmax
24 if {[interp issafe] || [catch {package require msgcat}]} {
25 # The msgcat package is not available. Supply our own
26 # minimal replacement.
27 proc mc {src args} {
28 return [eval [list format $src] $args]
29 }
30 proc mcmax {args} {
31 set max 0
32 foreach string $args {
33 set len [string length $string]
34 if {$len>$max} {
35 set max $len
36 }
37 }
38 return $max
39 }
40 } else {
41 # Get the commands from the msgcat package that Tk uses.
42 namespace import ::msgcat::mc
43 namespace import ::msgcat::mcmax
44 ::msgcat::mcload [file join $::tk_library msgs]
45 }
46 }
47 namespace import ::tk::msgcat::*
48}
49
50# Add Tk's directory to the end of the auto-load search path, if it
51# isn't already on the path:
52
53if {[info exists ::auto_path] && [string compare {} $::tk_library] && \
54 [lsearch -exact $::auto_path $::tk_library] < 0} {
55 lappend ::auto_path $::tk_library
56}
57
58# Turn off strict Motif look and feel as a default.
59
60set ::tk_strictMotif 0
61
62# Turn on useinputmethods (X Input Methods) by default.
63# We catch this because safe interpreters may not allow the call.
64
65catch {tk useinputmethods 1}
66
67# ::tk::PlaceWindow --
68# place a toplevel at a particular position
69# Arguments:
70# toplevel name of toplevel window
71# ?placement? pointer ?center? ; places $w centered on the pointer
72# widget widgetPath ; centers $w over widget_name
73# defaults to placing toplevel in the middle of the screen
74# ?anchor? center or widgetPath
75# Results:
76# Returns nothing
77#
78proc ::tk::PlaceWindow {w {place ""} {anchor ""}} {
79 wm withdraw $w
80 update idletasks
81 set checkBounds 1
82 if {$place eq ""} {
83 set x [expr {([winfo screenwidth $w]-[winfo reqwidth $w])/2}]
84 set y [expr {([winfo screenheight $w]-[winfo reqheight $w])/2}]
85 set checkBounds 0
86 } elseif {[string equal -len [string length $place] $place "pointer"]} {
87 ## place at POINTER (centered if $anchor == center)
88 if {[string equal -len [string length $anchor] $anchor "center"]} {
89 set x [expr {[winfo pointerx $w]-[winfo reqwidth $w]/2}]
90 set y [expr {[winfo pointery $w]-[winfo reqheight $w]/2}]
91 } else {
92 set x [winfo pointerx $w]
93 set y [winfo pointery $w]
94 }
95 } elseif {[string equal -len [string length $place] $place "widget"] && \
96 [winfo exists $anchor] && [winfo ismapped $anchor]} {
97 ## center about WIDGET $anchor, widget must be mapped
98 set x [expr {[winfo rootx $anchor] + \
99 ([winfo width $anchor]-[winfo reqwidth $w])/2}]
100 set y [expr {[winfo rooty $anchor] + \
101 ([winfo height $anchor]-[winfo reqheight $w])/2}]
102 } else {
103 set x [expr {([winfo screenwidth $w]-[winfo reqwidth $w])/2}]
104 set y [expr {([winfo screenheight $w]-[winfo reqheight $w])/2}]
105 set checkBounds 0
106 }
107 if {[tk windowingsystem] eq "win32"} {
108 # Bug 533519: win32 multiple desktops may produce negative geometry.
109 set checkBounds 0
110 }
111 if {$checkBounds} {
112 if {$x < 0} {
113 set x 0
114 } elseif {$x > ([winfo screenwidth $w]-[winfo reqwidth $w])} {
115 set x [expr {[winfo screenwidth $w]-[winfo reqwidth $w]}]
116 }
117 if {$y < 0} {
118 set y 0
119 } elseif {$y > ([winfo screenheight $w]-[winfo reqheight $w])} {
120 set y [expr {[winfo screenheight $w]-[winfo reqheight $w]}]
121 }
122 if {[tk windowingsystem] eq "macintosh" \
123 || [tk windowingsystem] eq "aqua"} {
124 # Avoid the native menu bar which sits on top of everything.
125 if {$y < 20} { set y 20 }
126 }
127 }
128 wm geometry $w +$x+$y
129 wm deiconify $w
130}
131
132# ::tk::SetFocusGrab --
133# swap out current focus and grab temporarily (for dialogs)
134# Arguments:
135# grab new window to grab
136# focus window to give focus to
137# Results:
138# Returns nothing
139#
140proc ::tk::SetFocusGrab {grab {focus {}}} {
141 set index "$grab,$focus"
142 upvar ::tk::FocusGrab($index) data
143
144 lappend data [focus]
145 set oldGrab [grab current $grab]
146 lappend data $oldGrab
147 if {[winfo exists $oldGrab]} {
148 lappend data [grab status $oldGrab]
149 }
150 # The "grab" command will fail if another application
151 # already holds the grab. So catch it.
152 catch {grab $grab}
153 if {[winfo exists $focus]} {
154 focus $focus
155 }
156}
157
158# ::tk::RestoreFocusGrab --
159# restore old focus and grab (for dialogs)
160# Arguments:
161# grab window that had taken grab
162# focus window that had taken focus
163# destroy destroy|withdraw - how to handle the old grabbed window
164# Results:
165# Returns nothing
166#
167proc ::tk::RestoreFocusGrab {grab focus {destroy destroy}} {
168 set index "$grab,$focus"
169 if {[info exists ::tk::FocusGrab($index)]} {
170 foreach {oldFocus oldGrab oldStatus} $::tk::FocusGrab($index) { break }
171 unset ::tk::FocusGrab($index)
172 } else {
173 set oldGrab ""
174 }
175
176 catch {focus $oldFocus}
177 grab release $grab
178 if {[string equal $destroy "withdraw"]} {
179 wm withdraw $grab
180 } else {
181 destroy $grab
182 }
183 if {[winfo exists $oldGrab] && [winfo ismapped $oldGrab]} {
184 if {[string equal $oldStatus "global"]} {
185 grab -global $oldGrab
186 } else {
187 grab $oldGrab
188 }
189 }
190}
191
192# ::tk::GetSelection --
193# This tries to obtain the default selection. On Unix, we first try
194# and get a UTF8_STRING, a type supported by modern Unix apps for
195# passing Unicode data safely. We fall back on the default STRING
196# type otherwise. On Windows, only the STRING type is necessary.
197# Arguments:
198# w The widget for which the selection will be retrieved.
199# Important for the -displayof property.
200# sel The source of the selection (PRIMARY or CLIPBOARD)
201# Results:
202# Returns the selection, or an error if none could be found
203#
204if {[string equal $tcl_platform(platform) "unix"]} {
205 proc ::tk::GetSelection {w {sel PRIMARY}} {
206 if {[catch {selection get -displayof $w -selection $sel \
207 -type UTF8_STRING} txt] \
208 && [catch {selection get -displayof $w -selection $sel} txt]} {
209 return -code error "could not find default selection"
210 } else {
211 return $txt
212 }
213 }
214} else {
215 proc ::tk::GetSelection {w {sel PRIMARY}} {
216 if {[catch {selection get -displayof $w -selection $sel} txt]} {
217 return -code error "could not find default selection"
218 } else {
219 return $txt
220 }
221 }
222}
223
224# ::tk::ScreenChanged --
225# This procedure is invoked by the binding mechanism whenever the
226# "current" screen is changing. The procedure does two things.
227# First, it uses "upvar" to make variable "::tk::Priv" point at an
228# array variable that holds state for the current display. Second,
229# it initializes the array if it didn't already exist.
230#
231# Arguments:
232# screen - The name of the new screen.
233
234proc ::tk::ScreenChanged screen {
235 set x [string last . $screen]
236 if {$x > 0} {
237 set disp [string range $screen 0 [expr {$x - 1}]]
238 } else {
239 set disp $screen
240 }
241
242 uplevel #0 upvar #0 ::tk::Priv.$disp ::tk::Priv
243 variable ::tk::Priv
244 global tcl_platform
245
246 if {[info exists Priv]} {
247 set Priv(screen) $screen
248 return
249 }
250 array set Priv {
251 activeMenu {}
252 activeItem {}
253 afterId {}
254 buttons 0
255 buttonWindow {}
256 dragging 0
257 focus {}
258 grab {}
259 initPos {}
260 inMenubutton {}
261 listboxPrev {}
262 menuBar {}
263 mouseMoved 0
264 oldGrab {}
265 popup {}
266 postedMb {}
267 pressX 0
268 pressY 0
269 prevPos 0
270 selectMode char
271 }
272 set Priv(screen) $screen
273 set Priv(tearoff) [string equal [tk windowingsystem] "x11"]
274 set Priv(window) {}
275}
276
277# Do initial setup for Priv, so that it is always bound to something
278# (otherwise, if someone references it, it may get set to a non-upvar-ed
279# value, which will cause trouble later).
280
281tk::ScreenChanged [winfo screen .]
282
283# ::tk::EventMotifBindings --
284# This procedure is invoked as a trace whenever ::tk_strictMotif is
285# changed. It is used to turn on or turn off the motif virtual
286# bindings.
287#
288# Arguments:
289# n1 - the name of the variable being changed ("::tk_strictMotif").
290
291proc ::tk::EventMotifBindings {n1 dummy dummy} {
292 upvar $n1 name
293
294 if {$name} {
295 set op delete
296 } else {
297 set op add
298 }
299
300 event $op <<Cut>> <Control-Key-w>
301 event $op <<Copy>> <Meta-Key-w>
302 event $op <<Paste>> <Control-Key-y>
303 event $op <<Undo>> <Control-underscore>
304}
305
306#----------------------------------------------------------------------
307# Define common dialogs on platforms where they are not implemented
308# using compiled code.
309#----------------------------------------------------------------------
310
311if {[string equal [info commands tk_chooseColor] ""]} {
312 proc ::tk_chooseColor {args} {
313 return [eval tk::dialog::color:: $args]
314 }
315}
316if {[string equal [info commands tk_getOpenFile] ""]} {
317 proc ::tk_getOpenFile {args} {
318 if {$::tk_strictMotif} {
319 return [eval tk::MotifFDialog open $args]
320 } else {
321 return [eval ::tk::dialog::file:: open $args]
322 }
323 }
324}
325if {[string equal [info commands tk_getSaveFile] ""]} {
326 proc ::tk_getSaveFile {args} {
327 if {$::tk_strictMotif} {
328 return [eval tk::MotifFDialog save $args]
329 } else {
330 return [eval ::tk::dialog::file:: save $args]
331 }
332 }
333}
334if {[string equal [info commands tk_messageBox] ""]} {
335 proc ::tk_messageBox {args} {
336 return [eval tk::MessageBox $args]
337 }
338}
339if {[string equal [info command tk_chooseDirectory] ""]} {
340 proc ::tk_chooseDirectory {args} {
341 return [eval ::tk::dialog::file::chooseDir:: $args]
342 }
343}
344
345#----------------------------------------------------------------------
346# Define the set of common virtual events.
347#----------------------------------------------------------------------
348
349switch [tk windowingsystem] {
350 "x11" {
351 event add <<Cut>> <Control-Key-x> <Key-F20>
352 event add <<Copy>> <Control-Key-c> <Key-F16>
353 event add <<Paste>> <Control-Key-v> <Key-F18>
354 event add <<PasteSelection>> <ButtonRelease-2>
355 event add <<Undo>> <Control-Key-z>
356 event add <<Redo>> <Control-Key-Z>
357 # Some OS's define a goofy (as in, not <Shift-Tab>) keysym
358 # that is returned when the user presses <Shift-Tab>. In order for
359 # tab traversal to work, we have to add these keysyms to the
360 # PrevWindow event.
361 # We use catch just in case the keysym isn't recognized.
362 # This is needed for XFree86 systems
363 catch { event add <<PrevWindow>> <ISO_Left_Tab> }
364 # This seems to be correct on *some* HP systems.
365 catch { event add <<PrevWindow>> <hpBackTab> }
366
367 trace variable ::tk_strictMotif w ::tk::EventMotifBindings
368 set ::tk_strictMotif $::tk_strictMotif
369 }
370 "win32" {
371 event add <<Cut>> <Control-Key-x> <Shift-Key-Delete>
372 event add <<Copy>> <Control-Key-c> <Control-Key-Insert>
373 event add <<Paste>> <Control-Key-v> <Shift-Key-Insert>
374 event add <<PasteSelection>> <ButtonRelease-2>
375 event add <<Undo>> <Control-Key-z>
376 event add <<Redo>> <Control-Key-y>
377 }
378 "aqua" {
379 event add <<Cut>> <Command-Key-x> <Key-F2>
380 event add <<Copy>> <Command-Key-c> <Key-F3>
381 event add <<Paste>> <Command-Key-v> <Key-F4>
382 event add <<PasteSelection>> <ButtonRelease-2>
383 event add <<Clear>> <Clear>
384 event add <<Undo>> <Command-Key-z>
385 event add <<Redo>> <Command-Key-y>
386 }
387 "classic" {
388 event add <<Cut>> <Control-Key-x> <Key-F2>
389 event add <<Copy>> <Control-Key-c> <Key-F3>
390 event add <<Paste>> <Control-Key-v> <Key-F4>
391 event add <<PasteSelection>> <ButtonRelease-2>
392 event add <<Clear>> <Clear>
393 event add <<Undo>> <Control-Key-z> <Key-F1>
394 event add <<Redo>> <Control-Key-Z>
395 }
396}
397# ----------------------------------------------------------------------
398# Read in files that define all of the class bindings.
399# ----------------------------------------------------------------------
400
401if {$::tk_library ne ""} {
402 if {[string equal $tcl_platform(platform) "macintosh"]} {
403 proc ::tk::SourceLibFile {file} {
404 if {[catch {
405 namespace eval :: \
406 [list source [file join $::tk_library $file.tcl]]
407 }]} {
408 namespace eval :: [list source -rsrc $file]
409 }
410 }
411 } else {
412 proc ::tk::SourceLibFile {file} {
413 namespace eval :: [list source [file join $::tk_library $file.tcl]]
414 }
415 }
416 namespace eval ::tk {
417 SourceLibFile button
418 SourceLibFile entry
419 SourceLibFile listbox
420 SourceLibFile menu
421 SourceLibFile panedwindow
422 SourceLibFile scale
423 SourceLibFile scrlbar
424 SourceLibFile spinbox
425 SourceLibFile text
426 }
427}
428# ----------------------------------------------------------------------
429# Default bindings for keyboard traversal.
430# ----------------------------------------------------------------------
431
432event add <<PrevWindow>> <Shift-Tab>
433bind all <Tab> {tk::TabToWindow [tk_focusNext %W]}
434bind all <<PrevWindow>> {tk::TabToWindow [tk_focusPrev %W]}
435
436# ::tk::CancelRepeat --
437# This procedure is invoked to cancel an auto-repeat action described
438# by ::tk::Priv(afterId). It's used by several widgets to auto-scroll
439# the widget when the mouse is dragged out of the widget with a
440# button pressed.
441#
442# Arguments:
443# None.
444
445proc ::tk::CancelRepeat {} {
446 variable ::tk::Priv
447 after cancel $Priv(afterId)
448 set Priv(afterId) {}
449}
450
451# ::tk::TabToWindow --
452# This procedure moves the focus to the given widget. If the widget
453# is an entry or a spinbox, it selects the entire contents of the widget.
454#
455# Arguments:
456# w - Window to which focus should be set.
457
458proc ::tk::TabToWindow {w} {
459 if {[string equal [winfo class $w] Entry] \
460 || [string equal [winfo class $w] Spinbox]} {
461 $w selection range 0 end
462 $w icursor end
463 }
464 focus $w
465}
466
467# ::tk::UnderlineAmpersand --
468# This procedure takes some text with ampersand and returns
469# text w/o ampersand and position of the ampersand.
470# Double ampersands are converted to single ones.
471# Position returned is -1 when there is no ampersand.
472#
473proc ::tk::UnderlineAmpersand {text} {
474 set idx [string first "&" $text]
475 if {$idx >= 0} {
476 set underline $idx
477 # ignore "&&"
478 while {[string match "&" [string index $text [expr {$idx + 1}]]]} {
479 set base [expr {$idx + 2}]
480 set idx [string first "&" [string range $text $base end]]
481 if {$idx < 0} {
482 break
483 } else {
484 set underline [expr {$underline + $idx + 1}]
485 incr idx $base
486 }
487 }
488 }
489 if {$idx >= 0} {
490 regsub -all -- {&([^&])} $text {\1} text
491 }
492 return [list $text $idx]
493}
494
495# ::tk::SetAmpText --
496# Given widget path and text with "magic ampersands",
497# sets -text and -underline options for the widget
498#
499proc ::tk::SetAmpText {widget text} {
500 foreach {newtext under} [::tk::UnderlineAmpersand $text] {
501 $widget configure -text $newtext -underline $under
502 }
503}
504
505# ::tk::AmpWidget --
506# Creates new widget, turning -text option into -text and
507# -underline options, returned by ::tk::UnderlineAmpersand.
508#
509proc ::tk::AmpWidget {class path args} {
510 set wcmd [list $class $path]
511 foreach {opt val} $args {
512 if {[string equal $opt {-text}]} {
513 foreach {newtext under} [::tk::UnderlineAmpersand $val] {
514 lappend wcmd -text $newtext -underline $under
515 }
516 } else {
517 lappend wcmd $opt $val
518 }
519 }
520 eval $wcmd
521 if {$class=="button"} {
522 bind $path <<AltUnderlined>> [list $path invoke]
523 }
524 return $path
525}
526
527# ::tk::FindAltKeyTarget --
528# search recursively through the hierarchy of visible widgets
529# to find button or label which has $char as underlined character
530#
531proc ::tk::FindAltKeyTarget {path char} {
532 switch [winfo class $path] {
533 Button -
534 Label {
535 if {[string equal -nocase $char \
536 [string index [$path cget -text] \
537 [$path cget -underline]]]} {return $path} else {return {}}
538 }
539 default {
540 foreach child \
541 [concat [grid slaves $path] \
542 [pack slaves $path] \
543 [place slaves $path] ] {
544 if {""!=[set target [::tk::FindAltKeyTarget $child $char]]} {
545 return $target
546 }
547 }
548 }
549 }
550 return {}
551}
552
553# ::tk::AltKeyInDialog --
554# <Alt-Key> event handler for standard dialogs. Sends <<AltUnderlined>>
555# to button or label which has appropriate underlined character
556#
557proc ::tk::AltKeyInDialog {path key} {
558 set target [::tk::FindAltKeyTarget $path $key]
559 if { $target == ""} return
560 event generate $target <<AltUnderlined>>
561}
562
563# ::tk::mcmaxamp --
564# Replacement for mcmax, used for texts with "magic ampersand" in it.
565#
566
567proc ::tk::mcmaxamp {args} {
568 set maxlen 0
569 foreach arg $args {
570 set length [string length [lindex [::tk::UnderlineAmpersand [mc $arg]] 0]]
571 if {$length>$maxlen} {
572 set maxlen $length
573 }
574 }
575 return $maxlen
576}
577# For now, turn off the custom mdef proc for the mac:
578
579if {[string equal [tk windowingsystem] "aqua"]} {
580 namespace eval ::tk::mac {
581 set useCustomMDEF 0
582 }
583}