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