~amsn-daily/amsn/amsn-packaging

5402 by kakaroto
Added console for unix users and new Ctrl-C binding for opening it
1
# FILE: console.tcl
2
 #
3
 #       Provides a console window.
4
 #
5
 # Last modified on: $Date$
6
 # Last modified by: $Author$
7
 #
8
 # This file is evaluated to provide a console window interface to the
9
 # root Tcl interpreter of an OOMMF application.  It calls on a script
10
 # included with the Tk script library to do most of the work, making use
11
 # of Tk interface details which are only semi-public.  For this reason,
12
 # there is some risk that future versions of Tk will no longer support
13
 # this script.  That is why this script has been isolated in a file of
14
 # its own.
15
16
 ########################################################################
17
 # If the Tcl command 'console' is already in the interpreter, our work
18
 # is done.
19
 ########################################################################
20
 if {![catch {console show}]} {
21
     return
22
 }
23
24
 ########################################################################
25
 # Check Tcl/Tk support
26
 ########################################################################
27
 if {[catch {package require Tcl 8}]} {
28
     package require Tcl 7.5
29
 }
30
31
 if {[catch {package require Tk 8}]} {
32
     if {[catch {package require Tk 4.1}]} {
33
         return -code error "Tk required but not loaded."
34
     }
35
 }
36
37
 set _ [file join $tk_library console.tcl]
38
 if {![file readable $_]} {
39
     return -code error "File not readable: $_"
40
 }
41
42
 ########################################################################
43
 # Provide the support which the Tk library script console.tcl assumes
44
 ########################################################################
45
 # 1. Create an interpreter for the console window widget and load Tk
46
 set consoleInterp [interp create]
47
 $consoleInterp eval [list set tk_library $tk_library]
48
 $consoleInterp alias exit exit
49
 load "" Tk $consoleInterp
50
51
 # 2. A command 'console' in the application interpreter
52
 ;proc console {sub {optarg {}}} [subst -nocommands {
53
     switch -exact -- \$sub {
54
        title {
55
            $consoleInterp eval wm title . [list \$optarg]
56
        }
57
        hide {
58
            $consoleInterp eval wm withdraw .
59
        }
60
        show {
61
            $consoleInterp eval wm deiconify .
62
        }
63
        eval {
64
            $consoleInterp eval \$optarg
65
        }
66
        default {
67
            error "bad option \\\"\$sub\\\": should be hide, show, or title"
68
        }
69
    }
70
 }]
71
72
 # 3. Alias a command 'consoleinterp' in the console window interpreter
73
 #       to cause evaluation of the command 'consoleinterp' in the
74
 #       application interpreter.
75
 ;proc consoleinterp {sub cmd} {
76
    switch -exact -- $sub {
77
        eval {
78
            uplevel #0 $cmd
79
        }
80
        record {
81
            history add $cmd
82
            catch {uplevel #0 $cmd} retval
83
            return $retval
84
        }
85
        default {
86
            error "bad option \"$sub\": should be eval or record"
87
        }
88
    }
89
 }
90
 if {[package vsatisfies [package provide Tk] 4]} {
91
    $consoleInterp alias interp consoleinterp
92
 } else {
93
    $consoleInterp alias consoleinterp consoleinterp
94
 }
95
96
 # 4. Bind the <Destroy> event of the application interpreter's main
97
 #    window to kill the console (via tkConsoleExit)
98
 bind . <Destroy> [list +if {[string match . %W]} [list catch \
99
        [list $consoleInterp eval tkConsoleExit]]]
100
101
 # 5. Redefine the Tcl command 'puts' in the application interpreter
102
 #    so that messages to stdout and stderr appear in the console.
103
 rename puts tcl_puts
104
 ;proc puts {args} [subst -nocommands {
105
    switch -exact -- [llength \$args] {
106
        1 {
107
            if {[string match -nonewline \$args]} {
108
                if {[catch {uplevel 1 [linsert \$args 0 tcl_puts]} msg]} {
109
                    regsub -all tcl_puts \$msg puts msg
110
                    return -code error \$msg
111
                }
112
            } else {
113
                $consoleInterp eval [list tkConsoleOutput stdout \
114
                        "[lindex \$args 0]\n"]
115
            }
116
        }
117
        2 {
118
            if {[string match -nonewline [lindex \$args 0]]} {
119
                $consoleInterp eval [list tkConsoleOutput stdout \
120
                        [lindex \$args 1]]
121
            } elseif {[string match stdout [lindex \$args 0]]} {
122
                $consoleInterp eval [list tkConsoleOutput stdout \
123
                        "[lindex \$args 1]\n"]
124
            } elseif {[string match stderr [lindex \$args 0]]} {
125
                $consoleInterp eval [list tkConsoleOutput stderr \
126
                        "[lindex \$args 1]\n"]
127
            } else {
128
                if {[catch {uplevel 1 [linsert \$args 0 tcl_puts]} msg]} {
129
                    regsub -all tcl_puts \$msg puts msg
130
                    return -code error \$msg
131
                }
132
            }
133
        }
134
        3 {
135
            if {![string match -nonewline [lindex \$args 0]]} {
136
                if {[catch {uplevel 1 [linsert \$args 0 tcl_puts]} msg]} {
137
                    regsub -all tcl_puts \$msg puts msg
138
                    return -code error \$msg
139
                }
140
            } elseif {[string match stdout [lindex \$args 1]]} {
141
                $consoleInterp eval [list tkConsoleOutput stdout \
142
                        [lindex \$args 2]]
143
            } elseif {[string match stderr [lindex \$args 1]]} {
144
                $consoleInterp eval [list tkConsoleOutput stderr \
145
                        [lindex \$args 2]]
146
            } else {
147
                if {[catch {uplevel 1 [linsert \$args 0 tcl_puts]} msg]} {
148
                    regsub -all tcl_puts \$msg puts msg
149
                    return -code error \$msg
150
                }
151
            }
152
        }
153
        default {
154
            if {[catch {uplevel 1 [linsert \$args 0 tcl_puts]} msg]} {
155
                regsub -all tcl_puts \$msg puts msg
156
                return -code error \$msg
157
            }
158
        }
159
    }
160
 }]
161
 $consoleInterp alias puts puts
162
163
 # 6. No matter what Tk_Main says, insist that this is an interactive  shell
164
 set tcl_interactive 1
165
166
 ########################################################################
167
 # Evaluate the Tk library script console.tcl in the console interpreter
168
 ########################################################################
169
 $consoleInterp eval source [list [file join $tk_library console.tcl]]
170
 $consoleInterp eval {
171
    if {![llength [info commands tkConsoleExit]]} {
172
        tk::unsupported::ExposePrivateCommand tkConsoleExit
173
    }
174
 }
175
 $consoleInterp eval {
176
    if {![llength [info commands tkConsoleOutput]]} {
177
        tk::unsupported::ExposePrivateCommand tkConsoleOutput
178
    }
179
 }
180
 if {[string match 8.3.4 $tk_patchLevel]} {
181
    # Workaround bug in first draft of the tkcon enhancments
182
    $consoleInterp eval {
183
        bind Console <Control-Key-v> {}
184
    }
185
 }
186
 # Restore normal [puts] if console widget goes away...
187
 proc Oc_RestorePuts {slave} {
188
     rename puts {}
189
     rename tcl_puts puts
190
     interp delete $slave
191
 }
192
 $consoleInterp alias Oc_RestorePuts Oc_RestorePuts $consoleInterp
193
 $consoleInterp eval {
194
     bind Console <Destroy> +Oc_RestorePuts
195
 }
196
197
 unset consoleInterp
198
199
 console title "[wm title .] Console"