/** * bonobo_ui_component_add_listener_full: * @component: the component to add it to * @id: the programmatic name of the id * @fn: the callback function for invoking it * @user_data: the associated user data for the callback * @destroy_fn: a destroy function for the callback data * * Add a listener for stateful events. **/ void bonobo_ui_component_add_listener_full (BonoboUIComponent *component, const char *id, GClosure *closure) { UIListener *list; BonoboUIComponentPrivate *priv; g_return_if_fail (closure != NULL); g_return_if_fail (BONOBO_IS_UI_COMPONENT (component)); priv = component->priv; if ((list = g_hash_table_lookup (priv->listeners, id))) { g_hash_table_remove (priv->listeners, id); listener_destroy (NULL, list, NULL); } list = g_new (UIListener, 1); list->id = g_strdup (id); list->closure = bonobo_closure_store (closure, bonobo_ui_marshal_VOID__STRING_INT_STRING); g_hash_table_insert (priv->listeners, list->id, list); }
static gboolean remove_listener (gpointer key, gpointer value, gpointer user_data) { RemoveInfo *info = user_data; UIListener *listener = value; if (info->by_name && info->name && !strcmp (listener->id, info->name)) return listener_destroy (NULL, listener, NULL); else if (info->by_closure && info->closure == listener->closure) return listener_destroy (NULL, listener, NULL); return FALSE; }
static int run_exec_wait(shell_t *shell, shell_argv_t *cmd_argv, char *tag) { int argc = cmd_argv->argc; char **argv = cmd_argv->argv; listener_t *listener; char *s; struct timeval tv0; long sec, usec; int unblock, timeout, error; /* Set and check wait timeout */ run_wait_timeout = run_timeout; if ( (argc > 1) && (argv[1][0] == '-') ) { if ( timer_value(shell, &(argv[1][1]), NULL, &run_wait_timeout) ) return -1; argv++; argc--; } if ( run_wait_timeout == -1 ) { shell_error(shell, "No timeout value initialized. Please use command 'timeout' before 'wait'\n"); return -1; } /* Setup wait conditions */ argv++; argc--; if ( (listener = listener_new(argc, argv)) == NULL ) return -1; /* Report what we are waiting for */ s = listener_str(listener); if ( debug_flag ) { /* For speedup in non-debug mode */ debug("Wait: '%s'\n", s); } result_puts(result_header_engine(tag)); result_puts(s); result_puts("\n"); free(s); /* Init timeout counter */ gettimeofday(&tv0, NULL); sec = run_wait_timeout / 1000; usec = (run_wait_timeout % 1000) * 1000; /* Wait until an unblocking condition is met */ unblock = 0; timeout = 0; error = 0; while ( ! (unblock || timeout || error) ) { /* Check unblocking conditions */ if ( listener_check(listener) ) { unblock = 1; } else { struct timeval tv1, tv; /* Update timeout counter */ gettimeofday(&tv1, NULL); tv_sub(&tv1, &tv0); /*fprintf(stderr, "** %ld.%06ld\n", tv1.tv_sec, tv1.tv_usec);*/ tv.tv_sec = sec; tv.tv_usec = usec; if ( tv_sub(&tv, &tv1) ) { timeout = 1; } else { /*fprintf(stderr, " %ld.%06ld\n", tv.tv_sec, tv.tv_usec);*/ /* Wait for events to arrive, and process incoming data */ switch ( run_wait_event(shell, tag, &tv) ) { case -1: error = 1; break; case 0: timeout = 1; break; default : break; } } } } if ( unblock ) { run_wait_event_unblock(shell, tag, listener); } else if ( timeout ) { run_wait_event_timeout(shell, tag); } /* Clear wait conditions */ listener_destroy(listener); return error ? -1 : 0; }