ASPN ActiveState Programmer Network
ActiveState
/ Home / Perl / PHP / Python / Tcl / XSLT /
/ Safari / My ASPN /
Cookbooks | Documentation | Mailing Lists | Modules | News Feeds | Products | User Groups


Recent Messages
List Archives
About the List
List Leaders
Subscription Options

View Subscriptions
Help

View by Topic
ActiveState
.NET Framework
Open Source
Perl
PHP
Python
Tcl
Web Services
XML & XSLT

View by Category
Database
General
SOAP
System Administration
Tools
User Interfaces
Web Programming
XML Programming


MyASPN >> Mail Archive >> php-gtk-dev
php-gtk-dev
Re: [PHP-GTK-DEV] Custom Signals Support
by Andrei Zmievski other posts by this author
Mar 8 2007 1:14PM messages near this date
Re: [PHP-GTK-DEV] Custom Signals Support | Re: [PHP-GTK-DEV] Custom Signals Support
Elizabeth,

Supporting custom signals will be quite a bit more involved than this. 
It'll probably be based on created a new class which will contain its 
signal descriptions and then registering it with GType system. If I 
have time this weekend I might work on that.. Unless we want to do beta 
release first.

-Andrei

On Mar 7, 2007, at 9:13 AM, Elizabeth Smith wrote:

>  I've been working on getting custom signal support written because I'd 
>  really like to use it in some work I'm doing.
> 
>  I have Gobject::signal_new implemented and working (also registered 
>  the signal run type constants).  I've attached the patch for it as 
>  well as a test script.  However, I've run into a few limitations with 
>  the implementation.
> 
>  First of all, signals are assigned globally for a gtype.  Right now 
>  php classes that extend a php-gtk gtype aren't creating their own 
>  gtype but just using their parents.  Why is this bad? Well if you 
>  extend gtkwindow and add a custom signal...the signal is added to 
>  gtkwindow (and by default also to your extended class) which may not 
>  be the intended behavior.  Now, it is possible to create new gtypes 
>  that extend a parent gtype so I know HOW to fix the problem, however I 
>  don't know WHERE that code needs to go.  Any suggestions?
> 
>  The second problem is I'd like to allow custom signals to be created 
>  using just a class name and not an object instance.  I can grab the 
>  zend_class_entry but right now the gtype is NOT stored in it.  You can 
>  get the class entry from the gtype...but not the other way around.  
>  Any suggestions for fixing that problem?
> 
>  Otherwise the patch allows custom signals.
> 
>  Index: phpg_gobject.c
>  ===================================================================
>  RCS file: /repository/php-gtk/main/phpg_gobject.c,v
>  retrieving revision 1.60
>  diff -u -r1.60 phpg_gobject.c
>  --- phpg_gobject.c	7 Dec 2006 07:14:20 -0000	1.60
>  +++ phpg_gobject.c	7 Mar 2007 16:12:36 -0000
>  @@ -886,6 +886,67 @@
>   }
>   /* }}} */
> 
>  +/* {{{ GObject::signal_new */
>  +static PHP_METHOD(GObject, signal_new)
>  +{
>  +	gchar *signal_name;
>  +	GType instance_type, *param_types = NULL, return_type = G_TYPE_NONE;
>  +    GSignalFlags signal_flags;
>  +	zval *callback, *extra, *instance, **item;
>  +	guint signal_id;
>  +	zend_class_entry *ce = NULL;
>  +	int n_params = 0, i;
>  +
>  +	if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), 5, &extra, "sViVi", 
>  &signal_name, &instance, &signal_flags, &callback, &return_type))
>  +        return;
>  +
>  +	if (Z_TYPE_P(instance) == IS_OBJECT) {
>  +		instance_type = phpg_gtype_from_zval(instance);
>  +	} else if (Z_TYPE_P(instance) == IS_STRING) {
>  +		zend_class_entry **pce;
>  +		if (zend_lookup_class(Z_STRVAL_P(instance), Z_STRLEN_P(instance), 
>  &pce TSRMLS_CC) == SUCCESS) {
>  +			ce = *pce;
>  +		}
>  +		php_printf("TODO: use zend_class_entry to grab ce->gtype?");
>  +		
>  +	}
>  +	if (!instance_type)
>  +		return;
>  +
>  +	if(extra)
>  +	{
>  +		n_params = zend_hash_num_elements(Z_ARRVAL_P(extra));
>  +
>  +		if (n_params > 0) {
>  +			param_types = safe_emalloc(n_params, sizeof(GType), 0);
>  +			for (i = 0, zend_hash_internal_pointer_reset(Z_ARRVAL_P(extra));
>  +				 zend_hash_get_current_data(Z_ARRVAL_P(extra), (void**)&item) == 
>  SUCCESS;
>  +				 zend_hash_move_forward(Z_ARRVAL_P(extra)), i++) {
>  +
>  +				param_types[i] = phpg_gtype_from_zval(*item);
>  +				if (param_types[i] == 0) {
>  +					efree(param_types);
>  +					php_error(E_WARNING, "could not set types for signal callback");
>  +					return;
>  +				}
>  +			}
>  +		}
>  +	}
>  +
>  +	signal_id = g_signal_newv(signal_name, instance_type, signal_flags,
>  +			      phpg_closure_new(callback, extra, PHPG_CONNECT_SIMPLE, NULL 
>  TSRMLS_CC),
>  +			      (GSignalAccumulator)0, NULL,
>  +			      (GSignalCMarshaller)0,
>  +			      return_type, n_params, param_types);
>  +
>  +	efree(param_types);
>  +	if (signal_id != 0)
>  +	RETURN_LONG(signal_id);
>  +	php_error(E_WARNING, "Unable to create signal");
>  +    return;
>  +	
>  +}
>  +/* }}} */
> 
>   /* {{{ GObject reflection info */
>   static
>  @@ -989,6 +1050,17 @@
>   ZEND_END_ARG_INFO();
> 
>   static
>  +ZEND_BEGIN_ARG_INFO_EX(arginfo_gobject_signal_new, 0, 0, 5)
>  +    ZEND_ARG_INFO(0, signal)
>  +    ZEND_ARG_INFO(0, instance)
>  +    ZEND_ARG_INFO(0, flags)
>  +    ZEND_ARG_INFO(0, callback)
>  +    ZEND_ARG_INFO(0, return_gtype)
>  +    ZEND_ARG_INFO(0, user_data)
>  +    ZEND_ARG_INFO(0, ...)
>  +ZEND_END_ARG_INFO();
>  +
>  +static
>   ZEND_BEGIN_ARG_INFO(arginfo_gobject_unblock, 0)
>       ZEND_ARG_INFO(0, handler_id)
>   ZEND_END_ARG_INFO();
>  @@ -1023,6 +1095,7 @@
>       PHP_ME(GObject, is_connected,         
>  arginfo_gobject_is_connected          , ZEND_ACC_PUBLIC)
>       PHP_ME(GObject, signal_query,         
>  arginfo_gobject_signal_query          , 
>  ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
>       PHP_ME(GObject, stop_emission,        
>  arginfo_gobject_stop_emission         , ZEND_ACC_PUBLIC)
>  +	PHP_ME(GObject, signal_new,			  arginfo_gobject_signal_new           
>   , ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
>       PHP_ME(GObject, signal_list_ids,      
>  arginfo_gobject_signal_list_ids       , 
>  ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
>       PHP_ME(GObject, signal_list_names,    
>  arginfo_gobject_signal_list_names     , 
>  ZEND_ACC_PUBLIC|ZEND_ACC_STATIC)
>       PHP_MALIAS(GObject, emit_stop_by_name, stop_emission, 
>  arginfo_gobject_stop_emission, ZEND_ACC_PUBLIC)
>  @@ -1055,8 +1128,15 @@
> 
>       gobject_ce = phpg_register_class("GObject", gobject_methods, 
>  NULL, 0, gobject_props_info, NULL, G_TYPE_OBJECT TSRMLS_CC);
>       phpg_register_int_constant(gobject_ce, "gtype", 
>  sizeof("gtype")-1, G_TYPE_OBJECT);
>  +	phpg_register_int_constant(gobject_ce, "SIGNAL_RUN_FIRST", 
>  sizeof("SIGNAL_RUN_FIRST")-1, G_SIGNAL_RUN_FIRST);
>  +    phpg_register_int_constant(gobject_ce, "SIGNAL_RUN_LAST", 
>  sizeof("SIGNAL_RUN_LAST")-1, G_SIGNAL_RUN_LAST);
>  +    phpg_register_int_constant(gobject_ce, "SIGNAL_RUN_CLEANUP", 
>  sizeof("SIGNAL_RUN_CLEANUP")-1, G_SIGNAL_RUN_CLEANUP);
>  +    phpg_register_int_constant(gobject_ce, "SIGNAL_NO_RECURSE", 
>  sizeof("SIGNAL_NO_RECURSE")-1, G_SIGNAL_NO_RECURSE);
>  +    phpg_register_int_constant(gobject_ce, "SIGNAL_DETAILED", 
>  sizeof("SIGNAL_DETAILED")-1, G_SIGNAL_DETAILED);
>  +    phpg_register_int_constant(gobject_ce, "SIGNAL_ACTION", 
>  sizeof("SIGNAL_ACTION")-1, G_SIGNAL_ACTION);
>  +    phpg_register_int_constant(gobject_ce, "SIGNAL_NO_HOOKS", 
>  sizeof("SIGNAL_NO_HOOKS")-1, G_SIGNAL_NO_HOOKS);
>   }
> 
>   #endif /* HAVE_PHP_GTK */
> 
>  -/* vim: set fdm=marker et sts=4: */
>  +/* vim: set fdm=marker et sts=4: */
>  \ No newline at end of file
>  <?php
>  function dome()
>  {
>  	echo "custom signal ahoy\n";
>  	return TRUE;
>  }
>  function do_mysignal()
>  {
>  	echo "this is always called on my-signal\n";
>  }
>  function do_goosignal($widget, $arg)
>  {
>  	echo "$widget\n$arg\n";
>  	return TRUE;
>  }
> 
>  class Mywindow extends GtkWindow{}
>  $widget = new Mywindow();
>  $arg1 = 'cat';
>  GObject::signal_new('my-signal', $widget, GObject::SIGNAL_RUN_LAST, 
>  'do_mysignal', Gtk::TYPE_NONE);
>  GObject::signal_new('goo-signal', $widget, GObject::SIGNAL_RUN_LAST, 
>  'do_goosignal_full', Gtk::TYPE_BOOLEAN, $widget, $arg1);
>  print_r(GObject::signal_list_names(GtkWindow::gtype));
>  $widget->connect_simple('destroy', array('Gtk', 'main_quit'));
>  $widget->connect_simple('my-signal', 'dome');
>  $widget->connect_simple('goo-signal', 'dome');
>  $widget->show_all();
>  $widget->emit('my-signal');
>  $widget->emit('goo-signal');
>  Gtk::main();
>  ?>
>  -- 
>  PHP-GTK Development Mailing List (http://gtk.php.net/)
>  To unsubscribe, visit: http://www.php.net/unsub.php

-- 
PHP-GTK Development Mailing List (http://gtk.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php
Thread:
Elizabeth Smith
Andrei Zmievski
Steph Fox
Andrei Zmievski
Elizabeth Smith

Privacy Policy | Email Opt-out | Feedback | Syndication
© ActiveState Software Inc. All rights reserved