From 1488f5525f69428d66b0cb2da6e610edae2ebf55 Mon Sep 17 00:00:00 2001 From: Andreas Fink Date: Sun, 15 Nov 2009 16:55:50 +0000 Subject: [PATCH] *add* changed everything to kernel timer for easier integration with new timer *todo* adapt tooltip also to the timer syntax *fix* memory leak --- src/Makefile.am | 2 + src/battery/battery.c | 12 +++++ src/clock/clock.c | 28 +++++----- src/clock/clock.h | 3 -- src/panel.c | 5 ++ src/panel.h | 1 - src/taskbar/task.c | 26 +++++++-- src/tint.c | 122 ++++++++++++++++++++---------------------- src/util/common.h | 1 - 9 files changed, 113 insertions(+), 87 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index bed1864..d872f43 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -14,6 +14,8 @@ tint2_SOURCES = config.c \ util/area.c \ util/window.h \ util/window.c \ + util/timer.h \ + util/timer.c \ panel.h \ clock/clock.c \ clock/clock.h \ diff --git a/src/battery/battery.c b/src/battery/battery.c index 5b98f13..f0498b7 100644 --- a/src/battery/battery.c +++ b/src/battery/battery.c @@ -31,6 +31,7 @@ #include "taskbar.h" #include "battery.h" #include "clock.h" +#include "timer.h" PangoFontDescription *bat1_font_desc=0; PangoFontDescription *bat2_font_desc=0; @@ -47,6 +48,14 @@ char *path_energy_full=0; char *path_current_now=0; char *path_status=0; +void update_batterys() +{ + int i; + update_battery(); + for (i=0 ; i < nb_panel ; i++) + panel1[i].battery.area.resize = 1; +} + void init_battery() { @@ -120,6 +129,9 @@ void init_battery() g_free(path1); g_free(battery_dir); + + if (battery_enabled) + install_timer(0, 1000000, 3, 0, update_batterys); } diff --git a/src/clock/clock.c b/src/clock/clock.c index c1504be..89bb250 100644 --- a/src/clock/clock.c +++ b/src/clock/clock.c @@ -30,6 +30,7 @@ #include "panel.h" #include "taskbar.h" #include "clock.h" +#include "timer.h" char *time1_format=0; @@ -37,7 +38,6 @@ char *time2_format=0; char *clock_lclick_command=0; char *clock_rclick_command=0; struct timeval time_clock; -int time_precision; PangoFontDescription *time1_font_desc=0; PangoFontDescription *time2_font_desc=0; static char buf_time[40]; @@ -45,25 +45,25 @@ static char buf_date[40]; int clock_enabled; -void init_precision() +void update_clocks() { - if (!time1_format) time_precision = 60; - else if (strchr(time1_format, 'S')) time_precision = 1; - else if (strchr(time1_format, 'T')) time_precision = 1; - else if (strchr(time1_format, 'r')) time_precision = 1; - else time_precision = 60; + gettimeofday(&time_clock, 0); + int i; + if (time1_format) { + for (i=0 ; i < nb_panel ; i++) + panel1[i].clock.area.resize = 1; + } + panel_refresh = 1; } void init_clock() { - init_precision(); - - // update clock to force update (-time_precision) - struct timeval stv; - gettimeofday(&stv, 0); - time_clock.tv_sec = stv.tv_sec - time_precision; - time_clock.tv_sec -= time_clock.tv_sec % time_precision; + if(time1_format) { + if (strchr(time1_format, 'S') || strchr(time1_format, 'T') || strchr(time1_format, 'r')) + install_timer(0, 1000000, 1, 0, update_clocks); + else install_timer(0, 1000000, 60, 0, update_clocks); + } } diff --git a/src/clock/clock.h b/src/clock/clock.h index 48538b3..8652ec5 100644 --- a/src/clock/clock.h +++ b/src/clock/clock.h @@ -26,8 +26,6 @@ typedef struct Clock { extern char *time1_format; extern char *time2_format; -extern struct timeval time_clock; -extern int time_precision; extern PangoFontDescription *time1_font_desc; extern PangoFontDescription *time2_font_desc; extern char *clock_lclick_command; @@ -38,7 +36,6 @@ extern int clock_enabled; // initialize clock : y position, precision, ... void init_clock(); void init_clock_panel(void *panel); -void init_precision(); void cleanup_clock(); void draw_clock (void *obj, cairo_t *c, int active); diff --git a/src/panel.c b/src/panel.c index 8058190..7b2fb1e 100644 --- a/src/panel.c +++ b/src/panel.c @@ -265,6 +265,11 @@ void cleanup_panel() if (panel1) free(panel1); panel1 = 0; + + if (panel_config.g_task.font_desc) { + pango_font_description_free(panel_config.g_task.font_desc); + panel_config.g_task.font_desc = 0; + } } diff --git a/src/panel.h b/src/panel.h index 30faf5f..864074c 100644 --- a/src/panel.h +++ b/src/panel.h @@ -51,7 +51,6 @@ extern int panel_refresh; extern Task *task_active; extern Task *task_drag; extern GSList *urgent_list; -extern int tick_urgent; extern int max_tick_urgent; extern Imlib_Image default_icon; diff --git a/src/taskbar/task.c b/src/taskbar/task.c index 07db372..94229a2 100644 --- a/src/taskbar/task.c +++ b/src/taskbar/task.c @@ -32,8 +32,9 @@ #include "server.h" #include "panel.h" #include "tooltip.h" +#include "timer.h" - +static int urgent_timer = 0; Task *add_task (Window win) { @@ -411,6 +412,21 @@ void active_task() } +void blink_urgent() +{ + GSList* urgent_task = urgent_list; + while (urgent_task) { + Task_urgent* t = urgent_task->data; + if ( t->tick < max_tick_urgent) { + t->tsk->area.is_active = !t->tsk->area.is_active; + t->tsk->area.redraw = 1; + t->tick++; + } + urgent_task = urgent_task->next; + } +} + + void add_urgent(Task *tsk) { // first check if task is already in the list and reset the counter @@ -431,7 +447,11 @@ void add_urgent(Task *tsk) t->tsk = tsk; t->tick = 0; urgent_list = g_slist_prepend(urgent_list, t); - time_precision = 1; + + if (urgent_timer == 0) + urgent_timer = install_timer(0, 1000000, 1, 0, blink_urgent); + else + reset_timer(urgent_timer, 0, 1000000, 1, 0); } @@ -444,7 +464,7 @@ void del_urgent(Task *tsk) urgent_list = g_slist_remove(urgent_list, t); free(t); if (!urgent_list) - init_precision(); + reset_timer(urgent_timer, 0, 0, 0, 0); return; } urgent_task = urgent_task->next; diff --git a/src/tint.c b/src/tint.c index 192fa36..a25e094 100644 --- a/src/tint.c +++ b/src/tint.c @@ -19,10 +19,10 @@ **************************************************************************/ #include -#include #include #include #include +#include #include #include #include @@ -38,7 +38,7 @@ #include "systraybar.h" #include "panel.h" #include "tooltip.h" - +#include "timer.h" void signal_handler(int sig) { @@ -74,12 +74,21 @@ void init (int argc, char *argv[]) } // Set signal handler - signal(SIGUSR1, signal_handler); - signal(SIGINT, signal_handler); - signal(SIGTERM, signal_handler); - signal(SIGHUP, signal_handler); + struct sigaction sa = { .sa_handler = signal_handler }; + sigaction(SIGUSR1, &sa, 0); + sigaction(SIGINT, &sa, 0); + sigaction(SIGTERM, &sa, 0); + sigaction(SIGHUP, &sa, 0); signal(SIGCHLD, SIG_IGN); // don't have to wait() after fork() signal(SIGALRM, tooltip_sighandler); + // block all signals, such that no race conditions occur before pselect in our main loop + sigset_t block_mask; + sigaddset(&block_mask, SIGINT); + sigaddset(&block_mask, SIGTERM); + sigaddset(&block_mask, SIGHUP); + sigaddset(&block_mask, SIGUSR1); + sigprocmask(SIG_BLOCK, &block_mask, 0); + // set global data memset(&server, 0, sizeof(Server_global)); @@ -111,7 +120,7 @@ void init (int argc, char *argv[]) setlocale (LC_ALL, ""); // load default icon - char *path; + gchar *path; const gchar * const *data_dirs; data_dirs = g_get_system_data_dirs (); for (i = 0; data_dirs[i] != NULL; i++) { @@ -660,42 +669,6 @@ void event_configure_notify (Window win) void event_timer() { - struct timeval stv; - int i; - - if (gettimeofday(&stv, 0)) return; - - if (abs(stv.tv_sec - time_clock.tv_sec) < time_precision) return; - time_clock.tv_sec = stv.tv_sec; - time_clock.tv_sec -= time_clock.tv_sec % time_precision; - - // urgent task - GSList* urgent_task = urgent_list; - while (urgent_task) { - Task_urgent* t = urgent_task->data; - if ( t->tick < max_tick_urgent) { - t->tsk->area.is_active = !t->tsk->area.is_active; - t->tsk->area.redraw = 1; - t->tick++; - } - urgent_task = urgent_task->next; - } - - // update battery -#ifdef ENABLE_BATTERY - if (battery_enabled) { - update_battery(); - for (i=0 ; i < nb_panel ; i++) - panel1[i].battery.area.resize = 1; - } -#endif - - // update clock - if (time1_format) { - for (i=0 ; i < nb_panel ; i++) - panel1[i].clock.area.resize = 1; - } - panel_refresh = 1; } @@ -732,11 +705,12 @@ void dnd_message(XClientMessageEvent *e) int main (int argc, char *argv[]) { XEvent e; - fd_set fd; + fd_set fd_set; int x11_fd, i; - struct timeval tv; Panel *panel; GSList *it; + GSList* timer_iter; + struct timer* timer; init (argc, argv); @@ -762,17 +736,25 @@ int main (int argc, char *argv[]) x11_fd = ConnectionNumber(server.dsp); XSync(server.dsp, False); + sigset_t empty_mask; + sigemptyset(&empty_mask); + while (1) { // thanks to AngryLlama for the timer - // Create a File Description Set containing x11_fd - FD_ZERO (&fd); - FD_SET (x11_fd, &fd); - - tv.tv_usec = 500000; - tv.tv_sec = 0; + // Create a File Description Set containing x11_fd, and every timer_fd + FD_ZERO (&fd_set); + FD_SET (x11_fd, &fd_set); + int max_fd = x11_fd; + timer_iter = timer_list; + while (timer_iter) { + timer = timer_iter->data; + max_fd = timer->id > max_fd ? timer->id : max_fd; + FD_SET(timer->id, &fd_set); + timer_iter = timer_iter->next; + } // Wait for X Event or a Timer - if (select(x11_fd+1, &fd, 0, 0, &tv)) { + if (pselect(max_fd+1, &fd_set, 0, 0, 0, &empty_mask) > 0) { while (XPending (server.dsp)) { XNextEvent(server.dsp, &e); @@ -844,22 +826,32 @@ int main (int argc, char *argv[]) break; } } + + timer_iter = timer_list; + while (timer_iter) { + timer = timer_iter->data; + if (FD_ISSET(timer->id, &fd_set)) { + uint64_t dummy; + read(timer->id, &dummy, sizeof(uint64_t)); + timer->_callback(); + } + timer_iter = timer_iter->next; + } } - event_timer(); switch (signal_pending) { - case SIGUSR1: // reload config file - signal_pending = 0; - init_config(); - config_read_file (config_path); - init_panel(); - cleanup_config(); - break; - case SIGINT: - case SIGTERM: - case SIGHUP: - cleanup (); - return 0; + case SIGUSR1: // reload config file + signal_pending = 0; + init_config(); + config_read_file (config_path); + init_panel(); + cleanup_config(); + break; + case SIGINT: + case SIGTERM: + case SIGHUP: + cleanup (); + return 0; } if (panel_refresh) { diff --git a/src/util/common.h b/src/util/common.h index 034666b..105b73e 100644 --- a/src/util/common.h +++ b/src/util/common.h @@ -64,6 +64,5 @@ void get_color (char *hex, double *rgb); // adjust Alpha/Saturation/Brightness on an ARGB icon // alpha from 0 to 100, satur from 0 to 1, bright from 0 to 1. void adjust_asb(DATA32 *data, int w, int h, int alpha, float satur, float bright); - #endif -- 2.44.0