set pd_nt 1 # (The above is 0 for unix, 1 for microsoft, and 2 for Mac OSX. The first # line is automatically munged by the relevant makefiles.) # Copyright (c) 1997-1999 Miller Puckette. # For information on usage and redistribution, and for a DISCLAIMER OF ALL # WARRANTIES, see the file, "LICENSE.txt," in this distribution. # changed by Thomas Musil 09.2001 # between "pdtk_graph_dialog -- dialog window for graphs" # and "pdtk_array_dialog -- dialog window for arrays" # a new dialogbox was inserted, named: # "pdtk_iemgui_dialog -- dialog window for iem guis" # # all this changes are labeled with #######iemlib########## # Tearoff is set to true by default: set pd_tearoff 1 if {$pd_nt == 1} { global pd_guidir global pd_tearoff set pd_gui2 [string range $argv0 0 [expr [string last \\ $argv0 ] - 1]] regsub -all \\\\ $pd_gui2 / pd_gui3 set pd_guidir $pd_gui3/.. load $pd_guidir/bin/pdtcl set pd_tearoff 1 } if {$pd_nt == 2} { global pd_guidir global pd_tearoff set pd_gui2 [string range $argv0 0 [expr [string last / $argv0 ] - 1]] set pd_guidir $pd_gui2/.. load $pd_guidir/bin/pdtcl set pd_tearoff 0 } # hack so you can easily test-run this script in linux... define pd_guidir # (which is normally defined at startup in pd under linux...) if {$pd_nt == 0} { if {! [info exists pd_guidir]} { global pd_guidir puts stderr {setting pd_guidir to '.'} set pd_guidir . } } # it's unfortunate but we seem to have to turn off global bindings # for Text objects to get control-s and control-t to do what we want for # "text" dialogs below. Also we have to get rid of tab's changing the focus. bind all "" bind all <> "" bind Text {} bind Text {} # puts stderr [bind all] ################## set up main window ######################### menu .mbar canvas .dummy -height 2p -width 6c frame .controls pack .controls .dummy -side top -fill x menu .mbar.file -tearoff $pd_tearoff .mbar add cascade -label "File" -menu .mbar.file menu .mbar.find -tearoff $pd_tearoff .mbar add cascade -label "Find" -menu .mbar.find menu .mbar.windows -postcommand [concat pdtk_fixwindowmenu] -tearoff $pd_tearoff menu .mbar.audio -tearoff $pd_tearoff if {$pd_nt != 2} { .mbar add cascade -label "Windows" -menu .mbar.windows .mbar add cascade -label "Media" -menu .mbar.audio } else { # Perhaps this is silly, but Mac HIG want "Window Help" as the last menus .mbar add cascade -label "Media" -menu .mbar.audio .mbar add cascade -label "Windows" -menu .mbar.windows } menu .mbar.help -tearoff $pd_tearoff .mbar add cascade -label "Help" -menu .mbar.help set ctrls_audio_on 0 set ctrls_meter_on 0 set ctrls_inlevel 0 set ctrls_outlevel 0 frame .controls.switches checkbutton .controls.switches.audiobutton -text {compute audio} \ -variable ctrls_audio_on \ -anchor w \ -command {pd [concat pd dsp $ctrls_audio_on \;]} checkbutton .controls.switches.meterbutton -text {peak meters} \ -variable ctrls_meter_on \ -anchor w \ -command {pd [concat pd meters $ctrls_meter_on \;]} pack .controls.switches.meterbutton .controls.switches.audiobutton -side left frame .controls.inout frame .controls.inout.in label .controls.inout.in.label -text IN entry .controls.inout.in.level -textvariable ctrls_inlevel -width 3 button .controls.inout.in.clip -text {CLIP} -state disabled pack .controls.inout.in.label .controls.inout.in.level \ .controls.inout.in.clip -side top -pady 2 frame .controls.inout.out label .controls.inout.out.label -text OUT entry .controls.inout.out.level -textvariable ctrls_outlevel -width 3 button .controls.inout.out.clip -text {CLIP} -state disabled pack .controls.inout.out.label .controls.inout.out.level \ .controls.inout.out.clip -side top -pady 2 button .controls.dio -text "DIO\nerrors" \ -command {pd [concat pd audiostatus \;]} pack .controls.switches -side bottom -pady 12 pack .controls.inout.in .controls.inout.out -side left -padx 6 pack .controls.inout -side left -padx 14 pack .controls.dio -side right -padx 20 bind . {pdtk_pd_ctrlkey %W %K 0} bind . {pdtk_pd_ctrlkey %W %K 1} wm title . "Pd" . configure -menu .mbar -width 200 -height 150 ############### set up global variables ################################ set untitled_number 1 set untitled_directory [pwd] set saveas_client doggy set pd_opendir $untitled_directory set pd_undoaction no set pd_redoaction no set pd_undocanvas no ################ utility functions ######################### proc pdtk_enquote {x} { set foo [string map {"," "" ";" "" \" ""} $x] set foo2 [string map {" " "\\ "} $foo] concat $foo2 } proc pdtk_debug {x} { tk_messageBox -message $x -type ok } proc pdtk_watchdog {} { pd [concat pd ping \;] after 2000 {pdtk_watchdog} } proc pdtk_check {x message} { set answer [tk_messageBox \-message $x \-type yesno \-icon question] switch $answer { yes {pd $message} } # no {tk_messageBox \-message "cancelled" \-type ok} } set menu_windowlist {} proc pdtk_fixwindowmenu {} { global menu_windowlist .mbar.windows delete 0 end foreach i $menu_windowlist { .mbar.windows add command -label [lindex $i 0] \ -command [concat menu_domenuwindow [lindex $i 1]] menu_fixwindowmenu [lindex $i 1] } } ####### Odd little function to make better Mac accelerators ##### proc accel_munge {acc} { global pd_nt if {$pd_nt == 2} { if [string is upper [string index $acc end]] { return [format "%s%s" "Shift+" \ [string toupper [string map {Ctrl Meta} $acc] end]] } else { return [string toupper [string map {Ctrl Meta} $acc] end] } } else { return $acc } } ############### the "New" menu command ######################## proc menu_new {} { global untitled_number global untitled_directory pd [concat pd filename Untitled-$untitled_number $untitled_directory \;] pd { #N canvas; #X pop 1; } set untitled_number [expr $untitled_number + 1] } ################## the "Open" menu command ######################### proc menu_open {} { global pd_opendir set filename [tk_getOpenFile -defaultextension .pd \ -filetypes { {{pd files} {.pd}} {{max files} {.pat}}} \ -initialdir $pd_opendir] if {$filename != ""} { set directory [string range $filename 0 \ [expr [string last / $filename ] - 1]] set pd_opendir $directory set basename [string range $filename \ [expr [string last / $filename ] + 1] end] # pd_debug [concat file $filename base $basename dir $directory] pd [concat pd open [pdtk_enquote $basename] \ [pdtk_enquote $directory]\;] } } ################## the "Message" menu command ######################### proc menu_send {} { toplevel .sendpanel entry .sendpanel.entry -textvariable send_textvariable pack .sendpanel.entry -side bottom -fill both -ipadx 100 .sendpanel.entry select from 0 .sendpanel.entry select adjust end bind .sendpanel.entry { pd [concat $send_textvariable \;] after 50 {destroy .sendpanel} } focus .sendpanel.entry } ################## the "Quit" menu command ######################### proc menu_really_quit {} {pd {pd quit;}} proc menu_quit {} {pdtk_check {Really quit?} {pd quit;}} ######### the "Pd" menu command, which puts the Pd window on top ######## proc menu_pop_pd {} {raise .} ######### the "audio" menu command ############### proc menu_audio {flag} {pd [concat pd dsp $flag \;]} ######### the "documentation" menu command ############### set doc_number 1 proc menu_opentext {filename} { global doc_number global pd_guidir global pd_myversion set name [format ".help%d" $doc_number] toplevel $name text $name.text -relief raised -bd 2 -font -*-courier-bold--normal--12-* \ -yscrollcommand "$name.scroll set" -background white scrollbar $name.scroll -command "$name.text yview" pack $name.scroll -side right -fill y pack $name.text -side left -fill both -expand 1 set f [open $filename] while {![eof $f]} { set bigstring [read $f 1000] regsub -all PD_BASEDIR $bigstring $pd_guidir bigstring2 regsub -all PD_VERSION $bigstring2 $pd_myversion bigstring3 $name.text insert end $bigstring3 } close $f set doc_number [expr $doc_number + 1] } set help_directory $pd_guidir/doc proc menu_documentation {} { global help_directory global pd_nt set filename [tk_getOpenFile -defaultextension .pd \ -filetypes { {{documentation} {.pd .txt .htm}} } \ -initialdir $help_directory] if {$filename != ""} { if {[string first .txt $filename] >= 0} { menu_opentext $filename } elseif {[string first .htm $filename] >= 0} { if {$pd_nt == 0} { exec sh -c \ [format "mozilla file:%s || netscape file:%s &\n" \ $filename $filename] } elseif {$pd_nt == 2} { puts stderr [format "open %s" $filename] exec sh -c \ [format "open %s" $filename] } else { exec rundll32 url.dll,FileProtocolHandler \ [format "file:%s" $filename] & } } else { set help_directory [string range $filename 0 \ [expr [string last / $filename ] - 1]] set basename [string range $filename \ [expr [string last / $filename ] + 1] end] pd [concat pd open [pdtk_enquote $basename] \ [pdtk_enquote $help_directory] \;] } } } proc menu_doc_open {subdir basename} { global pd_guidir set dirname $pd_guidir/$subdir if {[string first .txt $basename] >= 0} { menu_opentext $dirname/$basename } else { pd [concat pd open [pdtk_enquote $basename] \ [pdtk_enquote $dirname] \;] } } ############# routine to add audio and help menus ############### proc menu_addstd {mbar} { global pd_apilist # the "Audio" menu $mbar.audio add command -label {audio ON} -accelerator [accel_munge "Ctrl+/"] \ -command {menu_audio 1} $mbar.audio add command -label {audio OFF} -accelerator [accel_munge "Ctrl+."] \ -command {menu_audio 0} for {set x 0} {$x<[llength $pd_apilist]} {incr x} { $mbar.audio add radiobutton -label [lindex [lindex $pd_apilist $x] 0] \ -command {menu_audio 0} -variable pd_whichapi \ -value [lindex [lindex $pd_apilist $x] 1]\ -command {pd [concat pd audio-setapi $pd_whichapi \;]} } $mbar.audio add command -label {Audio settings...} \ -command {pd pd audio-properties \;} $mbar.audio add command -label {MIDI settings...} \ -command {pd pd midi-properties \;} $mbar.audio add command -label {Test Audio and MIDI} \ -command {menu_doc_open doc/7.stuff/tools testtone.pd} $mbar.audio add command -label {Load Meter} \ -command {menu_doc_open doc/7.stuff/tools load-meter.pd} # the "Help" menu $mbar.help add command -label {About Pd} \ -command {menu_doc_open doc/1.manual 1.introduction.txt} $mbar.help add command -label {Pure Documentation...} \ -command {menu_documentation} } #################### the "File" menu for the Pd window ############## .mbar.file add command -label New -command {menu_new} \ -accelerator [accel_munge "Ctrl+n"] .mbar.file add command -label Open -command {menu_open} \ -accelerator [accel_munge "Ctrl+o"] .mbar.file add separator .mbar.file add command -label Message -command {menu_send} \ -accelerator [accel_munge "Ctrl+m"] .mbar.file add command -label Path... \ -command {pd pd start-path-dialog \;} .mbar.file add separator .mbar.file add command -label Quit -command {menu_quit} \ -accelerator [accel_munge "Ctrl+q"] #################### the "Find" menu for the Pd window ############## .mbar.find add command -label {last error?} -command {menu_finderror} ########### functions for menu functions on document windows ######## proc menu_save {name} { pdtk_canvas_checkgeometry $name pd [concat $name menusave \;] } proc menu_saveas {name} { pdtk_canvas_checkgeometry $name pd [concat $name menusaveas \;] } proc menu_print {name} { set filename [tk_getSaveFile -initialfile pd.ps \ -defaultextension .ps \ -filetypes { {{postscript} {.ps}} }] if {$filename != ""} { $name.c postscript -file $filename } } proc menu_close {name} { pd [concat $name menuclose \;] } proc menu_undo {name} { global pd_undoaction global pd_redoaction global pd_undocanvas if {$name == $pd_undocanvas && $pd_undoaction != "no"} { pd [concat $name undo \;] } } proc menu_redo {name} { global pd_undoaction global pd_redoaction global pd_undocanvas if {$name == $pd_undocanvas && $pd_redoaction != "no"} { pd [concat $name redo \;] } } proc menu_cut {name} { pd [concat $name cut \;] } proc menu_copy {name} { pd [concat $name copy \;] } proc menu_paste {name} { pd [concat $name paste \;] } proc menu_duplicate {name} { pd [concat $name duplicate \;] } proc menu_selectall {name} { pd [concat $name selectall \;] } proc menu_texteditor {name} { pd [concat $name texteditor \;] } proc menu_font {name} { pd [concat $name menufont \;] } proc menu_tidyup {name} { pd [concat $name tidy \;] } proc menu_editmode {name} { pd [concat $name editmode 0 \;] } proc menu_object {name accel} { pd [concat $name obj $accel \;] } proc menu_message {name accel} { pd [concat $name msg $accel \;] } proc menu_floatatom {name accel} { pd [concat $name floatatom $accel \;] } proc menu_symbolatom {name accel} { pd [concat $name symbolatom $accel \;] } proc menu_comment {name accel} { pd [concat $name text $accel \;] } proc menu_graph {name} { pd [concat $name graph \;] } proc menu_array {name} { pd [concat $name menuarray \;] } ############iemlib################## proc menu_bng {name accel} { pd [concat $name bng $accel \;] } proc menu_toggle {name accel} { pd [concat $name toggle $accel \;] } proc menu_numbox {name accel} { pd [concat $name numbox $accel \;] } proc menu_vslider {name accel} { pd [concat $name vslider $accel \;] } proc menu_hslider {name accel} { pd [concat $name hslider $accel \;] } proc menu_hradio {name accel} { pd [concat $name hradio $accel \;] } proc menu_vradio {name accel} { pd [concat $name vradio $accel \;] } proc menu_vumeter {name accel} { pd [concat $name vumeter $accel \;] } proc menu_mycnv {name accel} { pd [concat $name mycnv $accel \;] } ############iemlib################## # correct edit menu, enabling or disabling undo/redo # LATER also cut/copy/paste proc menu_fixeditmenu {name} { global pd_undoaction global pd_redoaction global pd_undocanvas # puts stderr [concat menu_fixeditmenu $name $pd_undocanvas $pd_undoaction] if {$name == $pd_undocanvas && $pd_undoaction != "no"} { $name.m.edit entryconfigure "Undo*" -state normal \ -label [concat "Undo " $pd_undoaction] } else { $name.m.edit entryconfigure "Undo*" -state disabled -label "Undo" } if {$name == $pd_undocanvas && $pd_redoaction != "no"} { $name.m.edit entryconfigure "Redo*" -state normal\ -label [concat "Redo " $pd_redoaction] } else { $name.m.edit entryconfigure "Redo*" -state disabled } } # message from Pd to update the currently available undo/redo action proc pdtk_undomenu {name undoaction redoaction} { global pd_undoaction global pd_redoaction global pd_undocanvas # puts stderr [concat pdtk_undomenu $name $undoaction $redoaction] set pd_undocanvas $name set pd_undoaction $undoaction set pd_redoaction $redoaction if {$name != "nobody"} { # unpleasant way of avoiding a more unpleasant bug situation --atl 2002.11.25 menu_fixeditmenu $name } } proc menu_windowparent {name} { pd [concat $name findparent \;] } proc menu_findagain {name} { pd [concat $name findagain \;] } proc menu_finderror {} { pd [concat pd finderror \;] } proc menu_domenuwindow {i} { raise $i } proc menu_fixwindowmenu {name} { global menu_windowlist global pd_tearoff $name.m.windows add command if $pd_tearoff { $name.m.windows delete 4 end } else { $name.m.windows delete 3 end } foreach i $menu_windowlist { $name.m.windows add command -label [lindex $i 0] \ -command [concat menu_domenuwindow [lindex $i 1]] } } ################## the "find" menu item ################### set find_canvas nobody set find_string "" set find_count 1 proc find_apply {name} { global find_string global find_canvas regsub -all \; $find_string " _semi_ " find_string2 regsub -all \, $find_string2 " _comma_ " find_string3 # puts stderr [concat $find_canvas find $find_string3 \ # \;] pd [concat $find_canvas find $find_string3 \ \;] after 50 destroy $name } proc find_cancel {name} { after 50 destroy $name } proc menu_findobject {canvas} { global find_string global find_canvas global find_count set name [format ".find%d" $find_count] set find_count [expr $find_count + 1] set find_canvas $canvas toplevel $name label $name.label -text {find...} pack $name.label -side top entry $name.entry -textvariable find_string pack $name.entry -side top frame $name.buttonframe pack $name.buttonframe -side bottom -fill x -pady 2m button $name.buttonframe.cancel -text {Cancel}\ -command "find_cancel $name" button $name.buttonframe.ok -text {OK}\ -command "find_apply $name" pack $name.buttonframe.cancel -side left -expand 1 pack $name.buttonframe.ok -side left -expand 1 $name.entry select from 0 $name.entry select adjust end bind $name.entry [ concat find_apply $name] focus $name.entry } ############# pdtk_canvas_new -- create a new canvas ############### proc pdtk_canvas_new {name width height geometry editable} { global pd_opendir global pd_tearoff global pd_nt toplevel $name -menu $name.m # puts stderr [concat geometry: $geometry] wm geometry $name $geometry canvas $name.c -width $width -height $height -background white \ -yscrollcommand "$name.scrollvert set" \ -xscrollcommand "$name.scrollhort set" \ -scrollregion [concat 0 0 $width $height] scrollbar $name.scrollvert -command "$name.c yview" scrollbar $name.scrollhort -command "$name.c xview" \ -orient horizontal pack $name.scrollhort -side bottom -fill x pack $name.scrollvert -side right -fill y pack $name.c -side left -expand 1 -fill both wm minsize $name 1 1 wm geometry $name $geometry # the file menu menu $name.m menu $name.m.file -tearoff $pd_tearoff $name.m add cascade -label File -menu $name.m.file $name.m.file add command -label New -command {menu_new} \ -accelerator [accel_munge "Ctrl+n"] $name.m.file add command -label Open -command {menu_open} \ -accelerator [accel_munge "Ctrl+o"] $name.m.file add separator $name.m.file add command -label Message -command {menu_send} \ -accelerator [accel_munge "Ctrl+m"] $name.m.file add command -label Path... \ -command {pd pd start-path-dialog \;} $name.m.file add separator $name.m.file add command -label Close \ -command [concat menu_close $name] \ -accelerator [accel_munge "Ctrl+w"] $name.m.file add command -label Save -command [concat menu_save $name] \ -accelerator [accel_munge "Ctrl+s"] $name.m.file add command -label "Save as..." \ -command [concat menu_saveas $name] \ -accelerator [accel_munge "Ctrl+S"] $name.m.file add command -label Print -command [concat menu_print $name] \ -accelerator [accel_munge "Ctrl+p"] $name.m.file add separator $name.m.file add command -label Quit -command {menu_quit} \ -accelerator [accel_munge "Ctrl+q"] # the edit menu menu $name.m.edit -postcommand [concat menu_fixeditmenu $name] -tearoff $pd_tearoff $name.m add cascade -label Edit -menu $name.m.edit $name.m.edit add command -label Undo -command [concat menu_undo $name] \ -accelerator [accel_munge "Ctrl+z"] $name.m.edit add command -label Redo -command [concat menu_redo $name] \ -accelerator [accel_munge "Ctrl+Z"] $name.m.edit add separator $name.m.edit add command -label Cut -command [concat menu_cut $name] \ -accelerator [accel_munge "Ctrl+x"] $name.m.edit add command -label Copy -command [concat menu_copy $name] \ -accelerator [accel_munge "Ctrl+c"] $name.m.edit add command -label Paste \ -command [concat menu_paste $name] \ -accelerator [accel_munge "Ctrl+v"] $name.m.edit add command -label Duplicate \ -command [concat menu_duplicate $name] \ -accelerator [accel_munge "Ctrl+d"] $name.m.edit add command -label {Select all} \ -command [concat menu_selectall $name] \ -accelerator [accel_munge "Ctrl+a"] $name.m.edit add separator $name.m.edit add command -label {Text Editor} \ -command [concat menu_texteditor $name] \ -accelerator [accel_munge "Ctrl+t"] $name.m.edit add command -label Font \ -command [concat menu_font $name] $name.m.edit add command -label {Tidy Up} \ -command [concat menu_tidyup $name] $name.m.edit add separator ############iemlib################## # instead of "red = #BC3C60" we take "grey85", so there is no difference, # if widget is selected or not. $name.m.edit add checkbutton -label "Edit mode" \ -indicatoron true -selectcolor grey85 \ -command [concat menu_editmode $name] \ -accelerator [accel_munge "Ctrl+e"] if { $editable == 0 } { $name.m.edit entryconfigure "Edit mode" -indicatoron false } ############iemlib################## # the put menu menu $name.m.put -tearoff $pd_tearoff $name.m add cascade -label Put -menu $name.m.put $name.m.put add command -label Object \ -command [concat menu_object $name 0] \ -accelerator [accel_munge "Ctrl+1"] $name.m.put add command -label Message \ -command [concat menu_message $name 0] \ -accelerator [accel_munge "Ctrl+2"] $name.m.put add command -label Number \ -command [concat menu_floatatom $name 0] \ -accelerator [accel_munge "Ctrl+3"] $name.m.put add command -label Symbol \ -command [concat menu_symbolatom $name 0] \ -accelerator [accel_munge "Ctrl+4"] $name.m.put add command -label Comment \ -command [concat menu_comment $name 0] \ -accelerator [accel_munge "Ctrl+5"] $name.m.put add separator ############iemlib################## $name.m.put add command -label Bang \ -command [concat menu_bng $name 0] \ -accelerator [accel_munge "Alt+b"] $name.m.put add command -label Toggle \ -command [concat menu_toggle $name 0] \ -accelerator [accel_munge "Alt+t"] $name.m.put add command -label Number2 \ -command [concat menu_numbox $name 0] \ -accelerator [accel_munge "Alt+n"] $name.m.put add command -label Vslider \ -command [concat menu_vslider $name 0] \ -accelerator [accel_munge "Alt+v"] $name.m.put add command -label Hslider \ -command [concat menu_hslider $name 0] \ -accelerator [accel_munge "Alt+h"] $name.m.put add command -label Vradio \ -command [concat menu_vradio $name 0] \ -accelerator [accel_munge "Alt+d"] $name.m.put add command -label Hradio \ -command [concat menu_hradio $name 0] \ -accelerator [accel_munge "Alt+i"] $name.m.put add command -label VU \ -command [concat menu_vumeter $name 0] \ -accelerator [accel_munge "Alt+u"] $name.m.put add command -label Canvas \ -command [concat menu_mycnv $name 0] \ -accelerator [accel_munge "Alt+c"] ############iemlib################## $name.m.put add separator $name.m.put add command -label Graph \ -command [concat menu_graph $name] $name.m.put add command -label Array \ -command [concat menu_array $name] # the find menu menu $name.m.find -tearoff $pd_tearoff $name.m add cascade -label Find -menu $name.m.find $name.m.find add command -label {Find...} \ -accelerator [accel_munge "Ctrl+f"] \ -command [concat menu_findobject $name] $name.m.find add command -label {Find Again} \ -accelerator [accel_munge "Ctrl+g"] \ -command [concat menu_findagain $name] $name.m.find add command -label {Find last error} \ -command [concat menu_finderror] # the window menu menu $name.m.windows -postcommand [concat menu_fixwindowmenu $name] \ -tearoff $pd_tearoff $name.m.windows add command -label {parent window}\ -command [concat menu_windowparent $name] $name.m.windows add command -label {Pd window} -command menu_pop_pd $name.m.windows add separator # the audio menu menu $name.m.audio -tearoff $pd_tearoff if {$pd_nt != 2} { $name.m add cascade -label Windows -menu $name.m.windows $name.m add cascade -label Media -menu $name.m.audio } else { $name.m add cascade -label Media -menu $name.m.audio $name.m add cascade -label Window -menu $name.m.windows } # the help menu menu $name.m.help -tearoff $pd_tearoff $name.m add cascade -label Help -menu $name.m.help menu_addstd $name.m # the popup menu menu $name.popup -tearoff false $name.popup add command -label {Properties} \ -command [concat popup_action $name 0] $name.popup add command -label {Open} \ -command [concat popup_action $name 1] $name.popup add command -label {Help} \ -command [concat popup_action $name 2] # WM protocol wm protocol $name WM_DELETE_WINDOW [concat menu_close $name] # bindings. # this is idiotic -- how do you just sense what mod keys are down and # pass them on? I can't find it anywhere. # Here we encode shift as 1, control 2, alt 4, in agreement # with definitions in g_canvas.c. The third button gets "8" but we don't # bother with modifiers there. # We don't handle multiple clicks yet. bind $name.c