cvs: php-gtk /generator generator.php gtk.overrides /src php_gtk.h php_gtk_object.c /test gtk.php list.php
| From: | Andrei Zmievski | Date: | Wed, 07 Mar 2001 05:37:23 +0000 |
| Subject: | cvs: php-gtk /generator generator.php gtk.overrides /src php_gtk.h php_gtk_object.c /test gtk.php list.php | ||
| Groups: | php.gtk | ||
| Request: | Send a blank email to php-gtk+get-451@lists.php.net to get a copy of this message | ||
andrei Tue Mar 6 21:37:23 2001 EDT
Modified files:
/php-gtk/generator generator.php gtk.overrides
/php-gtk/src php_gtk.h php_gtk_object.c
/php-gtk/test gtk.php list.php
Log:
* Fixed function entry name generation.
* Added Gtk::true() and Gtk::false(). Yes, these are just what they look
like - functions that return true and false. Handy for certain callbacks.
* Fixed connect_object() semantics, it only requires two arguments now.
* Standardized all callback marshallers - callbacks are now smoother than
Jennifer Alba's bottom and they all take user supplied extra arguments.
* Moved callback validation right up to the call time, so that callbacks
included from other files could be used as well.
* This necessitated better error messages - so now if it the callback is
not valid, the filename and line number where it was specified are shown.
* Updated gtk.php and list.php to use connect_object() as an example.
Index: php-gtk/generator/generator.php diff -u php-gtk/generator/generator.php:1.12 php-gtk/generator/generator.php:1.13 --- php-gtk/generator/generator.php:1.12 Mon Mar 5 13:25:37 2001 +++ php-gtk/generator/generator.php Tue Mar 6 21:37:22 2001 @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: generator.php,v 1.12 2001/03/05 21:25:37 fmk Exp $ */ +/* $Id: generator.php,v 1.13 2001/03/07 05:37:22 andrei Exp $ */ /* * Significant portions of this generator are based on the pygtk code generator @@ -462,12 +462,10 @@ if ($this->overrides->is_overriden($function->c_name)) { list($function_name, $function_override) = $this->overrides->get_override($function->c_name); fwrite($fp, $function_override . "\n"); - if (!isset($function_name)) { - if ($function->name == $function->c_name) - $function_name = substr($function->name, 4); - else - $function_name = $function->name; - } + if ($function->name == $function->c_name) + $function_name = substr($function->name, 4); + else + $function_name = $function->name; $function_entry[substr($function->c_name, 0, 3)] .= sprintf($function_entry_tpl, strtolower($function_name), strtolower($function->c_name), Index: php-gtk/generator/gtk.overrides diff -u php-gtk/generator/gtk.overrides:1.25 php-gtk/generator/gtk.overrides:1.26 --- php-gtk/generator/gtk.overrides:1.25 Tue Mar 6 10:02:04 2001 +++ php-gtk/generator/gtk.overrides Tue Mar 6 21:37:22 2001 @@ -137,8 +137,6 @@ gtk_widget_newv %% ignore - gtk_true - gtk_false gtk_key_snooper_install gtk_key_snooper_remove gtk_get_current_event @@ -170,13 +168,28 @@ %% ignore-glob gtk_radio_button_new_* %% +override gtk_true +PHP_FUNCTION(wrap_gtk_true) +{ + RETURN_TRUE; +} +%% +override gtk_false +PHP_FUNCTION(wrap_gtk_false) +{ + RETURN_FALSE; +} +%% override gtk_timeout_add PHP_FUNCTION(wrap_gtk_timeout_add) { guint32 interval; - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); if (ZEND_NUM_ARGS() < 2) { php_error(E_WARNING, "%s() requires at least 2 arguments, %d given", @@ -184,17 +197,13 @@ return; } - if (!php_gtk_parse_args(2, "iV", &interval, &func)) + if (!php_gtk_parse_args(2, "iV", &interval, &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 2, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VN)", func, extra); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_timeout_add_full(interval, NULL, (GtkCallbackMarshal)php_gtk_handler_marshal, data, php_gtk_destroy_notify)); @@ -203,9 +212,12 @@ override gtk_idle_add PHP_FUNCTION(wrap_gtk_idle_add) { - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); if (ZEND_NUM_ARGS() < 1) { php_error(E_WARNING, "%s() requires at least 1 argument, %d given", @@ -213,17 +225,13 @@ return; } - if (!php_gtk_parse_args(1, "V", &func)) + if (!php_gtk_parse_args(1, "V", &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 1 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 1, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VN)", func, extra); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_idle_add_full(GTK_PRIORITY_DEFAULT, NULL, (GtkCallbackMarshal)php_gtk_handler_marshal, data, php_gtk_destroy_notify)); @@ -233,9 +241,12 @@ PHP_FUNCTION(wrap_gtk_quit_add) { gint main_level; - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); if (ZEND_NUM_ARGS() < 2) { php_error(E_WARNING, "%s() requires at least 2 arguments, %d given", @@ -243,20 +254,16 @@ return; } - if (!php_gtk_parse_args(2, "iV", &main_level, &func)) + if (!php_gtk_parse_args(2, "iV", &main_level, &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 2, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VN)", func, extra); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_quit_add_full(main_level, NULL, - (GtkCallbackMarshal)php_gtk_handler_marshal, - data, php_gtk_destroy_notify)); + (GtkCallbackMarshal)php_gtk_handler_marshal, + data, php_gtk_destroy_notify)); } %% override gtk_input_add_full @@ -264,36 +271,40 @@ { int source; GdkInputCondition condition; - zval *func = NULL; + zval *callback = NULL; + zval *extra, *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); - if (ZEND_NUM_ARGS() != 3) { - php_error(E_WARNING, "%s() requires exactly 3 arguments, %d given", + if (ZEND_NUM_ARGS() < 3) { + php_error(E_WARNING, "%s() requires at least 3 arguments, %d given", get_active_function_name(), ZEND_NUM_ARGS()); return; } - if (!php_gtk_parse_args(3, "iiV", &source, &condition, &func)) + if (!php_gtk_parse_args(3, "iiV", &source, &condition, &callback)) return; - - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 3 to be callable", - get_active_function_name()); - return; - } + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); + extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 3, ZEND_NUM_ARGS()); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_input_add_full(source, condition, NULL, (GtkCallbackMarshal)php_gtk_input_marshal, - func, php_gtk_destroy_notify)); + data, php_gtk_destroy_notify)); } %% override gtk_signal_connect -PHP_FUNCTION(wrap_gtk_signal_connect) +static void wrap_gtk_signal_connect_impl(INTERNAL_FUNCTION_PARAMETERS, int pass_object) { char *name = NULL; - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; - int signum; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); NOT_STATIC_METHOD(); @@ -303,61 +314,27 @@ return; } - if (!php_gtk_parse_args(2, "sV", &name, &func)) + if (!php_gtk_parse_args(2, "sV", &name, &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 2, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VNi)", func, extra, 1); - signum = gtk_signal_connect_full(PHP_GTK_GET(this_ptr), name, NULL, - (GtkCallbackMarshal)php_gtk_callback_marshal, - data, php_gtk_destroy_notify, FALSE, FALSE); - RETURN_LONG(signum); + data = php_gtk_build_value("(VNisi)", callback, extra, pass_object, callback_filename, callback_lineno); + RETURN_LONG(gtk_signal_connect_full(PHP_GTK_GET(this_ptr), name, NULL, + (GtkCallbackMarshal)php_gtk_callback_marshal, + data, php_gtk_destroy_notify, FALSE, FALSE)); } + +PHP_FUNCTION(wrap_gtk_signal_connect) +{ + wrap_gtk_signal_connect_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} %% override gtk_signal_connect_object PHP_FUNCTION(wrap_gtk_signal_connect_object) { - char *name = NULL; - char *func; - zval *extra, *data, *obj; - zval *method; - int signum; - - NOT_STATIC_METHOD(); - - if (ZEND_NUM_ARGS() < 2) { - php_error(E_WARNING, "%s() requires at least 3 arguments, %d given", - get_active_function_name(), ZEND_NUM_ARGS()); - return; - } - - if (!php_gtk_parse_args(3, "ssO", &name, &func, &obj, gtk_object_ce)) - return; - - MAKE_STD_ZVAL(method); - array_init(method); - zval_add_ref(&obj); - add_next_index_zval(method, obj); - add_next_index_string(method, func, 1); - - if (!php_gtk_is_callable(method, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable method of argument 3", get_active_function_name()); - zval_dtor(method); - return; - } - - extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 3, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VNi)", method, extra, 0); - signum = gtk_signal_connect_full(PHP_GTK_GET(this_ptr), name, NULL, - (GtkCallbackMarshal)php_gtk_callback_marshal, - data, php_gtk_destroy_notify, FALSE, FALSE); - RETURN_LONG(signum); + wrap_gtk_signal_connect_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } %% override gtk_widget_intersect @@ -931,21 +908,24 @@ { zval *retval = NULL; zval **callback, **extra; + zval **callback_filename, **callback_lineno; zval *params; zval ***args; - char *callable_name = NULL; + gchar *callable_name; ELS_FETCH(); zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&callback_filename); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 2, (void **)&callback_lineno); if (!php_gtk_is_callable(*callback, &callable_name)) { - php_error(E_WARNING, "unable to call item factory callback %s", callable_name); + php_error(E_WARNING, "unable to call item factory callback '%s' specified in %s on line %d", callable_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); g_free(callable_name); return; } params = php_gtk_build_value("(iN)", action, php_gtk_new((GtkObject *)widget)); - if (zend_hash_num_elements(Z_ARRVAL_P(callback_data)) > 1) { - zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + if (zend_hash_num_elements(Z_ARRVAL_P(callback_data)) > 3) { + zend_hash_index_find(Z_ARRVAL_P(callback_data), 3, (void **)&extra); php_array_merge(Z_ARRVAL_P(params), Z_ARRVAL_PP(extra), 0); } @@ -965,6 +945,9 @@ GtkItemFactoryEntry entry; GtkItemFactory *factory; int i = 0; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); NOT_STATIC_METHOD(); @@ -986,10 +969,12 @@ if (Z_TYPE_P(callback) == IS_NULL) entry.callback = NULL; else { + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); if (extra) - callback_data = php_gtk_build_value("(VV)", callback, extra); + callback_data = php_gtk_build_value("(VsiV)", callback, callback_filename, callback_lineno, extra); else - callback_data = php_gtk_build_value("(V)", callback); + callback_data = php_gtk_build_value("(Vsi)", callback, callback_filename, callback_lineno); entry.callback = (GtkItemFactoryCallback)item_factory_callback; } Index: php-gtk/src/php_gtk.h diff -u php-gtk/src/php_gtk.h:1.21 php-gtk/src/php_gtk.h:1.22 --- php-gtk/src/php_gtk.h:1.21 Mon Mar 5 07:57:42 2001 +++ php-gtk/src/php_gtk.h Tue Mar 6 21:37:22 2001 @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: php_gtk.h,v 1.21 2001/03/05 15:57:42 andrei Exp $: */ +/* $Id: php_gtk.h,v 1.22 2001/03/07 05:37:22 andrei Exp $: */ #ifndef _PHP_GTK_H #define _PHP_GTK_H @@ -98,7 +98,7 @@ void php_gtk_destroy_notify(gpointer user_data); void php_gtk_callback_marshal(GtkObject *o, gpointer data, guint nargs, GtkArg *args); void php_gtk_handler_marshal(gpointer a, gpointer data, int nargs, GtkArg *args); -void php_gtk_input_marshal(gpointer a, zval *func, int nargs, GtkArg *args); +void php_gtk_input_marshal(gpointer a, gpointer data, int nargs, GtkArg *args); void php_gtk_ret_from_value(GtkArg *ret, zval *value); zval *php_gtk_args_as_hash(int nargs, GtkArg *args); zval *php_gtk_arg_as_value(GtkArg *arg); Index: php-gtk/src/php_gtk_object.c diff -u php-gtk/src/php_gtk_object.c:1.18 php-gtk/src/php_gtk_object.c:1.19 --- php-gtk/src/php_gtk_object.c:1.18 Mon Mar 5 11:53:09 2001 +++ php-gtk/src/php_gtk_object.c Tue Mar 6 21:37:22 2001 @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: php_gtk_object.c,v 1.18 2001/03/05 19:53:09 fmk Exp $ */ +/* $Id: php_gtk_object.c,v 1.19 2001/03/07 05:37:22 andrei Exp $ */ #include "php_gtk.h" @@ -142,43 +142,77 @@ void php_gtk_callback_marshal(GtkObject *o, gpointer data, guint nargs, GtkArg *args) { zval *gtk_args; - zval *signal_data = (zval *)data; - zval **func, **extra = NULL, **pass_wrapper = NULL; + zval *callback_data = (zval *)data; + zval **callback, **extra = NULL, **pass_object = NULL; + zval **callback_filename = NULL, **callback_lineno = NULL; zval *wrapper = NULL; zval *params; zval *retval = NULL; zval *tmp; zval ***signal_args; + gchar *callback_name; ELS_FETCH(); + /* Callback is always passed as the first element. */ + zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + + /* + * If there is more than one element, it will be an array of: + * [1] an array of extra arguments + * [2] a flag indidicating whether the object should be passed to the + * callback + * [3] the filename where the callback was specified + * [4] the line number where the callback was specified + */ + if (zend_hash_num_elements(Z_ARRVAL_P(callback_data)) > 1) { + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 2, (void **)&pass_object); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 3, (void **)&callback_filename); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 4, (void **)&callback_lineno); + } + + if (!php_gtk_is_callable(*callback, &callback_name)) { + if (callback_filename) + php_error(E_WARNING, "Unable to call signal callback '%s' specified in %s on line %d", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); + else + php_error(E_WARNING, "Unable to call callback '%s'", callback_name); + g_free(callback_name); + return; + } + gtk_args = php_gtk_args_as_hash(nargs, args); - if (!php_gtk_is_callable(signal_data, NULL)) { - zend_hash_index_find(Z_ARRVAL_P(signal_data), 0, (void **)&func); - zend_hash_index_find(Z_ARRVAL_P(signal_data), 1, (void **)&extra); - zend_hash_index_find(Z_ARRVAL_P(signal_data), 2, (void **)&pass_wrapper); - } else - func = &signal_data; - - if (pass_wrapper && Z_LVAL_PP(pass_wrapper) && o) + /* + * If pass_object flag is not specified, or it's specified and true, and we + * have the actual object, construct the wrapper around it. + */ + if ((!pass_object || Z_LVAL_PP(pass_object)) && o) wrapper = php_gtk_new(o); + /* + * If there is a wrapper, construct array of parameters, set wrapper as + * the first parameter, and append the array of GTK signal arguments to it. + */ if (wrapper) { MAKE_STD_ZVAL(params); array_init(params); - if (Z_LVAL_PP(pass_wrapper)) - zend_hash_next_index_insert(Z_ARRVAL_P(params), &wrapper, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(params), &wrapper, sizeof(zval *), NULL); php_array_merge(Z_ARRVAL_P(params), Z_ARRVAL_P(gtk_args), 0); zval_ptr_dtor(>k_args); } else + /* Otherwise, the only parameters will be GTK signal arguments. */ params = 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); signal_args = php_gtk_hash_as_array(params); - call_user_function_ex(EG(function_table), NULL, *func, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), signal_args, 1, NULL); + call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), signal_args, 1, NULL); if (retval) { php_gtk_ret_from_value(&args[nargs], retval); @@ -191,23 +225,32 @@ void php_gtk_handler_marshal(gpointer a, gpointer data, int nargs, GtkArg *args) { - zval *handler_data = (zval *)data; - zval **func, **extra = NULL; + zval *callback_data = (zval *)data; + zval **callback, **extra = NULL; + zval **callback_filename = NULL, **callback_lineno = NULL; zval ***handler_args = NULL; int num_handler_args = 0; zval *retval = NULL; + gchar *callback_name; ELS_FETCH(); - if (!php_gtk_is_callable(handler_data, NULL)) { - zend_hash_index_find(Z_ARRVAL_P(handler_data), 0, (void **)&func); - zend_hash_index_find(Z_ARRVAL_P(handler_data), 1, (void **)&extra); - handler_args = php_gtk_hash_as_array(*extra); - num_handler_args = zend_hash_num_elements(Z_ARRVAL_PP(extra)); - } else - func = &handler_data; + /* Callback is always passed as the first element. */ + zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + 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_lineno); + + if (!php_gtk_is_callable(*callback, &callback_name)) { + php_error(E_WARNING, "Unable to call handler callback '%s' specified in %s on line %d", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); + g_free(callback_name); + return; + } - call_user_function_ex(EG(function_table), NULL, *func, &retval, num_handler_args, handler_args, 1, NULL); + 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); + *GTK_RETLOC_BOOL(args[0]) = FALSE; if (retval) { if (zval_is_true(retval)) @@ -221,23 +264,37 @@ efree(handler_args); } -void php_gtk_input_marshal(gpointer a, zval *func, int nargs, GtkArg *args) +void php_gtk_input_marshal(gpointer a, gpointer data, int nargs, GtkArg *args) { - zval **input_args[2]; - zval *source, *condition; - zval *retval = NULL; + zval *callback_data = (zval *)data; + zval *params; + zval *retval = NULL, **callback, **extra = NULL; + zval **callback_filename = NULL, **callback_lineno = NULL; + zval ***input_args; + gchar *callback_name; ELS_FETCH(); + + zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + 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_lineno); + + if (!php_gtk_is_callable(*callback, &callback_name)) { + php_error(E_WARNING, "Unable to call input callback '%s' specified in %s on line %d", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); + g_free(callback_name); + return; + } - source = php_gtk_arg_as_value(&args[0]); - condition = php_gtk_arg_as_value(&args[1]); - input_args[0] = &source; - input_args[1] = &condition; - - call_user_function_ex(EG(function_table), NULL, func, &retval, 2, input_args, 1, NULL); - zval_ptr_dtor(&source); - zval_ptr_dtor(&condition); + params = php_gtk_args_as_hash(nargs, args); + if (extra) + 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); if (retval) zval_ptr_dtor(&retval); + efree(input_args); + zval_ptr_dtor(¶ms); } void php_gtk_destroy_notify(gpointer user_data) Index: php-gtk/test/gtk.php diff -u php-gtk/test/gtk.php:1.11 php-gtk/test/gtk.php:1.12 --- php-gtk/test/gtk.php:1.11 Mon Mar 5 20:53:39 2001 +++ php-gtk/test/gtk.php Tue Mar 6 21:37:22 2001 @@ -1,5 +1,5 @@ <?php -/* $Id: gtk.php,v 1.11 2001/03/06 04:53:39 andrei Exp $ */ +/* $Id: gtk.php,v 1.12 2001/03/07 05:37:22 andrei Exp $ */ if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') dl('php_gtk.dll'); @@ -20,11 +20,6 @@ $window->hide(); } -function destroy($window) -{ - Gtk::main_quit(); -} - function create_buttons() { @@ -338,7 +333,7 @@ $button = &new GtkButton('[?]'); $box3->pack_start($button, false, false, 0); $button->show(); - $button->connect_object('clicked', 'start_query', $tips_query); + $button->connect_object('clicked', array($tips_query, 'start_query')); $tooltips->set_tip($button, 'Start the Tooltips Inspector', 'ContextHelp/buttons/?'); function tips_query_widget_entered($tips_query, $widget, $tip_text, @@ -566,8 +561,8 @@ $window->set_usize(200, 400); $window->set_uposition(20, 20); - $window->connect('destroy', 'destroy'); - $window->connect('delete-event', 'destroy'); + $window->connect_object('destroy', array('gtk', 'main_quit')); + $window->connect_object('delete-event', array('gtk', 'false')); $box1 = &new GtkVBox(); $window->add($box1); @@ -601,7 +596,7 @@ $box1->pack_start($box2, false); $button = &new GtkButton('close'); - $button->connect('clicked', 'destroy'); + $button->connect_object('clicked', array('gtk', 'main_quit')); $box2->pack_start($button); $button->set_flags(GTK_CAN_DEFAULT); $button->grab_default(); Index: php-gtk/test/list.php diff -u php-gtk/test/list.php:1.3 php-gtk/test/list.php:1.4 --- php-gtk/test/list.php:1.3 Fri Mar 2 05:18:36 2001 +++ php-gtk/test/list.php Tue Mar 6 21:37:22 2001 @@ -15,20 +15,13 @@ return false; } -/* - * Called when the window is being destroyed. Simply quit the main loop. - */ -function destroy() -{ - Gtk::main_quit(); -} /* * Create a new top-level window and connect the signals to the appropriate * functions. Note that all constructors must be assigned by reference. */ $window = &new GtkWindow(); -$window->connect('destroy', destroy); +$window->connect_object('destroy', array('gtk', 'main_quit'); $window->connect('delete-event', delete_event); /*
Index: php-gtk/generator/generator.php diff -u php-gtk/generator/generator.php:1.12 php-gtk/generator/generator.php:1.13 --- php-gtk/generator/generator.php:1.12 Mon Mar 5 13:25:37 2001 +++ php-gtk/generator/generator.php Tue Mar 6 21:37:22 2001 @@ -19,7 +19,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: generator.php,v 1.12 2001/03/05 21:25:37 fmk Exp $ */ +/* $Id: generator.php,v 1.13 2001/03/07 05:37:22 andrei Exp $ */ /* * Significant portions of this generator are based on the pygtk code generator @@ -462,12 +462,10 @@ if ($this->overrides->is_overriden($function->c_name)) { list($function_name, $function_override) = $this->overrides->get_override($function->c_name); fwrite($fp, $function_override . "\n"); - if (!isset($function_name)) { - if ($function->name == $function->c_name) - $function_name = substr($function->name, 4); - else - $function_name = $function->name; - } + if ($function->name == $function->c_name) + $function_name = substr($function->name, 4); + else + $function_name = $function->name; $function_entry[substr($function->c_name, 0, 3)] .= sprintf($function_entry_tpl, strtolower($function_name), strtolower($function->c_name), Index: php-gtk/generator/gtk.overrides diff -u php-gtk/generator/gtk.overrides:1.25 php-gtk/generator/gtk.overrides:1.26 --- php-gtk/generator/gtk.overrides:1.25 Tue Mar 6 10:02:04 2001 +++ php-gtk/generator/gtk.overrides Tue Mar 6 21:37:22 2001 @@ -137,8 +137,6 @@ gtk_widget_newv %% ignore - gtk_true - gtk_false gtk_key_snooper_install gtk_key_snooper_remove gtk_get_current_event @@ -170,13 +168,28 @@ %% ignore-glob gtk_radio_button_new_* %% +override gtk_true +PHP_FUNCTION(wrap_gtk_true) +{ + RETURN_TRUE; +} +%% +override gtk_false +PHP_FUNCTION(wrap_gtk_false) +{ + RETURN_FALSE; +} +%% override gtk_timeout_add PHP_FUNCTION(wrap_gtk_timeout_add) { guint32 interval; - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); if (ZEND_NUM_ARGS() < 2) { php_error(E_WARNING, "%s() requires at least 2 arguments, %d given", @@ -184,17 +197,13 @@ return; } - if (!php_gtk_parse_args(2, "iV", &interval, &func)) + if (!php_gtk_parse_args(2, "iV", &interval, &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 2, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VN)", func, extra); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_timeout_add_full(interval, NULL, (GtkCallbackMarshal)php_gtk_handler_marshal, data, php_gtk_destroy_notify)); @@ -203,9 +212,12 @@ override gtk_idle_add PHP_FUNCTION(wrap_gtk_idle_add) { - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); if (ZEND_NUM_ARGS() < 1) { php_error(E_WARNING, "%s() requires at least 1 argument, %d given", @@ -213,17 +225,13 @@ return; } - if (!php_gtk_parse_args(1, "V", &func)) + if (!php_gtk_parse_args(1, "V", &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 1 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 1, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VN)", func, extra); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_idle_add_full(GTK_PRIORITY_DEFAULT, NULL, (GtkCallbackMarshal)php_gtk_handler_marshal, data, php_gtk_destroy_notify)); @@ -233,9 +241,12 @@ PHP_FUNCTION(wrap_gtk_quit_add) { gint main_level; - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); if (ZEND_NUM_ARGS() < 2) { php_error(E_WARNING, "%s() requires at least 2 arguments, %d given", @@ -243,20 +254,16 @@ return; } - if (!php_gtk_parse_args(2, "iV", &main_level, &func)) + if (!php_gtk_parse_args(2, "iV", &main_level, &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 2, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VN)", func, extra); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_quit_add_full(main_level, NULL, - (GtkCallbackMarshal)php_gtk_handler_marshal, - data, php_gtk_destroy_notify)); + (GtkCallbackMarshal)php_gtk_handler_marshal, + data, php_gtk_destroy_notify)); } %% override gtk_input_add_full @@ -264,36 +271,40 @@ { int source; GdkInputCondition condition; - zval *func = NULL; + zval *callback = NULL; + zval *extra, *data; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); - if (ZEND_NUM_ARGS() != 3) { - php_error(E_WARNING, "%s() requires exactly 3 arguments, %d given", + if (ZEND_NUM_ARGS() < 3) { + php_error(E_WARNING, "%s() requires at least 3 arguments, %d given", get_active_function_name(), ZEND_NUM_ARGS()); return; } - if (!php_gtk_parse_args(3, "iiV", &source, &condition, &func)) + if (!php_gtk_parse_args(3, "iiV", &source, &condition, &callback)) return; - - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 3 to be callable", - get_active_function_name()); - return; - } + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); + extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 3, ZEND_NUM_ARGS()); + data = php_gtk_build_value("(VNsi)", callback, extra, callback_filename, callback_lineno); RETURN_LONG(gtk_input_add_full(source, condition, NULL, (GtkCallbackMarshal)php_gtk_input_marshal, - func, php_gtk_destroy_notify)); + data, php_gtk_destroy_notify)); } %% override gtk_signal_connect -PHP_FUNCTION(wrap_gtk_signal_connect) +static void wrap_gtk_signal_connect_impl(INTERNAL_FUNCTION_PARAMETERS, int pass_object) { char *name = NULL; - zval *func = NULL; + zval *callback = NULL; zval *extra; zval *data; - int signum; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); NOT_STATIC_METHOD(); @@ -303,61 +314,27 @@ return; } - if (!php_gtk_parse_args(2, "sV", &name, &func)) + if (!php_gtk_parse_args(2, "sV", &name, &callback)) return; - if (!php_gtk_is_callable(func, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable", - get_active_function_name()); - return; - } - + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 2, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VNi)", func, extra, 1); - signum = gtk_signal_connect_full(PHP_GTK_GET(this_ptr), name, NULL, - (GtkCallbackMarshal)php_gtk_callback_marshal, - data, php_gtk_destroy_notify, FALSE, FALSE); - RETURN_LONG(signum); + data = php_gtk_build_value("(VNisi)", callback, extra, pass_object, callback_filename, callback_lineno); + RETURN_LONG(gtk_signal_connect_full(PHP_GTK_GET(this_ptr), name, NULL, + (GtkCallbackMarshal)php_gtk_callback_marshal, + data, php_gtk_destroy_notify, FALSE, FALSE)); } + +PHP_FUNCTION(wrap_gtk_signal_connect) +{ + wrap_gtk_signal_connect_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} %% override gtk_signal_connect_object PHP_FUNCTION(wrap_gtk_signal_connect_object) { - char *name = NULL; - char *func; - zval *extra, *data, *obj; - zval *method; - int signum; - - NOT_STATIC_METHOD(); - - if (ZEND_NUM_ARGS() < 2) { - php_error(E_WARNING, "%s() requires at least 3 arguments, %d given", - get_active_function_name(), ZEND_NUM_ARGS()); - return; - } - - if (!php_gtk_parse_args(3, "ssO", &name, &func, &obj, gtk_object_ce)) - return; - - MAKE_STD_ZVAL(method); - array_init(method); - zval_add_ref(&obj); - add_next_index_zval(method, obj); - add_next_index_string(method, func, 1); - - if (!php_gtk_is_callable(method, NULL)) { - php_error(E_WARNING, "%s() expects argument 2 to be callable method of argument 3", get_active_function_name()); - zval_dtor(method); - return; - } - - extra = php_gtk_func_args_as_hash(ZEND_NUM_ARGS(), 3, ZEND_NUM_ARGS()); - data = php_gtk_build_value("(VNi)", method, extra, 0); - signum = gtk_signal_connect_full(PHP_GTK_GET(this_ptr), name, NULL, - (GtkCallbackMarshal)php_gtk_callback_marshal, - data, php_gtk_destroy_notify, FALSE, FALSE); - RETURN_LONG(signum); + wrap_gtk_signal_connect_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); } %% override gtk_widget_intersect @@ -931,21 +908,24 @@ { zval *retval = NULL; zval **callback, **extra; + zval **callback_filename, **callback_lineno; zval *params; zval ***args; - char *callable_name = NULL; + gchar *callable_name; ELS_FETCH(); zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&callback_filename); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 2, (void **)&callback_lineno); if (!php_gtk_is_callable(*callback, &callable_name)) { - php_error(E_WARNING, "unable to call item factory callback %s", callable_name); + php_error(E_WARNING, "unable to call item factory callback '%s' specified in %s on line %d", callable_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); g_free(callable_name); return; } params = php_gtk_build_value("(iN)", action, php_gtk_new((GtkObject *)widget)); - if (zend_hash_num_elements(Z_ARRVAL_P(callback_data)) > 1) { - zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + if (zend_hash_num_elements(Z_ARRVAL_P(callback_data)) > 3) { + zend_hash_index_find(Z_ARRVAL_P(callback_data), 3, (void **)&extra); php_array_merge(Z_ARRVAL_P(params), Z_ARRVAL_PP(extra), 0); } @@ -965,6 +945,9 @@ GtkItemFactoryEntry entry; GtkItemFactory *factory; int i = 0; + char *callback_filename; + uint callback_lineno; + ELS_FETCH(); NOT_STATIC_METHOD(); @@ -986,10 +969,12 @@ if (Z_TYPE_P(callback) == IS_NULL) entry.callback = NULL; else { + callback_filename = zend_get_executed_filename(ELS_C); + callback_lineno = zend_get_executed_lineno(ELS_C); if (extra) - callback_data = php_gtk_build_value("(VV)", callback, extra); + callback_data = php_gtk_build_value("(VsiV)", callback, callback_filename, callback_lineno, extra); else - callback_data = php_gtk_build_value("(V)", callback); + callback_data = php_gtk_build_value("(Vsi)", callback, callback_filename, callback_lineno); entry.callback = (GtkItemFactoryCallback)item_factory_callback; } Index: php-gtk/src/php_gtk.h diff -u php-gtk/src/php_gtk.h:1.21 php-gtk/src/php_gtk.h:1.22 --- php-gtk/src/php_gtk.h:1.21 Mon Mar 5 07:57:42 2001 +++ php-gtk/src/php_gtk.h Tue Mar 6 21:37:22 2001 @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: php_gtk.h,v 1.21 2001/03/05 15:57:42 andrei Exp $: */ +/* $Id: php_gtk.h,v 1.22 2001/03/07 05:37:22 andrei Exp $: */ #ifndef _PHP_GTK_H #define _PHP_GTK_H @@ -98,7 +98,7 @@ void php_gtk_destroy_notify(gpointer user_data); void php_gtk_callback_marshal(GtkObject *o, gpointer data, guint nargs, GtkArg *args); void php_gtk_handler_marshal(gpointer a, gpointer data, int nargs, GtkArg *args); -void php_gtk_input_marshal(gpointer a, zval *func, int nargs, GtkArg *args); +void php_gtk_input_marshal(gpointer a, gpointer data, int nargs, GtkArg *args); void php_gtk_ret_from_value(GtkArg *ret, zval *value); zval *php_gtk_args_as_hash(int nargs, GtkArg *args); zval *php_gtk_arg_as_value(GtkArg *arg); Index: php-gtk/src/php_gtk_object.c diff -u php-gtk/src/php_gtk_object.c:1.18 php-gtk/src/php_gtk_object.c:1.19 --- php-gtk/src/php_gtk_object.c:1.18 Mon Mar 5 11:53:09 2001 +++ php-gtk/src/php_gtk_object.c Tue Mar 6 21:37:22 2001 @@ -18,7 +18,7 @@ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* $Id: php_gtk_object.c,v 1.18 2001/03/05 19:53:09 fmk Exp $ */ +/* $Id: php_gtk_object.c,v 1.19 2001/03/07 05:37:22 andrei Exp $ */ #include "php_gtk.h" @@ -142,43 +142,77 @@ void php_gtk_callback_marshal(GtkObject *o, gpointer data, guint nargs, GtkArg *args) { zval *gtk_args; - zval *signal_data = (zval *)data; - zval **func, **extra = NULL, **pass_wrapper = NULL; + zval *callback_data = (zval *)data; + zval **callback, **extra = NULL, **pass_object = NULL; + zval **callback_filename = NULL, **callback_lineno = NULL; zval *wrapper = NULL; zval *params; zval *retval = NULL; zval *tmp; zval ***signal_args; + gchar *callback_name; ELS_FETCH(); + /* Callback is always passed as the first element. */ + zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + + /* + * If there is more than one element, it will be an array of: + * [1] an array of extra arguments + * [2] a flag indidicating whether the object should be passed to the + * callback + * [3] the filename where the callback was specified + * [4] the line number where the callback was specified + */ + if (zend_hash_num_elements(Z_ARRVAL_P(callback_data)) > 1) { + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 2, (void **)&pass_object); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 3, (void **)&callback_filename); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 4, (void **)&callback_lineno); + } + + if (!php_gtk_is_callable(*callback, &callback_name)) { + if (callback_filename) + php_error(E_WARNING, "Unable to call signal callback '%s' specified in %s on line %d", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); + else + php_error(E_WARNING, "Unable to call callback '%s'", callback_name); + g_free(callback_name); + return; + } + gtk_args = php_gtk_args_as_hash(nargs, args); - if (!php_gtk_is_callable(signal_data, NULL)) { - zend_hash_index_find(Z_ARRVAL_P(signal_data), 0, (void **)&func); - zend_hash_index_find(Z_ARRVAL_P(signal_data), 1, (void **)&extra); - zend_hash_index_find(Z_ARRVAL_P(signal_data), 2, (void **)&pass_wrapper); - } else - func = &signal_data; - - if (pass_wrapper && Z_LVAL_PP(pass_wrapper) && o) + /* + * If pass_object flag is not specified, or it's specified and true, and we + * have the actual object, construct the wrapper around it. + */ + if ((!pass_object || Z_LVAL_PP(pass_object)) && o) wrapper = php_gtk_new(o); + /* + * If there is a wrapper, construct array of parameters, set wrapper as + * the first parameter, and append the array of GTK signal arguments to it. + */ if (wrapper) { MAKE_STD_ZVAL(params); array_init(params); - if (Z_LVAL_PP(pass_wrapper)) - zend_hash_next_index_insert(Z_ARRVAL_P(params), &wrapper, sizeof(zval *), NULL); + zend_hash_next_index_insert(Z_ARRVAL_P(params), &wrapper, sizeof(zval *), NULL); php_array_merge(Z_ARRVAL_P(params), Z_ARRVAL_P(gtk_args), 0); zval_ptr_dtor(>k_args); } else + /* Otherwise, the only parameters will be GTK signal arguments. */ params = 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); signal_args = php_gtk_hash_as_array(params); - call_user_function_ex(EG(function_table), NULL, *func, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), signal_args, 1, NULL); + call_user_function_ex(EG(function_table), NULL, *callback, &retval, zend_hash_num_elements(Z_ARRVAL_P(params)), signal_args, 1, NULL); if (retval) { php_gtk_ret_from_value(&args[nargs], retval); @@ -191,23 +225,32 @@ void php_gtk_handler_marshal(gpointer a, gpointer data, int nargs, GtkArg *args) { - zval *handler_data = (zval *)data; - zval **func, **extra = NULL; + zval *callback_data = (zval *)data; + zval **callback, **extra = NULL; + zval **callback_filename = NULL, **callback_lineno = NULL; zval ***handler_args = NULL; int num_handler_args = 0; zval *retval = NULL; + gchar *callback_name; ELS_FETCH(); - if (!php_gtk_is_callable(handler_data, NULL)) { - zend_hash_index_find(Z_ARRVAL_P(handler_data), 0, (void **)&func); - zend_hash_index_find(Z_ARRVAL_P(handler_data), 1, (void **)&extra); - handler_args = php_gtk_hash_as_array(*extra); - num_handler_args = zend_hash_num_elements(Z_ARRVAL_PP(extra)); - } else - func = &handler_data; + /* Callback is always passed as the first element. */ + zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + 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_lineno); + + if (!php_gtk_is_callable(*callback, &callback_name)) { + php_error(E_WARNING, "Unable to call handler callback '%s' specified in %s on line %d", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); + g_free(callback_name); + return; + } - call_user_function_ex(EG(function_table), NULL, *func, &retval, num_handler_args, handler_args, 1, NULL); + 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); + *GTK_RETLOC_BOOL(args[0]) = FALSE; if (retval) { if (zval_is_true(retval)) @@ -221,23 +264,37 @@ efree(handler_args); } -void php_gtk_input_marshal(gpointer a, zval *func, int nargs, GtkArg *args) +void php_gtk_input_marshal(gpointer a, gpointer data, int nargs, GtkArg *args) { - zval **input_args[2]; - zval *source, *condition; - zval *retval = NULL; + zval *callback_data = (zval *)data; + zval *params; + zval *retval = NULL, **callback, **extra = NULL; + zval **callback_filename = NULL, **callback_lineno = NULL; + zval ***input_args; + gchar *callback_name; ELS_FETCH(); + + zend_hash_index_find(Z_ARRVAL_P(callback_data), 0, (void **)&callback); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 1, (void **)&extra); + 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_lineno); + + if (!php_gtk_is_callable(*callback, &callback_name)) { + php_error(E_WARNING, "Unable to call input callback '%s' specified in %s on line %d", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); + g_free(callback_name); + return; + } - source = php_gtk_arg_as_value(&args[0]); - condition = php_gtk_arg_as_value(&args[1]); - input_args[0] = &source; - input_args[1] = &condition; - - call_user_function_ex(EG(function_table), NULL, func, &retval, 2, input_args, 1, NULL); - zval_ptr_dtor(&source); - zval_ptr_dtor(&condition); + params = php_gtk_args_as_hash(nargs, args); + if (extra) + 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); if (retval) zval_ptr_dtor(&retval); + efree(input_args); + zval_ptr_dtor(¶ms); } void php_gtk_destroy_notify(gpointer user_data) Index: php-gtk/test/gtk.php diff -u php-gtk/test/gtk.php:1.11 php-gtk/test/gtk.php:1.12 --- php-gtk/test/gtk.php:1.11 Mon Mar 5 20:53:39 2001 +++ php-gtk/test/gtk.php Tue Mar 6 21:37:22 2001 @@ -1,5 +1,5 @@ <?php -/* $Id: gtk.php,v 1.11 2001/03/06 04:53:39 andrei Exp $ */ +/* $Id: gtk.php,v 1.12 2001/03/07 05:37:22 andrei Exp $ */ if (strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') dl('php_gtk.dll'); @@ -20,11 +20,6 @@ $window->hide(); } -function destroy($window) -{ - Gtk::main_quit(); -} - function create_buttons() { @@ -338,7 +333,7 @@ $button = &new GtkButton('[?]'); $box3->pack_start($button, false, false, 0); $button->show(); - $button->connect_object('clicked', 'start_query', $tips_query); + $button->connect_object('clicked', array($tips_query, 'start_query')); $tooltips->set_tip($button, 'Start the Tooltips Inspector', 'ContextHelp/buttons/?'); function tips_query_widget_entered($tips_query, $widget, $tip_text, @@ -566,8 +561,8 @@ $window->set_usize(200, 400); $window->set_uposition(20, 20); - $window->connect('destroy', 'destroy'); - $window->connect('delete-event', 'destroy'); + $window->connect_object('destroy', array('gtk', 'main_quit')); + $window->connect_object('delete-event', array('gtk', 'false')); $box1 = &new GtkVBox(); $window->add($box1); @@ -601,7 +596,7 @@ $box1->pack_start($box2, false); $button = &new GtkButton('close'); - $button->connect('clicked', 'destroy'); + $button->connect_object('clicked', array('gtk', 'main_quit')); $box2->pack_start($button); $button->set_flags(GTK_CAN_DEFAULT); $button->grab_default(); Index: php-gtk/test/list.php diff -u php-gtk/test/list.php:1.3 php-gtk/test/list.php:1.4 --- php-gtk/test/list.php:1.3 Fri Mar 2 05:18:36 2001 +++ php-gtk/test/list.php Tue Mar 6 21:37:22 2001 @@ -15,20 +15,13 @@ return false; } -/* - * Called when the window is being destroyed. Simply quit the main loop. - */ -function destroy() -{ - Gtk::main_quit(); -} /* * Create a new top-level window and connect the signals to the appropriate * functions. Note that all constructors must be assigned by reference. */ $window = &new GtkWindow(); -$window->connect('destroy', destroy); +$window->connect_object('destroy', array('gtk', 'main_quit'); $window->connect('delete-event', delete_event); /*