* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
static PurpleRequestUiOps *request_ui_ops = NULL;
static GList *handles = NULL;
} PurpleRequestCloseNotified;
struct _PurpleRequestField
PurpleRequestFieldType type;
PurpleRequestFieldGroup *group;
PurpleRequestFieldSensitivityCb sensitivity_cb;
GDestroyNotify data_destroy;
GHashTable *selected_table;
gboolean multiple_selection;
PurpleAccount *default_account;
PurpleFilterAccountFunc filter_func;
PurpleRequestDatasheet *sheet;
PurpleRequestFieldValidator validator;
struct _PurpleRequestFields
GList *autosensitive_fields;
struct _PurpleRequestFieldGroup
PurpleRequestFields *fields_list;
struct _PurpleRequestCommonParameters
PurpleConversation *conv;
PurpleRequestIconType icon_type;
PurpleRequestHelpCb help_cb;
purple_request_fields_check_others_sensitivity(PurpleRequestField *field);
PurpleRequestCommonParameters *
purple_request_cpar_new(void)
return g_new0(PurpleRequestCommonParameters, 1);
PurpleRequestCommonParameters *
purple_request_cpar_from_connection(PurpleConnection *gc)
return purple_request_cpar_new();
return purple_request_cpar_from_account(
purple_connection_get_account(gc));
PurpleRequestCommonParameters *
purple_request_cpar_from_account(PurpleAccount *account)
PurpleRequestCommonParameters *cpar;
cpar = purple_request_cpar_new();
purple_request_cpar_set_account(cpar, account);
PurpleRequestCommonParameters *
purple_request_cpar_from_conversation(PurpleConversation *conv)
PurpleRequestCommonParameters *cpar;
PurpleAccount *account = NULL;
account = purple_connection_get_account(
purple_conversation_get_connection(conv));
cpar = purple_request_cpar_new();
purple_request_cpar_set_account(cpar, account);
purple_request_cpar_set_conversation(cpar, conv);
purple_request_cpar_ref(PurpleRequestCommonParameters *cpar)
g_return_if_fail(cpar != NULL);
PurpleRequestCommonParameters *
purple_request_cpar_unref(PurpleRequestCommonParameters *cpar)
if (--cpar->ref_count > 0)
purple_request_cpar_set_extra_actions(cpar, NULL);
purple_request_cpar_set_account(PurpleRequestCommonParameters *cpar,
g_return_if_fail(cpar != NULL);
purple_request_cpar_get_account(PurpleRequestCommonParameters *cpar)
purple_request_cpar_set_conversation(PurpleRequestCommonParameters *cpar,
PurpleConversation *conv)
g_return_if_fail(cpar != NULL);
purple_request_cpar_get_conversation(PurpleRequestCommonParameters *cpar)
purple_request_cpar_set_icon(PurpleRequestCommonParameters *cpar,
PurpleRequestIconType icon_type)
g_return_if_fail(cpar != NULL);
cpar->icon_type = icon_type;
purple_request_cpar_get_icon(PurpleRequestCommonParameters *cpar)
return PURPLE_REQUEST_ICON_DEFAULT;
purple_request_cpar_set_custom_icon(PurpleRequestCommonParameters *cpar,
gconstpointer icon_data, gsize icon_size)
g_return_if_fail(cpar != NULL);
g_return_if_fail((icon_data == NULL) == (icon_size == 0));
cpar->icon_data = icon_data;
cpar->icon_size = icon_size;
purple_request_cpar_get_custom_icon(PurpleRequestCommonParameters *cpar,
*icon_size = cpar->icon_size;
purple_request_cpar_set_html(PurpleRequestCommonParameters *cpar,
g_return_if_fail(cpar != NULL);
purple_request_cpar_is_html(PurpleRequestCommonParameters *cpar)
purple_request_cpar_set_compact(PurpleRequestCommonParameters *cpar,
g_return_if_fail(cpar != NULL);
purple_request_cpar_is_compact(PurpleRequestCommonParameters *cpar)
purple_request_cpar_set_help_cb(PurpleRequestCommonParameters *cpar,
PurpleRequestHelpCb cb, gpointer user_data)
g_return_if_fail(cpar != NULL);
cpar->help_data = cb ? user_data : NULL;
purple_request_cpar_get_help_cb(PurpleRequestCommonParameters *cpar,
*user_data = cpar->help_data;
purple_request_cpar_set_extra_actions(PurpleRequestCommonParameters *cpar, ...)
GSList *extra = NULL, *it;
it = cpar->extra_actions;
PurpleRequestFieldsCb cb;
label = va_arg(args, const gchar*);
cb = va_arg(args, PurpleRequestFieldsCb);
extra = g_slist_append(extra, g_strdup(label));
extra = g_slist_append(extra, cb);
cpar->extra_actions = extra;
purple_request_cpar_get_extra_actions(PurpleRequestCommonParameters *cpar)
return cpar->extra_actions;
purple_request_cpar_set_parent_from(PurpleRequestCommonParameters *cpar,
g_return_if_fail(cpar != NULL);
cpar->parent_from = ui_handle;
purple_request_cpar_get_parent_from(PurpleRequestCommonParameters *cpar)
return cpar->parent_from;
static PurpleRequestInfo *
purple_request_info_from_ui_handle(void *ui_handle)
g_return_val_if_fail(ui_handle != NULL, NULL);
for (it = handles; it != NULL; it = g_list_next(it)) {
PurpleRequestInfo *info = it->data;
if (info->ui_handle == ui_handle)
purple_request_fields_new(void)
PurpleRequestFields *fields;
fields = g_new0(PurpleRequestFields, 1);
fields->fields = g_hash_table_new_full(g_str_hash, g_str_equal,
purple_request_fields_destroy(PurpleRequestFields *fields)
g_return_if_fail(fields != NULL);
g_strfreev(fields->tab_names);
g_list_free_full(fields->groups,
(GDestroyNotify)purple_request_field_group_destroy);
g_list_free(fields->required_fields);
g_list_free(fields->validated_fields);
g_list_free(fields->autosensitive_fields);
g_hash_table_destroy(fields->fields);
purple_request_fields_add_group(PurpleRequestFields *fields,
PurpleRequestFieldGroup *group)
PurpleRequestField *field;
g_return_if_fail(fields != NULL);
g_return_if_fail(group != NULL);
fields->groups = g_list_append(fields->groups, group);
group->fields_list = fields;
for (l = purple_request_field_group_get_fields(group);
g_hash_table_insert(fields->fields,
g_strdup(purple_request_field_get_id(field)), field);
if (purple_request_field_is_required(field)) {
fields->required_fields =
g_list_append(fields->required_fields, field);
if (purple_request_field_is_validatable(field)) {
fields->validated_fields =
g_list_append(fields->validated_fields, field);
if (field->sensitivity_cb != NULL) {
fields->autosensitive_fields =
g_list_append(fields->autosensitive_fields, field);
purple_request_fields_get_groups(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, NULL);
purple_request_fields_set_tab_names(PurpleRequestFields *fields,
g_return_if_fail(fields != NULL);
tab_count = (tab_names != NULL) ? g_strv_length((gchar **)tab_names) : 0;
new_names = (tab_count > 0) ? g_new0(gchar*, tab_count + 1) : NULL;
for (i = 0; i < tab_count; i++)
new_names[i] = g_strdup(tab_names[i]);
g_strfreev(fields->tab_names);
fields->tab_names = new_names;
purple_request_fields_get_tab_names(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, NULL);
return (const gchar **)fields->tab_names;
purple_request_fields_exists(const PurpleRequestFields *fields, const char *id)
g_return_val_if_fail(fields != NULL, FALSE);
g_return_val_if_fail(id != NULL, FALSE);
return (g_hash_table_lookup(fields->fields, id) != NULL);
purple_request_fields_get_required(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, NULL);
return fields->required_fields;
purple_request_fields_get_validatable(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, NULL);
return fields->validated_fields;
purple_request_fields_get_autosensitive(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, NULL);
return fields->autosensitive_fields;
purple_request_fields_is_field_required(const PurpleRequestFields *fields,
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, FALSE);
g_return_val_if_fail(id != NULL, FALSE);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return purple_request_field_is_required(field);
purple_request_field_get_ui_data(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
purple_request_field_set_ui_data(PurpleRequestField *field,
g_return_if_fail(field != NULL);
field->ui_data = ui_data;
purple_request_fields_all_required_filled(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, FALSE);
for (l = fields->required_fields; l != NULL; l = l->next)
PurpleRequestField *field = (PurpleRequestField *)l->data;
if (!purple_request_field_is_filled(field))
purple_request_fields_all_valid(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, FALSE);
for (l = fields->validated_fields; l != NULL; l = l->next)
PurpleRequestField *field = (PurpleRequestField *)l->data;
if (!purple_request_field_is_valid(field, NULL))
purple_request_fields_check_sensitivity(PurpleRequestFields *fields)
g_return_if_fail(fields != NULL);
for (it = fields->autosensitive_fields; it; it = g_list_next(it)) {
PurpleRequestField *field = it->data;
if (field->sensitivity_cb == NULL) {
purple_request_field_set_sensitive(field,
field->sensitivity_cb(field));
purple_request_fields_check_others_sensitivity(PurpleRequestField *field)
g_return_if_fail(field != NULL);
if (field->group == NULL || field->group->fields_list == NULL)
purple_request_fields_check_sensitivity(field->group->fields_list);
purple_request_fields_get_field(const PurpleRequestFields *fields, const char *id)
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
field = g_hash_table_lookup(fields->fields, id);
g_return_val_if_fail(field != NULL, NULL);
purple_request_fields_get_string(const PurpleRequestFields *fields, const char *id)
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return purple_request_field_string_get_value(field);
purple_request_fields_get_integer(const PurpleRequestFields *fields,
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, 0);
g_return_val_if_fail(id != NULL, 0);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return purple_request_field_int_get_value(field);
purple_request_fields_get_bool(const PurpleRequestFields *fields, const char *id)
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, FALSE);
g_return_val_if_fail(id != NULL, FALSE);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return purple_request_field_bool_get_value(field);
purple_request_fields_get_choice(const PurpleRequestFields *fields,
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return purple_request_field_choice_get_value(field);
purple_request_fields_get_account(const PurpleRequestFields *fields,
PurpleRequestField *field;
g_return_val_if_fail(fields != NULL, NULL);
g_return_val_if_fail(id != NULL, NULL);
if ((field = purple_request_fields_get_field(fields, id)) == NULL)
return purple_request_field_account_get_value(field);
gpointer purple_request_fields_get_ui_data(const PurpleRequestFields *fields)
g_return_val_if_fail(fields != NULL, NULL);
void purple_request_fields_set_ui_data(PurpleRequestFields *fields, gpointer ui_data)
g_return_if_fail(fields != NULL);
fields->ui_data = ui_data;
PurpleRequestFieldGroup *
purple_request_field_group_new(const char *title)
PurpleRequestFieldGroup *group;
group = g_new0(PurpleRequestFieldGroup, 1);
group->title = g_strdup(title);
purple_request_field_group_set_tab(PurpleRequestFieldGroup *group, guint tab_no)
g_return_if_fail(group != NULL);
purple_request_field_group_get_tab(const PurpleRequestFieldGroup *group)
purple_request_field_group_destroy(PurpleRequestFieldGroup *group)
g_return_if_fail(group != NULL);
g_list_free_full(group->fields,
(GDestroyNotify)purple_request_field_destroy);
purple_request_field_group_add_field(PurpleRequestFieldGroup *group,
PurpleRequestField *field)
g_return_if_fail(group != NULL);
g_return_if_fail(field != NULL);
group->fields = g_list_append(group->fields, field);
if (group->fields_list != NULL)
g_hash_table_insert(group->fields_list->fields,
g_strdup(purple_request_field_get_id(field)), field);
if (purple_request_field_is_required(field))
group->fields_list->required_fields =
g_list_append(group->fields_list->required_fields, field);
if (purple_request_field_is_validatable(field))
group->fields_list->validated_fields =
g_list_append(group->fields_list->validated_fields, field);
if (field->sensitivity_cb != NULL)
group->fields_list->autosensitive_fields =
g_list_append(group->fields_list->autosensitive_fields, field);
purple_request_field_group_get_title(const PurpleRequestFieldGroup *group)
g_return_val_if_fail(group != NULL, NULL);
purple_request_field_group_get_fields(const PurpleRequestFieldGroup *group)
g_return_val_if_fail(group != NULL, NULL);
purple_request_field_group_get_fields_list(const PurpleRequestFieldGroup *group)
g_return_val_if_fail(group != NULL, NULL);
return group->fields_list;
purple_request_field_new(const char *id, const char *text,
PurpleRequestFieldType type)
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(type != PURPLE_REQUEST_FIELD_NONE, NULL);
field = g_new0(PurpleRequestField, 1);
field->id = g_strdup(id);
purple_request_field_set_label(field, text);
purple_request_field_set_visible(field, TRUE);
purple_request_field_set_sensitive(field, TRUE);
purple_request_field_destroy(PurpleRequestField *field)
g_return_if_fail(field != NULL);
g_free(field->type_hint);
if (field->type == PURPLE_REQUEST_FIELD_STRING)
g_free(field->u.string.default_value);
g_free(field->u.string.value);
else if (field->type == PURPLE_REQUEST_FIELD_CHOICE)
if (field->u.choice.elements != NULL)
GList *it = field->u.choice.elements;
it = g_list_next(it); /* value */
if (it->data && field->u.choice.data_destroy)
field->u.choice.data_destroy(it->data);
it = g_list_next(it); /* next label */
g_list_free(field->u.choice.elements);
else if (field->type == PURPLE_REQUEST_FIELD_LIST)
g_list_free_full(field->u.list.items, g_free);
g_list_free_full(field->u.list.selected, g_free);
g_hash_table_destroy(field->u.list.item_data);
g_hash_table_destroy(field->u.list.selected_table);
else if (field->type == PURPLE_REQUEST_FIELD_DATASHEET)
purple_request_datasheet_free(field->u.datasheet.sheet);
purple_request_field_set_label(PurpleRequestField *field, const char *label)
g_return_if_fail(field != NULL);
field->label = g_strdup(label);
purple_request_field_set_visible(PurpleRequestField *field, gboolean visible)
g_return_if_fail(field != NULL);
field->visible = visible;
purple_request_field_set_type_hint(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_free(field->type_hint);
field->type_hint = g_strdup(type_hint);
purple_request_field_set_tooltip(PurpleRequestField *field, const char *tooltip)
g_return_if_fail(field != NULL);
field->tooltip = g_strdup(tooltip);
purple_request_field_set_required(PurpleRequestField *field, gboolean required)
g_return_if_fail(field != NULL);
if (field->required == required)
field->required = required;
if (field->group != NULL)
field->group->fields_list->required_fields =
g_list_append(field->group->fields_list->required_fields,
field->group->fields_list->required_fields =
g_list_remove(field->group->fields_list->required_fields,
purple_request_field_get_field_type(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, PURPLE_REQUEST_FIELD_NONE);
PurpleRequestFieldGroup *
purple_request_field_get_group(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
purple_request_field_get_id(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
purple_request_field_get_label(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
purple_request_field_is_visible(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
purple_request_field_get_field_type_hint(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
purple_request_field_get_tooltip(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
purple_request_field_is_required(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
purple_request_field_is_filled(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
switch (purple_request_field_get_field_type(field))
case PURPLE_REQUEST_FIELD_STRING:
return (purple_request_field_string_get_value(field) != NULL &&
*(purple_request_field_string_get_value(field)) != '\0');
purple_request_field_set_validator(PurpleRequestField *field,
PurpleRequestFieldValidator validator, void *user_data)
g_return_if_fail(field != NULL);
field->validator = validator;
field->validator_data = validator ? user_data : NULL;
if (field->group != NULL)
PurpleRequestFields *flist = field->group->fields_list;
flist->validated_fields = g_list_remove(flist->validated_fields,
flist->validated_fields = g_list_append(
flist->validated_fields, field);
purple_request_field_is_validatable(PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
return field->validator != NULL;
purple_request_field_is_valid(PurpleRequestField *field, gchar **errmsg)
g_return_val_if_fail(field != NULL, FALSE);
if (!purple_request_field_is_required(field) &&
!purple_request_field_is_filled(field))
valid = field->validator(field, errmsg, field->validator_data);
purple_request_field_set_sensitive(PurpleRequestField *field,
g_return_if_fail(field != NULL);
field->sensitive = sensitive;
purple_request_field_is_sensitive(PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
purple_request_field_set_sensitivity_cb(PurpleRequestField *field,
PurpleRequestFieldSensitivityCb cb)
PurpleRequestFields *flist;
g_return_if_fail(field != NULL);
field->sensitivity_cb = cb;
if (!field->group || !field->group->fields_list)
flist = field->group->fields_list;
flist->autosensitive_fields = g_list_remove(flist->autosensitive_fields,
flist->autosensitive_fields = g_list_append(
flist->autosensitive_fields, field);
purple_request_field_string_new(const char *id, const char *text,
const char *default_value, gboolean multiline)
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_STRING);
field->u.string.multiline = multiline;
purple_request_field_string_set_default_value(field, default_value);
purple_request_field_string_set_value(field, default_value);
purple_request_field_string_set_default_value(PurpleRequestField *field,
const char *default_value)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING);
g_free(field->u.string.default_value);
field->u.string.default_value = g_strdup(default_value);
purple_request_field_string_set_value(PurpleRequestField *field, const char *value)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING);
g_free(field->u.string.value);
field->u.string.value = g_strdup(value);
purple_request_fields_check_others_sensitivity(field);
purple_request_field_string_set_masked(PurpleRequestField *field, gboolean masked)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING);
field->u.string.masked = masked;
purple_request_field_string_get_default_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, NULL);
return field->u.string.default_value;
purple_request_field_string_get_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, NULL);
return field->u.string.value;
purple_request_field_string_is_multiline(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
return field->u.string.multiline;
purple_request_field_string_is_masked(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
return field->u.string.masked;
purple_request_field_int_new(const char *id, const char *text,
int default_value, int lower_bound, int upper_bound)
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_INTEGER);
purple_request_field_int_set_lower_bound(field, lower_bound);
purple_request_field_int_set_upper_bound(field, upper_bound);
purple_request_field_int_set_default_value(field, default_value);
purple_request_field_int_set_value(field, default_value);
purple_request_field_int_set_default_value(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
field->u.integer.default_value = default_value;
purple_request_field_int_set_lower_bound(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
field->u.integer.lower_bound = lower_bound;
purple_request_field_int_set_upper_bound(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
field->u.integer.upper_bound = upper_bound;
purple_request_field_int_set_value(PurpleRequestField *field, int value)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER);
if (value < field->u.integer.lower_bound ||
value > field->u.integer.upper_bound) {
purple_debug_error("request", "Int value out of bounds\n");
field->u.integer.value = value;
purple_request_fields_check_others_sensitivity(field);
purple_request_field_int_get_default_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.default_value;
purple_request_field_int_get_lower_bound(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.lower_bound;
purple_request_field_int_get_upper_bound(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.upper_bound;
purple_request_field_int_get_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_INTEGER, 0);
return field->u.integer.value;
purple_request_field_bool_new(const char *id, const char *text,
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_BOOLEAN);
purple_request_field_bool_set_default_value(field, default_value);
purple_request_field_bool_set_value(field, default_value);
purple_request_field_bool_set_default_value(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN);
field->u.boolean.default_value = default_value;
purple_request_field_bool_set_value(PurpleRequestField *field, gboolean value)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN);
field->u.boolean.value = value;
purple_request_fields_check_others_sensitivity(field);
purple_request_field_bool_get_default_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN, FALSE);
return field->u.boolean.default_value;
purple_request_field_bool_get_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_BOOLEAN, FALSE);
return field->u.boolean.value;
purple_request_field_choice_new(const char *id, const char *text,
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_CHOICE);
purple_request_field_choice_set_default_value(field, default_value);
purple_request_field_choice_set_value(field, default_value);
purple_request_field_choice_add(PurpleRequestField *field, const char *label,
g_return_if_fail(field != NULL);
g_return_if_fail(label != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.elements = g_list_append(field->u.choice.elements,
field->u.choice.elements = g_list_append(field->u.choice.elements,
purple_request_field_choice_set_default_value(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.default_value = default_value;
purple_request_field_choice_set_value(PurpleRequestField *field, gpointer value)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.value = value;
purple_request_fields_check_others_sensitivity(field);
purple_request_field_choice_get_default_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
return field->u.choice.default_value;
purple_request_field_choice_get_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
return field->u.choice.value;
purple_request_field_choice_get_elements(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE, NULL);
return field->u.choice.elements;
purple_request_field_choice_set_data_destructor(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_CHOICE);
field->u.choice.data_destroy = destroy;
purple_request_field_list_new(const char *id, const char *text)
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_LIST);
field->u.list.item_data = g_hash_table_new_full(g_str_hash, g_str_equal,
field->u.list.selected_table =
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
purple_request_field_list_set_multi_select(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
field->u.list.multiple_selection = multi_select;
purple_request_field_list_get_multi_select(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, FALSE);
return field->u.list.multiple_selection;
purple_request_field_list_get_data(const PurpleRequestField *field,
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return g_hash_table_lookup(field->u.list.item_data, text);
purple_request_field_list_add_icon(PurpleRequestField *field, const char *item, const char* icon_path,
g_return_if_fail(field != NULL);
g_return_if_fail(item != NULL);
g_return_if_fail(data != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
if (field->u.list.icons == NULL)
for (l = field->u.list.items ; l != NULL ; l = l->next)
/* Order doesn't matter, because we're just
* filing in blank items. So, we use
* g_list_prepend() because it's faster. */
field->u.list.icons = g_list_prepend(field->u.list.icons, NULL);
field->u.list.icons = g_list_append(field->u.list.icons, g_strdup(icon_path));
else if (field->u.list.icons)
/* Keep this even with the items list. */
field->u.list.icons = g_list_append(field->u.list.icons, NULL);
field->u.list.items = g_list_append(field->u.list.items, g_strdup(item));
g_hash_table_insert(field->u.list.item_data, g_strdup(item), data);
purple_request_field_list_add_selected(PurpleRequestField *field, const char *item)
g_return_if_fail(field != NULL);
g_return_if_fail(item != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
if (!purple_request_field_list_get_multi_select(field) &&
field->u.list.selected != NULL)
purple_debug_warning("request",
"More than one item added to non-multi-select "
purple_request_field_get_id(field));
field->u.list.selected = g_list_append(field->u.list.selected,
g_hash_table_insert(field->u.list.selected_table, g_strdup(item), NULL);
purple_request_field_list_clear_selected(PurpleRequestField *field)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
if (field->u.list.selected != NULL)
g_list_free_full(field->u.list.selected, g_free);
field->u.list.selected = NULL;
g_hash_table_destroy(field->u.list.selected_table);
field->u.list.selected_table =
g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
purple_request_field_list_set_selected(PurpleRequestField *field, GList *items)
g_return_if_fail(field != NULL);
g_return_if_fail(items != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST);
purple_request_field_list_clear_selected(field);
if (!purple_request_field_list_get_multi_select(field) && items->next) {
purple_debug_warning("request",
"More than one item added to non-multi-select "
purple_request_field_get_id(field));
for (l = items; l != NULL; l = l->next)
field->u.list.selected = g_list_append(field->u.list.selected,
g_hash_table_insert(field->u.list.selected_table,
g_strdup((char *)l->data), NULL);
purple_request_field_list_is_selected(const PurpleRequestField *field,
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(item != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, FALSE);
return g_hash_table_lookup_extended(field->u.list.selected_table,
purple_request_field_list_get_selected(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return field->u.list.selected;
purple_request_field_list_get_items(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return field->u.list.items;
purple_request_field_list_get_icons(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_LIST, NULL);
return field->u.list.icons;
purple_request_field_label_new(const char *id, const char *text)
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_LABEL);
purple_request_field_image_new(const char *id, const char *text, const char *buf, gsize size)
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
g_return_val_if_fail(buf != NULL, NULL);
g_return_val_if_fail(size > 0, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_IMAGE);
field->u.image.buffer = g_memdup(buf, size);
field->u.image.size = size;
field->u.image.scale_x = 1;
field->u.image.scale_y = 1;
purple_request_field_image_set_scale(PurpleRequestField *field, unsigned int x, unsigned int y)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE);
field->u.image.scale_x = x;
field->u.image.scale_y = y;
purple_request_field_image_get_buffer(PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, NULL);
return field->u.image.buffer;
purple_request_field_image_get_size(PurpleRequestField *field)
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, 0);
return field->u.image.size;
purple_request_field_image_get_scale_x(PurpleRequestField *field)
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, 0);
return field->u.image.scale_x;
purple_request_field_image_get_scale_y(PurpleRequestField *field)
g_return_val_if_fail(field != NULL, 0);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_IMAGE, 0);
return field->u.image.scale_y;
purple_request_field_account_new(const char *id, const char *text,
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(text != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_ACCOUNT);
if (account == NULL && purple_connections_get_all() != NULL)
account = purple_connection_get_account(
(PurpleConnection *)purple_connections_get_all()->data);
purple_request_field_account_set_default_value(field, account);
purple_request_field_account_set_value(field, account);
purple_request_field_account_set_default_value(PurpleRequestField *field,
PurpleAccount *default_value)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
field->u.account.default_account = default_value;
purple_request_field_account_set_value(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
field->u.account.account = value;
purple_request_fields_check_others_sensitivity(field);
purple_request_field_account_set_show_all(PurpleRequestField *field,
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
if (field->u.account.show_all == show_all)
field->u.account.show_all = show_all;
if (purple_account_is_connected(field->u.account.default_account))
purple_request_field_account_set_default_value(field,
(PurpleAccount *)purple_connections_get_all()->data);
if (purple_account_is_connected(field->u.account.account))
purple_request_field_account_set_value(field,
(PurpleAccount *)purple_connections_get_all()->data);
purple_request_field_account_set_filter(PurpleRequestField *field,
PurpleFilterAccountFunc filter_func)
g_return_if_fail(field != NULL);
g_return_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT);
field->u.account.filter_func = filter_func;
purple_request_field_account_get_default_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, NULL);
return field->u.account.default_account;
purple_request_field_account_get_value(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, NULL);
return field->u.account.account;
purple_request_field_account_get_show_all(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, FALSE);
return field->u.account.show_all;
purple_request_field_account_get_filter(const PurpleRequestField *field)
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_ACCOUNT, FALSE);
return field->u.account.filter_func;
purple_request_field_datasheet_new(const char *id,
const gchar *text, PurpleRequestDatasheet *sheet)
PurpleRequestField *field;
g_return_val_if_fail(id != NULL, NULL);
g_return_val_if_fail(sheet != NULL, NULL);
field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_DATASHEET);
field->u.datasheet.sheet = sheet;
purple_request_field_datasheet_get_sheet(PurpleRequestField *field)
g_return_val_if_fail(field != NULL, NULL);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_DATASHEET, NULL);
return field->u.datasheet.sheet;
purple_request_field_email_validator(PurpleRequestField *field, gchar **errmsg,
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
value = purple_request_field_string_get_value(field);
if (value != NULL && purple_email_is_valid(value))
*errmsg = g_strdup(_("Invalid email address"));
purple_request_field_alphanumeric_validator(PurpleRequestField *field,
gchar **errmsg, void *allowed_characters)
gchar invalid_char = '\0';
g_return_val_if_fail(field != NULL, FALSE);
g_return_val_if_fail(field->type == PURPLE_REQUEST_FIELD_STRING, FALSE);
value = purple_request_field_string_get_value(field);
g_return_val_if_fail(value != NULL, FALSE);
gchar *value_r = g_strdup(value);
g_strcanon(value_r, allowed_characters, '\0');
invalid_char = value[strlen(value_r)];
if (!g_ascii_isalnum(*value))
*errmsg = g_strdup_printf(_("Invalid character '%c'"),
purple_request_strip_html_custom(const gchar *html)
tmp = purple_strreplace(html, "\n", "<br>");
ret = purple_markup_strip_html(tmp);
purple_request_strip_html(PurpleRequestCommonParameters *cpar,
const char **primary, const char **secondary)
PurpleRequestUiOps *ops = purple_request_get_ui_ops();
if (!purple_request_cpar_is_html(cpar))
if (ops->features & PURPLE_REQUEST_FEATURE_HTML)
*primary = ret[0] = purple_request_strip_html_custom(*primary);
*secondary = ret[1] = purple_request_strip_html_custom(*secondary);
purple_request_input(void *handle, const char *title, const char *primary,
const char *secondary, const char *default_value,
gboolean multiline, gboolean masked, gchar *hint,
const char *ok_text, GCallback ok_cb,
const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar,
if (G_UNLIKELY(ok_text == NULL || ok_cb == NULL)) {
purple_request_cpar_unref(cpar);
g_warn_if_fail(ok_text != NULL);
g_warn_if_fail(ok_cb != NULL);
g_return_val_if_reached(NULL);
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_input != NULL) {
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_INPUT;
info->ui_handle = ops->request_input(title, primary, secondary,
default_value, multiline, masked, hint, ok_text, ok_cb,
cancel_text, cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
purple_request_cpar_unref(cpar);
purple_request_choice(void *handle, const char *title, const char *primary,
const char *secondary, gpointer default_value, const char *ok_text,
GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data, ...)
if (G_UNLIKELY(ok_text == NULL || ok_cb == NULL)) {
purple_request_cpar_unref(cpar);
g_warn_if_fail(ok_text != NULL);
g_warn_if_fail(ok_cb != NULL);
g_return_val_if_reached(NULL);
va_start(args, user_data);
ui_handle = purple_request_choice_varg(handle, title, primary, secondary,
default_value, ok_text, ok_cb,
purple_request_choice_varg(void *handle, const char *title, const char *primary,
const char *secondary, gpointer default_value, const char *ok_text,
GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data, va_list choices)
if (G_UNLIKELY(ok_text == NULL || ok_cb == NULL ||
purple_request_cpar_unref(cpar);
g_warn_if_fail(ok_text != NULL);
g_warn_if_fail(ok_cb != NULL);
g_warn_if_fail(cancel_text != NULL);
g_return_val_if_reached(NULL);
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_choice != NULL) {
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_CHOICE;
info->ui_handle = ops->request_choice(title, primary, secondary,
default_value, ok_text, ok_cb, cancel_text, cancel_cb,
cpar, user_data, choices);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
purple_request_cpar_unref(cpar);
purple_request_action(void *handle, const char *title, const char *primary,
const char *secondary, int default_action,
PurpleRequestCommonParameters *cpar, void *user_data,
size_t action_count, ...)
va_start(args, action_count);
ui_handle = purple_request_action_varg(handle, title, primary,
secondary, default_action, cpar, user_data, action_count, args);
purple_request_action_varg(void *handle, const char *title, const char *primary,
const char *secondary, int default_action,
PurpleRequestCommonParameters *cpar, void *user_data,
size_t action_count, va_list actions)
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_action != NULL) {
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_ACTION;
info->ui_handle = ops->request_action(title, primary, secondary,
default_action, cpar, user_data, action_count, actions);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
purple_request_cpar_unref(cpar);
purple_request_wait(void *handle, const char *title, const char *primary,
const char *secondary, gboolean with_progress,
PurpleRequestCancelCb cancel_cb, PurpleRequestCommonParameters *cpar,
primary = _("Please wait...");
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_wait != NULL) {
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_WAIT;
info->ui_handle = ops->request_wait(title, primary, secondary,
with_progress, cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
cpar = purple_request_cpar_new();
if (purple_request_cpar_get_icon(cpar) == PURPLE_REQUEST_ICON_DEFAULT)
purple_request_cpar_set_icon(cpar, PURPLE_REQUEST_ICON_WAIT);
return purple_request_action(handle, title, primary, secondary,
PURPLE_DEFAULT_ACTION_NONE, cpar, user_data,
cancel_cb ? 1 : 0, _("Cancel"), cancel_cb);
purple_request_wait_pulse(void *ui_handle)
ops = purple_request_get_ui_ops();
if (ops == NULL || ops->request_wait_update == NULL)
ops->request_wait_update(ui_handle, TRUE, 0.0);
purple_request_wait_progress(void *ui_handle, gfloat fraction)
ops = purple_request_get_ui_ops();
if (ops == NULL || ops->request_wait_update == NULL)
if (fraction < 0.0 || fraction > 1.0) {
purple_debug_warning("request", "Fraction parameter out of "
else /* if (fraction > 1.0) */
ops->request_wait_update(ui_handle, FALSE, fraction);
purple_request_fields_strip_html(PurpleRequestFields *fields)
for (itg = fields->groups; itg != NULL; itg = g_list_next(itg)) {
PurpleRequestFieldGroup *group = itg->data;
for (itf = group->fields; itf != NULL; itf = g_list_next(itf)) {
PurpleRequestField *field = itf->data;
new_label = purple_request_strip_html_custom(
if (g_strcmp0(new_label, field->label) == 0) {
field->label = new_label;
purple_request_fields(void *handle, const char *title, const char *primary,
const char *secondary, PurpleRequestFields *fields, const char *ok_text,
GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data)
if (G_UNLIKELY(fields == NULL ||
((ok_text == NULL) != (ok_cb == NULL)) ||
purple_request_cpar_unref(cpar);
g_warn_if_fail(fields != NULL);
g_warn_if_fail((ok_text == NULL) != (ok_cb == NULL));
g_warn_if_fail(cancel_text != NULL);
g_return_val_if_reached(NULL);
ops = purple_request_get_ui_ops();
if (purple_request_cpar_is_html(cpar) &&
!((ops->features & PURPLE_REQUEST_FEATURE_HTML)))
purple_request_fields_strip_html(fields);
purple_request_fields_check_sensitivity(fields);
if (ops != NULL && ops->request_fields != NULL) {
tmp = purple_request_strip_html(cpar, &primary, &secondary);
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_FIELDS;
info->ui_handle = ops->request_fields(title, primary, secondary,
fields, ok_text, ok_cb, cancel_text, cancel_cb,
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
purple_request_cpar_unref(cpar);
purple_request_file(void *handle, const char *title, const char *filename,
gboolean savedialog, GCallback ok_cb, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data)
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_file != NULL) {
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_FILE;
info->ui_handle = ops->request_file(title, filename, savedialog,
ok_cb, cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
purple_request_cpar_unref(cpar);
purple_request_folder(void *handle, const char *title, const char *dirname,
GCallback ok_cb, GCallback cancel_cb,
PurpleRequestCommonParameters *cpar, void *user_data)
ops = purple_request_get_ui_ops();
if (ops != NULL && ops->request_file != NULL) {
info = g_new0(PurpleRequestInfo, 1);
info->type = PURPLE_REQUEST_FOLDER;
info->ui_handle = ops->request_folder(title, dirname, ok_cb,
cancel_cb, cpar, user_data);
handles = g_list_append(handles, info);
purple_request_cpar_unref(cpar);
purple_request_cpar_unref(cpar);
purple_request_is_valid_ui_handle(void *ui_handle, PurpleRequestType *type)
info = purple_request_info_from_ui_handle(ui_handle);
purple_request_add_close_notify(void *ui_handle, GDestroyNotify notify,
PurpleRequestCloseNotified *notified;
g_return_if_fail(ui_handle != NULL);
g_return_if_fail(notify != NULL);
info = purple_request_info_from_ui_handle(ui_handle);
g_return_if_fail(info != NULL);
notified = g_new0(PurpleRequestCloseNotified, 1);
notified->data = notify_data;
info->notify_on_close = g_slist_append(info->notify_on_close, notified);
purple_request_close_info(PurpleRequestInfo *info)
ops = purple_request_get_ui_ops();
purple_notify_close_with_handle(info->ui_handle);
purple_request_close_with_handle(info->ui_handle);
if (ops != NULL && ops->close_request != NULL)
ops->close_request(info->type, info->ui_handle);
for (it = info->notify_on_close; it; it = g_slist_next(it)) {
PurpleRequestCloseNotified *notify = it->data;
notify->cb(notify->data);
g_slist_free_full(info->notify_on_close, g_free);
purple_request_close(PurpleRequestType type, void *ui_handle)
g_return_if_fail(ui_handle != NULL);
for (l = handles; l != NULL; l = l->next) {
PurpleRequestInfo *info = l->data;
if (info->ui_handle == ui_handle) {
handles = g_list_delete_link(handles, l);
purple_request_close_info(info);
purple_request_close_with_handle(void *handle)
g_return_if_fail(handle != NULL);
for (l = handles; l != NULL; l = l_next) {
PurpleRequestInfo *info = l->data;
if (info->handle == handle) {
handles = g_list_delete_link(handles, l);
purple_request_close_info(info);
purple_request_set_ui_ops(PurpleRequestUiOps *ops)
purple_request_get_ui_ops(void)
/**************************************************************************
**************************************************************************/
static PurpleRequestUiOps *
purple_request_ui_ops_copy(PurpleRequestUiOps *ops)
PurpleRequestUiOps *ops_new;
g_return_val_if_fail(ops != NULL, NULL);
ops_new = g_new(PurpleRequestUiOps, 1);
purple_request_ui_ops_get_type(void)
type = g_boxed_type_register_static("PurpleRequestUiOps",
(GBoxedCopyFunc)purple_request_ui_ops_copy,