/* $Id: gtk--sig.h,v 1.16 1998/11/14 19:31:28 terop Exp $ */
/* GTK-- - a C++ wrapper for the Gtk toolkit
 *
 * The signal system used by gtk--
 * 
 * Copyright (C) 1997 Elliot Lee <sopwith@redhat.com>      
 *                    Phil Dawes
 *                    Tero Pulkkinen
 *
 * Currently maintained by Tero Pulkkinen. <terop@modeemi.cs.tut.fi>
 *                                                        
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */


/* You can define GTKMM_SIGNALS_WITHOUT_GTK and include gtk--sig.h to
   use the signal system without gtk/gtk--. You still need the gtk--sig*.h
   files generated from .m4 files to use it. */


/*
  Some documentation on usage of signals:
  
  Each gtk's signal is represented in the class hierarchy with a function
  object of the signal's name. (cept in pathetic cases like Gtk_Entry, where
  signal's name is C++'s reserved word "delete", where C++'s signal's name
  was changed to deleted.) This function object provides way to emit
  signal by calling it and handles that connection can be made between it
  and other static and member functions.
  If you get compiler errors while trying to use it, there most probably is
  something wrong with your signal's argument types - check this header
  file for exact types needed. (g++ will give you type unification failed
  for Signal_proxy0<> -template, if you have bad args)
  
  class mywidget 
     : public Gtk_Object { // can be any of the gtk--'s classes
  public:
     Signal2<int,float> outputsignal; 
       // this widget will do outputsignal(10,50.2)
       // and outside people can use the signal in connect
       // to trap the call
       // 1 == number of arguments
       // <int,float> == types of arguments
  private:
     void foo() { outputsignal(10,50.2); } // calls a signal
  };

  class myclass 
   : public virtual Gtk_Signal_Base 
   // this implements some functions that signal
   // system calls - Gtk_Object already does this derivation, so
   // if you have Gtk_Object derived to this class already, no need to do 
   // the derivation
   //
   // note, this is virtual derivation, but Gtk_Object is not derived 
   // virtually!
  { 
  public:
     // after this, you can connect signals to this method
     void fooimpl(int a, float f) { 
       // use a and f here
     }
  };
  
  (on headerfiles, you might find Signal_proxyN-objects, they are the same
   as SignalN, but are used for interfacing with C language widgets)

  connections can be created like this:

   mywidget w;
   myclass c;
   void static_function(int a, float b);
   // we specify here the signal, receiving object and function inside 
   // receiving object
   connect_to_method(w.outputsignal, &c, &myclass::fooimpl); // connect to member function
   connect_to_function(w.outputsignal, &static_function);      // connect to static function

   Connection cc=connect_to_method(w.outputsignal, &c, &myclass::fooimpl);
   ..
   cc.disconnect(); // we can also disconnect signals at runtime when
                    // needed - If Connection-object is copied, the old
                    // one loses its ability to disconnect -- i.e. works like
                    // auto_ptr.

 */

/*
  Some implementation documentation about how we deal with existing C widgets:
  * Each C widget has its signals represented in 4 parts:
        (we'll handle Gtk_Object::destroy as example)
     1) function object handling connections and emitting the signal
          Signal_proxy0<void,Gtk_Object> destroy;
     2) *_impl -virtual method for trapping the calls to existing C
        implementation of the signal
          virtual void destroy_impl();
     3) a static method as an replacement of gtk_real_object_destroy,
        which figures out from first arg about which C++ object we have
        and calls the *_impl method on that object
          static void destroy_callback(GtkObject *o);
     4) A structure (c_signals) keeping all old function pointers
     5) c_class static object keeping all per-class data/methods needed,
        for example the signals are kept there.

     * Calling Gtk_Object::destroy starts the following
       function calls:
       * Gtk_Object::destroy()    (called by user)
        * gtk_object_destroy(o)   (see  NOTE1 below)
	* Gtk_Object::destroy_callback(o) (see NOTE2 below)  
        * Gtk_Object::destroy_impl()
        * gtk_real_object_destroy(o) (see NOTE3 below)

      And this way, by overriding the destroy_impl function does work
      as supposed.

  NOTE1: that isnt done correctly currently (13 Dec 97), now it calls 
         gtk_signal_emit instead and works in most cases, not all.
  NOTE2: Gtk does call this, because we did set the value of the virtual 
         function table pointing to Gtk_Object::destroy_callback
  NOTE3: We have stored old pointer from the virtual function table to
         an instance of C class and that points to gtk_real_object_destroy(o) 
         and we can thus call it from Gtk_Object::destroy_impl
  */


#ifndef GTK_MINUS_MINUS_SIG_H
#define GTK_MINUS_MINUS_SIG_H 1


/*********************************************************/

class Gtk_Object;

/***********************************************************************/

/* Gtk_Signal_Base was separated from Gtk_Object, because this way people
   can more freely use it as base for their own objects and thus adds
   less bloat for their own objects that want to receive signals.
*/
  

#include <gtk--sigcommon.h>
#include <gtk--sigconn.h>
#ifndef GTKMM_SIGNALS_WITHOUT_GTK
#include <gtk--sigproxy.h>
#endif
#include <gtk--sigslot.h>
#include <gtk--sigcpp.h>

/*

  Static initialization requires this hack (got about from iostream)  

 */

/*
class static_init_for_gtkmm {
public:
    static_init_for_gtkmm();
};

static static_init_for_gtkmm static_init_for_gtkmm_c;
*/

#endif

   


/**************** end of Tero's signal stuffs ************/

