From 2a29eca2a9aaf0c405cc6c5088e90c60b69a5e5f Mon Sep 17 00:00:00 2001
From: ram <ram>
Date: Mon, 26 Jul 1993 15:53:55 +0000
Subject: [PATCH] Initial revision

---
 docs/interface/internals.doc | 380 +++++++++++++++++++++++++++++++++++
 docs/interface/toolkit.doc   | 350 ++++++++++++++++++++++++++++++++
 2 files changed, 730 insertions(+)
 create mode 100644 docs/interface/internals.doc
 create mode 100644 docs/interface/toolkit.doc

diff --git a/docs/interface/internals.doc b/docs/interface/internals.doc
new file mode 100644
index 000000000..016511718
--- /dev/null
+++ b/docs/interface/internals.doc
@@ -0,0 +1,380 @@
+                         -*- Mode: Text,Fill -*-
+
+
+              General Design Notes on the Motif Toolkit Interface
+              ---------------------------------------------------
+
+
+
+
+Data Transport --
+-----------------
+
+Packet format -
+
+   Header:
+	32 bits ... serial number                       |
+	16 bits ... sequence position                   | This header
+	16 bits ... sequence length                     | takes 12 bytes
+	32 bits ... packet length (including header)    |
+   Data:
+	(packet_length - 12) bytes of information
+
+   - Packets have a fixed maximum size (4k).
+   - Packets a grouped together to form random length messages.  The
+sequence length refers to how many packets comprise the message, and each
+packet is tagged with its position in that sequence.
+   - All packets in the same message have the same serial number.
+   - Messages are built up as their constituent packets arrive.  It should
+be possible to interleave the packets of different messages and still have
+the individual messages be constructued properly.
+   - It is tacitly assumed that packets arrive in their proper sequence order.
+   - A packet with a sequence position/length field denoting [0 of 0] is a
+cancellation packet.  The message having that serial number should be
+discarded.
+
+Data format -
+
+   - Each data entry in a message is represented as:
+	 8 bits ... type tag
+	24 bits ... immediate data
+	 rest   ... other data (if necessary)
+
+
+
+
+Greeting Protocol --
+-------------------
+
+   When a Lisp process first establishes a connection to the server, it
+sends a 16 bit quantity which represents "1" to it.  The server using this
+to decide whether to byte swap words when sending them to Lisp.  The
+general policy is that all data is presented to the Lisp process in the
+order that Lisp uses.
+
+   Following the byte swapping information, the Lisp process sends an
+initial message which contains:
+
+	- A string giving the target X display name
+	- A string for the application name
+	- A string for the application class
+
+
+
+Request Protocol --
+-------------------
+
+   Request format:
+	16 bits ... request opcode
+	 8 bits ... request flags (0=nothing, 1=require confirm)
+	 8 bits ... argument count (unused)
+
+   At the moment, the request flags field is used only to indicate whether
+the Lisp client desires a confirmation message when the request is finished
+processing.  If the request returns any values, this counts as the
+confirmation.  Otherwise, an empty confirmation message will be sent.
+
+   Server reply format:
+	32 bits ... response tag
+	  rest  ... return data (if any)
+
+   The response tag can have the following values:
+	- CONFIRM_REPLY  ... confirmation (for synchronization)
+	- VALUES_REPLY   ... return values from a request
+	- CALLBACK_REPLY ... a widget callback has been invoked
+	- EVENT_REPLY    ... an X event handler has been invoked
+	- ERROR_REPLY    ... an error has occurred
+	- WARNING_REPLY  ... a non-fatal problem has occurred
+	- PROTOCOL_REPLY ... a protocol callback has been invoked
+
+
+
+Object Representations --
+-------------------------
+
+Data format in message -
+
+   Accelerators		32 bit integer ID
+   Atom			32 bit Atom ID
+   Boolean		24 bit immediate data
+   Color		24 bit immediate data (Red value) followed by
+			2 16 bit words for Green and Blue
+   Colormap		32 bit Colormap XID
+   Compound Strings	32 bit address
+   Cursor		32 bit Cursor XID
+   Enumeration		24 bit immediate integer
+   Font			32 bit Font XID
+   Font List		32 bit integer ID
+   Function		24 bit immediate token
+   Int			32 bit integer
+   List			24 bit immediate data (length) followed by each element
+			recorded in order
+   Pixmap		32 bit Pixmap XID
+   Short		24 bit immediate integer
+   Strings		24 bit immediate data (length of string including \0)
+			followed by string data padded to end on a word boundary
+			... or ...
+   Strings		24 bit immediate token (for common strings)
+   Translations		32 bit integer ID
+   Widgets		32 bit integer ID
+   Window		32 bit Window XID
+   
+
+   - For objects such as translations, widgets, accelerators, font lists,
+and compound strings, the 32 bit ID is just the address of the object in
+the C server process.  They are represented in Lisp by structures which
+encapsulate their ID's and provide them with Lisp data types (other than
+simply INTEGER).
+
+Information in widget structure -
+
+   - integer ID for identifying the widget to the C server
+   - widget class keyword (eg. :FORM, :PUSH-BUTTON-GADGET, :UNKNOWN)
+   - parent widget
+   - list of (knowen) children
+   - USER-DATA slot for programmer use
+   - list of active callback lists             | These are for internal use
+   - list of active protocol lists             | in cleaning up Lisp state
+   - list of active event handlers             | on widget destruction
+
+
+
+Callback handlers --
+--------------------
+
+   - A callback handler is defined as:
+
+	(defun handler (widget call-data &rest client-data) ....)
+
+   - The WIDGET argument is the widget for which the callback is being invoked.
+   - The CLIENT-DATA &rest argument allows the programmer to pass an
+arbitrary number of Lisp objects to the callback procedure. [Note: this
+deviates from CLM and Motif in C].
+   - The CALL-DATA argument provides the information passed by Motif
+regarding the reason for the callback and any other relevant information.
+   - The XEvent which generated the event may be accessed by:
+
+	(with-callback-event (event call-data)
+	  ....)
+
+   - Action procedures are used in translation tables as:
+
+	<Key> q: Lisp(SOME-PACKAGE:MY-FUNCTION)\n
+
+   - Action procedures may access their event information by:
+
+	(with-action-event (event call-data)
+	  ....)
+
+   - Where callback data is passed in structures, XEvents are represented
+as aliens.  This is because XEvents are rather large.  This saves the
+consing of large structures for each event processed.
+
+   - Actions to be taken after the callback handler terminates the server's
+callback loop can be registered by:
+
+	(with-callback-deferred-actions <forms>)
+
+
+
+Structure of the Server --
+----------------------------------
+
+   When the server process is started, it establishes standard sockets for
+clients to connect to it and waits for incoming connections.  When a client
+connects to the server, the server will fork a new process (unless
+"-nofork" was specified on the command line) to deal with incoming requests
+from the client.  The result of this is that each logical application has
+its own dedicated request server.  This prevents event handling in one
+application from blocking event dispatching in another.
+
+   Each request server is essentially an event loop.  It waits for an event
+to occur, and dispatchs that event to the appropriate handlers.  If the
+event represents input available on the client connection, it reads the
+message off the stream and executes the corresponding request.  If the
+event is an X event or a Motif callback, relevant information about that
+event is packed into a message and sent to the Lisp client.  After sending
+the event notification, the server will enter a callback event loop to
+allow processing of requests from the client's callback procedure.
+However, during the callback event loop, only input events from the client
+will be processed; all other events will be deferred until the callback is
+terminated.
+
+   The server supports a standard means for reading and writing data
+objects into messages for communication with the Lisp client.  For every
+available type of data which may be transported there are reader and writer
+functions.  For instance, WIDGET is a valid type for argument data.  Two
+functions are defined in the server: message_read_widget() and
+message_write_widget().  To allow for a more generalized interface to
+argument passing, the server defines the functions toolkit_write_value()
+and toolkit_read_value().  These functions are passed data and a type
+identifier; it is their job to look up the correct reader/writer function.
+Clearly, if the type of an argument is known at compile time then it is
+best to use the specific reader/writer functions.  However, if such type
+information is not known at compile time, as is the case with arbitrary
+resource lists, the higher level toolkit_xxx_value() functions are the only
+available options.
+
+
+
+Structure of the Client --
+--------------------------
+
+
+
+
+
+Adding New Requests to the System --
+------------------------------------
+
+   In order to add a new function to the toolkit interface, this new
+function must be declared in both C and Lisp.
+
+   Lisp provides a convenient macro interface for writing the necessary RPC
+stub.  The form of this definition is:
+
+	(def-toolkit-request <C name> <Lisp name> <:confirm|:no-confirm>
+	  "Documentation string"
+	  (<arguments>)
+	  (<return-values>)
+	  <optional forms>)
+
+Entries in the argument list should be of the form (<name> <type>).  The
+return value list is simply a list of types of the return value(s).  Any
+forms supplied at the end will be executed in a context where the arguments
+are bound to the given names and the return value is bound to RESULT (if
+there was only one) or FIRST, SECOND, ..., FOURTH (for up to 4 return
+values).  At the moment, the interface does not support any more than 4
+return values.  You must also specify a value for the confirmation option
+(:CONFIRM or :NO-CONFIRM).  If you expect return values, you must specify
+:CONFIRM in order to receive them.  Otherwise, you may specify :NO-CONFIRM.
+Use of :NO-CONFIRM allows for increased efficiency since the client will
+issue a request but not wait for any response.  All function prototypes
+should be placed in the prototypes.lisp file.  A few examples of request
+prototypes:
+
+	(def-toolkit-request "XtSetSensitive" set-sensitive :no-confirm
+	  "Sets the event sensitivity of the given widget."
+	  ;;
+	  ;; Takes two arguments:  widget and sensitivep
+	  ((widget widget) (sensitivep (member t nil)))
+	  ;;
+	  ;; No return values expected
+	  ())
+
+	(def-toolkit-request "XtIsManaged" is-managed :confirm
+	  "Returns a value indicating whether the specified widget is managed."
+	  ;;
+	  ;; Takes one argument: widget
+	  ((widget widget))
+	  ;;
+	  ;; Expects one return value (which is a boolean)
+	  ((member t nil)))
+
+	(def-toolkit-request "XmSelectionBoxGetChild" selection-box-get-child
+	                     :confirm
+	  "Accesses a child component of a SelectionBox widget."
+	  ;;
+	  ;; Takes two arguments: w and child
+	  ((w widget) (child keyword))
+	  ;;
+	  ;; Expects a return value which is a widget
+	  (widget)
+	  ;;
+	  ;; Now we execute some code to maintain the state of the world.
+	  ;; Given that this widget may be one we don't know about, we must
+	  ;; register it as the child of one we do know about.
+	  (widget-add-child w result)
+	  (setf (widget-type result) :unknown))
+
+
+   After adding a request prototype in Lisp, you must add the actual code
+to process the request to the C server code.  The general form of the
+request function should be:
+
+	int R<name>(message_t message)
+	{
+	  int arg;
+	  ...
+	  toolkit_read_value(message,&arg,XtRInt);
+	  ...
+	}
+
+Where <name> is the C name given in the request prototype above.  You must
+also add an entry for this function in the functions.h file.  An example of
+a standard request function is:
+
+	int RXtCreateWidget(message_t message)
+	{
+	  String name;
+	  WidgetClass class;
+	  Widget w,parent;
+	  ResourceList resources;
+
+	  toolkit_read_value(message,&name,XtRString);
+	  toolkit_read_value(message,&class,XtRWidgetClass);
+	  toolkit_read_value(message,&parent,XtRWidget);
+
+	  resources.class = class;
+	  resources.parent = parent;
+	  toolkit_read_value(message,&resources,ExtRResourceList);
+
+	  w = XtCreateWidget(name,class,parent,
+			     resources.args,resources.length);
+	  reply_with_widget(message,w);
+	}
+
+Certain standard functions for returning arguments are provided in the file
+requests.c; reply_with_widget() is an example of these.
+
+
+
+Summary of differences with CLM --
+----------------------------------
+
+   - X objects (eg. windows, fonts, pixmaps) are represented as CLX objects
+rather than the home-brewed representations of CLM.  As a consequence, this
+requires that CLX be present in the core.  If this were to cause
+unacceptable core bloat, a skeletal CLX could be built which only supported
+the required functionality.
+
+   - Stricter naming conventions are used, in particular for enumerated
+types.  A value named XmFOO_BAR in C will be called :foo-bar in Lisp,
+consistently.  Abbreviations such as :form (for :attach-form) are not
+allowed since they are often ambiguous.  Where CLM abbreviates callback
+names (eg. XmNactivateCallback becomes :activate), we do not (eg.
+:activate-callback).
+
+   - Some differently named functions which can be resolved without undo
+hassle.
+
+   - Passing of information to callbacks and event handlers.  In CLM,
+callback handlers are defined as:
+
+	(defun handler (widget client-data &rest call-data) .... )
+
+The client-data argument is some arbitrary data which was stashed with the
+callback when it was registered by the application.  The call-data
+represents the call-data information provided by Motif to the callback
+handler.  Each data item of the callback information is passed as a
+separate argument.  In our world, callback handlers are defined as:
+
+	(defun handler (widget call-data &rest client-data) .... )
+
+The call-data is packaged into a structure and passed as a single argument
+and the user is allowed to register any number of items to be passed to the
+callback as client-data.  Being able to pass several items of client-data
+is more convenient for the programmer and the packaging of the call-data
+information is more appealing than splitting it apart into separate
+arguments.  Also, CLM only transports a limited subset of the available
+callback information.  We transport all information.  Event handlers differ
+in the same way.  The client-data is the &rest arg and the event info is
+packaged as a single object.  Accessing the generating event in a callback
+handler is done in the following manner:
+
+	(defun handler (widget call-data &rest client-data)
+	  (with-callback-event (event call-data)
+	    ;; Access slots of event such as:
+	    ;;  (event-window event) or
+	    ;;  (button-event-x event)
+	))
diff --git a/docs/interface/toolkit.doc b/docs/interface/toolkit.doc
new file mode 100644
index 000000000..a72bae669
--- /dev/null
+++ b/docs/interface/toolkit.doc
@@ -0,0 +1,350 @@
+-*- Mode: Text, Fill -*-
+
+
+
+Naming conventions --
+---------------------
+
+   In general, names in the Lisp Motif interface are derived directly from
+the C original.  The following rules apply:
+
+   1) Drop "Xt" and "Xm" (also "XmN","XmC", etc.) prefixes
+   2) Separate words by dashes ("-") rather than capitalization
+   3) Resource names and enumeration values are given as keywords
+   4) Replace underscores ("_") with dashes ("-")
+
+   Examples:
+
+	- XtCreateWidget --> create-widget
+	- XmNlabelString --> :label-string
+	- XmVERTICAL     --> :vertical
+
+   Some exceptions:
+
+	- Compound string functions (XmString...) are prefixed by
+"compound-string-" rather than "string-" in Lisp.
+
+   Functions or resources, with the exception of the compound-string-xxx
+functions, which require compound string arguments, may be given Lisp
+SIMPLE-STRINGs instead.
+
+   The arguments to functions are typically the same as the C Motif
+equivalents.  Some exceptions are:
+
+	- Widget creation functions have a &rest arg for resource values.
+	- Functions which take a string table/length pair in C only take a
+list of strings in Lisp.
+	- Registering functions such as ADD-CALLBACK use a &rest arg for
+registering an arbitrary number of client-data items.
+
+
+
+Starting things up --
+---------------------
+
+   The Motif toolkit interface is divided into two parts.  First, there is
+a server process written in C which provides an RPC interface to Motif
+functions.  The other half is a Lisp package which connects to the server
+and makes requests on the user's behalf.  The Motif interface is exported
+from the TOOLKIT (or XT) package.
+
+
+   Variables controlling connections:
+
+   *DEFAULT-SERVER-HOST* - a string naming the machine where the Motif
+server is to be found.  The default is NIL, which causes a connection to
+be made using a Unix domain socket on the local machine.  Any other name
+must be a valid machine name, and the client will connect using Internet
+domain sockets.
+
+   *DEFAULT-DISPLAY* - determines the display on which to open windows.
+The default value of NIL instructs the system to consult the DISPLAY
+environment variable.  Any other value must be a string naming a valid X
+display.
+
+   *DEFAULT-TIMEOUT-INTERVAL* - an integer specifying how many seconds the
+Lisp process will wait for input before assuming that the connection to the
+server has timed out.
+
+
+   Handling Connections:
+
+   OPEN-MOTIF-CONNECTION (hostname xdisplay-name app-name app-class) --
+Opens a connection to a server on the named host and opens a display
+connection to the named X display.  The app-name and app-class are for
+defining the application name and class for use in resource specifications.
+An optional process-id argument can be passed if a local server process has
+already been created.  This returns a MOTIF-CONNECTION object.
+
+   CLOSE-MOTIF-CONNECTION (connection) -- This closes a toolkit
+connection which was created by OPEN-MOTIF-CONNECTION.
+
+   *MOTIF-CONNECTION* -- Bound in contexts such as callback handlers to
+the currently active toolkit connection.
+
+   *X-DISPLAY* -- Bound in contexts such as callback handlers to the
+currently active CLX display.
+
+   WITH-MOTIF-CONNECTION ((connection) &body forms) -- This macro
+establishes the necessary context for invoking toolkit functions outside of
+callback/event handlers.
+
+   WITH-CLX-REQUESTS (&body forms) -- Macro that ensures that all CLX
+requests made within its body will be flushed to the X server before
+proceeding so that Motif functions may use the results.
+
+   RUN-MOTIF-APPLICATION (init-function) -- This is the standard CLM
+entry point for creating a Motif application.  The init-function argument
+will be called to create and realize the interface.  It returns the created
+MOTIF-CONNECTION object.  Available keyword arguments are:
+		:init-args -- list of arguments to pass to init-function
+		:application-class -- application class (default "Lisp")
+		:application-name -- application name (default "lisp")
+		:server-host -- name of Motif server to connect to
+		:display -- name of X display to connect to
+
+   QUIT-APPLICATION () -- This is the standard function for closing down a
+Motif application.  You can call it within your callbacks to terminate the
+application.
+
+
+
+The Server --
+-------------
+
+   The C server is run by the "motifd" program.  This will create both Inet
+and Unix sockets for the Lisp client to connect to.  By default, the Inet
+and Unix sockets will be specific to the user.
+
+   When a Lisp client connects to the server, it forks a copy of itself.
+Thus each Lisp application has an exclusive connection to a single C server
+process.  To terminate the server, just ^C it.
+
+   Switches to change behavior:
+
+	-global ... Sockets created for use by everyone rather than
+	            being user-specific.
+	-local  ... No Inet socket is created and the Unix socket is
+	            process-specific
+	-noinet ... Instructs the server not to create an Inet socket.
+	-nounix ... Instructs the server not to create a Unix socket.
+	-nofork ... Will keep the server from forking when connections are
+	            made.  This is useful when debugging the server or when
+	            you want the server to die when the application terminates.
+	-trace  ... Will spit out lots of stuff about what the server is
+	            doing.  This is only for debugging purposes.
+	
+   Typically, users do not need to be concerned with server switches since,
+by default, servers are created automatically by your Lisp process.
+However, if you wish to share servers, or use servers across the network,
+you will need to run the server manually.
+
+
+
+Widget creation --
+------------------
+
+   CREATE-APPLICATION-SHELL (&rest resources) -- Creates the
+applicationShell widget for a new Motif application.
+
+   CREATE-WIDGET
+   CREATE-MANAGED-WIDGET (name class parent &rest resources) -- These
+create new widgets.  CREATE-WIDGET does not automatically manage the
+created widget, while CREATE-MANAGED-WIDGET does.
+
+   CREATE-<widget_class> (parent name &rest resources) -- Convenience
+function which creates a new widget of class <widget_class>.  For instance,
+CREATE-FORM will create a new XmForm widget.
+
+   *CONVENIENCE-AUTO-MANAGE* -- Controls whether convenience functions
+automatically manage the widgets they create.  The default is NIL.
+
+
+
+Callbacks --
+------------
+
+   Callbacks are registered with the ADD-CALLBACK function.  Unlike Motif
+in C, an arbitrary number of client-data items can be registered with the
+callback.  Callback functions should be defined as:
+
+	(defun callback-handler (widget call-data &rest client-data) ... )
+
+   The passed widget is that in which the callback has occurred, and the
+call-data is a structure which provides more detailed information on the
+callback.  Client-data is some number of arguments which have been
+registered with the callback handler.  The slots of the call-data structure
+can be derived from the C structure name using the standard name conversion
+rules.  For example, the call-data structure for button presses has the
+following slot (aside from the standard ones): click-count.
+
+   To access the X event which generated the callback, use the following:
+
+	(defun handler (widget call-data &rest client-data)
+	  (with-callback-event (event call-data)
+	    ;; Use event structure here
+	  ))
+
+   Since callback procedures are processed synchronously, the Motif server
+will remain blocked to event handling until the callback finishes.  This
+can be potentially troublesome, but there are two ways of dealing with this
+problem.  The first alternative is the function UPDATE-DISPLAY.  Invoking
+this function during your callback function will force the server to
+process any pending redraw events before continuing.  The other (slightly
+more general) method is to register deferred actions with the callback
+handling mechanism.  Deferred actions will be invoked after the server is
+released to process other events and the callback is officially terminated.
+Deferred actions are not invoked if the current application was destroyed
+as a result of the callback, since any requests to the server would refer
+to an application context which was no longer valid.  The syntax for their
+usage is:
+
+	(with-callback-deferred-actions <forms>)
+
+   You may register only one set of deferred actions within the body of any
+particular callback procedure, as well as within event handlers and action
+procedures.  Registering a second (or more) set of deferred actions will
+overwrite all previous ones.
+
+   When using deferred action procedures, care must be taken to avoid
+referencing invalid data.  Some information available within callbacks is
+only valid within the body of that callback and is discarded after the
+callback terminates.  For instance, events can only be retrieved from the
+call-data structure within the callback procedure.  Thus the code
+
+	(with-callback-deferred-actions
+	  (with-callback-event (event call-data)
+	    (event-type event)))
+
+is incorrect since the event will be fetched after the callback is
+terminated, at which point the event information will be unavailable.
+However, the code
+
+	(with-callback-event (event call-data)
+	  (with-callback-deferred-actions
+	    (event-type event)))
+
+is perfectly legitimate.  The event will be fetched during the callback and
+will be closed over in the deferred action procedure.
+
+
+
+Action procedures --
+--------------------
+
+   Action procedures can be registerd in translation tables as in the
+following example:
+
+	<Key> q: Lisp(SOME-PACKAGE:MY-FUNCTION)\n
+
+The generating X event can be accessed within the action handler using:
+
+	(with-action-event (event call-data)
+	  ... use event here ...
+	)
+
+
+
+Event handlers --
+-----------------
+
+   X events are also represented as structured objects with slot names
+which are directly translated from the C equivalent.  The accessor
+functions are named by <event name>-<slot name>.  Some examples:
+
+	(event-window event)  ... This applies to all events
+	(event-type event)    ... So does this
+
+	(button-event-x event)       | Some button event
+	(button-event-button event)  | accessors
+
+   At the moment, XClientMessage and XKeyMap events are not supported (they
+will be in the not too distant future).
+
+
+
+Provided conveniences --
+------------------------
+
+   Since Motif requires the use of font lists for building non-trivial
+compound strings, there are some Lisp functions to ease the pain of building
+them:
+	BUILD-SIMPLE-FONT-LIST (name font-spec) -- Returns a font list of
+with the given name associated with the given font.  For example,
+	(build-simple-font-list "MyFont" "8x13")
+
+	BUILD-FONT-LIST (flist-spec) -- This allows for the construction of
+font lists with more than one font.  An example:
+	(build-font-list `(("EntryFont" ,entry-font-name)
+	                   ("HeaderFont" ,header-font-name)
+	                   ("ItalicFont" ,italic-font-name)))
+
+   There are certain callbacks which are of general use, and standard ones
+are provided for the programmer's convenience.  For all callbacks except
+QUIT-APPLICATION-CALLBACK, you register some number of widgets with
+ADD-CALLBACK.  These will be the widgets acted upon by the callback:
+
+	QUIT-APPLICATION-CALLBACK () -- Callback to terminate the current
+application.
+
+	DESTROY-CALLBACK -- Destroys all the widgets passed to it.
+	MANAGE-CALLABCK  -- Manages all the widgets passed to it.
+	UNMANAGE-CALLBACK -- Unmanages all the widgets passed to it.
+	POPUP-CALLBACK  -- Calls popup on all widgets passed to it.
+	POPDOWN-CALLBACK -- Calls popdown on all widgets passed to it.
+
+
+
+Some random notes --
+--------------------
+
+   - When using functions such as REMOVE-CALLBACK, the client-data passed
+must be EQUAL to the client-data passed to ADD-CALLBACK.
+   - When using REMOVE-CALLBACK, etc., the function may be supplied as
+either 'FUNCTION or #'FUNCTION.  However, they are considered different so
+use the same one when adding and removing callbacks.
+   - You cannot directly access the XmNitems resources for List widgets and
+relatives.  Instead, use (SET-ITEMS <widget> ....) and (GET-ITEMS
+<widget>).
+
+
+
+Things that are missing --
+--------------------------
+
+   1) Real documentation
+   2) Support for XClientMessage and XKeyMap events
+   3) Callback return values (eg. XmTextCallback's)
+   4) Ability to send strings longer than 4096 bytes.
+
+   All these things should start appearing in the next few weeks.
+
+
+
+A brief example --
+------------------
+
+(defun my-callback (widget call-data quit)
+  (format t "Got callback on ~A~%" widget)
+  (format t "Callback reason was ~A~%" (any-callback-reason call-data))
+  (format t "Quit button is ~A~%" quit))
+
+(defun test-init ()
+  (let* ((shell (create-application-shell))
+	 (rc (create-row-column shell "rowColumn"))
+	 (quit (create-push-button-gadget rc "quitButton"
+					  :label-string "Quit"))
+	 (button (create-push-button-gadget rc "button"
+					    :highlight-on-enter t
+					    :shadow-thickness 0
+					    :label-string "This is a button")))
+
+    (add-callback quit :activate-callback #'quit-application-callback)
+    (add-callback button :activate-callback 'my-callback quit)
+
+    (manage-child rc)
+    (manage-children quit button)
+    (realize-widget shell)))
+
+(defun test ()
+  (run-motif-application 'test-init))
-- 
GitLab