source: vmdshow/branches/0.2/vmdserver.tcl @ 6716

Last change on this file since 6716 was 6559, checked in by ldelgass, 8 years ago

merge r6558 from vdmshow trunk

  • Property svn:eol-style set to native
File size: 52.3 KB
Line 
1# -*- mode: tcl; indent-tabs-mode: nil -*-
2# ----------------------------------------------------------------------
3#  HUBZERO: server for VMD
4#
5#  This program runs VMD and acts as a server for client applications.
6# ----------------------------------------------------------------------
7#  Michael McLennan (mmclennan@purdue.edu)
8# ======================================================================
9#  Copyright (c) 2013 - HUBzero Foundation, LLC
10# ======================================================================
11
12proc bgerror {mesg} {
13    puts stderr "SERVER ERROR: $mesg"
14}
15
16proc FramesDefView { frameNum matrixNameList matrixValueList } {
17    global Views
18    if { ![string is int $frameNum] } {
19        error "bad frame value \"$frameNum\""
20    }
21    set Views($frameNum) [list $matrixNameList $matrixValueList]
22}
23
24proc FramesSetCmds { frameNum cmds } {
25    global ViewCmds
26    if { ![string is int $frameNum] } {
27        error "bad frame value \"$frameNum\""
28    }
29    set ViewCmds($frameNum) [join $cmds \;]
30}
31
32proc RestoreMaterials {} {
33    set mlist {
34        Opaque Transparent BrushedMetal Diffuse Ghost
35        Glass1 Glass2 Glass3 Glossy HardPlastic MetallicPastel
36        Steel Translucent Edgy EdgyShiny EdgyGlass Goodsell
37        AOShiny AOChalky AOEdgy BlownGlass GlassBubble RTChrome
38        Phantom Dead WaterColor Hallucination GlowWorm Transparent2
39        protein pro2tube waterfile off water
40    }
41    set mymlist [material list]
42    foreach mat $mlist {
43        if { [lsearch $mymlist $mat] == -1 } {
44            material add $mat
45        }
46    }
47    material change ambient Opaque 0.000000
48    material change diffuse Opaque 0.650000
49    material change specular Opaque 0.500000
50    material change shininess Opaque 0.534020
51    material change mirror Opaque 0.000000
52    material change opacity Opaque 1.000000
53    material change outline Opaque 0.000000
54    material change outlinewidth Opaque 0.000000
55    material change transmode Opaque 0.000000
56    material change ambient Transparent 0.000000
57    material change diffuse Transparent 0.650000
58    material change specular Transparent 0.500000
59    material change shininess Transparent 0.534020
60    material change mirror Transparent 0.000000
61    material change opacity Transparent 0.300000
62    material change outline Transparent 0.000000
63    material change outlinewidth Transparent 0.000000
64    material change transmode Transparent 0.000000
65    material change ambient BrushedMetal 0.080000
66    material change diffuse BrushedMetal 0.390000
67    material change specular BrushedMetal 0.340000
68    material change shininess BrushedMetal 0.150000
69    material change mirror BrushedMetal 0.000000
70    material change opacity BrushedMetal 1.000000
71    material change outline BrushedMetal 0.000000
72    material change outlinewidth BrushedMetal 0.000000
73    material change transmode BrushedMetal 0.000000
74    material change ambient Diffuse 0.000000
75    material change diffuse Diffuse 0.620000
76    material change specular Diffuse 0.000000
77    material change shininess Diffuse 0.530000
78    material change mirror Diffuse 0.000000
79    material change opacity Diffuse 1.000000
80    material change outline Diffuse 0.000000
81    material change outlinewidth Diffuse 0.000000
82    material change transmode Diffuse 0.000000
83    material change ambient Ghost 0.000000
84    material change diffuse Ghost 0.000000
85    material change specular Ghost 1.000000
86    material change shininess Ghost 0.230000
87    material change mirror Ghost 0.000000
88    material change opacity Ghost 0.100000
89    material change outline Ghost 0.000000
90    material change outlinewidth Ghost 0.000000
91    material change transmode Ghost 0.000000
92    material change ambient Glass1 0.000000
93    material change diffuse Glass1 0.500000
94    material change specular Glass1 0.650000
95    material change shininess Glass1 0.530000
96    material change mirror Glass1 0.000000
97    material change opacity Glass1 0.150000
98    material change outline Glass1 0.000000
99    material change outlinewidth Glass1 0.000000
100    material change transmode Glass1 0.000000
101    material change ambient Glass2 0.520000
102    material change diffuse Glass2 0.760000
103    material change specular Glass2 0.220000
104    material change shininess Glass2 0.590000
105    material change mirror Glass2 0.000000
106    material change opacity Glass2 0.680000
107    material change outline Glass2 0.000000
108    material change outlinewidth Glass2 0.000000
109    material change transmode Glass2 0.000000
110    material change ambient Glass3 0.150000
111    material change diffuse Glass3 0.250000
112    material change specular Glass3 0.750000
113    material change shininess Glass3 0.800000
114    material change mirror Glass3 0.000000
115    material change opacity Glass3 0.500000
116    material change outline Glass3 0.000000
117    material change outlinewidth Glass3 0.000000
118    material change transmode Glass3 0.000000
119    material change ambient Glossy 0.000000
120    material change diffuse Glossy 0.650000
121    material change specular Glossy 1.000000
122    material change shininess Glossy 0.880000
123    material change mirror Glossy 0.000000
124    material change opacity Glossy 1.000000
125    material change outline Glossy 0.000000
126    material change outlinewidth Glossy 0.000000
127    material change transmode Glossy 0.000000
128    material change ambient HardPlastic 0.000000
129    material change diffuse HardPlastic 0.560000
130    material change specular HardPlastic 0.280000
131    material change shininess HardPlastic 0.690000
132    material change mirror HardPlastic 0.000000
133    material change opacity HardPlastic 1.000000
134    material change outline HardPlastic 0.000000
135    material change outlinewidth HardPlastic 0.000000
136    material change transmode HardPlastic 0.000000
137    material change ambient MetallicPastel 0.000000
138    material change diffuse MetallicPastel 0.260000
139    material change specular MetallicPastel 0.550000
140    material change shininess MetallicPastel 0.190000
141    material change mirror MetallicPastel 0.000000
142    material change opacity MetallicPastel 1.000000
143    material change outline MetallicPastel 0.000000
144    material change outlinewidth MetallicPastel 0.000000
145    material change transmode MetallicPastel 0.000000
146    material change ambient Steel 0.250000
147    material change diffuse Steel 0.000000
148    material change specular Steel 0.380000
149    material change shininess Steel 0.320000
150    material change mirror Steel 0.000000
151    material change opacity Steel 1.000000
152    material change outline Steel 0.000000
153    material change outlinewidth Steel 0.000000
154    material change transmode Steel 0.000000
155    material change ambient Translucent 0.000000
156    material change diffuse Translucent 0.700000
157    material change specular Translucent 0.600000
158    material change shininess Translucent 0.300000
159    material change mirror Translucent 0.000000
160    material change opacity Translucent 0.800000
161    material change outline Translucent 0.000000
162    material change outlinewidth Translucent 0.000000
163    material change transmode Translucent 0.000000
164    material change ambient Edgy 0.000000
165    material change diffuse Edgy 0.660000
166    material change specular Edgy 0.000000
167    material change shininess Edgy 0.750000
168    material change mirror Edgy 0.000000
169    material change opacity Edgy 1.000000
170    material change outline Edgy 0.620000
171    material change outlinewidth Edgy 0.940000
172    material change transmode Edgy 0.000000
173    material change ambient EdgyShiny 0.000000
174    material change diffuse EdgyShiny 0.660000
175    material change specular EdgyShiny 0.960000
176    material change shininess EdgyShiny 0.750000
177    material change mirror EdgyShiny 0.000000
178    material change opacity EdgyShiny 1.000000
179    material change outline EdgyShiny 0.760000
180    material change outlinewidth EdgyShiny 0.940000
181    material change transmode EdgyShiny 0.000000
182    material change ambient EdgyGlass 0.000000
183    material change diffuse EdgyGlass 0.660000
184    material change specular EdgyGlass 0.500000
185    material change shininess EdgyGlass 0.750000
186    material change mirror EdgyGlass 0.000000
187    material change opacity EdgyGlass 0.620000
188    material change outline EdgyGlass 0.620000
189    material change outlinewidth EdgyGlass 0.940000
190    material change transmode EdgyGlass 0.000000
191    material change ambient Goodsell 0.520000
192    material change diffuse Goodsell 1.000000
193    material change specular Goodsell 0.000000
194    material change shininess Goodsell 0.000000
195    material change mirror Goodsell 0.000000
196    material change opacity Goodsell 1.000000
197    material change outline Goodsell 4.000000
198    material change outlinewidth Goodsell 0.900000
199    material change transmode Goodsell 0.000000
200    material change ambient AOShiny 0.000000
201    material change diffuse AOShiny 0.850000
202    material change specular AOShiny 0.200000
203    material change shininess AOShiny 0.530000
204    material change mirror AOShiny 0.000000
205    material change opacity AOShiny 1.000000
206    material change outline AOShiny 0.000000
207    material change outlinewidth AOShiny 0.000000
208    material change transmode AOShiny 0.000000
209    material change ambient AOChalky 0.000000
210    material change diffuse AOChalky 0.850000
211    material change specular AOChalky 0.000000
212    material change shininess AOChalky 0.530000
213    material change mirror AOChalky 0.000000
214    material change opacity AOChalky 1.000000
215    material change outline AOChalky 0.000000
216    material change outlinewidth AOChalky 0.000000
217    material change transmode AOChalky 0.000000
218    material change ambient AOEdgy 0.000000
219    material change diffuse AOEdgy 0.900000
220    material change specular AOEdgy 0.200000
221    material change shininess AOEdgy 0.530000
222    material change mirror AOEdgy 0.000000
223    material change opacity AOEdgy 1.000000
224    material change outline AOEdgy 0.620000
225    material change outlinewidth AOEdgy 0.930000
226    material change transmode AOEdgy 0.000000
227    material change ambient BlownGlass 0.040000
228    material change diffuse BlownGlass 0.340000
229    material change specular BlownGlass 1.000000
230    material change shininess BlownGlass 1.000000
231    material change mirror BlownGlass 0.000000
232    material change opacity BlownGlass 0.100000
233    material change outline BlownGlass 0.000000
234    material change outlinewidth BlownGlass 0.000000
235    material change transmode BlownGlass 1.000000
236    material change ambient GlassBubble 0.250000
237    material change diffuse GlassBubble 0.340000
238    material change specular GlassBubble 1.000000
239    material change shininess GlassBubble 1.000000
240    material change mirror GlassBubble 0.000000
241    material change opacity GlassBubble 0.040000
242    material change outline GlassBubble 0.000000
243    material change outlinewidth GlassBubble 0.000000
244    material change transmode GlassBubble 1.000000
245    material change ambient RTChrome 0.000000
246    material change diffuse RTChrome 0.650000
247    material change specular RTChrome 0.500000
248    material change shininess RTChrome 0.530000
249    material change mirror RTChrome 0.700000
250    material change opacity RTChrome 1.000000
251    material change outline RTChrome 0.000000
252    material change outlinewidth RTChrome 0.000000
253    material change transmode RTChrome 0.000000
254    material change ambient Phantom 0.000000
255    material change diffuse Phantom 0.700000
256    material change specular Phantom 0.100000
257    material change shininess Phantom 0.280000
258    material change mirror Phantom 0.000000
259    material change opacity Phantom 0.150000
260    material change outline Phantom 0.000000
261    material change outlinewidth Phantom 0.000000
262    material change transmode Phantom 0.000000
263    material change ambient Dead 0.580000
264    material change diffuse Dead 0.000000
265    material change specular Dead 0.000000
266    material change shininess Dead 0.000000
267    material change mirror Dead 0.000000
268    material change opacity Dead 1.000000
269    material change outline Dead 0.000000
270    material change outlinewidth Dead 0.000000
271    material change transmode Dead 0.000000
272    material change ambient WaterColor 0.000000
273    material change diffuse WaterColor 0.350000
274    material change specular WaterColor 0.440000
275    material change shininess WaterColor 0.110000
276    material change mirror WaterColor 0.000000
277    material change opacity WaterColor 1.000000
278    material change outline WaterColor 4.000000
279    material change outlinewidth WaterColor 0.570000
280    material change transmode WaterColor 0.000000
281    material change ambient Hallucination 0.100000
282    material change diffuse Hallucination 0.810000
283    material change specular Hallucination 1.000000
284    material change shininess Hallucination 0.250000
285    material change mirror Hallucination 0.000000
286    material change opacity Hallucination 0.300000
287    material change outline Hallucination 0.000000
288    material change outlinewidth Hallucination 0.000000
289    material change transmode Hallucination 1.000000
290    material change ambient GlowWorm 0.250000
291    material change diffuse GlowWorm 0.650000
292    material change specular GlowWorm 0.500000
293    material change shininess GlowWorm 0.534020
294    material change mirror GlowWorm 0.000000
295    material change opacity GlowWorm 1.000000
296    material change outline GlowWorm 0.000000
297    material change outlinewidth GlowWorm 0.000000
298    material change transmode GlowWorm 0.000000
299    material change ambient Transparent2 0.000000
300    material change diffuse Transparent2 0.650000
301    material change specular Transparent2 0.500000
302    material change shininess Transparent2 0.534020
303    material change mirror Transparent2 0.000000
304    material change opacity Transparent2 0.750000
305    material change outline Transparent2 0.000000
306    material change outlinewidth Transparent2 0.000000
307    material change transmode Transparent2 0.000000
308    material change ambient protein 0.000000
309    material change diffuse protein 0.650000
310    material change specular protein 1.000000
311    material change shininess protein 0.534020
312    material change mirror protein 0.000000
313    material change opacity protein 1.000000
314    material change outline protein 0.000000
315    material change outlinewidth protein 0.000000
316    material change transmode protein 0.000000
317    material change ambient pro2tube 0.000000
318    material change diffuse pro2tube 0.650000
319    material change specular pro2tube 1.000000
320    material change shininess pro2tube 0.534020
321    material change mirror pro2tube 0.000000
322    material change opacity pro2tube 1.000000
323    material change outline pro2tube 0.000000
324    material change outlinewidth pro2tube 0.000000
325    material change transmode pro2tube 0.000000
326    material change ambient waterfile 0.000000
327    material change diffuse waterfile 0.650000
328    material change specular waterfile 1.000000
329    material change shininess waterfile 0.534020
330    material change mirror waterfile 0.000000
331    material change opacity waterfile 1.000000
332    material change outline waterfile 0.000000
333    material change outlinewidth waterfile 0.000000
334    material change transmode waterfile 0.000000
335    material change ambient off 0.000000
336    material change diffuse off 0.650000
337    material change specular off 1.000000
338    material change shininess off 0.534020
339    material change mirror off 0.000000
340    material change opacity off 0.000000
341    material change outline off 0.000000
342    material change outlinewidth off 0.000000
343    material change transmode off 0.000000
344    material change ambient water 0.000000
345    material change diffuse water 1.000000
346    material change specular water 0.750000
347    material change shininess water 0.000000
348    material change mirror water 0.000000
349    material change opacity water 0.000000
350    material change outline water 0.000000
351    material change outlinewidth water 0.000000
352    material change transmode water 1.000000
353}
354
355# ========================================================================
356#        Command aliases for VMD cmds in the slave interpreter
357# ========================================================================
358
359# ----------------------------------------------------------------------
360# USAGE: animate <option> <args>...
361#
362# The usual VMD "animate" command is problematic for this server.  If we're
363# going to play the animation, the client will do it.  Intercept any
364# "animate" commands in the scene scripts and do nothing.
365# ----------------------------------------------------------------------
366proc Animate {args} {
367    # do nothing
368}
369
370# ----------------------------------------------------------------------
371# USAGE: atomselect <args>...
372#
373# Allow the usual VMD "atomselect" command to pass through, prohibiting
374# only the "writepdb" operation.
375# ----------------------------------------------------------------------
376proc AtomSelect {args} {
377    foreach arg $args {
378        if { [string match "write*" $arg] } {
379            error "atomselect \"$arg\" option is disallowed"
380        }
381    }
382    return [uplevel 1 [concat atomselect $args]]
383}
384
385# ----------------------------------------------------------------------
386# USAGE: atomselect_instance <args>...
387#
388# Called by the unknown proceduce when it encounters atom selections in the
389# form "atomselect[0-9]+".  Pass through commands to the VMD interpreter.
390# ----------------------------------------------------------------------
391proc AtomSelectInstance {args} {
392    set cmd [lindex $args 0]
393    if { [regexp {atomselect[0-9]+} $cmd] } {
394        return [uplevel 1 $args]
395    }
396}
397
398# ----------------------------------------------------------------------
399# USAGE: display option ?arg arg...?
400#
401# Executes the "command arg arg..." string in the server and substitutes
402# the result into the template string in place of each "%v" field.
403# Sends the result back to the client.
404# ----------------------------------------------------------------------
405proc Display {args} {
406    set option [lindex $args 0]
407    if {[lsearch {resize reposition rendermode update fps} $option] >= 0} {
408        # ignore these commands -- they cause trouble
409        return ""
410    }
411    eval display $args
412}
413
414# ----------------------------------------------------------------------
415# USAGE: Drag start|end
416#
417# Resizes the visualization window to the given width <w> and height
418# <h>.  The next image sent should be this size.
419# ----------------------------------------------------------------------
420proc Drag {action} {
421    global DisplayProps
422
423    switch -- $action {
424        start {
425            # simplify rendering so it goes faster during drag operations
426            set neww [expr {round($DisplayProps(framew)/2.0)}]
427            set newh [expr {round($DisplayProps(frameh)/2.0)}]
428            server_safe_resize $neww $newh
429            display rendermode Normal
430            display shadows off
431
432            # gah: turn off rep change
433            if 0 {
434                foreach nmol [molinfo list] {
435                    set max [molinfo $nmol get numreps]
436                    for {set nrep 0} {$nrep < $max} {incr nrep} {
437                        mol modstyle $nrep $nmol "Lines"
438                    }
439                }
440            }
441        }
442        end {
443            # put original rendering options back
444            server_safe_resize $DisplayProps(framew) $DisplayProps(frameh)
445            display rendermode $DisplayProps(rendermode)
446            display shadows $DisplayProps(shadows)
447
448            # gah: turn off rep change
449            if 0 {
450                # restore rendering methods for all representations
451                foreach nmol [molinfo list] {
452                    set max [molinfo $nmol get numreps]
453                    for {set nrep 0} {$nrep < $max} {incr nrep} {
454                        mol modstyle $nrep $nmol $DisplayProps(rep-$nmol-$nrep)
455                    }
456                }
457               }
458        }
459        default {
460            error "bad option \"$action\": should be start or end"
461        }
462    }
463}
464
465# ----------------------------------------------------------------------
466# USAGE: frames defview <frame> {matrixNames...} {matrixValues...}
467# USAGE: frames time <epochValue> <start> ?<finish>? ?<inc>? ?-defview?
468# USAGE: frames rotate <epochValue> <xa> <ya> <za> <number>
469# USAGE: frames max
470#
471# Used to request one or more frames for an animation.  A "time"
472# animation is a series of frames between two time points.  A "rotate"
473# animation is a series of frames that rotate the view 360 degrees.
474#
475# The <epochValue> is passed by the client to indicate the relevance of
476# the request.  Whenever the client enters a new epoch, it is no longer
477# concerned with any earlier epochs, so the server can ignore pending
478# images that are out of date.  The server sends back the epoch with
479# all frames so the client can understand if the frames are relevant.
480#
481# The "defview" operation sets the default view associated with each
482# frame.  Animation scripts can change the default view to a series of
483# fly-through views.  This operation provides a way of storing those
484# views.
485#
486# For a "time" animation, the <start> is a number of a requested frame.
487# The <finish> is the last frame in the series.  The <inc> is the step
488# by which the frames should be generated, which may be larger than 1.
489#
490# For a "rotate" animation, the <xa>,<ya>,<za> angles indicate the
491# direction of the rotation.  The <number> is the number of frames
492# requested for a full 360 degree rotation.
493#
494# The "frames max" query returns the maximum number of frames in the
495# trajectory.  The server uses this to figure out the limits of
496# animation.
497# ----------------------------------------------------------------------
498proc Frames {what args} {
499    global client Epoch Work Views
500
501    # check incoming parameters
502    switch -- $what {
503        time {
504            set epochValue [lindex $args 0]
505            set start [lindex $args 1]
506
507            set i [lsearch $args -defview]
508            if {$i >= 0} {
509                set defview 1
510                set args [lreplace $args $i $i]
511            } else {
512                set defview 0
513            }
514
515            set finish [lindex $args 2]
516            if {$finish eq ""} {
517                set finish $start
518            }
519            set inc [lindex $args 3]
520            if {$inc eq ""} {
521                set inc 1
522            }
523
524            if {![string is integer $finish]} {
525                server_oops $client \
526                    "bad animation end \"$finish\" should be integer"
527                return
528            }
529            if {![string is integer $inc] || $inc == 0} {
530                server_oops $client \
531                    "bad animation inc \"$inc\" should be non-zero integer"
532                return
533            }
534            if {($finish < $start && $inc > 0) ||
535                ($finish > $start && $inc < 0)} {
536                server_oops $client \
537                    "bad animation limits: from $start to $finish by $inc"
538            }
539
540            # new epoch? then clean out work queue
541            if {$epochValue > $Epoch} {
542                array unset Work
543                set Work(queue) ""
544                set Epoch $epochValue
545            }
546
547            # add these frames to the queue
548            if {$inc > 0} {
549                # generate frames in play>> direction
550                for {set n $start} {$n <= $finish} {incr n $inc} {
551                    if {![info exists Work($n)]} {
552                        lappend Work(queue) [list epoch $epochValue frame $n num $n defview $defview]
553                        set Work($n) 1
554                    }
555                }
556            } else {
557                # generate frames in <<play direction
558                for {set n $start} {$n >= $finish} {incr n $inc} {
559                    if {![info exists Work($n)]} {
560                        lappend Work(queue) [list epoch $epochValue frame $n num $n defview $defview]
561                        set Work($n) 1
562                    }
563                }
564            }
565        }
566        rotate {
567            set epochValue [lindex $args 0]
568            set mx [lindex $args 1]
569            if {![string is double -strict $mx]} {
570                server_oops $client \
571                    "bad mx rotation value \"$mx\" should be double"
572                return
573            }
574            set my [lindex $args 2]
575            if {![string is double -strict $my]} {
576                server_oops $client \
577                    "bad my rotation value \"$my\" should be double"
578                return
579            }
580            set mz [lindex $args 3]
581            if {![string is double -strict $mz]} {
582                server_oops $client \
583                    "bad mz rotation value \"$mz\" should be double"
584                return
585            }
586            set num [lindex $args 4]
587            if {![string is integer -strict $num] || $num < 2} {
588                server_oops $client \
589            "bad number of rotation frames \"$num\" should be integer > 1"
590                return
591            }
592
593            #
594            # Compute the rotation matrix for each rotated view.  Start
595            # with the current rotation matrix.  Rotate that around a
596            # vector perpendicular to the plane of rotation for the given
597            # angles (mx,my,mz).  Find vector that by rotating some vector
598            # such as (1,1,1) by the angles (mx,my,mz).  Do a couple of
599            # times and compute the differences between those vectors.
600            # Then, compute the cross product of the differences.  The
601            # result is the axis of rotation.
602            #
603            set lastrotx [trans axis x $mx deg]
604            set lastroty [trans axis y $my deg]
605            set lastrotz [trans axis z $mz deg]
606            set lastrot [transmult $lastrotx $lastroty $lastrotz]
607
608            set lastvec [list 1 1 1]
609            foreach v {1 2} {
610                foreach row $lastrot comp {x y z w} {
611                    # multiply each row by last vector
612                    set vec($comp) 0
613                    for {set i 0} {$i < 3} {incr i} {
614                        set vec($comp) [expr {$vec($comp) + [lindex $row $i]}]
615                    }
616                }
617                set vec${v}(x) [expr {$vec(x)-[lindex $lastvec 0]}]
618                set vec${v}(y) [expr {$vec(y)-[lindex $lastvec 1]}]
619                set vec${v}(z) [expr {$vec(z)-[lindex $lastvec 2]}]
620
621                set lastvec [list $vec(x) $vec(y) $vec(z)]
622                set lastrot [transmult $lastrot $lastrotx $lastroty $lastrotz]
623            }
624
625            set crx [expr {$vec1(y)*$vec2(z)-$vec1(z)*$vec2(y)}]
626            set cry [expr {$vec1(z)*$vec2(x)-$vec1(x)*$vec2(z)}]
627            set crz [expr {$vec1(x)*$vec2(y)-$vec1(y)*$vec2(x)}]
628
629            set angle [expr {360.0/$num}]
630            set rotby [transabout [list $crx $cry $crz] $angle deg]
631            set rotm [lindex [molinfo top get rotate_matrix] 0]
632
633            # compute cross product of (1,1,1,0) and rotated vector from above
634
635            for {set n 0} {$n < $num} {incr n} {
636                lappend Work(queue) \
637                    [list epoch $epochValue rotate $rotm num $n defview 0]
638                set rotm [transmult $rotby $rotm]
639                set Work($n) 1
640            }
641        }
642        defview {
643            eval FramesDefView $args
644        }
645        setcmds {
646            eval FramesSetCmds $args
647        }
648        max {
649            set maxFrames 0
650            foreach mol [molinfo list] {
651                set n [molinfo $mol get numframes]
652                if { $n > $maxFrames } {
653                    set maxFrames $n
654                }
655            }
656            return $maxFrames
657            # gah: fix to return max correct max frames.
658            if 0 {
659                set nmol [lindex [molinfo list] 0]
660                if {$nmol ne ""} {
661                    return [molinfo $nmol get numframes]
662                }
663                return 0
664            }
665        }
666        default {
667            error "bad option \"$what\": should be defview, time, rotate, setcmds, or max"
668        }
669    }
670
671    # service the queue at some point
672    server_send_image -eventually
673}
674
675# ----------------------------------------------------------------------
676# USAGE: getview
677#
678# Used to query the scaling and centering of the initial view set
679# by VMD after a molecule is loaded.  Returns the following:
680#   <viewName> -rotate <mtx> -global <mtx> -scale <mtx> -center <mtx>
681# ----------------------------------------------------------------------
682proc GetView {} {
683    global Scenes
684
685    if { [llength [molinfo list]] == 0 } {
686        return ""
687    }
688    if { $Scenes(@CURRENT) eq "" } {
689        return ""
690    }
691
692    set rval [list $Scenes(@CURRENT)]  ;# start with the scene id
693
694    lappend rval \
695        -rotate [lindex [molinfo top get rotate_matrix] 0] \
696        -scale  [lindex [molinfo top get scale_matrix] 0]  \
697        -center [lindex [molinfo top get center_matrix] 0] \
698        -global [lindex [molinfo top get global_matrix] 0]
699
700    return $rval
701}
702
703# ----------------------------------------------------------------------
704# USAGE: load <file> <file>...
705#
706# Loads the molecule data from one or more files, which may be PDB,
707# DCD, PSF, etc.
708# ----------------------------------------------------------------------
709proc Load { fileList } {
710    global MolInfo MolNames tmpDir
711
712    # clear all existing molecules
713    foreach nmol [molinfo list] {
714        mol delete $nmol
715    }
716    catch {unset MolInfo}
717    set MolNames ""
718
719    # load new files
720    if {![regexp {^@name:} $fileList]} {
721        # make sure that there is at least one name in the list
722        set fileList [linsert $fileList 0 "@name:0"]
723    }
724
725    set slot 0
726    set op "badOp"
727    foreach file $fileList {
728        if {[regexp {^@name:(.+)} $file match name]} {
729            set op "new"
730            continue
731        }
732        if { $tmpDir != "" } {
733            set tmpFile [file join $tmpDir [file tail $file]]
734            if { [file exists $tmpFile] } {
735                set file $tmpFile
736            }
737        }
738        mol $op $file waitfor all
739        if { ![info exists name] } {
740            puts stderr "can't find name for file: file=$file"
741        }
742        if {$op eq "new"} {
743            set newnum [lindex [molinfo list] end]
744            if {[lsearch -exact MolNames $name] < 0} {
745                lappend MolNames $name
746            }
747            set MolInfo($name) $newnum
748            set MolInfo($slot) $newnum
749            incr slot
750            set op "addfile"
751        }
752    }
753
754    # BE CAREFUL -- force a "display update" here
755    # that triggers something in VMD that changes view matrices now,
756    # so if we change them later, the new values stick
757    display update
758}
759
760# ----------------------------------------------------------------------
761# These commands just confuse things, so ignore them silently.
762# ----------------------------------------------------------------------
763proc NoOp {args} {
764    # do nothing
765}
766
767# ----------------------------------------------------------------------
768# USAGE: queryinfo <x> <y> ?-prev atomid atomid?
769# USAGE: queryinfo <x> <y> ?-prev atomid?
770# USAGE: queryinfo <x> <y>
771#
772# Picks the atom at screen coordinate <x>,<y> and returns information
773# about it.  If one previous atom is specified, then this command
774# returns the bond length between the previous atom and the current
775# one.  If two previous atoms are specified, then it returns the
776# angle between the three atoms.
777# ----------------------------------------------------------------------
778proc QueryInfo {x y args} {
779    global DisplayProps MolNames MolInfo
780
781    # handle command arguments
782    set prevatoms ""
783    while {[llength $args] > 0} {
784        set option [lindex $args 0]
785        set args [lrange $args 1 end]
786        if {$option eq "-prev"} {
787            while {[llength $args] > 0} {
788                set val [lindex $args 0]
789                if {[regexp {^[0-9]} $val]} {
790                    lappend prevatoms $val
791                    set args [lrange $args 1 end]
792                } else {
793                    break
794                }
795            }
796        } else {
797            error "bad option \"$option\": should be -prev"
798        }
799    }
800
801    # be careful -- VMD uses coordinates from LOWER-left corner of window
802    set vmdy [expr {$DisplayProps(frameh)-$y}]
803
804    set vals [pick $x $vmdy]
805    if {$vals ne ""} {
806        array set data $vals
807
808        # map the molecule ID back to the name used within MD Showcase
809        foreach molname $MolNames {
810            if {$MolInfo($molname) == $data(mol)} {
811                set data(molname) $molname
812                break
813            }
814        }
815
816        # pass back the click coord on screen so we know where this came from
817        set data(screenx) $x
818        set data(screeny) $y
819
820        # if there are -prev atoms, query extra info
821        set curr [list $data(index) $data(mol)]
822        set meas $prevatoms
823        set i [lsearch -exact $meas $curr]
824        if {$i >= 0} {
825            set meas [lreplace $meas $i $i]
826        }
827        set meas [linsert $meas 0 $curr]
828        set meas [lrange $meas 0 2]
829
830        switch -- [llength $meas] {
831            2 {
832                set data(bondlength) [measure bond $meas]
833            }
834            3 {
835                set data(bondlength) [measure bond [lrange $meas 0 1]]
836                set data(bondlength2) [measure bond [lrange $meas 1 2]]
837                set data(angle) [measure angle $meas]
838            }
839        }
840
841        # convert data back to return value
842        set vals [array get data]
843    }
844    return $vals
845}
846
847
848# ----------------------------------------------------------------------
849# USAGE: resize <w> <h>
850#
851# Resizes the visualization window to the given width <w> and height
852# <h>.  The next image sent should be this size.
853# ----------------------------------------------------------------------
854proc Resize {w h} {
855    global DisplayProps
856
857    # store the desired size in case we downscale
858    set DisplayProps(framew) $w
859    set DisplayProps(frameh) $h
860
861    server_safe_resize $w $h
862}
863
864# ----------------------------------------------------------------------
865# USAGE: rock off
866# USAGE: rock x|y|z by <step> ?<n>?
867#
868# The usual VMD "rock" command is problematic for this server.  If we're
869# going to rock the animation, the client will do it.  Intercept any "rock"
870# commands in the scene scripts and do nothing.
871# ----------------------------------------------------------------------
872proc Rock {args} {
873    # do nothing
874}
875
876
877# ----------------------------------------------------------------------
878# USAGE: scene define id <script>
879# USAGE: scene show id ?-before <viewCmd>? ?-after <viewCmd>?
880# USAGE: scene clear
881# USAGE: scene forget ?id id...?
882#
883# Used to define and manipulate scenes of the trajectory information
884# loaded previously by the "load" command.  The "define" operation
885# defines the script that loads a scene called <id>.  The "show"
886# operation executes that script to show the scene.  The "clear"
887# operation clears the current scene (usually in preparation for
888# showing another scene).  The "forget" operation erases one or more
889# scene definitions; if no ids are specified, then all scenes are
890# forgotten.
891# ----------------------------------------------------------------------
892proc Scene {option args} {
893    global Scenes Views MolInfo DisplayProps parser
894
895    switch -- $option {
896        define {
897            if {[llength $args] != 2} {
898                error "wrong # args: should be \"scene define id script\""
899            }
900            set id [lindex $args 0]
901            set script [lindex $args 1]
902            set Scenes($id) $script
903        }
904        show {
905            if {[llength $args] < 1 || [llength $args] > 5} {
906                error "wrong # args: should be \"scene show id ?-before cmd? ?-after cmd?\""
907            }
908            set id [lindex $args 0]
909            if {![info exists Scenes($id)]} {
910                error "bad scene id \"$id\": should be one of [join [array names Scenes] {, }]"
911            }
912
913            set triggers(before) ""
914            set triggers(after) ""
915            foreach {key val} [lrange $args 1 end] {
916                switch -- $key {
917                    -before {
918                        set triggers(before) $val
919                    }
920                    -after {
921                        set triggers(after) $val
922                    }
923                    default {
924                        error "bad option \"$key\": should be -before, -after"
925                    }
926                }
927            }
928
929            # if -before arg was given, send back the view right now
930            if {$triggers(before) ne "" && $Scenes(@CURRENT) ne ""} {
931                TellMe $triggers(before) getview
932            }
933
934            # clear the old scene
935            Scene clear
936            display resetview
937
938            # use a safe interp to keep things safe
939            foreach val [$parser eval {info vars}] {
940                # clear all variables created by previous scripts
941                $parser eval [list catch [list unset $val]]
942            }
943            $parser eval [list array set mol [array get MolInfo]]
944
945            if {[catch {$parser eval $Scenes($id)} result]} {
946                global errorInfo
947                error "$errorInfo\n$result\nwhile loading scene \"$id\""
948            }
949
950            # capture display characteristics in case we ever need to reset
951            set DisplayProps(rendermode) "Normal"
952            set DisplayProps(shadows) [display get shadows]
953
954            foreach nmol [molinfo list] {
955                set max [molinfo $nmol get numreps]
956                for {set nrep 0} {$nrep < $max} {incr nrep} {
957                    set style [lindex [molinfo $nmol get "{rep $nrep}"] 0]
958                    set DisplayProps(rep-$nmol-$nrep) $style
959                }
960            }
961
962            # store the scene id for later
963            set Scenes(@CURRENT) $id
964
965            # if -after arg was given, send back the view after the script
966            if {$triggers(after) ne ""} {
967                TellMe $triggers(after) getview
968            }
969        }
970        clear {
971            foreach mol [molinfo list] {
972                set numOfRep [lindex [mol list $mol] 12]
973                for {set i 1} {$i <= $numOfRep} {incr i} {
974                    mol delrep 0 $mol
975                }
976            }
977            set Scenes(@CURRENT) ""
978            array unset Views
979            array unset ViewCmds
980
981            # reset the server properties
982            axes location off
983            color Display Background black
984            RestoreMaterials
985            eval $DisplayProps(options)
986        }
987        forget {
988            if {[llength $args] == 0} {
989                set args [array names Scenes]
990            }
991            foreach id $args {
992                if {$id eq "@CURRENT"} continue
993                catch {unset Scenes($id)}
994                if {$id eq $Scenes(@CURRENT)} {
995                    set Scenes(@CURRENT) ""
996                }
997            }
998        }
999        default {
1000            error "bad option \"$option\": should be define, show, clear, forget"
1001        }
1002    }
1003}
1004
1005# ----------------------------------------------------------------------
1006# USAGE: setquality normal|high
1007#
1008# Sets the rendering quality for the scene--either "high" (GLSL) or
1009# normal.
1010# ----------------------------------------------------------------------
1011proc SetQuality {newval} {
1012    global DisplayProps
1013
1014    switch -- $newval {
1015        high {
1016            display rendermode GLSL
1017            set DisplayProps(rendermode) "GLSL"
1018        }
1019        normal {
1020            display rendermode Normal
1021            set DisplayProps(rendermode) "Normal"
1022        }
1023        default {
1024            error "bad quality value \"$newval\": should be normal or high"
1025        }
1026    }
1027}
1028
1029# ----------------------------------------------------------------------
1030# USAGE: setview ?-rotate <mtx>? ?-scale <mtx>? ?-center <mtx>? ?-global <mtx>?
1031#
1032# Sets the view matrix for one or more components of the view.  This
1033# is a convenient way of getting a view for a particular frame just
1034# right in one shot.
1035# ----------------------------------------------------------------------
1036proc SetView {args} {
1037    if {[llength $args] == 8} {
1038        # setting all matrices? then start clean
1039        display resetview
1040    }
1041    foreach {key val} $args {
1042        switch -- $key {
1043            -rotate {
1044                foreach mol [molinfo list] {
1045                    molinfo $mol set rotate_matrix [list $val]
1046                }
1047            }
1048            -scale {
1049                foreach mol [molinfo list] {
1050                    molinfo $mol set scale_matrix [list $val]
1051                }
1052            }
1053            -center {
1054                foreach mol [molinfo list] {
1055                    molinfo $mol set center_matrix [list $val]
1056                }
1057            }
1058            -global {
1059                foreach mol [molinfo list] {
1060                    molinfo $mol set global_matrix [list $val]
1061                }
1062            }
1063            default {
1064                error "bad option \"$key\": should be -rotate, -scale, -center, or -global"
1065            }
1066        }
1067    }
1068}
1069
1070# ----------------------------------------------------------------------
1071# USAGE: smoothreps <value>
1072#
1073# Changes the smoothing factor for all representations of the current
1074# molecule.
1075# ----------------------------------------------------------------------
1076proc SmoothReps {val} {
1077    if {$val < 0} {
1078        error "bad smoothing value \"$val\": should be >= 0"
1079    }
1080    foreach nmol [molinfo list] {
1081        set max [molinfo $nmol get numreps]
1082        for {set nrep 0} {$nrep < $max} {incr nrep} {
1083            mol smoothrep $nmol $nrep $val
1084        }
1085    }
1086}
1087
1088# ----------------------------------------------------------------------
1089# USAGE: tellme "command template with %v" command arg arg...
1090#
1091# Executes the "command arg arg..." string in the server and substitutes
1092# the result into the template string in place of each "%v" field.
1093# Sends the result back to the client.
1094# ----------------------------------------------------------------------
1095proc TellMe {fmt args} {
1096    global parser client
1097
1098    # evaluate args as a command and subst the result in the fmt string
1099    if {[catch {$parser eval $args} result] == 0} {
1100        server_send_result $client "nv>[string map [list %v $result] $fmt]"
1101    } else {
1102        server_oops $client $result
1103    }
1104}
1105
1106
1107# ========================================================================
1108#        Server procedures
1109# ========================================================================
1110
1111#
1112# USAGE: server_safe_resize <width> <height>
1113#
1114# Use this version instead of "display resize" whenever possible.
1115# The VMD "display resize" goes into the event loop, so calling that
1116# causes things to execute out of order.  Use this method instead to
1117# store the change and actually resize later.
1118#
1119proc server_safe_resize {w h} {
1120    global DisplaySize
1121
1122    if {$w != $DisplaySize(w) || $h != $DisplaySize(h)} {
1123        set DisplaySize(w) $w
1124        set DisplaySize(h) $h
1125        set DisplaySize(changed) yes
1126    }
1127}
1128
1129# ----------------------------------------------------------------------
1130# SERVER CORE
1131# ----------------------------------------------------------------------
1132proc server_accept {cid addr port} {
1133    global env
1134
1135    fileevent $cid readable [list server_handle $cid $cid]
1136    fconfigure $cid -buffering none -blocking 0
1137
1138    if {[info exists env(LOCAL)]} {
1139        # identify server type to this client
1140        # VMD on the hub has this built in, but stock versions can
1141        # set the environment variable as a work-around
1142        puts $cid "vmd 0.1"
1143    }
1144}
1145
1146proc server_handle {cin cout} {
1147    global parser buffer client
1148
1149    if {[gets $cin line] < 0} {
1150        # when client drops connection, we can exit
1151        # nanoscale will spawn a new server next time we need it
1152        if {[eof $cin]} {
1153            server_exit $cin $cout 0
1154        }
1155    } else {
1156        append buffer($cin) $line "\n"
1157        if {[info complete $buffer($cin)]} {
1158            set request $buffer($cin)
1159            set buffer($cin) ""
1160            set client $cout
1161            if {[catch {$parser eval $request} result] == 0} {
1162                server_send_image -eventually
1163            } else {
1164                server_oops $cout $result
1165                if { [string match "invalid command*" $result] } {
1166                    bgerror "server received invalid command: $result"
1167                    server_exit $cin $cout 1
1168                }
1169            }
1170        }
1171    }
1172}
1173
1174proc server_send {cout} {
1175    global Epoch Sendqueue
1176
1177    # grab the next chunk of output and send it along
1178    # discard any chunks from an older epoch
1179    while {[llength $Sendqueue] > 0} {
1180        set chunk [lindex $Sendqueue 0]
1181        set Sendqueue [lrange $Sendqueue 1 end]
1182
1183        catch {unset data}; array set data $chunk
1184        if {$data(epoch) < 0 || $data(epoch) == $Epoch} {
1185            catch {puts $cout $data(cmd)}
1186
1187            # if this command has a binary data block, send it specially
1188            if {[string length $data(bytes)] > 0} {
1189                fconfigure $cout -translation binary
1190                catch {puts $cout $data(bytes)}
1191                fconfigure $cout -translation auto
1192            }
1193            break
1194        }
1195    }
1196
1197    # nothing left? Then stop callbacks until we get more
1198    if {[llength $Sendqueue] == 0} {
1199        fileevent $cout writable ""
1200        server_send_image -eventually
1201    }
1202}
1203
1204proc server_exit {cin cout code} {
1205    catch {close $cin}
1206    catch {exit $code}
1207
1208}
1209
1210# ----------------------------------------------------------------------
1211# SERVER RESPONSES
1212# ----------------------------------------------------------------------
1213
1214proc server_send_image {{when -now}} {
1215    global client Epoch Work Views ViewCmds Sendqueue DisplaySize
1216
1217    if {$when eq "-eventually"} {
1218        after cancel server_send_image
1219        after 1 server_send_image
1220        return
1221    } elseif {$when ne "-now"} {
1222        error "bad option \"$when\" for server_send_image: should be -now or -eventually"
1223    }
1224
1225    # is there a display resize pending? then resize and try again later
1226    if {$DisplaySize(changed)} {
1227        set DisplaySize(changed) 0
1228        after idle [list display resize $DisplaySize(w) $DisplaySize(h)]
1229        after 20 server_send_image
1230        return
1231    }
1232
1233    # loop through requests in the work queue and skip any from an older epoch
1234    while {1} {
1235        if {[llength $Work(queue)] == 0} {
1236            return
1237        }
1238
1239        set rec [lindex $Work(queue) 0]
1240        set Work(queue) [lrange $Work(queue) 1 end]
1241
1242        catch {unset item}; array set item $rec
1243        if {$item(epoch) < $Epoch} {
1244            catch {unset Work($item(num))}
1245            continue
1246        }
1247
1248        # set the frame characteristics and render this frame
1249        if {[info exists item(frame)]} {
1250            animate goto $item(frame)
1251        } elseif {[info exists item(rotate)]} {
1252            foreach mol [molinfo list] {
1253                molinfo $mol set rotate_matrix [list $item(rotate)]
1254            }
1255            # send rotation matrix back to the client so we can pause later
1256            server_send_latest $client [list nv>rotatemtx $item(num) $item(rotate)]
1257        } else {
1258            puts "ERROR: bad work frame: [array get item]"
1259        }
1260
1261        # flag to use the stored default view? then set that
1262        if {[info exists item(defview)] && $item(defview)} {
1263            if {[info exists Views($item(frame))]} {
1264                foreach mol [molinfo list] {
1265                    eval molinfo $mol set $Views($item(frame))
1266                }
1267            }
1268        }
1269        if { [info exists item(frame)] &&
1270             [info exists ViewCmds($item(frame))] } {
1271            if { [catch {
1272                eval $ViewCmds($item(frame))
1273            } errs] != 0 }  {
1274                puts stderr "viewcmd error: $errs"
1275            }
1276        }
1277        array unset Work $item(num)
1278        break
1279    }
1280
1281    # force VMD to update and grab the screen
1282    display update
1283    tkrender SnapShot
1284
1285    set data [SnapShot data -format PPM]
1286    server_send_latest $client "nv>image epoch $item(epoch) frame $item(num) length [string length $data]" $data
1287
1288    # if there's more work in the queue, try again later
1289    if {[llength $Work(queue)] > 0} {
1290        after 1 server_send_image
1291    }
1292}
1293
1294proc SetTemporaryDirectory { path } {
1295    global tmpDir
1296
1297    set tmpDir $path
1298}
1299
1300proc server_send_result {cout cmd {data ""}} {
1301    global Sendqueue
1302
1303    # add this result to the output queue
1304    # use the epoch -1 to force the send even if the epoch has changed
1305    lappend Sendqueue [list epoch -1 cmd $cmd bytes $data]
1306    fileevent $cout writable [list server_send $cout]
1307}
1308
1309proc server_send_latest {cout cmd {data ""}} {
1310    global Epoch Sendqueue
1311
1312    # add this result to the output queue
1313    # wait until the client is ready, then send the output
1314    lappend Sendqueue [list epoch $Epoch cmd $cmd bytes $data]
1315    fileevent $cout writable [list server_send $cout]
1316}
1317
1318proc server_oops {cout mesg} {
1319    # remove newlines -- all lines must start with nv>
1320    set mesg [string map {\n " "} $mesg]
1321    server_send_result $cout "nv>oops [list $mesg]"
1322}
1323
1324# =========================================================================
1325
1326# turn off constant updates -- only need them during server_send_image
1327display update off
1328
1329# parse command line args
1330set Paradigm "socket"
1331while {[llength $argv] > 0} {
1332    set opt [lindex $argv 0]
1333    set argv [lrange $argv 1 end]
1334
1335    switch -- $opt {
1336        -socket { set Paradigm "socket" }
1337        -stdio  { set Paradigm "stdio" }
1338        default {
1339            puts stderr "bad option \"$opt\": should be -socket or -stdio"
1340        }
1341    }
1342}
1343
1344# use this to take snapshots to send to clients
1345image create photo SnapShot
1346
1347# set the screen to a good size
1348set DisplaySize(w) 300
1349set DisplaySize(h) 300
1350display resize $DisplaySize(w) $DisplaySize(h)
1351set DisplaySize(changed) 0
1352
1353# capture initial display settings for later reset
1354display antialias on
1355
1356# Always turn on GL shading language.
1357display rendermode GLSL
1358
1359set DisplayProps(options) ""
1360foreach key {
1361    ambientocclusion
1362    antialias
1363    aoambient
1364    aodirect
1365    backgroundgradient
1366    cuedensity
1367    cueend
1368    cuemode
1369    cuestart
1370    culling
1371    depthcue
1372    distance
1373    eyesep
1374    farclip
1375    focallength
1376    height
1377    nearclip
1378    projection
1379    shadows
1380    stereo
1381} {
1382    if {$key eq "nearclip" || $key eq "farclip"} {
1383        append DisplayProps(options) [list display $key set [display get $key]] "\n"
1384    } else {
1385        append DisplayProps(options) [list display $key [display get $key]] "\n"
1386    }
1387}
1388
1389# initialize work queue and epoch counter (see server_send_image)
1390set Epoch 0
1391set Work(queue) ""
1392set Sendqueue ""
1393set Scenes(@CURRENT) ""
1394set tmpDir ""
1395
1396set parser [interp create -safe]
1397
1398$parser eval {
1399    # Add unknown procedure to safe interpreter to handle generated
1400    # instances (commands) of atom selections.
1401    proc unknown { args } {
1402        set cmd [lindex $args 0]
1403        if { [regexp {atomselect[0-9]+} $cmd] } {
1404            return [uplevel 1 [eval list atomselect_instance $args]]
1405        }
1406        return -code error "unknown command $args"
1407    }
1408}
1409
1410foreach cmd {
1411    axes
1412    color
1413    gettimestep
1414    graphics
1415    imd
1416    label
1417    vmd_label
1418    light
1419    material
1420    measure
1421    mobile
1422    mol
1423    molinfo
1424    molecule
1425    mouse
1426    parallel
1427    plugin
1428    rawtimestep
1429    render
1430    rotate
1431    rotmat
1432    scale
1433    vmd_scale
1434    spaceball
1435    stage
1436    tkrender
1437    tool
1438    translate
1439    user
1440    vecadd
1441    veccross
1442    vecdist
1443    vecdot
1444    vecinvert
1445    veclength
1446    veclength2
1447    vecmean
1448    vecmul
1449    vecnorm
1450    vecscale
1451    vecscale
1452    vecstddev
1453    vecsub
1454    vecsum
1455    veczero
1456    vmdcollab
1457    vmdcon
1458    vmdinfo
1459    vmdbench
1460    volmap
1461} {
1462    $parser alias $cmd $cmd
1463}
1464
1465$parser alias animate                   Animate
1466$parser alias atomselect                AtomSelect
1467$parser alias atomselect_instance       AtomSelectInstance
1468$parser alias display                   Display
1469$parser alias drag                      Drag
1470$parser alias frames                    Frames
1471$parser alias getview                   GetView
1472$parser alias load                      Load
1473$parser alias menu                      NoOp
1474$parser alias play                      NoOp
1475$parser alias queryinfo                 QueryInfo
1476$parser alias quit                      NoOp
1477$parser alias resize                    Resize
1478$parser alias rock                      Rock
1479$parser alias scene                     Scene
1480$parser alias setquality                SetQuality
1481$parser alias setview                   SetView
1482$parser alias sleep                     NoOp
1483$parser alias smoothreps                SmoothReps
1484$parser alias tellme                    TellMe
1485$parser alias vmd_menu                  NoOp
1486
1487$parser alias set_temporary_directory   SetTemporaryDirectory
1488
1489if {$Paradigm eq "socket"} {
1490    socket -server server_accept 2018
1491} else {
1492    set cin $vmd_client(read)
1493    set cout $vmd_client(write)
1494
1495    fileevent $cin readable [list server_handle $cin $cout]
1496    fconfigure $cout -buffering none -blocking 0
1497}
1498
1499# vmd automatically drops into an event loop at this point...
1500#
1501# The VMD TCL interpreter is by default interactive.  Their version
1502# of tkconsole always turns this on.  Turn this off
1503# so that unknown commands like "scene" don't get exec-ed.
1504set ::tcl_interactive 0
Note: See TracBrowser for help on using the repository browser.