com gtk/php-gtk: Implement Gtk::io_add_watch() an d Gtk::io_add_watch_priority(). These sho uld work with any stream that can be cast to a file descriptor (files, pipes, sockets, and maybe something else).: ext/gtk+/gtk.ove rrides
[email protected] (David Soria Parra) Thu, 05 Jan 2006 05:41:01 +0000
| Newsgroups | php.gtk.cvs |
|---|---|
| Message-ID | <[email protected]> |
Commit: 416f8552476b057982d6280fa9d103bd4a59ca5a Author: Andrei Zmievski <[email protected]> Thu, 5 Jan 2006 05:41:01 +0000 Parents: dc00401c4fd8a698f2644b26e00ef4c8ac05c7ae Branches: master Link: http://git.php.net/?p=gtk/php-gtk.git;a=commitdiff;h=416f8552476b057982d6280fa9d103bd4a59ca5a Log: Implement Gtk::io_add_watch() and Gtk::io_add_watch_priority(). These should work with any stream that can be cast to a file descriptor (files, pipes, sockets, and maybe something else). # I only did minimal testing here, so feel free to give it a try and get # back to me. Changed paths: M ext/gtk+/gtk.overrides Diff: 416f8552476b057982d6280fa9d103bd4a59ca5a diff --git a/ext/gtk+/gtk.overrides b/ext/gtk+/gtk.overrides index e0d9736..0a02270 100644 --- a/ext/gtk+/gtk.overrides +++ b/ext/gtk+/gtk.overrides @@ -189,11 +189,20 @@ constants /* register non-enum constants */ phpg_register_int_constant(gtk_ce, "PRIORITY_HIGH", sizeof("PRIORITY_HIGH")-1, G_PRIORITY_HIGH); - phpg_register_int_constant(gtk_ce, "PRIORITY_DEFAULT", sizeof("PRIORITY_HIGH")-1, G_PRIORITY_HIGH); + phpg_register_int_constant(gtk_ce, "PRIORITY_DEFAULT", sizeof("PRIORITY_DEFAULT")-1, G_PRIORITY_DEFAULT); phpg_register_int_constant(gtk_ce, "PRIORITY_HIGH_IDLE", sizeof("PRIORITY_HIGH_IDLE")-1, G_PRIORITY_HIGH_IDLE); phpg_register_int_constant(gtk_ce, "PRIORITY_DEFAULT_IDLE", sizeof("PRIORITY_DEFAULT_IDLE")-1, G_PRIORITY_DEFAULT_IDLE); phpg_register_int_constant(gtk_ce, "PRIORITY_LOW", sizeof("PRIORITY_LOW")-1, G_PRIORITY_LOW); + + phpg_register_int_constant(gtk_ce, "IO_IN", sizeof("IO_IN")-1, G_IO_IN); + phpg_register_int_constant(gtk_ce, "IO_OUT", sizeof("IO_OUT")-1, G_IO_OUT); + phpg_register_int_constant(gtk_ce, "IO_PRI", sizeof("IO_PRI")-1, G_IO_PRI); + phpg_register_int_constant(gtk_ce, "IO_ERR", sizeof("IO_ERR")-1, G_IO_ERR); + phpg_register_int_constant(gtk_ce, "IO_HUP", sizeof("IO_HUP")-1, G_IO_HUP); + phpg_register_int_constant(gtk_ce, "IO_NVAL", sizeof("IO_NVAL")-1, G_IO_NVAL); + + /* Fundamental GTypes */ phpg_register_int_constant(gtk_ce, "TYPE_INVALID", sizeof("TYPE_INVALID")-1, G_TYPE_INVALID); phpg_register_int_constant(gtk_ce, "TYPE_NONE", sizeof("TYPE_NONE")-1, G_TYPE_NONE); @@ -397,6 +406,126 @@ PHP_METHOD RETURN_LONG(handler_id); } +%% +add Gtk io_add_watch + +static gboolean phpg_iowatch_marshal(GIOChannel *source, GIOCondition condition, gpointer user_data) +{ + zval *callback_data = (zval *) user_data; + zval **callback, **extra = NULL, **stream_rsrc; + zval **callback_filename = NULL, **callback_lineno = NULL; + zval ***args = NULL, *z_condition = NULL; + int n_args = 0; + zval *retval = NULL; + char *callback_name; + gboolean result; + TSRMLS_FETCH(); + + /* 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 **)&stream_rsrc); + zend_hash_index_find(Z_ARRVAL_P(callback_data), 2, (void **)&extra); + 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 (!zend_is_callable(*callback, 0, &callback_name)) { + php_error(E_WARNING, "Unable to invoke handler callback '%s' specified in %s on line %ld", callback_name, Z_STRVAL_PP(callback_filename), Z_LVAL_PP(callback_lineno)); + efree(callback_name); + return 0; + } + + args = php_gtk_hash_as_array_offset(*extra, 2, &n_args); + args[0] = stream_rsrc; + MAKE_STD_ZVAL(z_condition); + ZVAL_LONG(z_condition, condition); + args[1] = &z_condition; + + call_user_function_ex(EG(function_table), NULL, *callback, &retval, n_args, args, 0, NULL TSRMLS_CC); + + zval_ptr_dtor(&z_condition); + + result = FALSE; + if (retval) { + result = zval_is_true(retval); + zval_ptr_dtor(&retval); + } + + efree(callback_name); + if (args) + efree(args); + + return result; +} + +static void phpg_io_add_watch_impl(INTERNAL_FUNCTION_PARAMETERS, zend_bool with_priority) +{ + gint priority = G_PRIORITY_DEFAULT; + GIOCondition condition; + zval *stream_rsrc = NULL; + zval *callback = NULL; + zval *extra = NULL; + zval *data = NULL; + char *callback_filename; + uint callback_lineno; + guint handler_id; + GIOChannel *channel = NULL; + php_stream *stream = NULL; + int fd; + int req_args = with_priority ? 4 : 3; + + if (ZEND_NUM_ARGS() < req_args) { + php_error(E_WARNING, "%s::%s() requires at least %d arguments, %d given", + get_active_class_name(NULL TSRMLS_CC), + get_active_function_name(TSRMLS_C), req_args, ZEND_NUM_ARGS()); + return; + } + + if (with_priority) { + if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), req_args, &extra, "riVi", &stream_rsrc, &condition, &callback, &priority)) + return; + } else { + if (!php_gtk_parse_varargs(ZEND_NUM_ARGS(), req_args, &extra, "riV", &stream_rsrc, &condition, &callback)) + return; + } + + php_stream_from_zval(stream, &stream_rsrc); + if (php_stream_can_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT) == SUCCESS) { + php_stream_cast(stream, PHP_STREAM_AS_FD_FOR_SELECT, (void*)&fd, 0); + } else { + php_error(E_WARNING, "%s::%s() could not use stream of type '%s'", + get_active_class_name(NULL TSRMLS_CC), + get_active_function_name(TSRMLS_C), stream->ops->label); + return; + } + + if (!extra) { + MAKE_STD_ZVAL(extra); + array_init(extra); + } + + channel = g_io_channel_unix_new(fd); + callback_filename = zend_get_executed_filename(TSRMLS_C); + callback_lineno = zend_get_executed_lineno(TSRMLS_C); + php_gtk_build_value(&data, "(VVNsi)", callback, stream_rsrc, extra, callback_filename, callback_lineno); + handler_id = g_io_add_watch_full(channel, priority, condition, phpg_iowatch_marshal, data, phpg_destroy_notify); + g_io_channel_unref(channel); + + RETURN_LONG(handler_id); +} + +PHP_METHOD +{ + phpg_io_add_watch_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0); +} + +%% +add Gtk io_add_watch_priority + +PHP_METHOD +{ + phpg_io_add_watch_impl(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1); +} + %% }}} %% {{{ functions