You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1141 lines
31 KiB

#include "e.h"
typedef struct _E_Widget_Queue_Item E_Widget_Queue_Item;
typedef struct _E_Widget_Data E_Widget_Data;
typedef struct _E_Widget_Callback E_Widget_Callback;
struct _E_Widget_Data
{
Evas_Object *o_widget, *o_scrollframe, *o_ilist;
Eina_List *callbacks;
const char **value;
struct
{
Eina_List *queue;
Ecore_Timer *timer;
int count;
int show_nth;
int select_nth;
} queue;
};
struct _E_Widget_Callback
{
void (*func)(void *data);
void *data;
const char *value;
};
struct _E_Widget_Queue_Item
{
int command;
Evas_Object *icon;
Evas_Object *end;
const char *label;
int header;
void (*func)(void *data);
void *data;
const char *val;
int relative, use_relative;
int item;
};
static void _e_wid_del_hook(Evas_Object *obj);
static void _e_wid_focus_hook(Evas_Object *obj);
static void _e_wid_cb_scrollframe_resize(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _e_wid_cb_item_sel(void *data, void *data2);
static void _e_wid_cb_item_hilight(void *data, void *data2);
static void _e_wid_cb_selected(void *data, Evas_Object *obj, void *event_info);
static void _e_wid_focus_steal(void *data, Evas *e, Evas_Object *obj, void *event_info);
static Eina_Bool _queue_timer(void *data);
static void _queue_queue(Evas_Object *obj);
static void _queue_append(Evas_Object *obj, int command, Evas_Object *icon, Evas_Object *end, const char *label, int header, void (*func)(void *data), void *data, const char *val, int relative, int use_relative, int item);
static void _queue_remove(Evas_Object *obj, E_Widget_Queue_Item *qi, int del);
enum
{
CMD_ADD,
CMD_REMOVE,
CMD_APPEND,
CMD_PREPEND,
CMD_APPEND_RELATIVE,
CMD_PREPEND_RELATIVE,
CMD_SELECT,
CMD_UNSELECT,
CMD_RANGE_SELECT,
CMD_MULTI_SELECT,
CMD_LABEL_SET,
CMD_ICON_SET,
CMD_END_SET,
CMD_SHOW
};
static Eina_Bool
_queue_timer(void *data)
{
Evas_Object *obj;
E_Widget_Data *wd;
int num;
double start = ecore_time_get();
obj = data;
wd = e_widget_data_get(obj);
if (!wd) return EINA_FALSE;
wd->queue.timer = NULL;
e_widget_ilist_freeze(obj);
num = 0;
while (wd->queue.queue)
{
E_Widget_Queue_Item *qi;
qi = eina_list_data_get(wd->queue.queue);
if (qi->command == CMD_ADD)
{
E_Widget_Callback *wcb, *rcb;
wcb = E_NEW(E_Widget_Callback, 1);
if (!wcb) break;
wcb->func = qi->func;
wcb->data = qi->data;
if (qi->val) wcb->value = eina_stringshare_add(qi->val);
if (qi->use_relative == CMD_APPEND)
{
wd->callbacks = eina_list_append(wd->callbacks, wcb);
e_ilist_append(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
_e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
}
else if (qi->use_relative == CMD_PREPEND)
{
wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
e_ilist_prepend(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
_e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
}
else if (qi->use_relative == CMD_APPEND_RELATIVE)
{
rcb = eina_list_nth(wd->callbacks, qi->relative);
if (rcb)
{
wd->callbacks = eina_list_append_relative(wd->callbacks, wcb, rcb);
e_ilist_append_relative(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
_e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, qi->relative);
}
else
{
wd->callbacks = eina_list_append(wd->callbacks, wcb);
e_ilist_append(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
_e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
}
}
else if (qi->use_relative == CMD_PREPEND_RELATIVE)
{
rcb = eina_list_nth(wd->callbacks, qi->relative);
if (rcb)
{
wd->callbacks = eina_list_prepend_relative(wd->callbacks, wcb, rcb);
e_ilist_prepend_relative(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
_e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, qi->relative);
}
else
{
wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
e_ilist_prepend(wd->o_ilist, qi->icon, qi->end, qi->label, qi->header,
_e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
}
}
Dear all, As I've said before, I'm attached a patch for minor bugs in the e17 again. Please take a look at attached patch. 01. missing E_FREE(wev) if zone is null File: src/bin/e_actions.c: 1467 Function: ACT_FN_GO_EDGE macro function null check of zone and wev, it would be better to separate them. 02. dead code File: src/bin/e_configure.c: 338 Function: _e_configure_efreet_desktop_update 03. array buf might be overwritten by "buf[i] = '\0'" File: src/bin/e_eap_editor.c: 412 Function: _e_desktop_edit_user_local_desktop_filename_generate 04. missing null check File: src/bin/e_fm.c Function: e_fm2_icon_get: 2196 It would be better to check ic->info.file in e_fm2_icon_get before passing to _e_fm2_file_is_edje because it doesn't check null pointer. 05. array 'path' might be overwritten by "path[i + 1] = XXX" File: src/bin/e_fm.c: 4299 Function: _e_fm2_uri_parse 06. missing null check File: src/bin/e_fm_device.c: 468 Function: e_fm2_device_mount_find If the null pointer is passed to e_fm2_device_mount_find, then it attempt to compare string using strncmp without null check. e.g., e_fm2_path_set -> real_path = _e_fm2_dev_path_map: this function could return null. -> sd->realpath = real_path; -> e_fm2_device_mount_find(sd->realpath) 07. missing free(fstrip) File: src/bin/e_import_config_dialog.c: 34 Function: _import_edj_gen 08. missing _module_free(cfm) File: src/bin/e_int_config_modules.c: 530 Function: _load_modules 09. missing free(class) in for loop File: src/bin/e_int_menus.c: 1187 Function: _e_int_menus_clients_add_by_class 10. missing free(roots) File: src/bin/e_main.c: 1646 Function: _e_main_screens_init Actually only e_win_init function could return 0. But I've added free to other codes for the consistency. 11. missing null check of 'es->cfg' File: src/bin/e_shelf.c: 2583 Function: _e_shelf_bindings_add 'es->cfg' might be null. please look at e_shelf_position_calc. 12. no ect->category check before comparing string values File: src/bin/e_theme.c: 387 Function: e_theme_config_remove I'm not sure, but inner if block checks ect->category before deleting a string. 13. missing E_FREE(wcb) in while loop File: src/bin/e_widget_ilist.c: 146 Function: _queue_timer 14. dereferencing freed pointer 'entry' File: src/modules/quickaccess/e_mod_quickaccess.c: 583 Function: _e_qa_event_border_remove_cb 15. missing E_FREE(trov) File: src/modules/tiling/e_mod_tiling.c: 3106 Function: _do_transition_overlay Thanks & Regards, Gwanglim SVN revision: 80231
10 years ago
else
{
E_FREE(wcb);
}
if (qi->icon) evas_object_show(qi->icon);
if (qi->end) evas_object_show(qi->end);
}
else if (qi->command == CMD_LABEL_SET)
e_ilist_nth_label_set(wd->o_ilist, qi->item, qi->label);
else if (qi->command == CMD_ICON_SET)
e_ilist_nth_icon_set(wd->o_ilist, qi->item, qi->icon);
else if (qi->command == CMD_SHOW)
{
Evas_Coord x, y, w, h;
if (num > 0) break;
e_ilist_nth_geometry_get(wd->o_ilist, qi->item, &x, &y, &w, &h);
if (qi->use_relative)
e_scrollframe_child_pos_set(wd->o_scrollframe, x, y);
else
e_scrollframe_child_region_show(wd->o_scrollframe, x, y + h, w, h);
}
else if (qi->command == CMD_SELECT)
e_ilist_selected_set(wd->o_ilist, qi->item);
else if (qi->command == CMD_UNSELECT)
{
if ((wd->value) && *(wd->value))
{
eina_stringshare_del(*(wd->value));
*(wd->value) = NULL;
}
e_ilist_unselect(wd->o_ilist);
}
#if 0
else if (qi->command == CMD_REMOVE)
{
E_Widget_Callback *wcb;
Eina_List *item;
e_ilist_remove_num(wd->o_ilist, qi->item);
item = eina_list_nth_list(wd->callbacks, qi->item);
if (item)
{
wcb = eina_list_data_get(item);
if (wcb && wcb->value) eina_stringshare_del(wcb->value);
free(wcb);
wd->callbacks = eina_list_remove_list(wd->callbacks, item);
}
}
#endif
else if (qi->command == CMD_MULTI_SELECT)
e_ilist_multi_select(wd->o_ilist, qi->item);
else if (qi->command == CMD_RANGE_SELECT)
e_ilist_range_select(wd->o_ilist, qi->item);
else if (qi->command == CMD_END_SET)
e_ilist_nth_end_set(wd->o_ilist, qi->item, qi->end);
_queue_remove(obj, qi, 0);
if ((num++ >= 10) && (ecore_time_get() - start > 0.01))
break;
}
e_widget_ilist_thaw(obj);
e_widget_ilist_go(obj);
_queue_queue(obj);
return ECORE_CALLBACK_CANCEL;
}
static void
_queue_queue(Evas_Object *obj)
{
E_Widget_Data *wd;
wd = e_widget_data_get(obj);
if (!wd) return;
if (!wd->queue.queue) return;
if (wd->queue.timer) return;
wd->queue.timer = ecore_timer_loop_add(0.00001, _queue_timer, obj);
}
static void
_queue_append(Evas_Object *obj, int command, Evas_Object *icon, Evas_Object *end,
const char *label, int header, void (*func)(void *data), void *data,
const char *val, int relative, int use_relative, int item)
{
E_Widget_Data *wd;
E_Widget_Queue_Item *qi;
wd = e_widget_data_get(obj);
if (!wd) return;
qi = E_NEW(E_Widget_Queue_Item, 1);
if (!qi) return;
qi->command = command;
qi->icon = icon;
qi->end = end;
qi->label = eina_stringshare_add(label);
qi->header = header;
qi->func = func;
qi->data = data;
qi->val = eina_stringshare_add(val);
qi->relative = relative;
qi->use_relative = use_relative;
qi->item = item;
wd->queue.queue = eina_list_append(wd->queue.queue, qi);
_queue_queue(obj);
}
static void
_queue_remove(Evas_Object *obj, E_Widget_Queue_Item *qi, int del)
{
E_Widget_Data *wd;
wd = e_widget_data_get(obj);
if (!wd) return;
wd->queue.queue = eina_list_remove(wd->queue.queue, qi);
if (del)
{
if (qi->icon) evas_object_del(qi->icon);
if (qi->end) evas_object_del(qi->end);
}
eina_stringshare_del(qi->label);
eina_stringshare_del(qi->val);
free(qi);
}
static void
_queue_clear(Evas_Object *obj)
{
E_Widget_Data *wd;
wd = e_widget_data_get(obj);
if (!wd) return;
while (wd->queue.queue)
_queue_remove(obj, eina_list_data_get(wd->queue.queue), 1);
if (wd->queue.timer) ecore_timer_del(wd->queue.timer);
wd->queue.timer = NULL;
}
static void
_e_wid_disable_hook(Evas_Object *obj)
{
Eina_Bool disabled;
E_Widget_Data *wd;
disabled = e_widget_disabled_get(obj);
wd = e_widget_data_get(obj);
if (!wd) return;
e_ilist_disabled_set(wd->o_ilist, disabled);
evas_object_freeze_events_set(wd->o_scrollframe, disabled);
}
/* externally accessible functions */
E_API Evas_Object *
e_widget_ilist_add(Evas *evas, int icon_w, int icon_h, const char **value)
{
Evas_Object *obj, *o;
E_Widget_Data *wd;
wd = E_NEW(E_Widget_Data, 1);
if (!wd) return NULL;
obj = e_widget_add(evas);
e_widget_del_hook_set(obj, _e_wid_del_hook);
e_widget_focus_hook_set(obj, _e_wid_focus_hook);
e_widget_disable_hook_set(obj, _e_wid_disable_hook);
e_widget_data_set(obj, wd);
wd->value = value;
o = e_scrollframe_add(evas);
wd->o_scrollframe = o;
evas_object_show(o);
e_widget_sub_object_add(obj, o);
e_widget_resize_object_set(obj, o);
evas_object_event_callback_add(o, EVAS_CALLBACK_MOUSE_DOWN,
_e_wid_focus_steal, obj);
o = e_ilist_add(evas);
wd->o_ilist = o;
e_ilist_icon_size_set(o, icon_w, icon_h);
evas_object_event_callback_add(wd->o_scrollframe, EVAS_CALLBACK_RESIZE,
_e_wid_cb_scrollframe_resize, o);
e_scrollframe_child_set(wd->o_scrollframe, o);
e_widget_sub_object_add(obj, o);
evas_object_show(o);
evas_object_smart_callback_add(o, "selected", _e_wid_cb_selected, obj);
evas_object_resize(obj, 32, 32);
e_widget_size_min_set(obj, 32, 32);
return obj;
}
E_API void
e_widget_ilist_freeze(Evas_Object *obj)
{
E_Widget_Data *wd;
wd = e_widget_data_get(obj);
if (!wd) return;
e_ilist_freeze(wd->o_ilist);
}
E_API void
e_widget_ilist_thaw(Evas_Object *obj)
{
E_Widget_Data *wd;
wd = e_widget_data_get(obj);
if (!wd) return;
e_ilist_thaw(wd->o_ilist);
}
E_API void
e_widget_ilist_append(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, 0, CMD_APPEND, 0);
/*
E_Widget_Data *wd;
E_Widget_Callback *wcb;
wcb = E_NEW(E_Widget_Callback, 1);
if (!wcb) return;
wd = e_widget_data_get(obj);
wcb->func = func;
wcb->data = data;
if (val) wcb->value = strdup(val);
wd->callbacks = eina_list_append(wd->callbacks, wcb);
e_ilist_append(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
if (icon) evas_object_show(icon);
*/
}
E_API void
e_widget_ilist_append_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val)
{
_queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, 0, CMD_APPEND, 0);
}
E_API void
e_widget_ilist_header_append_relative(Evas_Object *obj, Evas_Object *icon, const char *label, int relative)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, relative, CMD_APPEND_RELATIVE, 0);
}
E_API void
e_widget_ilist_header_prepend_relative(Evas_Object *obj, Evas_Object *icon, const char *label, int relative)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, relative, CMD_PREPEND_RELATIVE, 0);
}
E_API void
e_widget_ilist_append_relative(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, relative, CMD_APPEND_RELATIVE, 0);
/*
E_Widget_Data *wd;
E_Widget_Callback *wcb, *rcb;
wcb = E_NEW(E_Widget_Callback, 1);
if (!wcb) return;
wd = e_widget_data_get(obj);
wcb->func = func;
wcb->data = data;
if (val) wcb->value = strdup(val);
rcb = eina_list_nth(wd->callbacks, relative);
if (rcb)
{
wd->callbacks = eina_list_append_relative(wd->callbacks, wcb, rcb);
e_ilist_append_relative(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, relative);
}
else
{
wd->callbacks = eina_list_append(wd->callbacks, wcb);
e_ilist_append(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
}
if (icon) evas_object_show(icon);
*/
}
E_API void
e_widget_ilist_append_relative_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
{
_queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, relative, CMD_APPEND_RELATIVE, 0);
}
E_API void
e_widget_ilist_prepend(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, 0, CMD_PREPEND, 0);
/*
E_Widget_Data *wd;
E_Widget_Callback *wcb;
wcb = E_NEW(E_Widget_Callback, 1);
if (!wcb) return;
wd = e_widget_data_get(obj);
wcb->func = func;
wcb->data = data;
if (val) wcb->value = strdup(val);
wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
e_ilist_prepend(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
if (icon) evas_object_show(icon);
*/
}
E_API void
e_widget_ilist_header_prepend(Evas_Object *obj, Evas_Object *icon, const char *label)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, 0, CMD_PREPEND, 0);
}
E_API void
e_widget_ilist_prepend_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val)
{
_queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, 0, CMD_PREPEND, 0);
}
E_API void
e_widget_ilist_prepend_relative(Evas_Object *obj, Evas_Object *icon, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 0, func, data, val, relative, CMD_PREPEND_RELATIVE, 0);
/*
E_Widget_Data *wd;
E_Widget_Callback *wcb, *rcb;
wcb = E_NEW(E_Widget_Callback, 1);
if (!wcb) return;
wd = e_widget_data_get(obj);
wcb->func = func;
wcb->data = data;
if (val) wcb->value = strdup(val);
rcb = eina_list_nth(wd->callbacks, relative);
if (rcb)
{
wd->callbacks = eina_list_prepend_relative(wd->callbacks, wcb, rcb);
e_ilist_prepend_relative(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb, relative);
}
else
{
wd->callbacks = eina_list_prepend(wd->callbacks, wcb);
e_ilist_prepend(wd->o_ilist, icon, label, 0, _e_wid_cb_item_sel, _e_wid_cb_item_hilight, wd, wcb);
}
if (icon) evas_object_show(icon);
*/
}
E_API void
e_widget_ilist_prepend_relative_full(Evas_Object *obj, Evas_Object *icon, Evas_Object *end, const char *label, void (*func)(void *data), void *data, const char *val, int relative)
{
_queue_append(obj, CMD_ADD, icon, end, label, 0, func, data, val, relative, CMD_PREPEND_RELATIVE, 0);
}
E_API void
e_widget_ilist_header_append(Evas_Object *obj, Evas_Object *icon, const char *label)
{
_queue_append(obj, CMD_ADD, icon, NULL, label, 1, NULL, NULL, NULL, 0, CMD_APPEND, 0);
/*
E_Widget_Data *wd;
E_Widget_Callback *wcb;
wcb = E_NEW(E_Widget_Callback, 1);
if (!wcb) return;
wd = e_widget_data_get(obj);
wd->callbacks = eina_list_append(wd->callbacks, wcb);
e_ilist_append(wd->o_ilist, icon, label, 1, NULL, NULL, NULL, NULL);
if (icon) evas_object_show(icon);
*/
}
E_API void
e_widget_ilist_selector_set(Evas_Object *obj, int selector)
{
E_Widget_Data *wd;
wd = e_widget_data_get(obj);
if (!wd) return;
e_ilist_selector_set(wd->o_ilist, selector);
}
E_API void
e_widget_ilist_go(Evas_Object *obj)
{
E_Widget_Data *wd;
Evas_Coord mw, mh, vw, vh, w, h;