From: Frode Vatvedt Fjeld
Subject: GUI event loops
Date: 
Message-ID: <2h1za27472.fsf@dslab7.cs.uit.no>
I'm doing some work on using the GTK+ GUI library in lisp. Regarding
this, does anyone have suggestions as to what is the natural way to
express event loops in lisp? Or rather, the bindings between events
and lisp code.

Currently, I have events bound to symbols, such that whenever an event
occurs, that symbol's function-cell is called. But I'm not quite
satisfied with this approach, as it is very static and the resulting
code becomes numerous DEFUNs without the typical funtional flow.

It strikes me that these kinds of event bindings are perhaps not too
different from lexical variable bindings, so maybe I should look at
something like EVENT-LET.

Anyways, I'd like to hear if people with more experience with LISP
GUIs have some thoughts to share.


If you are interested in lisp/GTK/Glade, you can find my code here:
<URL:http//www.cs.uit.no/~frodef/sw/cl-glade/>. It currently only
supports Allegro CL 5, as I can't get CMUCL's or CLISP's FFIs to work.


Thanks,
-- 
Frode Vatvedt Fjeld

From: Larry Hunter
Subject: Re: GUI event loops
Date: 
Message-ID: <3isu2mvzobb.fsf@work.nci.nih.gov>
Frode Vatvedt Fjeld asks:

  [W]hat is the natural way to express event loops in lisp? Or rather, the
  bindings between events and lisp code.  Currently, I have events bound to
  symbols, such that whenever an event occurs, that symbol's function-cell
  is called. But I'm not quite satisfied with this approach, as it is very
  static and the resulting code becomes numerous DEFUNs without the typical
  funtional flow.

If I were designing this, I would probably define event structures
(DEFSTRUCT) to store useful information about each event.  That way, you can
associate one or more actions (function calls) with an event -- say, having
both a begin-event and an end-event call for drags.  You can also use other
slots for items you'd also like to associate with events, perhaps including
equivalencies (keyboard, mouse, menu, etc.).   If you wanted non-trivial
inheritance among events, you might also consider using CLOS objects as your
events.  If you did that, you could also design generic functions with
methods for various kinds of events, and do event dispatch by calling the
generic function on the event object.

Try looking at the CLIM specs.  You probably don't want to try to implement
all of CLIM on your own, but some of the design ideas are worth considering
for your system.

Good luck.  It would be nice to have a well designed GTK+ GUI library in
for lisp...

Larry

-- 
Lawrence Hunter, Ph.D.        Chief, Molecular Statistics and Bioinformatics
National Cancer Institute                             email: ·······@nih.gov
Federal Building, Room 3C06                         phone: +1 (301) 402-0389
7550 Wisconsin Ave.                                   fax: +1 (301) 480-0223
Bethesda, MD 20892  USA
From: Fred Gilham
Subject: Re: GUI event loops
Date: 
Message-ID: <u7ogd2jflr.fsf@snapdragon.csl.sri.com>
In Garnet, event handling is encapsulated in objects called
`interactors'.  These interactors are created independently of
graphics.

Here's an example:

  (create-instance nil inter:button-interactor
		   (:window *w*)
		   (:start-event :middledown)
		   (:start-where T)
		   (:continuous nil)
		   (:final-function #'zoom-in))

This adds an interactor for the middle button to the window *w*.  The
function in the :final-function slot, `zoom-in', will get called when
the middle button is clicked.

Here's another, a `two-point' interactor:

  (create-instance nil inter:two-point-interactor
		   (:window *w*)
		   (:start-event :leftdown)
		   (:start-action #'(lambda (i p)
				      (declare (ignore i p))
				      (s-value *outline-rectangle* :visible nil)))
		   (:start-where T)
		   (:final-function #'set-outline-rectangle)
		   (:feedback-obj *moving-rectangle*)
		   (:line-p nil)
		   (:Min-height 0)
		   (:Min-width 0))

The idea here is that you click on the left button and drag to select
an area.  The area is indicated by a feedback rectangle and once the
area is selected, the function in the final-function slot is called.

There are eight different kinds of interactors in Garnet, covering
most kinds of user input.

I like this better than programming event loops myself.

-- 
Fred Gilham                                        ······@csl.sri.com
The real point is how much easier it was to conceive of and design the
Lisp version.  I hadn't even realized the problem was hard until
people started to recode it in C....         --Lawrence Hunter, Ph.D.
From: Rainer Joswig
Subject: Re: GUI event loops
Date: 
Message-ID: <joswig-1111990220160001@194.163.195.67>
In article <··············@dslab7.cs.uit.no>, Frode Vatvedt Fjeld <······@acm.org> wrote:

> I'm doing some work on using the GTK+ GUI library in lisp. Regarding
> this, does anyone have suggestions as to what is the natural way to
> express event loops in lisp? Or rather, the bindings between events
> and lisp code.

MCL has a simple model.

All things on the screen are objects (windows, dialog-items, ...).
The MacOS event system calls the MCL event system. So
MCL takes the window where an event takes place (key press, mouse
click, ...) and determines the kind of event. It then calls
a generic function for that event on the particular item of
the window (say, a view-click-event handler for a button).
This function then determines what kind of event for the
item it is (say, a dialog-item-action) and calls another
generic function on the object.
A default handler might look for a function that is stored
in a certain slot of the (say, a dialog-item-action-function) object.

MacOS event -> MCL event -> View event -> handler

So you have certain levels of event handling where you
can change things (the translation of OS events into
MCL events, ..., override handlers, store specific handlers
per object).


Just create a button with an on-the-fly behaviour:

(make-instance 'window
  :view-subviews (list
                  (make-instance 'button-dialog-item
                    :dialog-item-action (lambda (button)
                                          (inspect button)))))


Or: create a special button object you can reuse:

(defclass inspect-mixin () ())

(defmethod dialog-item-action :after ((item inspect-mixin))
  (inspect item))

(defclass my-button (inspect-mixin button-dialog-item) ())

(make-instance 'window
  :view-subviews (list (make-instance 'my-button)))


Or: Modify the event-handler for views. The primary method for
dialog-items calls DIALOG-ITEM-ACTION.

(defmethod view-click-event-handler :after ((view my-button) where)
  (inspect where))


The event-handler of MCL is run as a kind of interrupt in a thread.
That means that other threads can run and the MCL event handler
is independent of the state of, say, running listeners. So you can
move, resize, etc. windows at any time (minus WITHOUT-INTERRUPTS,
and the general problem of non-preemtive threads on the Mac)
- even if they have a running thread. If the special event routine
needs to do a longer and more complicated task, one just would enqueue
a function and the first non-active listener would run that - or one could
create a new listener executing this task - or one could
start a thread that runs in the background and executes the
function.

The MCL model was first implemented as a very flexible way
of writing UIs using a prototype-based object system (Object Lisp).
Later the system has been rewritten completely for CLOS, trying
to preserve some of the nice features of the old system.

Rainer Joswig, ISION Internet AG, Harburger Schlossstra�e 1, 
21079 Hamburg, Germany, Tel: +49 40 77175 226
Email: ·············@ision.de , WWW: http://www.ision.de/
From: Fernando D. Mato Mira
Subject: Re: GUI event loops
Date: 
Message-ID: <383020A6.7D27D8F2@iname.com>
Frode Vatvedt Fjeld wrote:

> I'm doing some work on using the GTK+ GUI library in lisp. Regarding

I'd suggest taking a look at CLM to see upto what extent this can be
generalized to support both GTK+ and Motif, to start turning it into a
toolkit abstraction layer over which higher-level frameworks can sit.

Until I get them hosted, I can send you a prerelease of CLM 2.4 and GINA
2.4 if you want.

BTW, there's a copyright notice in your files, and a GPL COPYING file in
the distribution, but there's no explicit notice explaining what's the
role of the latter.
If you do intend to go the FSF way, the LGPL would be better.

Regards,

--
Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1                   email: matomira AT acm DOT org
CH-2007 Neuchatel                 tel:       +41 (32) 720-5157
Switzerland                       FAX:       +41 (32) 720-5720

www.csem.ch      www.vrai.com     ligwww.epfl.ch/matomira.html
From: Marco Antoniotti
Subject: Re: GUI event loops
Date: 
Message-ID: <lwn1sfvdlj.fsf@parades.rm.cnr.it>
"Fernando D. Mato Mira" <········@iname.com> writes:

> Frode Vatvedt Fjeld wrote:
> 
> > I'm doing some work on using the GTK+ GUI library in lisp. Regarding
> 
> I'd suggest taking a look at CLM to see upto what extent this can be
> generalized to support both GTK+ and Motif, to start turning it into a
> toolkit abstraction layer over which higher-level frameworks can
> sit.

This is a worthy goal.  However, note that the CMUCL/Motif interface
(patterned after CLM) is slightly better (it does cons less).

> Until I get them hosted, I can send you a prerelease of CLM 2.4 and GINA
> 2.4 if you want.
> 
> BTW, there's a copyright notice in your files, and a GPL COPYING file in
> the distribution, but there's no explicit notice explaining what's the
> role of the latter.
> If you do intend to go the FSF way, the LGPL would be better.

I strongly agree with this.   The GPL is more restrictive.  CL
packages do not need restrictions at this moment.

Cheers

Marco


-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: Fernando D. Mato Mira
Subject: Re: GUI event loops
Date: 
Message-ID: <38313F4A.A342255C@iname.com>
Marco Antoniotti wrote:

> This is a worthy goal.  However, note that the CMUCL/Motif interface
> (patterned after CLM) is slightly better (it does cons less).

I guess I'll have to take a look sometime. Note however that CLM 2.4 includes

a lot of performance improvements by `monty', specially w.r.t. CMUCL
[or is anybody getting serious about the CMUCL GC first? >:-I ]

--
((( DANGER )) LISP BIGOT (( DANGER )) LISP BIGOT (( DANGER )))

Fernando D. Mato Mira
Real-Time SW Eng & Networking
Advanced Systems Engineering Division
CSEM
Jaquet-Droz 1                   email: matomira AT acm DOT org
CH-2007 Neuchatel                 tel:       +41 (32) 720-5157
Switzerland                       FAX:       +41 (32) 720-5720

www.csem.ch      www.vrai.com     ligwww.epfl.ch/matomira.html
From: Marco Antoniotti
Subject: Re: GUI event loops
Date: 
Message-ID: <lwd7tavcj3.fsf@parades.rm.cnr.it>
"Fernando D. Mato Mira" <········@iname.com> writes:

> Marco Antoniotti wrote:
> 
> > This is a worthy goal.  However, note that the CMUCL/Motif interface
> > (patterned after CLM) is slightly better (it does cons less).
> 
> I guess I'll have to take a look sometime. Note however that CLM 2.4 includes
> 
> a lot of performance improvements by `monty', specially w.r.t. CMUCL
> [or is anybody getting serious about the CMUCL GC first? >:-I ]

First of all, CMUCL/Motif is more consistent when it comes to naming
things.  No shortcuts w.r.t. Motif naming have been made, only
"trivial" transformations.  Secondly, some functions have had their
arguments switched, therefore, in CMUCL they now are &rest functions,
instead of functions where you need to cons up a structure/list to be
passed back and forth.

Anyway, CMUCL/Motif works pretty well with CMUCL, I guess it'd be
rather easy to port it to other CLs as well.

Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa
From: Frode Vatvedt Fjeld
Subject: Re: GUI event loops
Date: 
Message-ID: <2h3dtte20n.fsf@dslab7.cs.uit.no>
"Fernando D. Mato Mira" <········@iname.com> writes:

> BTW, there's a copyright notice in your files, and a GPL COPYING
> file in the distribution, but there's no explicit notice explaining
> what's the role of the latter.

I have now changed the license to a BSD-style one. The copyright
notice informs who the "owner" of the software is, and the COPYING
file explains under what terms this "owner" allows the stuff to be
copied. I've added a "Distribution" entry in the file headers to
indicate this.

Have a look at <URL:http://www.cs.uit.no/~frodef/sw/cl-glade/> :-)

-- 
Frode Vatvedt Fjeld