How CLUE Works

CLUE combines all of these ideas. A CLUE program consists of an event loop, a set of UI objects called contacts, and a set of application functions called callbacks. All CLUE programs look pretty much like this:

;; Open a connection to the X server.
(let ((display (open-contact-display 'my-application :host "server-host" ...)))
  ;; Initialize UI objects and callbacks.  
  (setf c (make-contact ... ))
  (add-callback c ... )
       ...
  ;; Process events until the event loop is terminated.
  (catch :event-loop
    (loop
      (process-next-event display)))  
  (close-display display))

A CLUE program creates a contact-display object which represents a connection to a specific X server. This contact-display then becomes a two-way channel through which the program requests the creation and display of contact windows and receives input events sent to its contacts.

Each contact is a UI ``agent'' that is prepared to present some application information, to accept user events which manipulate this information, and then to report the results back to the application. This reporting action is the critical connection between the UI and the application, and it's done using callbacks. A callback consists of a callback name and an associated callback function. A contact is programmed to associate a specific result with a callback name, which it reports by calling the associated callback function (with a predefined argument list).

Here is where CLUE contributes to the separation of UI and application. Every CLUE program usually has two programmers! A contact programmer is one who defines a contact class and implements its methods. An application programmer is one who decides to create a contact instance and employ it for a particular UI role. The contact programmer decides what callback names his contact class will use and what the argument lists to the associated callback functions have to be. The application programmer defines callback functions to perform specific jobs and plugs them into the appropriate contact callback. The contact programmer will frequently use the basic CLX interface, typically to display the contact's information. The application programmer will use CLUE interfaces but will almost never need to call CLX functions directly.

Now we can see the operation of a CLUE program in a bit more detail. The make-contact function is used to create and initialize contacts. The add-callback function associates application semantics (i.e. callback functions) with each contact. Then, the program enters the event loop. Each call to process-next-event reads the next input event and dispatches it to the contact to which it belongs. This contact then goes through a process of event translation, which determines which contact action functions will be executed. Contact action functions, in turn, perform all the details of input feedback and display. Finally, if the user event has completed an application result, the action function will look up and call the associated callback function. What has happened? CLUE has provided all the machinery, the contact programmer has defined the detailed UI behavior, and the application programmer has furnished the real results.

The rest of this guide will be a closer look at each of these parts of a CLUE program.