/** * Test a string setting for some value. * * @param settings a settings object * @param name a setting's name * @param s a string to be tested * @return 1 if the value exists and is equal to 's', 0 otherwise */ int fluid_settings_str_equal (fluid_settings_t* settings, const char *name, const char *s) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_return_val_if_fail (s != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get (settings, name, &node)) { if (node->type == FLUID_STR_TYPE) { fluid_str_setting_t *setting = (fluid_str_setting_t *)node; if (setting->value) retval = FLUID_STRCMP (setting->value, s) == 0; } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { fluid_int_setting_t *setting = (fluid_int_setting_t *)node; if (setting->hints & FLUID_HINT_TOGGLED) retval = FLUID_STRCMP (setting->value ? "yes" : "no", s) == 0; } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Add a rule to a MIDI router. * @param router MIDI router * @param rule Rule to add (used directly and should not be accessed again following a * successful call to this function). * @param type The type of rule to add (#fluid_midi_router_rule_type) * @return #FLUID_OK on success, #FLUID_FAILED otherwise (invalid rule for example) * @since 1.1.0 */ int fluid_midi_router_add_rule (fluid_midi_router_t *router, fluid_midi_router_rule_t *rule, int type) { fluid_midi_router_rule_t *free_rules, *next_rule; fluid_return_val_if_fail (router != NULL, FLUID_FAILED); fluid_return_val_if_fail (rule != NULL, FLUID_FAILED); fluid_return_val_if_fail (type >= 0 && type < FLUID_MIDI_ROUTER_RULE_COUNT, FLUID_FAILED); fluid_mutex_lock (router->rules_mutex); /* ++ lock */ /* Take over free rules list, if any (to free outside of lock) */ free_rules = router->free_rules; router->free_rules = NULL; rule->next = router->rules[type]; router->rules[type] = rule; fluid_mutex_unlock (router->rules_mutex); /* -- unlock */ /* Free any deactivated rules which were waiting for events and are now done */ for (; free_rules; free_rules = next_rule) { next_rule = free_rules->next; FLUID_FREE (free_rules); } return FLUID_OK; }
/** * Ask whether the setting is changeable in real-time. * * @param settings a settings object * @param name a setting's name * @return non zero if the setting is changeable in real-time */ int fluid_settings_is_realtime(fluid_settings_t* settings, const char *name) { fluid_setting_node_t *node; int isrealtime = FALSE; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node)) { if (node->type == FLUID_NUM_TYPE) { fluid_num_setting_t* setting = (fluid_num_setting_t*) node; isrealtime = setting->update != NULL; } else if (node->type == FLUID_STR_TYPE) { fluid_str_setting_t* setting = (fluid_str_setting_t*) node; isrealtime = setting->update != NULL; } else if (node->type == FLUID_INT_TYPE) { fluid_int_setting_t* setting = (fluid_int_setting_t*) node; isrealtime = setting->update != NULL; } } fluid_rec_mutex_unlock (settings->mutex); return isrealtime; }
/** * Remove an option previously assigned by fluid_settings_add_option(). * @param settings a settings object * @param name a setting's name * @param s option string to remove * @return 1 if the setting exists and option was removed, 0 otherwise */ int fluid_settings_remove_option(fluid_settings_t* settings, const char *name, const char* s) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_return_val_if_fail (s != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) && (node->type == FLUID_STR_TYPE)) { fluid_str_setting_t* setting = (fluid_str_setting_t*) node; fluid_list_t* list = setting->options; while (list) { char* option = (char*) fluid_list_get(list); if (FLUID_STRCMP(s, option) == 0) { FLUID_FREE (option); setting->options = fluid_list_remove_link(setting->options, list); retval = 1; break; } list = fluid_list_next(list); } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Get the hints for the named setting as an integer bitmap * * @param settings a settings object * @param name a setting's name * @return the hints associated to the named setting if it exists, zero otherwise */ int fluid_settings_get_hints(fluid_settings_t* settings, const char *name) { fluid_setting_node_t *node; int hints = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node)) { if (node->type == FLUID_NUM_TYPE) { fluid_num_setting_t* setting = (fluid_num_setting_t*) node; hints = setting->hints; } else if (node->type == FLUID_STR_TYPE) { fluid_str_setting_t* setting = (fluid_str_setting_t*) node; hints = setting->hints; } else if (node->type == FLUID_INT_TYPE) { fluid_int_setting_t* setting = (fluid_int_setting_t*) node; hints = setting->hints; } } fluid_rec_mutex_unlock (settings->mutex); return hints; }
/** * Add an option to a string setting (like an enumeration value). * @param settings a settings object * @param name a setting's name * @param s option string to add * @return 1 if the setting exists and option was added, 0 otherwise * * Causes the setting's #FLUID_HINT_OPTIONLIST hint to be set. */ int fluid_settings_add_option(fluid_settings_t* settings, const char *name, const char *s) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_return_val_if_fail (s != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) && (node->type == FLUID_STR_TYPE)) { fluid_str_setting_t* setting = (fluid_str_setting_t*) node; char* copy = FLUID_STRDUP(s); setting->options = fluid_list_append(setting->options, copy); setting->hints |= FLUID_HINT_OPTIONLIST; retval = 1; } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Get the default value of a string setting. Note that the returned string is * not owned by the caller and should not be modified or freed. * * @param settings a settings object * @param name a setting's name * @return the default string value of the setting if it exists, NULL otherwise */ char* fluid_settings_getstr_default(fluid_settings_t* settings, const char *name) { fluid_setting_node_t *node; char *retval = NULL; fluid_return_val_if_fail (settings != NULL, NULL); fluid_return_val_if_fail (name != NULL, NULL); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get (settings, name, &node)) { if (node->type == FLUID_STR_TYPE) { fluid_str_setting_t* setting = (fluid_str_setting_t*) node; retval = setting->def; } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { fluid_int_setting_t *setting = (fluid_int_setting_t *)node; if (setting->hints & FLUID_HINT_TOGGLED) retval = setting->def ? "yes" : "no"; } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * fluid_hashtable_ref: * @hashtable: a valid #fluid_hashtable_t. * * Atomically increments the reference count of @hashtable by one. * This function is MT-safe and may be called from any thread. * * Return value: the passed in #fluid_hashtable_t. * * Since: 2.10 **/ fluid_hashtable_t* fluid_hashtable_ref (fluid_hashtable_t *hashtable) { fluid_return_val_if_fail (hashtable != NULL, NULL); fluid_return_val_if_fail (hashtable->ref_count > 0, hashtable); fluid_atomic_int_add (&hashtable->ref_count, 1); return hashtable; }
/** * fluid_hashtable_foreach_steal: * @hashtable: a #fluid_hashtable_t. * @func: the function to call for each key/value pair. * @user_data: user data to pass to the function. * * Calls the given function for each key/value pair in the #fluid_hashtable_t. * If the function returns %TRUE, then the key/value pair is removed from the * #fluid_hashtable_t, but no key or value destroy functions are called. * * See #fluid_hashtable_iter_t for an alternative way to loop over the * key/value pairs in the hash table. * * Return value: the number of key/value pairs removed. **/ unsigned int fluid_hashtable_foreach_steal (fluid_hashtable_t *hashtable, fluid_hr_func_t func, void *user_data) { fluid_return_val_if_fail (hashtable != NULL, 0); fluid_return_val_if_fail (func != NULL, 0); return fluid_hashtable_foreach_remove_or_steal (hashtable, func, user_data, FALSE); }
/** * Set a string value for a named setting * * @param settings a settings object * @param name a setting's name * @param str new string value * @return 1 if the value has been set, 0 otherwise */ int fluid_settings_setstr(fluid_settings_t* settings, const char *name, const char *str) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get (settings, name, &node)) { if (node->type == FLUID_STR_TYPE) { fluid_str_setting_t *setting = (fluid_str_setting_t *)node; if (setting->value) FLUID_FREE (setting->value); setting->value = str ? FLUID_STRDUP (str) : NULL; /* Call under lock to keep update() synchronized with the current value */ if (setting->update) (*setting->update)(setting->data, name, str); retval = 1; } else if (node->type == FLUID_INT_TYPE) /* Handle yes/no for boolean values for backwards compatibility */ { fluid_int_setting_t *setting = (fluid_int_setting_t *)node; if (setting->hints & FLUID_HINT_TOGGLED) { if (FLUID_STRCMP (str, "yes") == 0) { setting->value = TRUE; if (setting->update) (*setting->update)(setting->data, name, TRUE); } else if (FLUID_STRCMP (str, "no") == 0) { setting->value = FALSE; if (setting->update) (*setting->update)(setting->data, name, FALSE); } } } } else { /* insert a new setting */ fluid_str_setting_t* setting; setting = new_fluid_str_setting(str, NULL, 0, NULL, NULL); retval = fluid_settings_set(settings, name, setting); if (retval != 1) delete_fluid_str_setting (setting); } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Get the type of the setting with the given name * * @param settings a settings object * @param name a setting's name * @return the type for the named setting, or #FLUID_NO_TYPE when it does not exist */ int fluid_settings_get_type(fluid_settings_t* settings, const char *name) { fluid_setting_node_t *node; int type; fluid_return_val_if_fail (settings != NULL, FLUID_NO_TYPE); fluid_return_val_if_fail (name != NULL, FLUID_NO_TYPE); fluid_rec_mutex_lock (settings->mutex); type = fluid_settings_get (settings, name, &node) ? node->type : FLUID_NO_TYPE; fluid_rec_mutex_unlock (settings->mutex); return (type); }
/** * Copy the value of a string setting * @param settings a settings object * @param name a setting's name * @param str Caller supplied buffer to copy string value to * @param len Size of 'str' buffer (no more than len bytes will be written, which * will always include a zero terminator) * @return 1 if the value exists, 0 otherwise * @since 1.1.0 * * Like fluid_settings_getstr() but is thread safe. A size of 256 should be * more than sufficient for the string buffer. */ int fluid_settings_copystr(fluid_settings_t* settings, const char *name, char *str, int len) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_return_val_if_fail (str != NULL, 0); fluid_return_val_if_fail (len > 0, 0); str[0] = 0; fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get (settings, name, &node)) { if (node->type == FLUID_STR_TYPE) { fluid_str_setting_t *setting = (fluid_str_setting_t *)node; if (setting->value) { FLUID_STRNCPY (str, setting->value, len); str[len - 1] = 0; /* Force terminate, in case of truncation */ } retval = 1; } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { fluid_int_setting_t *setting = (fluid_int_setting_t *)node; if (setting->hints & FLUID_HINT_TOGGLED) { FLUID_STRNCPY (str, setting->value ? "yes" : "no", len); str[len - 1] = 0; /* Force terminate, in case of truncation */ retval = 1; } } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * fluid_hashtable_size: * @hashtable: a #fluid_hashtable_t. * * Returns the number of elements contained in the #fluid_hashtable_t. * * Return value: the number of key/value pairs in the #fluid_hashtable_t. **/ unsigned int fluid_hashtable_size (fluid_hashtable_t *hashtable) { fluid_return_val_if_fail (hashtable != NULL, 0); return hashtable->nnodes; }
/** * fluid_hashtable_find: * @hashtable: a #fluid_hashtable_t. * @predicate: function to test the key/value pairs for a certain property. * @user_data: user data to pass to the function. * * Calls the given function for key/value pairs in the #fluid_hashtable_t until * @predicate returns %TRUE. The function is passed the key and value of * each pair, and the given @user_data parameter. The hash table may not * be modified while iterating over it (you can't add/remove items). * * Note, that hash tables are really only optimized for forward lookups, * i.e. fluid_hashtable_lookup(). * So code that frequently issues fluid_hashtable_find() or * fluid_hashtable_foreach() (e.g. in the order of once per every entry in a * hash table) should probably be reworked to use additional or different * data structures for reverse lookups (keep in mind that an O(n) find/foreach * operation issued for all n values in a hash table ends up needing O(n*n) * operations). * * Return value: The value of the first key/value pair is returned, for which * func evaluates to %TRUE. If no pair with the requested property is found, * %NULL is returned. * * Since: 2.4 **/ void * fluid_hashtable_find (fluid_hashtable_t *hashtable, fluid_hr_func_t predicate, void *user_data) { fluid_hashnode_t *node; int i; fluid_return_val_if_fail (hashtable != NULL, NULL); fluid_return_val_if_fail (predicate != NULL, NULL); for (i = 0; i < hashtable->size; i++) for (node = hashtable->nodes[i]; node; node = node->next) if (predicate (node->key, node->value, user_data)) return node->value; return NULL; }
/** * fluid_hashtable_iter_get_hash_table: * @iter: an initialized #fluid_hashtable_iter_t. * * Returns the #fluid_hashtable_t associated with @iter. * * Return value: the #fluid_hashtable_t associated with @iter. * * Since: 2.16 **/ fluid_hashtable_t * fluid_hashtable_iter_get_hash_table (fluid_hashtable_iter_t *iter) { fluid_return_val_if_fail (iter != NULL, NULL); return ((RealIter *) iter)->hashtable; }
/** * Count option string values for a string setting. * @param settings a settings object * @param name Name of setting * @return Count of options for this string setting (0 if none, -1 if not found * or not a string setting) * @since 1.1.0 */ int fluid_settings_option_count (fluid_settings_t *settings, const char *name) { fluid_setting_node_t *node; int count = -1; fluid_return_val_if_fail (settings != NULL, -1); fluid_return_val_if_fail (name != NULL, -1); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) && node->type == FLUID_STR_TYPE) count = fluid_list_size (((fluid_str_setting_t *)node)->options); fluid_rec_mutex_unlock (settings->mutex); return (count); }
/** * Duplicate the value of a string setting * @param settings a settings object * @param name a setting's name * @param str Location to store pointer to allocated duplicate string * @return 1 if the value exists and was successfully duplicated, 0 otherwise * @since 1.1.0 * * Like fluid_settings_copystr() but allocates a new copy of the string. Caller * owns the string and should free it with free() when done using it. */ int fluid_settings_dupstr(fluid_settings_t* settings, const char *name, char** str) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_return_val_if_fail (str != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node)) { if (node->type == FLUID_STR_TYPE) { fluid_str_setting_t *setting = (fluid_str_setting_t *)node; if (setting->value) { *str = FLUID_STRDUP (setting->value); if (!*str) FLUID_LOG (FLUID_ERR, "Out of memory"); } if (!setting->value || *str) retval = 1; /* Don't set to 1 if out of memory */ } else if (node->type == FLUID_INT_TYPE) /* Handle boolean integers for backwards compatibility */ { fluid_int_setting_t *setting = (fluid_int_setting_t *)node; if (setting->hints & FLUID_HINT_TOGGLED) { *str = FLUID_STRDUP (setting->value ? "yes" : "no"); if (!*str) FLUID_LOG (FLUID_ERR, "Out of memory"); if (!setting->value || *str) retval = 1; /* Don't set to 1 if out of memory */ } } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** returns 1 if the value has been register correctly, zero otherwise. */ int fluid_settings_register_int(fluid_settings_t* settings, char* name, int def, int min, int max, int hints, fluid_int_update_t fun, void* data) { fluid_setting_node_t *node; int retval; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); /* For now, all integer settings are bounded below and above */ hints |= FLUID_HINT_BOUNDED_BELOW | FLUID_HINT_BOUNDED_ABOVE; fluid_rec_mutex_lock (settings->mutex); if (!fluid_settings_get(settings, name, &node)) { /* insert a new setting */ fluid_int_setting_t* setting; setting = new_fluid_int_setting(min, max, def, hints, fun, data); retval = fluid_settings_set(settings, name, setting); if (retval != 1) delete_fluid_int_setting (setting); } else { if (node->type == FLUID_INT_TYPE) { /* update the existing setting but don't change its value */ fluid_int_setting_t* setting = (fluid_int_setting_t*) node; setting->update = fun; setting->data = data; setting->min = min; setting->max = max; setting->def = def; setting->hints = hints; retval = 1; } else { /* type mismatch */ FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name); retval = 0; } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * fluid_hashtable_lookup: * @hashtable: a #fluid_hashtable_t. * @key: the key to look up. * * Looks up a key in a #fluid_hashtable_t. Note that this function cannot * distinguish between a key that is not present and one which is present * and has the value %NULL. If you need this distinction, use * fluid_hashtable_lookup_extended(). * * Return value: the associated value, or %NULL if the key is not found. **/ void * fluid_hashtable_lookup (fluid_hashtable_t *hashtable, const void *key) { fluid_hashnode_t *node; fluid_return_val_if_fail (hashtable != NULL, NULL); node = *fluid_hashtable_lookup_node (hashtable, key, NULL); return node ? node->value : NULL; }
/** * Clear all rules in a MIDI router. Such a router will drop all events until * rules are added. * @param router Router to clear all rules from * @return #FLUID_OK on success, #FLUID_FAILED otherwise * @since 1.1.0 */ int fluid_midi_router_clear_rules (fluid_midi_router_t *router) { fluid_midi_router_rule_t *del_rules[FLUID_MIDI_ROUTER_RULE_COUNT]; fluid_midi_router_rule_t *rule, *next_rule, *prev_rule; int i; fluid_return_val_if_fail (router != NULL, FLUID_FAILED); fluid_mutex_lock (router->rules_mutex); /* ++ lock */ for (i = 0; i < FLUID_MIDI_ROUTER_RULE_COUNT; i++) { del_rules[i] = NULL; prev_rule = NULL; /* Process existing rules */ for (rule = router->rules[i]; rule; rule = next_rule) { next_rule = rule->next; if (rule->pending_events == 0) /* Rule has no pending events? */ { /* Remove rule from rule list */ if (prev_rule) prev_rule->next = next_rule; else if (rule == router->rules[i]) router->rules[i] = next_rule; /* Prepend to delete list */ rule->next = del_rules[i]; del_rules[i] = rule; } else { rule->waiting = TRUE; /* Pending events, mark as waiting */ prev_rule = rule; } } } fluid_mutex_unlock (router->rules_mutex); /* -- unlock */ /* Free old rules outside of lock */ for (i = 0; i < FLUID_MIDI_ROUTER_RULE_COUNT; i++) { for (rule = del_rules[i]; rule; rule = next_rule) { next_rule = rule->next; FLUID_FREE (rule); } } return FLUID_OK; }
/** * Get the default value of a named numeric (double) setting * * @param settings a settings object * @param name a setting's name * @return the default value if the named setting exists, 0.0f otherwise */ double fluid_settings_getnum_default(fluid_settings_t* settings, const char *name) { fluid_setting_node_t *node; double retval = 0.0; fluid_return_val_if_fail (settings != NULL, 0.0); fluid_return_val_if_fail (name != NULL, 0.0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) && (node->type == FLUID_NUM_TYPE)) { fluid_num_setting_t* setting = (fluid_num_setting_t*) node; retval = setting->def; } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Get the default value of an integer setting. * * @param settings a settings object * @param name a setting's name * @return the setting's default integer value it it exists, zero otherwise */ int fluid_settings_getint_default(fluid_settings_t* settings, const char *name) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) && (node->type == FLUID_INT_TYPE)) { fluid_int_setting_t* setting = (fluid_int_setting_t*) node; retval = setting->def; } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Set an integer value for a setting * * @param settings a settings object * @param name a setting's name * @param val new setting's integer value * @return 1 if the value has been set, 0 otherwise */ int fluid_settings_setint(fluid_settings_t* settings, const char *name, int val) { fluid_setting_node_t *node; fluid_int_setting_t* setting; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node)) { if (node->type == FLUID_INT_TYPE) { setting = (fluid_int_setting_t*) node; if (val < setting->min) val = setting->min; else if (val > setting->max) val = setting->max; setting->value = val; /* Call under lock to keep update() synchronized with the current value */ if (setting->update) (*setting->update)(setting->data, name, val); retval = 1; } } else { /* insert a new setting */ fluid_int_setting_t* setting; setting = new_fluid_int_setting(INT_MIN, INT_MAX, 0, 0, NULL, NULL); setting->value = val; retval = fluid_settings_set(settings, name, setting); if (retval != 1) delete_fluid_int_setting (setting); } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * Get the numeric value of a named setting * * @param settings a settings object * @param name a setting's name * @param val variable pointer to receive the setting's numeric value * @return 1 if the value exists, 0 otherwise */ int fluid_settings_getnum(fluid_settings_t* settings, const char *name, double* val) { fluid_setting_node_t *node; int retval = 0; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_return_val_if_fail (val != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (fluid_settings_get(settings, name, &node) && (node->type == FLUID_NUM_TYPE)) { fluid_num_setting_t* setting = (fluid_num_setting_t*) node; *val = setting->value; retval = 1; } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** returns 1 if the value has been registered correctly, 0 otherwise */ int fluid_settings_register_str(fluid_settings_t* settings, char* name, char* def, int hints, fluid_str_update_t fun, void* data) { fluid_setting_node_t *node; fluid_str_setting_t* setting; int retval; fluid_return_val_if_fail (settings != NULL, 0); fluid_return_val_if_fail (name != NULL, 0); fluid_rec_mutex_lock (settings->mutex); if (!fluid_settings_get(settings, name, &node)) { setting = new_fluid_str_setting(def, def, hints, fun, data); retval = fluid_settings_set(settings, name, setting); if (retval != 1) delete_fluid_str_setting (setting); } else { /* if variable already exists, don't change its value. */ if (node->type == FLUID_STR_TYPE) { setting = (fluid_str_setting_t*) node; setting->update = fun; setting->data = data; setting->def = def? FLUID_STRDUP(def) : NULL; setting->hints = hints; retval = 1; } else { FLUID_LOG(FLUID_WARN, "Type mismatch on setting '%s'", name); retval = 0; } } fluid_rec_mutex_unlock (settings->mutex); return retval; }
/** * fluid_hashtable_get_values: * @hashtable: a #fluid_hashtable_t * * Retrieves every value inside @hashtable. The returned data is * valid until @hashtable is modified. * * Return value: a #GList containing all the values inside the hash * table. The content of the list is owned by the hash table and * should not be modified or freed. Use delete_fluid_list() when done * using the list. * * Since: 2.14 */ fluid_list_t * fluid_hashtable_get_values (fluid_hashtable_t *hashtable) { fluid_hashnode_t *node; int i; fluid_list_t *retval; fluid_return_val_if_fail (hashtable != NULL, NULL); retval = NULL; for (i = 0; i < hashtable->size; i++) for (node = hashtable->nodes[i]; node; node = node->next) retval = fluid_list_prepend (retval, node->value); return retval; }
/* * fluid_hashtable_remove_internal: * @hashtable: our #fluid_hashtable_t * @key: the key to remove * @notify: %TRUE if the destroy notify handlers are to be called * Return value: %TRUE if a node was found and removed, else %FALSE * * Implements the common logic for the fluid_hashtable_remove() and * fluid_hashtable_steal() functions. * * Do a lookup of @key and remove it if it is found, calling the * destroy notify handlers only if @notify is %TRUE. */ static int fluid_hashtable_remove_internal (fluid_hashtable_t *hashtable, const void *key, int notify) { fluid_hashnode_t **node_ptr; fluid_return_val_if_fail (hashtable != NULL, FALSE); node_ptr = fluid_hashtable_lookup_node (hashtable, key, NULL); if (*node_ptr == NULL) return FALSE; fluid_hashtable_remove_node (hashtable, &node_ptr, notify); fluid_hashtable_maybe_resize (hashtable); return TRUE; }
/* Unref a tuning object, when it reaches 0 it is deleted, returns TRUE if deleted */ int fluid_tuning_unref (fluid_tuning_t *tuning, int count) { fluid_return_val_if_fail (tuning != NULL, FALSE); /* Add and compare are separate, but that is OK, since refcount will only * reach 0 when there are no references and therefore no possibility of * another thread adding a reference in between */ fluid_atomic_int_add (&tuning->refcount, -count); /* Delete when refcount reaches 0 */ if (!fluid_atomic_int_get (&tuning->refcount)) { delete_fluid_tuning (tuning); return TRUE; } else return FALSE; }
/** * fluid_hashtable_iter_next: * @iter: an initialized #fluid_hashtable_iter_t. * @key: a location to store the key, or %NULL. * @value: a location to store the value, or %NULL. * * Advances @iter and retrieves the key and/or value that are now * pointed to as a result of this advancement. If %FALSE is returned, * @key and @value are not set, and the iterator becomes invalid. * * Return value: %FALSE if the end of the #fluid_hashtable_t has been reached. * * Since: 2.16 **/ int fluid_hashtable_iter_next (fluid_hashtable_iter_t *iter, void **key, void **value) { RealIter *ri = (RealIter *) iter; fluid_return_val_if_fail (iter != NULL, FALSE); if (ri->pre_advanced) { ri->pre_advanced = FALSE; if (ri->node == NULL) return FALSE; } else { if (ri->node != NULL) { ri->prev_node = ri->node; ri->node = ri->node->next; } while (ri->node == NULL) { ri->position++; if (ri->position >= ri->hashtable->size) return FALSE; ri->prev_node = NULL; ri->node = ri->hashtable->nodes[ri->position]; } } if (key != NULL) *key = ri->node->key; if (value != NULL) *value = ri->node->value; return TRUE; }
/** * fluid_hashtable_lookup_extended: * @hashtable: a #fluid_hashtable_t. * @lookup_key: the key to look up. * @orig_key: returns the original key. * @value: returns the value associated with the key. * * Looks up a key in the #fluid_hashtable_t, returning the original key and the * associated value and a #gboolean which is %TRUE if the key was found. This * is useful if you need to free the memory allocated for the original key, * for example before calling fluid_hashtable_remove(). * * Return value: %TRUE if the key was found in the #fluid_hashtable_t. **/ int fluid_hashtable_lookup_extended (fluid_hashtable_t *hashtable, const void *lookup_key, void **orig_key, void **value) { fluid_hashnode_t *node; fluid_return_val_if_fail (hashtable != NULL, FALSE); node = *fluid_hashtable_lookup_node (hashtable, lookup_key, NULL); if (node == NULL) return FALSE; if (orig_key) *orig_key = node->key; if (value) *value = node->value; return TRUE; }