\documentclass[11pt,twoside,onecolumn]{article} \usepackage[]{fontenc} \usepackage{palatino} \usepackage{a4} \addtolength{\oddsidemargin}{-0.2in} \addtolength{\evensidemargin}{-0.6in} \addtolength{\textwidth}{0.5in} % So that the headers use the new dimensions, the package is % included after the dimensions are reset: \pagestyle{headings} %\usepackage{fancyheadings} %\pagestyle{fancyplain} \def\omniParTcl{{\tt omniParTcl}} \def\tcltk{{\tt Tcl/Tk}} \def\tcl{{\tt Tcl}} \def\tk{{\tt Tk}} \def\CXX{{\tt C++}} \begin{document} \title{{\bf \omniParTcl}\\ {\normalsize Creating \tcltk\ GUIs for \CXX\ applications}} \author{Kenneth R.\ Wood\\ ORL\\ {\small (ODE version 4.0 revisions by Tristan Richardson)}} \date{13 Mar, 1997} \maketitle \begin{abstract} \noindent We describe a clean and simple method for integrating \tcltk\ and \CXX\ in order to provide the means to create graphical user interfaces for Orbix-based applications, both clients and servers. In fact, the method is a general one which allows the creation of a \tcltk\ GUI for any \CXX\ program. The method allows \CXX\ functions to be invoked from a \tcltk\ script and allows \tcltk\ commands to be scheduled for evaluation from \CXX. Although most \omniParTcl\ applications will be multithreaded, all \tcltk\ processing is guaranteed to be confined to a single thread. No modification to the Tk scheduler is required. \end{abstract} \section{Introduction} \omniParTcl\ (pronounced ``omni-{\em particle}'' and intended to evoke the idea of ``{\em Par\/}allel {\em \tcl\/}'') provides a mechanism for attaching a graphical front-end written in \tcltk\ to a \CXX\ program. It was motivated by the perceived need for better-than-command-line interfaces for Omni/Orbix applications. In discussion, the following criteria were established for any integration of \tcltk\ and \CXX: \begin{itemize} \item It must be possible for the \tcltk\ interface to run in parallel with \CXX\ computation. This requirement stems from potential delays in Orbix RPCs, but it is also desirable in the general case to allow the user to continue to interact with an application during lengthy computations of any sort. \item All \tcltk\ primitives should be invoked from a single thread. This frees us---at least to a certain extent---from worries about thread-aware i/o and, more importantly, prevents dangerous inter-thread recursion which could otherwise easily occur given the diverse range of execution triggers in \tcltk. \item Polling should not be used in synchronizing \tcltk\ and \CXX\ threads. This obviates the need to predetermine the balance between interactive response time and CPU wastage on polling. More generally, it also removes the danger of multiple \omniParTcl\ applications dominating the CPU simply due to polling. \item If possible, no modifications to the Tk scheduler should be required. That is, we would like our \tcltk\ interface to be managed by a {\tt wish} which has been constructed using only the standard hooks. This makes it much more likely that the integration technique will work with future releases of \tcltk, and also means that upgrading to such future releases will involve little, if any, work. \end{itemize} \noindent \omniParTcl\ has been designed to meet all of these criteria. \section{Using \omniParTcl} To write an application using \omniParTcl, you create two related pieces of code: \begin{enumerate} \sloppy{ \item The application code. This is the \CXX\ source of your application, which will consist of any number of \CXX\ functions and may, of course, include Orbix code. Your application code must define {\tt Tcl\_Appinit()} and {\tt main()}. Your {\tt Tcl\_Appinit()} must call {\tt omniParTcl\_Init()} which takes the same form as {\tt Tcl\_Init()} and {\tt Tk\_Init()}. Your {\tt main()} must call {\tt Tk\_Main()}.} By using {\tt Tcl\_CreateCommand} within your definition of {\tt Tcl\_Appinit}, you will nominate certain of your \CXX\ functions as callable from \tcl. Usually these \tcl-callable \CXX\ functions will launch one or more parallel threads and return control to the main \tcltk\ thread, although simple functions can be run in the main thread if their execution does not interfere unduly with the \tcltk\ user interface. For communication in the other direction, \omniParTcl\ provides two \CXX\ functions which schedule \tcltk\ commands for evaluation in the primary thread. \begin{itemize} \item {\tt omniTclMeAndRun(s)} schedules \tcltk\ script {\tt s} for evaluation as soon as possible and returns control immediately to the calling \CXX\ thread. \item {\tt omniTclMeAndWait(s)} schedules the script for evaluation and does not return control to the caller until the script has been evaluated. \end{itemize} \noindent Clearly, {\tt omniTclMeAndWait()} cannot be used by a \CXX\ function running in the main thread. \item The \tcltk\ script. This implements your graphical user interface, and will contain calls to the \CXX\ functions nominated in {\tt Tcl\_Appinit()} as callable from \tcltk. One way of running your program is with {\tt myApp -file