Next: Summary of differences with CLM, Previous: Structure of the Client [Contents]
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.
Next: Summary of differences with CLM, Previous: Structure of the Client [Contents]