Fix dangling pointers causing erratic timer behaviour (affects taskbar with spacing); use calloc instead of malloc for safer initializations
git-svn-id: http://tint2.googlecode.com/svn/trunk@758 121b4492-b84c-0410-8b4c-0d4edfb3f3cc
This commit is contained in:
parent
778b9f0ebf
commit
66cae4bb7c
17 changed files with 135 additions and 123 deletions
|
@ -2,26 +2,38 @@
|
|||
# For information on manually configuring tint2 see http://code.google.com/p/tint2/wiki/Configure
|
||||
|
||||
# Background definitions
|
||||
# ID 1
|
||||
# Background 1: panel
|
||||
rounded = 7
|
||||
border_width = 2
|
||||
border_width = 1
|
||||
background_color = #000000 60
|
||||
border_color = #FFFFFF 16
|
||||
|
||||
# ID 2
|
||||
# Background 2: normal/iconified tasks
|
||||
rounded = 5
|
||||
border_width = 0
|
||||
background_color = #777777 40
|
||||
border_color = #FFFFFF 48
|
||||
background_color = #777777 20
|
||||
border_color = #777777 30
|
||||
|
||||
# ID 3
|
||||
# Background 3: active tasks
|
||||
rounded = 5
|
||||
border_width = 1
|
||||
background_color = #777777 40
|
||||
border_color = #FFFFFF 60
|
||||
background_color = #777777 20
|
||||
border_color = #ffffff 40
|
||||
|
||||
# Background 4: urgent tasks
|
||||
rounded = 5
|
||||
border_width = 1
|
||||
background_color = #aa4400 100
|
||||
border_color = #aa7733 100
|
||||
|
||||
# Background 5: tooltips
|
||||
rounded = 2
|
||||
border_width = 1
|
||||
background_color = #ffffaa 100
|
||||
border_color = #999999 100
|
||||
|
||||
# Panel
|
||||
panel_items = LTSC
|
||||
panel_items = LTSBC
|
||||
panel_monitor = all
|
||||
panel_position = bottom center horizontal
|
||||
panel_size = 95% 30
|
||||
|
@ -34,8 +46,8 @@ panel_background_id = 1
|
|||
|
||||
# Panel Autohide
|
||||
autohide = 0
|
||||
autohide_show_timeout = 0.3
|
||||
autohide_hide_timeout = 2
|
||||
autohide_show_timeout = 0
|
||||
autohide_hide_timeout = 0.5
|
||||
autohide_height = 2
|
||||
strut_policy = follow_size
|
||||
|
||||
|
@ -63,13 +75,13 @@ task_maximum_size = 140 35
|
|||
task_padding = 6 2
|
||||
task_background_id = 2
|
||||
task_active_background_id = 3
|
||||
task_urgent_background_id = 2
|
||||
task_urgent_background_id = 4
|
||||
task_iconified_background_id = 2
|
||||
task_tooltip = 0
|
||||
task_tooltip = 1
|
||||
urgent_nb_of_blink = 100000
|
||||
|
||||
# Task Icons
|
||||
task_icon_asb = 80 0 0
|
||||
task_icon_asb = 100 0 0
|
||||
task_active_icon_asb = 100 0 0
|
||||
task_urgent_icon_asb = 100 0 0
|
||||
task_iconified_icon_asb = 70 0 0
|
||||
|
@ -86,8 +98,8 @@ font_shadow = 0
|
|||
mouse_left = toggle_iconify
|
||||
mouse_middle = none
|
||||
mouse_right = close
|
||||
mouse_scroll_up = toggle
|
||||
mouse_scroll_down = iconify
|
||||
mouse_scroll_up = prev_task
|
||||
mouse_scroll_down = next_task
|
||||
|
||||
# System Tray
|
||||
systray_padding = 0 4 5
|
||||
|
@ -101,18 +113,18 @@ time1_format = %H:%M
|
|||
time1_font = sans 8
|
||||
time2_format = %A %d %B
|
||||
time2_font = sans 7
|
||||
clock_font_color = #FFFFFF 74
|
||||
clock_font_color = #FFFFFF 90
|
||||
clock_padding = 1 0
|
||||
clock_background_id = 0
|
||||
clock_rclick_command = orage
|
||||
|
||||
# Tooltips
|
||||
tooltip_padding = 2 2
|
||||
tooltip_show_timeout = 0.7
|
||||
tooltip_hide_timeout = 0.3
|
||||
tooltip_background_id = 1
|
||||
tooltip_font = sans 10
|
||||
tooltip_font_color = #000000 80
|
||||
tooltip_show_timeout = 0.5
|
||||
tooltip_hide_timeout = 0.1
|
||||
tooltip_background_id = 5
|
||||
tooltip_font = sans 9
|
||||
tooltip_font_color = #222222 100
|
||||
|
||||
# Battery
|
||||
battery_low_status = 10
|
||||
|
@ -120,7 +132,7 @@ battery_low_cmd = notify-send "battery low"
|
|||
battery_hide = 98
|
||||
bat1_font = sans 8
|
||||
bat2_font = sans 6
|
||||
battery_font_color = #FFFFFF 74
|
||||
battery_font_color = #FFFFFF 94
|
||||
battery_padding = 1 0
|
||||
battery_background_id = 0
|
||||
|
||||
|
|
|
@ -274,9 +274,8 @@ void init_battery()
|
|||
}
|
||||
#endif
|
||||
|
||||
if (battery_timeout == 0) {
|
||||
battery_timeout = add_timeout(10, 10000, update_battery_tick, 0);
|
||||
}
|
||||
if (!battery_timeout)
|
||||
battery_timeout = add_timeout(10, 10000, update_battery_tick, 0, &battery_timeout);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -152,9 +152,9 @@ void init_clock()
|
|||
if (!clock_timeout) {
|
||||
if (time_format_needs_sec_ticks(time1_format) ||
|
||||
time_format_needs_sec_ticks(time2_format)) {
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0);
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks_sec, 0, &clock_timeout);
|
||||
} else {
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0);
|
||||
clock_timeout = add_timeout(10, 1000, update_clocks_min, 0, &clock_timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ void expand_exec(DesktopEntry *entry, const char *path)
|
|||
// %c -> Name
|
||||
// %k -> path
|
||||
if (entry->exec) {
|
||||
char *exec2 = malloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100);
|
||||
char *exec2 = calloc(strlen(entry->exec) + (entry->name ? strlen(entry->name) : 1) + (entry->icon ? strlen(entry->icon) : 1) + 100, 1);
|
||||
char *p, *q;
|
||||
// p will never point to an escaped char
|
||||
for (p = entry->exec, q = exec2; *p; p++, q++) {
|
||||
|
|
|
@ -561,8 +561,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
|||
char *theme_name = ((IconTheme*)theme->data)->name;
|
||||
char *dir_name = ((IconThemeDir*)dir->data)->name;
|
||||
char *extension = (char*) ext->data;
|
||||
char *file_name = malloc(strlen(base_name) + strlen(theme_name) +
|
||||
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100);
|
||||
char *file_name = calloc(strlen(base_name) + strlen(theme_name) +
|
||||
strlen(dir_name) + strlen(icon_name) + strlen(extension) + 100, 1);
|
||||
// filename = directory/$(themename)/subdirectory/iconname.extension
|
||||
sprintf(file_name, "%s/%s/%s/%s%s", base_name, theme_name, dir_name, icon_name, extension);
|
||||
if (DEBUG_ICON_SEARCH)
|
||||
|
@ -620,8 +620,8 @@ char *get_icon_path_helper(GSList *themes, const char *icon_name, int size)
|
|||
for (ext = extensions; ext; ext = g_slist_next(ext)) {
|
||||
char *base_name = (char*) base->data;
|
||||
char *extension = (char*) ext->data;
|
||||
char *file_name = malloc(strlen(base_name) + strlen(icon_name) +
|
||||
strlen(extension) + 100);
|
||||
char *file_name = calloc(strlen(base_name) + strlen(icon_name) +
|
||||
strlen(extension) + 100, 1);
|
||||
// filename = directory/iconname.extension
|
||||
sprintf(file_name, "%s/%s%s", base_name, icon_name, extension);
|
||||
if (DEBUG_ICON_SEARCH)
|
||||
|
|
|
@ -391,7 +391,7 @@ void free_icon(Imlib_Image icon)
|
|||
|
||||
void launcher_action(LauncherIcon *icon, XEvent* evt)
|
||||
{
|
||||
char *cmd = malloc(strlen(icon->cmd) + 10);
|
||||
char *cmd = calloc(strlen(icon->cmd) + 10, 1);
|
||||
sprintf(cmd, "(%s&)", icon->cmd);
|
||||
#if HAVE_SN
|
||||
SnLauncherContext* ctx;
|
||||
|
|
|
@ -235,14 +235,14 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
|
|||
goto out;
|
||||
}
|
||||
|
||||
setting = malloc (sizeof *setting);
|
||||
setting = calloc (1, sizeof *setting);
|
||||
if (!setting) {
|
||||
result = XSETTINGS_NO_MEM;
|
||||
goto out;
|
||||
}
|
||||
setting->type = XSETTINGS_TYPE_INT; /* No allocated memory */
|
||||
|
||||
setting->name = malloc (name_len + 1);
|
||||
setting->name = calloc (name_len + 1, 1);
|
||||
if (!setting->name) {
|
||||
result = XSETTINGS_NO_MEM;
|
||||
goto out;
|
||||
|
@ -276,7 +276,7 @@ static XSettingsList *parse_settings (unsigned char *data, size_t len)
|
|||
goto out;
|
||||
}
|
||||
|
||||
setting->data.v_string = malloc (v_int + 1);
|
||||
setting->data.v_string = calloc (v_int + 1, 1);
|
||||
if (!setting->data.v_string) {
|
||||
result = XSETTINGS_NO_MEM;
|
||||
goto out;
|
||||
|
@ -400,7 +400,7 @@ XSettingsClient *xsettings_client_new (Display *display, int screen, XSettingsNo
|
|||
{
|
||||
XSettingsClient *client;
|
||||
|
||||
client = malloc (sizeof *client);
|
||||
client = calloc (1, sizeof *client);
|
||||
if (!client)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -34,12 +34,12 @@ xsettings_setting_copy (XSettingsSetting *setting)
|
|||
XSettingsSetting *result;
|
||||
size_t str_len;
|
||||
|
||||
result = malloc (sizeof *result);
|
||||
result = calloc (1, sizeof *result);
|
||||
if (!result)
|
||||
return NULL;
|
||||
|
||||
str_len = strlen (setting->name);
|
||||
result->name = malloc (str_len + 1);
|
||||
result->name = calloc (str_len + 1, 1);
|
||||
if (!result->name)
|
||||
goto err;
|
||||
|
||||
|
@ -57,7 +57,7 @@ xsettings_setting_copy (XSettingsSetting *setting)
|
|||
break;
|
||||
case XSETTINGS_TYPE_STRING:
|
||||
str_len = strlen (setting->data.v_string);
|
||||
result->data.v_string = malloc (str_len + 1);
|
||||
result->data.v_string = calloc (str_len + 1, 1);
|
||||
if (!result->data.v_string)
|
||||
goto err;
|
||||
|
||||
|
@ -90,7 +90,7 @@ xsettings_list_copy (XSettingsList *list)
|
|||
{
|
||||
XSettingsList *new_node;
|
||||
|
||||
new_node = malloc (sizeof *new_node);
|
||||
new_node = calloc (1, sizeof *new_node);
|
||||
if (!new_node)
|
||||
goto error;
|
||||
|
||||
|
@ -180,7 +180,7 @@ xsettings_list_insert (XSettingsList **list,
|
|||
XSettingsList *iter;
|
||||
XSettingsList *last = NULL;
|
||||
|
||||
node = malloc (sizeof *node);
|
||||
node = calloc (1, sizeof *node);
|
||||
if (!node)
|
||||
return XSETTINGS_NO_MEM;
|
||||
node->setting = setting;
|
||||
|
|
20
src/panel.c
20
src/panel.c
|
@ -126,6 +126,7 @@ void cleanup_panel()
|
|||
if (p->main_win)
|
||||
XDestroyWindow(server.dsp, p->main_win);
|
||||
p->main_win = 0;
|
||||
stop_timeout(p->autohide_timeout);
|
||||
}
|
||||
|
||||
free(panel_items_order);
|
||||
|
@ -167,7 +168,7 @@ void init_panel()
|
|||
else
|
||||
nb_panel = server.nb_monitor;
|
||||
|
||||
panel1 = malloc(nb_panel * sizeof(Panel));
|
||||
panel1 = calloc(nb_panel, sizeof(Panel));
|
||||
for (i=0 ; i < nb_panel ; i++) {
|
||||
memcpy(&panel1[i], &panel_config, sizeof(Panel));
|
||||
}
|
||||
|
@ -231,7 +232,7 @@ void init_panel()
|
|||
}
|
||||
|
||||
if (panel_autohide)
|
||||
add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p);
|
||||
autohide_trigger_hide(p);
|
||||
|
||||
visible_taskbar(p);
|
||||
}
|
||||
|
@ -811,10 +812,7 @@ Area* click_area(Panel *panel, int x, int y)
|
|||
|
||||
void stop_autohide_timeout(Panel* p)
|
||||
{
|
||||
if (p->autohide_timeout) {
|
||||
stop_timeout(p->autohide_timeout);
|
||||
p->autohide_timeout = 0;
|
||||
}
|
||||
stop_timeout(p->autohide_timeout);
|
||||
}
|
||||
|
||||
|
||||
|
@ -875,10 +873,7 @@ void autohide_trigger_show(Panel* p)
|
|||
{
|
||||
if (!p)
|
||||
return;
|
||||
if (p->autohide_timeout)
|
||||
change_timeout(p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
|
||||
else
|
||||
p->autohide_timeout = add_timeout(panel_autohide_show_timeout, 0, autohide_show, p);
|
||||
change_timeout(&p->autohide_timeout, panel_autohide_show_timeout, 0, autohide_show, p);
|
||||
}
|
||||
|
||||
|
||||
|
@ -893,8 +888,5 @@ void autohide_trigger_hide(Panel* p)
|
|||
if (XQueryPointer(server.dsp, p->main_win, &root, &child, &xr, &yr, &xw, &yw, &mask))
|
||||
if (child) return; // mouse over one of the system tray icons
|
||||
|
||||
if (p->autohide_timeout)
|
||||
change_timeout(p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
|
||||
else
|
||||
p->autohide_timeout = add_timeout(panel_autohide_hide_timeout, 0, autohide_hide, p);
|
||||
change_timeout(&p->autohide_timeout, panel_autohide_hide_timeout, 0, autohide_hide, p);
|
||||
}
|
||||
|
|
|
@ -295,14 +295,14 @@ void get_monitors()
|
|||
}
|
||||
|
||||
printf("xRandr: Found crtc's: %d\n", res->ncrtc );
|
||||
server.monitor = malloc(res->ncrtc * sizeof(Monitor));
|
||||
server.monitor = calloc(res->ncrtc, sizeof(Monitor));
|
||||
for (i=0; i<res->ncrtc; ++i) {
|
||||
XRRCrtcInfo* crtc_info = XRRGetCrtcInfo(server.dsp, res, res->crtcs[i]);
|
||||
server.monitor[i].x = crtc_info->x;
|
||||
server.monitor[i].y = crtc_info->y;
|
||||
server.monitor[i].width = crtc_info->width;
|
||||
server.monitor[i].height = crtc_info->height;
|
||||
server.monitor[i].names = malloc((crtc_info->noutput+1) * sizeof(gchar*));
|
||||
server.monitor[i].names = calloc((crtc_info->noutput+1), sizeof(gchar*));
|
||||
for (j=0; j<crtc_info->noutput; ++j) {
|
||||
XRROutputInfo* output_info = XRRGetOutputInfo(server.dsp, res, crtc_info->outputs[j]);
|
||||
printf("xRandr: Linking output %s with crtc %d\n", output_info->name, i);
|
||||
|
@ -315,7 +315,7 @@ void get_monitors()
|
|||
nbmonitor = res->ncrtc;
|
||||
}
|
||||
else if (info && nbmonitor > 0) {
|
||||
server.monitor = malloc(nbmonitor * sizeof(Monitor));
|
||||
server.monitor = calloc(nbmonitor, sizeof(Monitor));
|
||||
for (i=0 ; i < nbmonitor ; i++) {
|
||||
server.monitor[i].x = info[i].x_org;
|
||||
server.monitor[i].y = info[i].y_org;
|
||||
|
@ -353,7 +353,7 @@ next:
|
|||
|
||||
if (!server.nb_monitor) {
|
||||
server.nb_monitor = 1;
|
||||
server.monitor = malloc(sizeof(Monitor));
|
||||
server.monitor = calloc(1, sizeof(Monitor));
|
||||
server.monitor[0].x = server.monitor[0].y = 0;
|
||||
server.monitor[0].width = DisplayWidth (server.dsp, server.screen);
|
||||
server.monitor[0].height = DisplayHeight (server.dsp, server.screen);
|
||||
|
|
|
@ -496,8 +496,7 @@ void remove_icon(TrayWindow *traywin)
|
|||
XDestroyWindow(server.dsp, traywin->id);
|
||||
XSync(server.dsp, False);
|
||||
XSetErrorHandler(old);
|
||||
if (traywin->render_timeout)
|
||||
stop_timeout(traywin->render_timeout);
|
||||
stop_timeout(traywin->render_timeout);
|
||||
g_free(traywin);
|
||||
|
||||
// check empty systray
|
||||
|
@ -619,8 +618,8 @@ void systray_render_icon(TrayWindow* traywin)
|
|||
{
|
||||
if (FORCE_COMPOSITED_RENDERING || server.real_transparency || systray.alpha != 100 || systray.brightness != 0 || systray.saturation != 0) {
|
||||
// wine tray icons update whenever mouse is over them, so we limit the updates to 50 ms
|
||||
if (traywin->render_timeout == 0)
|
||||
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_now, traywin);
|
||||
if (!traywin->render_timeout)
|
||||
traywin->render_timeout = add_timeout(50, 0, systray_render_icon_now, traywin, &traywin->render_timeout);
|
||||
}
|
||||
else {
|
||||
// Pixmap pix = XCreatePixmap(server.dsp, server.root_win, traywin->width, traywin->height, server.depth);
|
||||
|
|
|
@ -87,7 +87,7 @@ Task *add_task (Window win)
|
|||
if (new_tsk.desktop != ALLDESKTOP && new_tsk.desktop != j) continue;
|
||||
|
||||
tskbar = &panel1[monitor].taskbar[j];
|
||||
new_tsk2 = malloc(sizeof(Task));
|
||||
new_tsk2 = calloc(1, sizeof(Task));
|
||||
memcpy(&new_tsk2->area, &panel1[monitor].g_task.area, sizeof(Area));
|
||||
new_tsk2->area.parent = tskbar;
|
||||
new_tsk2->win = new_tsk.win;
|
||||
|
@ -115,7 +115,7 @@ Task *add_task (Window win)
|
|||
g_ptr_array_add(task_group, new_tsk2);
|
||||
//printf("add_task panel %d, desktop %d, task %s\n", i, j, new_tsk2->title);
|
||||
}
|
||||
Window* key = malloc(sizeof(Window));
|
||||
Window* key = calloc(1, sizeof(Window));
|
||||
*key = new_tsk.win;
|
||||
g_hash_table_insert(win_to_task_table, key, task_group);
|
||||
set_task_state(new_tsk2, new_tsk.current_state);
|
||||
|
@ -195,14 +195,14 @@ int get_title(Task *tsk)
|
|||
if (!name || !strlen(name)) {
|
||||
name = server_get_property (tsk->win, server.atom.WM_NAME, XA_STRING, 0);
|
||||
if (!name || !strlen(name)) {
|
||||
name = malloc(10);
|
||||
name = calloc(10, 1);
|
||||
strcpy(name, "Untitled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// add space before title
|
||||
title = malloc(strlen(name)+2);
|
||||
title = calloc(strlen(name)+2, 1);
|
||||
if (panel->g_task.icon) strcpy(title, " ");
|
||||
else title[0] = 0;
|
||||
strcat(title, name);
|
||||
|
@ -620,7 +620,7 @@ void add_urgent(Task *tsk)
|
|||
urgent_list = g_slist_prepend(urgent_list, tsk);
|
||||
|
||||
if (!urgent_timeout)
|
||||
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0);
|
||||
urgent_timeout = add_timeout(10, 1000, blink_urgent, 0, &urgent_timeout);
|
||||
|
||||
Panel *panel = tsk->area.panel;
|
||||
if (panel->is_hidden)
|
||||
|
|
|
@ -109,7 +109,6 @@ void cleanup_taskbar()
|
|||
urgent_list = NULL;
|
||||
|
||||
stop_timeout(urgent_timeout);
|
||||
urgent_timeout = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1350,7 +1350,7 @@ start:
|
|||
cmd_length += 2; // &)
|
||||
cmd_length += 1; // terminator
|
||||
|
||||
char *cmd = malloc(cmd_length);
|
||||
char *cmd = calloc(cmd_length, 1);
|
||||
cmd[0] = '\0';
|
||||
strcat(cmd, "(");
|
||||
strcat(cmd, dnd_launcher_exec);
|
||||
|
|
|
@ -86,7 +86,7 @@ void init_tooltip()
|
|||
void tooltip_trigger_show(Area* area, Panel* p, XEvent *e)
|
||||
{
|
||||
// Position the tooltip in the center of the area
|
||||
x = area->posx + area->width / 2 + e->xmotion.x_root - e->xmotion.x;
|
||||
x = area->posx + MIN(area->width / 3, 22) + e->xmotion.x_root - e->xmotion.x;
|
||||
y = area->posy + area->height / 2 + e->xmotion.y_root - e->xmotion.y;
|
||||
just_shown = 1;
|
||||
g_tooltip.panel = p;
|
||||
|
@ -108,7 +108,6 @@ void tooltip_show(void* arg)
|
|||
XTranslateCoordinates( server.dsp, server.root_win, g_tooltip.panel->main_win, x, y, &mx, &my, &w);
|
||||
Area* area;
|
||||
area = click_area(g_tooltip.panel, mx, my);
|
||||
stop_tooltip_timeout();
|
||||
if (!g_tooltip.mapped && area->_get_tooltip_text) {
|
||||
tooltip_copy_text(area);
|
||||
g_tooltip.mapped = True;
|
||||
|
@ -275,7 +274,6 @@ void tooltip_trigger_hide(Tooltip* tooltip)
|
|||
|
||||
void tooltip_hide(void* arg)
|
||||
{
|
||||
stop_tooltip_timeout();
|
||||
if (g_tooltip.mapped) {
|
||||
g_tooltip.mapped = False;
|
||||
XUnmapWindow(server.dsp, g_tooltip.window);
|
||||
|
@ -286,26 +284,19 @@ void tooltip_hide(void* arg)
|
|||
|
||||
void start_show_timeout()
|
||||
{
|
||||
if (g_tooltip.timeout)
|
||||
change_timeout(g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
||||
else
|
||||
g_tooltip.timeout = add_timeout(g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
||||
change_timeout(&g_tooltip.timeout, g_tooltip.show_timeout_msec, 0, tooltip_show, 0);
|
||||
}
|
||||
|
||||
|
||||
void start_hide_timeout()
|
||||
{
|
||||
if (g_tooltip.timeout)
|
||||
change_timeout(g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
||||
else
|
||||
g_tooltip.timeout = add_timeout(g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
||||
change_timeout(&g_tooltip.timeout, g_tooltip.hide_timeout_msec, 0, tooltip_hide, 0);
|
||||
}
|
||||
|
||||
|
||||
void stop_tooltip_timeout()
|
||||
{
|
||||
stop_timeout(g_tooltip.timeout);
|
||||
g_tooltip.timeout = NULL;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ struct _timeout {
|
|||
void (*_callback)(void*);
|
||||
void* arg;
|
||||
multi_timeout* multi_timeout;
|
||||
timeout **self;
|
||||
};
|
||||
|
||||
void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(void*), void* arg, timeout* t);
|
||||
|
@ -74,6 +75,8 @@ void cleanup_timeout()
|
|||
timeout* t = timeout_list->data;
|
||||
if (t->multi_timeout)
|
||||
stop_multi_timeout(t);
|
||||
if (t->self)
|
||||
*t->self = NULL;
|
||||
free(t);
|
||||
timeout_list = g_slist_remove(timeout_list, t);
|
||||
}
|
||||
|
@ -95,25 +98,26 @@ void cleanup_timeout()
|
|||
* however it's save to call it.
|
||||
**/
|
||||
|
||||
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg)
|
||||
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self)
|
||||
{
|
||||
timeout* t = malloc(sizeof(timeout));
|
||||
t->multi_timeout = 0;
|
||||
timeout* t = calloc(1, sizeof(timeout));
|
||||
t->self = self;
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, t);
|
||||
return t;
|
||||
}
|
||||
|
||||
|
||||
void change_timeout(timeout *t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
|
||||
void change_timeout(timeout **t, int value_msec, int interval_msec, void(*_callback)(), void* arg)
|
||||
{
|
||||
if ( g_slist_find(timeout_list, t) == 0 && g_hash_table_lookup(multi_timeouts, t) == 0)
|
||||
printf("programming error: timeout already deleted...");
|
||||
if (!((timeout_list && g_slist_find(timeout_list, *t)) ||
|
||||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, *t))))
|
||||
*t = add_timeout(value_msec, interval_msec, _callback, arg, t);
|
||||
else {
|
||||
if (t->multi_timeout)
|
||||
remove_from_multi_timeout((timeout*)t);
|
||||
if ((*t)->multi_timeout)
|
||||
remove_from_multi_timeout(*t);
|
||||
else
|
||||
timeout_list = g_slist_remove(timeout_list, t);
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, (timeout*)t);
|
||||
timeout_list = g_slist_remove(timeout_list, *t);
|
||||
add_timeout_intern(value_msec, interval_msec, _callback, arg, *t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -149,31 +153,40 @@ void callback_timeout_expired()
|
|||
if (compare_timespecs(&t->timeout_expires, &cur_time) <= 0) {
|
||||
// it's time for the callback function
|
||||
t->_callback(t->arg);
|
||||
// If _callback() calls stop_timeout(t) the timer 't' was freed and is not in the timeout_list
|
||||
if (g_slist_find(timeout_list, t)) {
|
||||
// if _callback() calls stop_timeout(t) the timeout 't' was freed and is not in the timeout_list
|
||||
// Timer still exists
|
||||
timeout_list = g_slist_remove(timeout_list, t);
|
||||
if (t->interval_msec > 0)
|
||||
if (t->interval_msec > 0) {
|
||||
add_timeout_intern(t->interval_msec, t->interval_msec, t->_callback, t->arg, t);
|
||||
else
|
||||
} else {
|
||||
// Destroy single-shot timer
|
||||
if (t->self)
|
||||
*t->self = NULL;
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void stop_timeout(timeout* t)
|
||||
{
|
||||
if (!multi_timeouts || !t)
|
||||
if (!t)
|
||||
return;
|
||||
// if not in the list, it was deleted in callback_timeout_expired
|
||||
if (g_slist_find(timeout_list, t) || g_hash_table_lookup(multi_timeouts, t)) {
|
||||
if (t->multi_timeout)
|
||||
remove_from_multi_timeout((timeout*)t);
|
||||
timeout_list = g_slist_remove(timeout_list, t);
|
||||
free((void*)t);
|
||||
if ((timeout_list && g_slist_find(timeout_list, t)) ||
|
||||
(multi_timeouts && g_hash_table_lookup(multi_timeouts, t))) {
|
||||
if (multi_timeouts && t->multi_timeout)
|
||||
remove_from_multi_timeout(t);
|
||||
if (timeout_list)
|
||||
timeout_list = g_slist_remove(timeout_list, t);
|
||||
if (t->self)
|
||||
*t->self = NULL;
|
||||
free(t);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,7 +211,7 @@ void add_timeout_intern(int value_msec, int interval_msec, void(*_callback)(), v
|
|||
gint compare_timeouts(gconstpointer t1, gconstpointer t2)
|
||||
{
|
||||
return compare_timespecs(&((timeout*)t1)->timeout_expires,
|
||||
&((timeout*)t2)->timeout_expires);
|
||||
&((timeout*)t2)->timeout_expires);
|
||||
}
|
||||
|
||||
|
||||
|
@ -262,12 +275,13 @@ int align_with_existing_timeouts(timeout *t)
|
|||
if (t->interval_msec % t2->interval_msec == 0 || t2->interval_msec % t->interval_msec == 0) {
|
||||
if (multi_timeouts == 0)
|
||||
multi_timeouts = g_hash_table_new(0, 0);
|
||||
if (!t->multi_timeout && !t2->multi_timeout)
|
||||
if (!t->multi_timeout && !t2->multi_timeout) {
|
||||
// both timeouts can be aligned, but there is no multi timeout for them
|
||||
create_multi_timeout(t, t2);
|
||||
else
|
||||
} else {
|
||||
// there is already a multi timeout, so we append the new timeout to the multi timeout
|
||||
append_multi_timeout(t, t2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -295,10 +309,10 @@ int calc_multi_timeout_interval(multi_timeout_handler* mth)
|
|||
|
||||
void create_multi_timeout(timeout* t1, timeout* t2)
|
||||
{
|
||||
multi_timeout* mt1 = malloc(sizeof(multi_timeout));
|
||||
multi_timeout* mt2 = malloc(sizeof(multi_timeout));
|
||||
multi_timeout_handler* mth = malloc(sizeof(multi_timeout_handler));
|
||||
timeout* real_timeout = malloc(sizeof(timeout));
|
||||
multi_timeout* mt1 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout* mt2 = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler* mth = calloc(1, sizeof(multi_timeout_handler));
|
||||
timeout* real_timeout = calloc(1, sizeof(timeout));
|
||||
|
||||
mth->timeout_list = 0;
|
||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t1);
|
||||
|
@ -331,7 +345,7 @@ void append_multi_timeout(timeout* t1, timeout* t2)
|
|||
t1 = tmp;
|
||||
}
|
||||
|
||||
multi_timeout* mt = malloc(sizeof(multi_timeout));
|
||||
multi_timeout* mt = calloc(1, sizeof(multi_timeout));
|
||||
multi_timeout_handler* mth = g_hash_table_lookup(multi_timeouts, t1);
|
||||
|
||||
mth->timeout_list = g_slist_prepend(mth->timeout_list, t2);
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
extern GSList* timeout_list;
|
||||
extern struct timeval next_timeout;
|
||||
|
||||
|
||||
|
@ -30,26 +29,33 @@ typedef struct _timeout timeout;
|
|||
|
||||
// timer functions
|
||||
/**
|
||||
* Single shot timer (i.e. timer with interval_msec == 0) are deleted automatically as soon as they expire
|
||||
* Single shot timers (i.e. timers with interval_msec == 0) are deleted automatically as soon as they expire,
|
||||
* i.e. you do not need to stop them, however it is safe to call stop_timeout for these timers.
|
||||
* You can pass the address of the variable storing the pointer to the timer as 'self' in add_timeout, in which
|
||||
* case it is used to clear the pointer if the timer is destroyed automatically. This enforces the timeout pointers
|
||||
* to be either valid or NULL.
|
||||
* Periodic timeouts are aligned to each other whenever possible, i.e. one interval_msec is an
|
||||
* integral multiple of the other.
|
||||
**/
|
||||
|
||||
/** default global data **/
|
||||
/** Initializes default global data. **/
|
||||
void default_timeout();
|
||||
|
||||
/** freed memory : stops all timeouts **/
|
||||
/** Cleans up: stops all timers and frees memory. **/
|
||||
void cleanup_timeout();
|
||||
|
||||
/** installs a timeout with the first timeout of 'value_msec' and then a periodic timeout with
|
||||
* 'interval_msec'. '_callback' is the callback function when the timer reaches the timeout.
|
||||
* returns a pointer to the timeout, which is needed for stopping it again
|
||||
/** Installs a timer with the first timeout after 'value_msec' and then an optional periodic timeout every
|
||||
* 'interval_msec' (set it to 0 to prevent periodic timeouts).
|
||||
* '_callback' is the function called when the timer reaches the timeout.
|
||||
* 'arg' is the argument passed to the callback function.
|
||||
* 'self' is an optional pointer to a timeout* variable. If non-NULL, the variable is set to NULL when the timer
|
||||
* is destroyed (with stop_timeout, cleanup_timeout or when the timer expires and it is single-shot).
|
||||
* Returns a pointer to the timer, which is needed for stopping/changing it.
|
||||
**/
|
||||
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
|
||||
timeout* add_timeout(int value_msec, int interval_msec, void (*_callback)(void*), void* arg, timeout **self);
|
||||
|
||||
/** changes timeout 't'. If timeout 't' does not exist, nothing happens **/
|
||||
void change_timeout(timeout* t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
|
||||
/** Changes timer 't'. If it does not exist, a new timer is created, with self set to 't'. **/
|
||||
void change_timeout(timeout** t, int value_msec, int interval_msec, void (*_callback)(void*), void* arg);
|
||||
|
||||
/** stops the timeout 't' **/
|
||||
void stop_timeout(timeout* t);
|
||||
|
|
Loading…
Reference in a new issue