hook functions (Re: Sound events in Gtk)



On 23 Aug 1998, Owen Taylor wrote:

> 
> "yiyus" <jg_yiyus@jet.es> writes:
> 
> > Hello,
> > I am trying to put some sound events in Gtk, in
> > the same way which enlightenment does it. I had a
> > Gtk+ 1.0.4 working with some E code where buttons
> > played .wav where they where pressed. Now, I have
> > to remove the E stuff from some files to make it
> > only for Gtk. My question is, which is the best
> > place to put the function which play sounds?
> > (please give me file and function name, since I
> > don't know very well Gtk, thank you).
> > And I would like to know your opinion about this
> > (if you like to have sound, etc). Think it would
> > be implemented as in enlightenment, the sound:
> > - use ESD.
> > - is an option at compile time.
> > - is an option at run time.
> 
> The slick and clean way to do it (I should credit Raster for 
> the basic concept), is to add a single function to GTK+:
> 
>  gtk_signal_snooper_install (GtkSignalSnooperFunc snooper,
> 	                     gpointer             func_data);
> 
> if there are snooper's installed, they get called on
> every signal emission.

hm, you omitted the prototype and exact semantics.
there are some things that need to be thought out first.
invoking a snooper function for all signal emissions would be pretty
expensive so the signal id (or name) pluss associated class should
at least be specified. also, will a snooper be invoked if an emission
is stopped?
i'm not sure i like the snooper name, currently we have
gtk_key_snooper_install() which can optionally intercept the
processing of a key event. this is not needed for sounds, and could
even be dangerous for signal emissions (especially on widgets) in general.
i'd rather have something like

typedef void (*GtkSignalHook) (GtkObject *object,
                               guint      signal_id,
                               gpointer   data);

guint gtk_signal_add_emission_hook (GtkObjectClass *class,
                                    guint           signal_id,
                                    GtkSignalHook   func,
                                    gpointer        data);
guint gtk_signal_remove_hook (guint  hook_id);

the GtkSignalHook function will then be executed for signals !=destroy
after a normal emission has finished, and has not been stopped.
the reason i'm trying to be overly carefull here is, that people
will soon find other applications for signal hooks, and things like
intercepting, overriding of return values and stopping of emissions
is probably not something generally affordable. maybe we shouldn't even
supply the object pointer itself to the hook...
the reason i'm requiring gtk_signal_add_emission_hook() to provide
the class pointer itself is because pattern match attempts for very
signal emission would be too expensive and slow things down like hell.
i do recognize though, that a dynamic module couldn't know every class
type in advance, especially if it uses class patterns in its rc-file.
this will also be an issue when we implement object args in rc-files someday.
a possible solution to this (maybe the only one) is adding class-creation
hooks to the type system and a callback that will iterate over all existing
class instances, e.g.

typedef void (*GtkTypeClassHook) (GtkObjectClass *class,
                                  gpointer        data);
guint gtk_type_add_class_hook (GtkTypeClassHook func,
                               gpointer         data);
void  gtk_type_remove_class_hook (guint         id);

void  gtk_type_foreach_class (GtkType          base_type,
                              GtkTypeClassHook func,
                              gpointer         data);
                              
such a GtkTypeClassHook func would then install signal hooks
if one of its patterns matches the current class.

on a related issue, currently gtktype.c internaly implements
limited knowledge about classes in general (in practice, it
assumes that all classes have a GtkType type; identifier as
first structure memeber). since someday, we may want to derive
types from somethign else than GtkObjectClass, a GtkTypeClassHook
should probably better look like:

typedef struct _GtkTypeBaseClass GtkTypeBaseClass;
struct GtkTypeBaseClass
{
  /* This structure needs to be kept in sync with other
   * class structures, e.g. GtkObjectClass.
   */
   
  /* The type identifier for the type's class. There is
   * one unique identifier per class. The base type can
   * be retrived with GTK_FUNDAMENTAL_TYPE (class->type).
   */
  GtkType type;
};

typedef void (*GtkTypeClassHook) (GtkTypeBaseClass *class,
                                  gpointer          data);

inside a GtkTypeClassHook func, *class can be casted to
for instance a GtkObjectClass or GtkButtonClass, if
gtk_type_is_a (class->type, GTK_TYPE_OBJECT [or GTK_TYPE_BUTTON,
respectively]); returns TRUE.


> Then, you write your sound code in a dynamically loaded
> module (a recent addition to GTK+, not in a released
> version yet, but will be soon), and when your module
> is initialized it adds a signal snooper, and parses
> a configuration file like:
> 
>  "GtkWidget" "button-press-event" "my-mouse-isnt-load-enough.au"
>  "GtkMenu"   "show"               "scraping-noise.au"
> 
> Then, on each signal, it does a lookup of against the
> configuration file, and if it finds a matching sound,
> plays it. There will be some performance penalty
> when running with sound enabled, but it shouldn't be that
> bad if you are clever enough about doing the lookups.
> 
> The user configures all GTK+ applications to use sound by
> adding a line like:
>  
>  module "gtk-esound"
> 
> to their gtkrc.
> 
> > And I would like to know where I can obtain the
> > latest Gtk via ftp (I can't use CVS, since I don't
> > have modem in my Linux box).
> 
> Releases of the 1.1 development branch are now
> available on ftp://ftp.gtk.org.
> 
> Regards,
>                                         Owen
> 
> 

---
ciaoTJ



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