packages icon

KLM is intended to provide easy access to Motif, just like Tcl does it for
Tk. It is base on the Lisp dialect called Klone and provides a small and simple
API to the Motif world.

* Introduction

- klm is not another Lisp/Motif binding

klm is not intended to be a full Klone binding to the Xt/Motif API. It is a set
of functions that allow to build easily full Motif applications in a LISP
dialect called Klone. Each existing Motif widget class is associated with a
convenience Klone function to build corresponding widgets. These functions are
called 'constructor'. Each constructor has the following signature:

ConstructorName(parent widget-name)

an returns the newly created widget.
Constructor-Name is simply the Motif Class Name without the Xm Prefix.
ex: constuctor for XmPushButton is 'PushButton'

One can set attributes in a constructor by giving extra parameters with the
SetValue syntax (see below).

ex: (PushButton top "button" :labelString 'Hello :foreground 'red)

Be aware that this just perfomrs a SetValue *after* widget creation and
*before* management, so that it does not allow to set resources that are
settable at creation time only (use resource file for this).

- Building widgets

klm will automatically manage any created widget, so that the klm programmer
has not to deal with the XtManage stuff. Drawback is that it may considerally
slow down application's load time, if you create widgets in an already built
(realized) widgets hierachy. Prevent this in script files by calling the
'build' command *after* widgets creation.

- setting resource values

Once you have built a widget, you can set attributes value like this:

(setq button (PushButton parent "hello"))
(button :background 'red :labelString "Hello world!!!")

Using the widget as function, you can give a list of attribute/value
association that will set corresponding resource on the widget. attribute's
value may be a KlString, KlAtom, KlNumber and KlList (if this has sense).

- getting resource values

? (button :background)
= #FFFF00000000

returned values are usually KlString except for:
	. Boolean attributes that are returned as t or ()
	. numeric attributes that are returned as KlNumber
	. StringTables that are returned as KlList (of KlString)

- accessing children

To retrieve a given (named) child from a widget, you can use the 'get-widget
function (see below) or a syntaxic approach that allows to specify a widget's
path using dots. For example

	(setq button (PushButton parent "hello"))
	(parent.hello :background 'red)

the 'parent.hello' variable references the widget named 'hello', starting from
the variable 'parent'. Depth is unlimited, so that you can specify
parent.hello.child1.child, ...
There is also an absolute syntax that allow to start from the top of the widget hierarchy: For example:

	(Toplevel "hello" "Hello")
	(PushButton ^hello "button")
	(^hello.button :background 'red)

If the specified widget does not exist, issue an 'undefined variable'

* Widgets

- Toplevel(app-name app-class)				XtAppInitialize

this basically calls XtAppInitialize, so that:
	. it initializes the connection to the X server
	. it initializes the resource database
	. it creates a first application shell
It returns the newly created widget.
app-name is used as widget name if it is not ""; else name is taken from the 
resource database (-name option). 
app-class is used as application class.

Here is the list of the defined constructors. There is no further explication,
since it's better to refer to a Motif manual.

	HPack				1
	PulldownMenu			2
	RadioBox			3
	VPack				4
	ItemList			5

1 - A RowColumn with packing = PACK_COLUMNS, orientation = HORIZONTAL 

2 - Builds both the XmCascadeButton and the XmPulldownMenu menu returns the

3 - An XmRowColumn with radioBehavior = True

4 - A RowColumn with packing = PACK_COLUMNS, orientation = VERTICAL 

5 - the exception to the constructors naming rule. (Klone already has a List

* Functions

- build(KlWidget)					XtRealize

Physically build a widget hierachy. Build the windows and display them. The
paramater must be a toplevel widget. 'build' will recurse on all the toplevel

(setq top (Toplevel "top" "Top"))
(setq button (PushButton top "hello"))
(build top)

Typically, this should be called only once on the toplevel widget.

- hide(KlWidget)					XtUnmanageChild

Remove a widget from the hierachy. The widget is not destroyed. It is just
unlinked from its parent. it may be displayed again using 'show'.

(setq top (Toplevel "top" "Top"))
(setq fs (FileSelectionDialog top "fs"))
(build top)
(hide fs)

- show(KlWidget)					XtManageChild

Redisplay a widget that had been previously hidden with 'hide'. When applied on
a dialog widget, this function makes it appear (pop). Make it disappear (unpop)
with hide.

(setq top (Toplevel "top" "Top"))
(setq fs (FileSelectionDialog top "fs"))
(hide top)
(build top)
(show fs)

You can use this function to make popup menus appears. They will be
automatically positionned (using XmMenuPosition).

- callback(KlWidget CallbackName LispForm)		XtAddCallback

Add the LispForm expression in the callback list named callbackName. 
CallbackName is the Motif CallbackName without the 'Callback' Suffix.

	(callback button 'activate '(quit))

The specified lisp form is appended to the XmNactivateCallback list.

- observe(KlStream LispForm)

Add the KlStream in the input list that will be oberved by the klm MainLoop.
When "there is something to read" on the stream, the LispForm will be executed
as callback.

- timeout(KlNumber LispForm)				XtAppAddTimeOut

Adds a timeout specified in msthat will execute the LispForm.

- bind(KlWidget EventSpec LispForm)			XtOverrideTranslations

binds the given event description (using the Xt translation TableSyntax to
execute the Lisp Form given as parameter. The EventSpec must be an Event
description according to the syntaxic rules defined for translation tables.

	(setq top (Toplevel "" "Top")
	(bind top "<Key>" '(print "ouch!\n"))

- unbind(KlWidget EventSpec)

remove a previously defined binding from the specified widget. The \EventSpec
must be identicalcal to the EventSpec that was given to the bind function.

	((setq to (Toplevel "" "Top"))
	(bind top "<Key>" '(print "ouch!\n"))
	(unbind top "<Key>")

- cursor(KlWidget CursorName)

Sets the specified cursor on the widget's window. Does not recurse on popups.
if CursorName is (), unset the previously defined cursor.

- get-widget(KlWidget KlString)

Returns the widget with the specified name, starting from the 'KlWidget'.
Widget's name may contain more than one level (i.e, "toto.tutu").
returns NULL if the widget was not found.

- destroy(KlWidget)

Physically destroys the widget (and its subtree) given as parameter. Further
reference to a destroyed widget will trigger the BAD_WIDGET exception.  Also
accepts a widget list instead of a single widget as parameter.

* Variables

- *fallback-resources*			default=()
  may contain a list of strings that are resource specifications.

(setq *fallback-resources*
      '("*geometry: +200+200"
	"*background: grey"))

These resources will be used by Motif when no app-defaults or user-defaults
file is found. (see XtAppSetFallbackResources).

- *event*

inside a callback or an action proc (see 'bind'), you can refer to this
varialbe to get fields from the X Event that trigerred tha callback (action).

Available fields are:
	- type
	- x
	- y
	- window
	- time
Event types are available as autoloaded atom:

Ex: (if (= (get *event* 'type) 'MouseMotion)

* pseudo-resources

Some informations may be obtained from a widget using the GetValue
syntax. These are not widget's resources in the full sense and are called

- (w :parent)		returns the widget's parent (or NIL)
- (w :class)		returns the widget's class name
- (w :name)		returns the widget's name
- (w :window)		returns the widget's window id or NIL if unmanaged
- (w :managed)		returns t or '() regarding the the widget's state
- (w :realized)		returns t or '() regarding the the widget's state