Re: [g-a-devel]Gnome-speech and the callbacks



On Fri, 2003-01-17 at 13:22, Draghi Puterity wrote:
> > I agree with Michael here, this is the 'signal handling' approach to
> > adding listener callbacks which I mentioned in my previous email.
> > 
> > Since your listener must be (by definition) a BonoboObject and thus a
> > GObject, you have an in-process signal-listener mechanism waiting to be
> > used. :-)
> 
> Could you please point me to some good doc where I can learn about this?

I wish I could ;-)

The g_signal and g_closure APIs are among the most poorly documented
APIs in GTK+ and Glib.  Go bug Tim Janik and the GTK+ team about that 
:-)

However a good place to learn by example (assuming I haven't made too
many horrible goofs) is to look at the implementation code in cspi and
libspi which uses this mechanism already.  For example, in
libspi/eventlistener.c, we have a BonoboObject-based implementation of
at-spi's 'GNOME::Accessibility::Listener' interface, called
SpiEventListener.  (It inherits from Accessibility_EventListener, but it
could just as well have directly inherited from BonoboObject, so don't
let that small detail throw you off track).

This SpiEventListener object shows not only how you build a server-side
BonoboObject class, but it also defines a GObject signal called "event",
which it emits whenever it receives a ::notifyEvent method call from a
client.  In your case, the 'client' is the gnome-speech voice which is
issuing the speech-completion notifications, and your server's
impl_notify_event() method, or a similarly named method which is
associated with GNOME::Speech::SpeechCallback:notify via the 'epv' table
(see spi_event_listener_class_init for an example).

You will see that in SpiEventListener, the only thing the listener
object does when if gets a notify is emit the 'event' signal.  So the
listener object is just a relaying device bridging the out-of-process
CORBA world and the in-process 'callback' world.  

There's a tricky bit in the code in spi_event_listener_class_init, where
the signal is defined; the snippet of code:

       signals [EVENT] = g_signal_new (
                "event",
                G_TYPE_FROM_CLASS (klass),
                G_SIGNAL_RUN_LAST,
====>>>>        G_STRUCT_OFFSET (SpiEventListenerClass, event),
                NULL, NULL,
                g_cclosure_marshal_VOID__POINTER,
                G_TYPE_NONE, 1, G_TYPE_POINTER);
                                                
                
sets up a default handler for the 'event' signal, namely, it calls the
virtual method 'event' in the SpiEventListenerClass struct when the
'event' signal is emitted.

This default handler isn't necessary, but it's where cspi does its magic
relaying to a list of callbacks.  

For your purposes, rather than creating a default handler and then
having to manage your own callbacks list internally, I suggest just
attaching signal handlers directly to the 'event' signal (or whatever
you call it, perhaps 'speech_progress' or 'speech_marker_event'.  The
APIs to choose from are:

 g_signal_connect
 g_signal_connect_closure
 g_signal_connect_data

etc.  I suggest starting with g_signal_connect or
g_signal_connect_object and seeing if that will work for you.  The
second API has the advantage that the data passed to the signal handler
is treated as a GObject and kept 'alive' for the duration of the call.

'gail' is a good place to look for g_signal_connect examples, I think,
since Padraig will be able to answer specific questions about the hows
and whys.

Padraig, do you have a simple example handy?           

Draghi: note that different GSignals carry with them different parameter
lists, which are defined when the signal is defined, so different signal
handlers will (despite the fact that GCallback is defined as
(*func)(void)) need to have different signatures; keep this in mind when
copying an example.

Once you've done it, it doesn't seem so bad, but the docs are a bit
thin.  If you have the old gtk+-1.2 book by Havoc Pennington, you can
read the GtkSignals section; 1.2-version GTK signals were the
predecessors to the 2.0 GObject signals, and the book is a bit more
verbose than the API docs at the moment.

best regards,

Bill

> Thanx,
> Draghi
-- 
Bill Haneman <bill haneman sun com>




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]