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(>k_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(¶ms);
+}
+
+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--