GRAPHICAL REAL-TIME SYSTEMS
by Harry Beker

Listing One
#include <tcl.h>
#include <tk.h>
Tcl_Interp *globint;

int start_run(ClientData clientData,Tcl_Interp *interp,int argc,char** argv)
{  /*    start other tasks */
  return TCL_OK;
}
int stop_run(ClientData clientData,Tcl_Interp *interp,int arg,char** argv)
{
  /* kill other processes and await termination */
  return TCL_OK;
}
int poll_run(ClientData clientData,Tcl_Interp *interp,int argc,char** argv)
{ /* check whether run has to be stopped and update display */
  return TCL_OK;
}
int daq_start(ClientData clientData,Tcl_Interp *interp,int argc, char** argv)

{
  /* link to global section; */
  return TCL_OK;
}
int main(int argc, char** argv)
{
  Tk_Main(argc, argv, Tcl_AppInit);
  return 0;
}
int Tcl_AppInit(interp)
    Tcl_Interp *interp;
{
    Tk_Window main;
    globint = interp;
    main = Tk_MainWindow(interp);
    if (Tcl_Init(interp) == TCL_ERROR) return TCL_ERROR;
    if (Tk_Init(interp) == TCL_ERROR) return TCL_ERROR;

    Tcl_CreateCommand(interp,"daq_start",daq_start,(ClientData) NULL,
                      (Tcl_CmdDeleteProc*)NULL);
    Tcl_CreateCommand(interp, "start_run", start_run,(ClientData) NULL,
                      (Tcl_CmdDeleteProc*)NULL);
    Tcl_CreateCommand(interp, "stop_run", stop_run,(ClientData) NULL,
                      (Tcl_CmdDeleteProc*)NULL);
    Tcl_CreateCommand(interp, "poll_run", poll_run,(ClientData) NULL,
                      (Tcl_CmdDeleteProc*)NULL);
    tcl_RcFileName = "../src/startup.tcl";
    return TCL_OK;
}

Listing Two
# Procedure: next_event
proc next_event {} {
#
# declare global variable. In Tcl the are local by default

global nr_hits hit_x hit_y hit_charge
glonal radius range_col charge
global projection center_x center_y center_radius
global nr_rings inpmode
global nr_event
.CF.rich_canvas delete rings
.CF.rich_canvas delete hits
if {$projection} {
# check whether projections should be visible or not
        set ccol #e0e0e0
        set cwidth 30
} else {
set ccol White
        set cwidth 0
}
switch $inpmode {
        File File_event
        Online Online_event
        Boss   MC_event
      }
#
#  draw rings
incr nr_event
for { set i 0} { $i<$nr_rings } { incr i} {
      set x_pos [ expr $center_x($i)*5+4]
      set y_pos [ expr (120-$center_y($i))*5+4 ]
      set r     [ expr $center_radius($i)*5 ]
      .cf.rich_canvas create oval                  \
           [ expr $x_pos-$r ]  [ expr $y_pos-$r ]  \
           [ expr $x_pos+$r ]   [ expr $y_pos+$r ] \
          -outline $ccol  -width $cwidth -tag rings
}
#
#  draw hits
for { set i 0} { $i<$nr_hits } { incr i} {
   set x_pos [ expr $hit_x($i)*5 ]
   set y_pos [ expr (36-$hit_y($i))*5 ]
   if {$hit_charge($i)>0} {
#      apply logarithmic color coding
        set color \
        $range_col([ expr \
        round(floor(log($hit_charge($i))/log(2)))])
   } else {
        set color green
   }
   set id  [  .cf.rich_canvas create rectangle  \
     [ expr $x_pos-1+5 ]    [ expr $y_pos-1+5 ] \
     [ expr $x_pos+5+4 ]   [ expr $y_pos+5+4 ]  \
     -fill $color  -outline {} -tag hits]
#
#   make bindings for displaying the charge when the mouse enters a pad
   .cf.rich_canvas bind $id <Enter> \
            "set  charge $hit_charge($i) "
   .cf.rich_canvas bind $id <Leave> \
             "set  charge ****"
   }
}


Listing Three
menu .selectbar.inmodebt.m

selectbar.inpmodebt.m add radiobutton \
-label Online -value Online -variable inpmode

selectbar.inpmodebt.m add radiobutton \
-label File -value File -variable inpmode

selectbar.inpmodebt.m add separator

selectbar.inpmodebt.m add radiobutton
-label "Boss around" -value Boss -variable inpmode

Listing Four
# Procedure auto_display
proc auto_display {} {
        if { $automode } {
#         only as long as the user did not get tired of it
        next_event
        after 100 auto_display
#         reschedule next display in 100 ms
        }
}
# to start with we are in stopped mode
set automode 0
set autobt_text "Auto"
button .selectbar.autbutton \
        -textvariable autobt_text -command {
    if {$automode} {
#       we were in automode
              set automode 0
#                prevent rescheduling
              set autobt_text "Auto"
#                     change button text
     } else {
#     we were in stopped mode, lets start
        set automode 1
#        enable rescheduling
        set autobt_text "Stop"
#        change button label
        after 1000 auto_display
#        first time wait a bit as to allow redraw of screen
      }
}


Example 1:

(a)
for {set i 0} { $i<100 } { incr i } {
label .label$i  ..... -text "Label$i"

pack .label$i
}

(b)
label .label0  ..... -text "Label0"
 . . .
label .label99  ..... -text "Label9"
pack .label0 ..... label99


Example 2:

 button .print -text Print -command {
 .richcanvas postscript -file /tmp/rich_display.ps
 exec (lpr -Pmy_color_printer /tmp/rich_display.ps;
 \ rm /tmp/rich_display)& }


