cvs: php-gtk /ext/gtk+ gtk.overrides /main php_gtk_object.c /test gtk.php

[email protected] ("Andrei Zmievski") Sat, 18 Aug 2001 05:49:34 -0000
Newsgroups php.gtk
Message-ID <cvsandrei998113774@cvsserver>
--andrei998113774
Content-Type: text/plain

andrei		Sat Aug 18 01:49:34 2001 EDT

  Modified files:              
    /php-gtk/ext/gtk+	gtk.overrides 
    /php-gtk/main	php_gtk_object.c 
    /php-gtk/test	gtk.php 
  Log:
  
  - Fixed callbacks bug that would not invoke a callback if it took a parameter
    by reference.
  - Changed "GTK_TYPE_POINTER not supported" from warning to notice and made it
    return NULL instead of aborting.
  - Integrated a patch from Markus that implements functions
    signal_(add|remove)_emission_hook(), signal_lookup(), signal_name() and adds
    a few more examples to gtk.php.
  
  
  
--andrei998113774
Content-Type: text/plain
Content-Disposition: attachment; filename="andrei-20010818014934.txt"

Index: php-gtk/ext/gtk+/gtk.overrides
diff -u php-gtk/ext/gtk+/gtk.overrides:1.12 php-gtk/ext/gtk+/gtk.overrides:1.13
--- php-gtk/ext/gtk+/gtk.overrides:1.12	Wed Aug 15 13:05:15 2001
+++ php-gtk/ext/gtk+/gtk.overrides	Sat Aug 18 01:49:33 2001
@@ -9,7 +9,6 @@
 	gtk_arg_*
 	gtk_args_*
 	gtk_signal_connect*
-	gtk_signal_add_emission_hook*
 	gtk_signal_new*
 	gtk_init_add_*
 	gtk_quit_add_*
@@ -43,8 +42,8 @@
 	gtk_accel_group_create_remove
 	gtk_accel_groups_from_object
 	gtk_accel_group_entries_from_object
+	gtk_signal_add_emission_hook_full
 	gtk_signal_set_funcs
-	gtk_signal_lookup
 	gtk_signal_disconnect_by_func
 	gtk_signal_disconnect_by_data
 	gtk_signal_handler_block_by_func
@@ -54,8 +53,6 @@
 	gtk_signal_handler_pending_by_func
 	gtk_signal_n_emissions
 	gtk_signal_n_emissions_by_name
-	gtk_signal_name
-	gtk_signal_remove_emission_hook
 	gtk_signal_query
 	gtk_signal_emit
 	gtk_signal_emit_by_name
@@ -297,6 +294,103 @@
 								 data, php_gtk_destroy_notify));
 }
 %%
+override gtk_signal_add_emission_hook
+
+static void php_gtk_emission_hook_marshal(GtkObject *o, guint signal_id, guint nargs, GtkArg *args, gpointer data)
+{
+	zval *callback_data = (zval *)data;
+	zval *gtk_args;
+	zval **callback, **extra = NULL;
+	zval **callback_filename = NULL, **callback_fileno = NULL;
+	zval ***hook_args;
+	zval *wrapper = NULL;
+	zval *params;
+	zval *retval = NULL;
+	char *callback_name;
+	TSRMLS_FETCH();
+
+	/* Callback is always passed as the first element. */
+	zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void**)&callback);
+
+	/* Extra parametrers are always passed as the second element. */
+	zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void**)&extra);
+
+	/* Third and fourth parameter are always filename and the line number where
+	 * the callback was specified. */
+	zend_hash_index_find(Z_ARRVAL_P(callback_data), 2, (void**)&callback_filename);
+	zend_hash_index_find(Z_ARRVAL_P(callback_data), 3, (void**)&callback_fileno);
+
+	if (!php_gtk_is_callable(*callback, 0, &callback_name)) {
+		php_error(E_WARNING, "Unable to call emission hook '%s' specified in %s on line %d", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_fileno));
+		efree(callback_name);
+		return;
+	}
+
+	wrapper = php_gtk_new(o);
+
+	/* Prepare the parameters to be passed to the user function. */
+	MAKE_STD_ZVAL(params);
+	array_init(params);
+	/* Pass the object which emitted the signal as first parameer. */
+	add_next_index_zval(params, wrapper);
+	/* Pass the signal id as second parameter. */
+	add_next_index_long(params, signal_id);
+
+	gtk_args = php_gtk_args_as_hash(nargs, args);
+	php_array_merge(Z_ARRVAL_P(params), Z_ARRVAL_P(gtk_args), 0);
+
+	zval_ptr_dtor(&gtk_args);
+
+	/*
+	 * If there are extra arguments specified by user, add them to the parameter
+	 * array.
+	 */
+	if (extra)
+		php_array_merge(Z_ARRVAL_P(params), Z_ARRVAL_PP(extra), 0);
+	
+	hook_args = php_gtk_hash_as_array(params);
+
+	call_user_function_ex(EG(function_table), NULL, *callback, &retval,
+						  zend_hash_num_elements(Z_ARRVAL_P(params)), hook_args,
+						  0, NULL TSRMLS_CC);
+	
+	if (retval) {
+		if (args)
+			php_gtk_ret_from_value(&args[nargs], retval);
+		zval_ptr_dtor(&retval);
+	}
+
+	efree(hook_args);
+	zval_ptr_dtor(&params);
+}
+
+PHP_FUNCTION(gtk_signal_add_emission_hook)
+{
+	guint signal_id;
+	zval  *callback;
+	char  *callback_filename;
+	uint  callback_lineno;
+	zval  *extra;
+	zval  *data;
+
+	if (ZEND_NUM_ARGS() < 2) {
+		php_error(E_WARNING, "%s() requires at least 2 arguments, %d given",
+				  get_active_function_name(TSRMLS_C), ZEND_NUM_ARGS());
+		return;
+	}
+
+	if (!php_gtk_parse_args(2, "iV", &signal_id, &callback))
+		return;
+	
+	callback_filename = zend_get_executed_filename(TSRMLS_C);
+	callback_lineno   = zend_get_executed_lineno(TSRMLS_C);
+	extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 2, ZEND_NUM_ARGS());
+	data  = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno);
+	RETURN_LONG(gtk_signal_add_emission_hook_full(signal_id,
+												  (GtkEmissionHook)php_gtk_emission_hook_marshal,
+												  data, php_gtk_destroy_notify));
+}
+%%
 override gtk_signal_connect
 static void gtk_signal_connect_impl(INTERNAL_FUNCTION_PARAMETERS, int pass_object, int after)
 {
@@ -1260,7 +1354,7 @@
 
 	args = php_gtk_hash_as_array(params);
 
-	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), args, 1, NULL TSRMLS_CC);
+	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), args, 0, NULL TSRMLS_CC);
 	if (retval)
 		zval_ptr_dtor(&retval);
 	efree(args);
@@ -1426,7 +1520,7 @@
 
 	args = php_gtk_hash_as_array(params);
 
-	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), args, 1, NULL TSRMLS_CC);
+	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), args, 0, NULL TSRMLS_CC);
 	if (retval)
 		zval_ptr_dtor(&retval);
 	efree(args);
@@ -2001,7 +2095,7 @@
 	params = php_gtk_build_value("(Nii)", php_gtk_new(GTK_OBJECT(menu)), *x, *y);
 	args = php_gtk_hash_as_array(params);
 
-	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), args, 1, NULL TSRMLS_CC);
+	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), args, 0, NULL TSRMLS_CC);
 
 	if (retval) {
 		if (Z_TYPE_P(retval) == IS_ARRAY &&
Index: php-gtk/main/php_gtk_object.c
diff -u php-gtk/main/php_gtk_object.c:1.45 php-gtk/main/php_gtk_object.c:1.46
--- php-gtk/main/php_gtk_object.c:1.45	Mon Aug  6 13:08:11 2001
+++ php-gtk/main/php_gtk_object.c	Sat Aug 18 01:49:34 2001
@@ -18,7 +18,7 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
-/* $Id: php_gtk_object.c,v 1.45 2001/08/06 17:08:11 fmk Exp $ */
+/* $Id: php_gtk_object.c,v 1.46 2001/08/18 05:49:34 andrei Exp $ */
 
 #include "php_gtk.h"
 
@@ -218,7 +218,7 @@
 	
 	signal_args = php_gtk_hash_as_array(params);
 
-	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), signal_args, 1, NULL TSRMLS_CC);
+	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), signal_args, 0, NULL TSRMLS_CC);
 
 	if (retval) {
 		if (args)
@@ -256,7 +256,7 @@
 	handler_args = php_gtk_hash_as_array(*extra);
 	num_handler_args = zend_hash_num_elements(Z_ARRVAL_PP(extra));
 
-	call_user_function_ex(EG(function_table), NULL, *callback, &retval, num_handler_args, handler_args, 1, NULL TSRMLS_CC);
+	call_user_function_ex(EG(function_table), NULL, *callback, &retval, num_handler_args, handler_args, 0, NULL TSRMLS_CC);
 
 	*GTK_RETLOC_BOOL(args[0]) = FALSE;
 	if (retval) {
@@ -297,7 +297,7 @@
 		php_array_merge(Z_ARRVAL_P(params), Z_ARRVAL_PP(extra), 0);
 	input_args = php_gtk_hash_as_array(params);
 
-	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), input_args, 1, NULL TSRMLS_CC);
+	call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), input_args, 0, NULL TSRMLS_CC);
 	if (retval)
 		zval_ptr_dtor(&retval);
 	efree(input_args);
@@ -510,9 +510,11 @@
 			break;
 
 		case GTK_TYPE_POINTER:
-			php_error(E_WARNING, "%s(): internal error: GTK_TYPE_POINTER unsupported",
+			php_error(E_NOTICE, "%s(): internal error: GTK_TYPE_POINTER unsupported",
 					  get_active_function_name(TSRMLS_C));
-			return NULL;
+			MAKE_STD_ZVAL(value);
+			ZVAL_NULL(value);
+			break;
 
 		case GTK_TYPE_BOXED:
 			if (arg->type == GTK_TYPE_GDK_EVENT)
@@ -801,9 +803,11 @@
 			break;
 
 		case GTK_TYPE_POINTER:
-			php_error(E_WARNING, "%s(): internal error: GTK_TYPE_POINTER unsupported",
+			php_error(E_NOTICE, "%s(): internal error: GTK_TYPE_POINTER unsupported",
 					  get_active_function_name(TSRMLS_C));
-			return NULL;
+			MAKE_STD_ZVAL(value);
+			ZVAL_NULL(value);
+			break;
 
 		case GTK_TYPE_BOXED:
 			if (ret->type == GTK_TYPE_GDK_EVENT)
Index: php-gtk/test/gtk.php
diff -u php-gtk/test/gtk.php:1.32 php-gtk/test/gtk.php:1.33
--- php-gtk/test/gtk.php:1.32	Wed Aug  8 16:49:09 2001
+++ php-gtk/test/gtk.php	Sat Aug 18 01:49:34 2001
@@ -1,5 +1,5 @@
 <?php
-/* $Id: gtk.php,v 1.32 2001/08/08 20:49:09 andrei Exp $ */
+/* $Id: gtk.php,v 1.33 2001/08/18 05:49:34 andrei Exp $ */
 
 if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN')
 	dl('php_gtk.dll');
@@ -1938,6 +1938,317 @@
 	$windows['entry']->show();
 }
 
+function toggle_resize($child)
+{
+	$paned = $child->parent;
+
+	$is_child1 = ($child == $paned->child1);
+
+	$resize = $is_child1 ? $paned->child1_resize : $paned->child2_resize;
+	$shrink = $is_child1 ? $paned->child1_shrink : $paned->child2_shrink;
+
+	$child->ref();
+
+	// Zend doesn't yet support overloaded method calls
+	$parent = $child->parent;
+	$parent->remove($child);
+
+	if ($is_child1)
+		$paned->pack1($child, !$resize, $shrink);
+	else
+		$paned->pack2($child, !$resize, $shrink);
+
+	$child->unref();
+}
+
+function toggle_shrink($child)
+{
+	$paned = $child->parent;
+	
+	$is_child1 = ($child == $paned->child1);
+
+	$resize = $is_child1 ? $paned->child1_resize : $paned->child2_resize;
+	$shrink = $is_child1 ? $paned->child1_shrink : $paned->child2_shrink;
+
+	$child->ref();
+
+	// Zend doesn't yet support overloaded method calls
+	$parent = $child->parent;
+	$parent->remove($child);
+
+	if ($is_child1)
+		$paned->pack1($child, $resize, !$shrink);
+	else
+		$paned->pack2($child, $resize, !$shrink);
+
+	$child->unref();
+}
+
+function create_pane_options($paned, $frame_label, $label1, $label2)
+{
+	$frame = &new GtkFrame($frame_label);
+	$frame->set_border_width(0);
+
+	$table = &new GtkTable(3, 2, true);
+	$frame->add($table);
+
+	$label = &new GtkLabel($label1);
+	$table->attach_defaults($label, 0, 1, 0, 1);
+
+	$check_button = &new GtkCheckButton('Resize');
+	$table->attach_defaults($check_button, 0, 1, 1, 2);
+	$check_button->connect_object('toggled', 'toggle_resize', $paned->child1);
+
+	$check_button = &new GtkCheckButton('Shrink');
+	$table->attach_defaults($check_button, 0, 1, 2, 3);
+	$check_button->set_active( true);
+	$check_button->connect_object('toggled', 'toggle_shrink', $paned->child1);
+
+	$label = &new GtkLabel($label2);
+	$table->attach_defaults($label,1,2,0,1);
+
+	$check_button = &new GtkCheckButton('Resize');
+	$table->attach_defaults($check_button, 1, 2, 1, 2);
+	$check_button->set_active( true);
+	$check_button->connect_object('toggled', 'toggle_resize', $paned->child2);
+
+	$check_button = &new GtkCheckButton('Shrink');
+	$table->attach_defaults($check_button, 1, 2, 2, 3);
+	$check_button->set_active( true);
+	$check_button->connect_object('toggled', 'toggle_shrink', $paned->child2);
+
+	return $frame;
+}
+
+function create_panes()
+{
+	global $windows;
+
+	if (!isset($windows['panes'])) {
+		$window = &new GtkWindow;
+		$windows['panes'] = $window;
+		$window->connect('delete_event', 'delete_event');
+		$window->set_title('GtkPane');
+
+		$vbox = &new GtkVBox;
+		$window->add( $vbox);
+
+		$vpaned = &new GtkVPaned;
+		$vbox->pack_start($vpaned, true, true, 0);
+		$vpaned->set_border_width( 5);
+
+		$hpaned = &new GtkHPaned;
+		$vpaned->add1($hpaned);
+
+		$frame = &new GtkFrame;
+		$frame->set_shadow_type(GTK_SHADOW_IN);
+		$frame->set_usize(60, 60);
+		$hpaned->add1($frame);
+
+		$button = &new GtkButton('Hi there');
+		$frame->add($button);
+
+		$frame = &new GtkFrame;
+		$frame->set_shadow_type(GTK_SHADOW_IN);
+		$frame->set_usize(80, 60);
+		$hpaned->add2($frame);
+
+		$frame = &new GtkFrame;
+		$frame->set_shadow_type(GTK_SHADOW_IN);
+		$frame->set_usize(60, 80);
+		$vpaned->add2($frame);
+
+		$vbox->pack_start(
+			create_pane_options(
+				$hpaned,
+				'Horizontal',
+				'Left',
+				'Right'),
+			false, false, 0);
+
+		$vbox->pack_start(
+			create_pane_options(
+				$vpaned,
+				'Vertical',
+				'Top',
+				'Bottom'),
+			false, false, 0);
+
+		$separator = &new GtkHSeparator();
+		$vbox->pack_start($separator, false);
+
+		$button = &new GtkButton('Close');
+		$button->connect('clicked', 'close_window');
+		$vbox->pack_start($button);
+		$button->set_flags(GTK_CAN_DEFAULT);
+		$button->grab_default();
+		$button->show();
+	}
+	$windows['panes']->show_all();
+}
+
+function create_file_selection()
+{
+	static $window;
+
+	if (!$window)
+	{
+		function file_selection_ok($button, $fs)
+		{
+			print "selected '" . $fs->get_filename() . "'\n";
+			$fs->destroy();
+		}
+
+		$window = new GtkFileSelection('File selection dialog');
+		$window->hide_fileop_buttons();
+		$window->set_position(GTK_WIN_POS_MOUSE);
+		$window->connect_object('destroy',create_function('&$w','$w=null;'), $window);
+
+		$button_ok = $window->ok_button;
+		$button_ok->connect('clicked','file_selection_ok', $window);
+
+		$button_cancel = $window->cancel_button;
+		$button_cancel->connect_object('clicked', array(&$window, 'destroy'));
+
+		$action_area = $window->action_area;
+
+		$button = &new GtkButton('Hide Fileops');
+		$button->connect_object('clicked', create_function('$w', '$w->hide_fileop_buttons();'), $window);
+		$action_area->pack_start($button, false, false, 0);
+		$button->show();
+
+		$button = &new GtkButton('Show Fileops');
+		$button->connect_object('clicked', create_function('$w', '$w->show_fileop_buttons();'), $window);
+		$action_area->pack_start($button, false, false, 0);
+		$button->show();
+	}
+
+	if (!($window->flags() & GTK_VISIBLE))
+		$window->show_all();
+	else 
+		$window->destroy();
+}
+
+function label_toggle( $dialog, $label, $dialog)
+{
+	if (!$label)
+	{
+		$label = new GtkLabel('Dialog Test');
+		$label->set_padding(10, 10);
+		$label->connect_object('destroy', create_function('$w', '$w=null;'), &$label);
+		$vbox = $dialog->vbox;
+		$vbox->pack_start($label, true, true, 0);
+		$label->show();
+	} else
+		$label->destroy();
+}
+
+function create_dialog()
+{
+	static $dialog = null;
+	static $label = null;
+
+	if (!$dialog)
+	{
+		$dialog = new GtkDialog;
+		$dialog->set_title('GtkDialog');
+		$dialog->set_border_width(0);
+		$dialog->set_usize(200,110);
+		$dialog->connect_object('destroy', create_function('$w', '$w = null;'), &$dialog);
+
+		$button = &new GtkButton('Ok');
+		$button->set_flags(GTK_CAN_DEFAULT);
+		$button->connect( 'clicked', 'close_window');
+
+		$action_area = $dialog->action_area;
+		$action_area->pack_start($button, true, true, 0);
+		$button->grab_default();
+		$button->show();
+
+		$button = &new GtkButton('Toggle');
+		$button->connect('clicked', 'label_toggle', &$label, $dialog);
+		$button->set_flags(GTK_CAN_DEFAULT);
+		$action_area->pack_start($button, true, true, 0);
+		$button->show();
+	}
+
+	if (!($dialog->flags() & GTK_VISIBLE))
+		$dialog->show();
+	else
+		$dialog->destroy();
+}
+
+function event_watcher( $object, $signal_id)
+{
+	echo 'Event watch: ' . gtk::signal_name( $signal_id) . ' emitted for ' . gtk::type_name( $object->get_type()) . "\n";
+	return true;
+}
+
+function event_watcher_toggle(&$event_watcher_enter_id, &$event_watcher_leave_id)
+{
+	var_dump($event_watcher_enter_id);
+	if ($event_watcher_enter_id)
+		event_watcher_down($event_watcher_enter_id, $event_watcher_leave_id);
+	else
+	{
+		$signal_id = Gtk::signal_lookup( 'enter_notify_event', GtkWidget::get_type());
+		$event_watcher_enter_id = gtk::signal_add_emission_hook( $signal_id, 'event_watcher');
+		$signal_id = Gtk::signal_lookup( 'leave_notify_event', GtkWidget::get_type());
+		$event_watcher_leave_id = gtk::signal_add_emission_hook( $signal_id, 'event_watcher');
+	}
+}
+
+function event_watcher_down(&$event_watcher_enter_id, &$event_watcher_leave_id)
+{
+	if ($event_watcher_enter_id)
+	{
+		$signal_id = Gtk::signal_lookup( 'enter_notify_event', GtkWidget::get_type());
+		gtk::signal_remove_emission_hook($signal_id, $event_watcher_enter_id);
+		$event_watcher_enter_id = 0;
+		$signal_id = Gtk::signal_lookup( 'leave_notify_event', GtkWidget::get_type());
+		gtk::signal_remove_emission_hook($signal_id, $event_watcher_leave_id);
+		$event_watcher_leave_id = 0;
+	}
+}
+		
+function create_event_watcher()
+{
+	static $dialog = null;
+	static $event_watcher_enter_id = 0;
+	static $event_watcher_leave_id = 0;
+
+	if (!$dialog)
+	{
+		$dialog = new GtkDialog;
+		$dialog->connect_object('delete_event','event_watcher_down', $event_watcher_enter_id, $event_watcher_leave_id);
+		$dialog->connect_object('delete_event', 'delete_event');
+		$dialog->set_title('Event Watcher');
+		$dialog->set_border_width(0);
+		$dialog->set_usize(200, 110);
+
+		$vbox = $dialog->vbox;
+		$action_area = $dialog->action_area;
+
+		$button = &new GtkToggleButton('Activate Watch');
+		$button->connect_object('clicked', 'event_watcher_toggle', $event_watcher_enter_id, $event_watcher_leave_id);
+		$button->set_border_width(10);
+		$vbox->pack_start($button);
+		$button->show();
+
+		$button = &new GtkButton('Close');
+		$button->connect_object('clicked', 'event_watcher_down', $event_watcher_enter_id, $event_watcher_leave_id);
+		$button->connect('clicked', 'close_window');
+		$button->set_flags(GTK_CAN_DEFAULT);
+		$action_area->pack_start($button);
+		$button->grab_default();
+		$button->show();
+	}
+
+	if (!($dialog->flags() & GTK_VISIBLE))
+		$dialog->show();
+	else
+		$dialog->destroy();
+}
 
 function create_main_window()
 {
@@ -1954,12 +2265,12 @@
 					 'color selection'	=> 'create_color_selection',
 					 'cursors'			=> 'create_cursor_test',
 					 'ctree'			=> 'create_ctree',
-					 'event watcher'	=> null,
+					 'event watcher'	=> 'create_event_watcher',
 					 'notebook'			=> null,
 					 'drawing area'		=> null,
-					 'file selection'	=> null,
-					 'dialog'			=> null,
-					 'panes'			=> null,
+					 'file selection'	=> 'create_file_selection',
+					 'dialog'			=> 'create_dialog',
+					 'panes'			=> 'create_panes',
 					 'pixmap'			=> 'create_pixmap',
 					 'drag\'n\'drop'	=> 'create_dnd',
 					);

--andrei998113774--