Updated 2013-02-27 22:23:18 by SEH

TP WeirdX is an X11 server, a Java application that can run as an applet in a web browser.

Here's an example of using Tcl and WeirdX to deliver Tcl (or any other X application) to a browser. This method probably won't work if you have a restrictive firewall, but should be fine for internal networks.

You will need:

You can use any other window manager you happen to have lying around. aewm is tiny and command line options can turn off starting xterm, and other potentially dangerous X clients. You probably don't want users of your application starting shells on your server. aewm is only about 17kb when stripped of symbols.

As an alternative, you can skip starting a window manager, and instead use the WeirdX property 'weirdx.windowmode' to use your browser machine's native window manager. In this mode, windows will open outside of your browser. To try this, add the following line in the 'weirdx_html_start' chunk of html code, in the PARAM section:
    <PARAM NAME="weirdx.windowmode" VALUE="RootlessWM">

and also comment or remove the 'exec aewm...' line near the end of tcldemo.cgi.

Be sure to read the WeirdX docs; you may want to use the applet tags that use Java plugins /w Swing, and set the appropriate property values. You can also experiment with dxpc, rexec, xdmp, sound and other cool things that WeirdX supports.

How to:

  1. You probably already have Tcl/Tk installed, if not, do so.
  2. Unpack WeirdX.
  3. Unpack, build, and install aewm, including the 'goodies' programs.
  4. Unpack, build, and install cgi.tcl.
  5. Make some directory in your web server htdocs, say 'weirdx'.
  6. Copy the weirdx.jar file from weirdx-1.0.xx/misc to your htdocs/weirdx.
  7. Cut out the sample 'index.html' below and copy to htdocs/weirdx.
  8. Cut out the sample 'tcldemo.cgi' below and copy to htdocs/weirdx. Make any changes to tclsh & wish versions, paths to wish, aewm, etc. This sample runs the Tcl/Tk 'widget' demo, so change to run your own application.
  9. Make tcldemo.cgi executable: chmod +x tcldemo.cgi.
  10. If needed: fudge your web server config to execute cgi out of htdocs/weirdx.
  11. Start your browser and point to http://your_webserver/weirdx/index.html

Notes: The cgi program checks for a valid REMOTE_ADDR (the ip address of the browser), then sends the html code that causes WeirdX to be loaded. Then we check for WeirdX to start accepting connections by trying to open a socket to the X server's port. If that fails, you are probably behind a firewall or proxy that is filtering out incoming connections to your browser machine, or don't have Java enabled in your browser. When the socket connection succeeds, then start the window manager and Tcl application. Redirect stdin/stdout/stderr so that we don't hose up the web server. aewm is set to start 'xaw-switch' when a mouse button is pressed on the root window, allowing a user to select windows. To move windows in aewm, button-2 drag on the title bar.

Also, be aware that the actual Tcl/Tk application will run as your webserver user, unless you take steps to run as setuid to another user. You should probably be familiar with how your web server starts and runs CGI applications.

index.html
 <html>
 <head>
 <title>WeirdX Tcl Demo</title>
 <body>
 <p>
 Press <a href="tcldemo.cgi">here</a> to start the Tcl/WeirdX demo.
 </body>
 </html>

tcldemo.cgi
 #!/usr/local/bin/tclsh8.3

 package require cgi

 # html to start weirdx
 # note that specific html samples are provided in weirdx/misc for use with
 # IE, or Java plugins.

 set weirdx_html_start {
 <html>
  <head>
      <title>Tcl/WeirdX 1.0</title>
  </head>
  <body>
      <h1>Tcl/WeirdX 1.0</h1>
      <hr>
      <applet code="com.jcraft.weirdx.WeirdX.class" archive="weirdx.jar"
              width="800" height="600">
        <PARAM NAME="weirdx.displaynum" VALUE="2">
        <PARAM NAME="weirdx.ddxwindow" VALUE="com.jcraft.weirdx.DDXWindowImp">
        <PARAM NAME="weirdx.display.visual" VALUE="TrueColor16">
        <PARAM NAME="weirdx.display.acl" VALUE="+">
        <PARAM NAME="weirdx.display.threebutton" VALUE="yes">
        <PARAM NAME="weirdx.display.width" VALUE="800">
        <PARAM NAME="weirdx.display.height" VALUE="600">
      </applet>
      <hr>
 }
 set weirdx_html_end {
   </body>
 </html>
 }

 cgi_eval {

     cgi_debug -on
     cgi_input

     if {![info exists env(REMOTE_ADDR)]} {
         cgi_body {
             cgi_p "You don't have an IP address. How do expect this to work?"
             cgi_exit
         }
     }

     # WeirdX defaults to display # 2, set port accordingly

     set ip $env(REMOTE_ADDR)
     set disp 2
     set port [expr 6000 + $disp]

     # start the weirdx applet

     cgi_http_head {
         cgi_content_type text/html
     }
     cgi_puts $weirdx_html_start

     # wait for the X server to start accepting connections
     # we try to open a socket back to the browser to check for WeirdX running.

     cgi_puts "[cgi_nl]Starting WeirdX......"
     for {set max 20} {$max >= 0} {incr max -1} {
         after 2000
         if {[catch {set sock [socket $ip $port]}] == 0} {
             # X is running and accepting connections, break out
             catch {close $sock}
             break
         } else {
             cgi_puts " $max"
         }
     }
     if {$max < 0} {
         cgi_p "Couldn't connect to your machine, perhaps you are behind \
                 a firewall/proxy or don't have Java enabled in your browser?"
         cgi_puts $weirdx_html_end
         cgi_exit
     }

     # WeirdX is running, start up application and window manager.
     # aewm 1.1.12 doesn't have -display option, so set env(DISPLAY)
     # specify aewm goodie program 'xaw-switch' so that user can switch
     # active windows, but not start potentially dangerous programs like xterm.
     # you could even xrsh the apps over to another machine to load balance.
     # you also may have to specify full paths to the programs you want to
     # start if they are not in the PATH accessable by your web server.

     set env(DISPLAY) $ip:$disp
     exec aewm -new1 xaw-switch -new2 xaw-switch -new3 xaw-switch \
       < /dev/null >& /dev/null  &
     exec wish8.3  /usr/local/lib/tk8.3/demos/widget \
       < /dev/null >& /dev/null  &

     cgi_puts "[cgi_nl] Ready, starting application."
     cgi_puts $weirdx_html_end
 }

 exit