From 1b04f51d674463252c41d0edffc997ca06b34d92 Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Wed, 12 Dec 2012 12:48:21 +0100 Subject: [PATCH] use n_queue for displayed notifications --- container.c | 288 +++++----------------------------------------------- container.h | 67 +++--------- dunst.c | 103 +++++++------------ 3 files changed, 76 insertions(+), 382 deletions(-) diff --git a/container.c b/container.c index 8f1883b..8e89fa3 100644 --- a/container.c +++ b/container.c @@ -3,266 +3,6 @@ #include "container.h" -int l_push(list * l, void *data) -{ - l_node *n; - int ret; - - /* invalid input */ - if (!l || !data) { - return -1; - } - - n = l_init_node(data); - if (!n) { - /* something went wrong */ - return -2; - } - - ret = l_node_push(l, n); - - return ret; -} - -int l_node_push(list * l, l_node * n) -{ - l_node *end; - - /* invalid input */ - if (!l || !n) { - return -1; - } - - n->next = NULL; - - /* empty list */ - if (!l->head) { - l->head = n; - - return 0; - } - - for (end = l->head; end->next; end = end->next) ; - - if (end != n) { - end->next = n; - } - - return 0; -} - -void *l_pop(list * l) -{ - l_node *penultimate; - void *data; - - /* invalid input */ - if (!l) { - return NULL; - } - - /* empty list */ - if (!l->head) { - return NULL; - } - - /* len(l) == 1 */ - if (!l->head->next) { - data = l->head->data; - free(l->head); - l->head = NULL; - - return data; - } - - for (penultimate = l->head; - penultimate->next->next; penultimate = penultimate->next) ; - data = penultimate->next->data; - free(penultimate->next); - penultimate->next = NULL; - - return data; -} - -int l_insert(l_node * node, void *data) -{ - int ret; - l_node *to_be_inserted; - - /* invalid input */ - if (!node || !data) { - return -1; - } - - to_be_inserted = l_init_node(data); - if (!to_be_inserted) { - return -2; - } - - ret = l_node_insert(node, to_be_inserted); - - return ret; -} - -int l_node_insert(l_node * node, l_node * to_be_inserted) -{ - l_node *tmp; - - /* invalid input */ - if (!node || !to_be_inserted) { - return -1; - } - - tmp = node->next; - node->next = to_be_inserted; - to_be_inserted->next = tmp; - - return 0; -} - -void *l_remove(list * l, l_node * node) -{ - void *data; - if (l != NULL) { - l_node_remove(l, node); - } - - if (node == NULL) { - return NULL; - } - - data = node->data; - free(node); - - return data; -} - -l_node *l_node_remove(list * l, l_node * node) -{ - l_node *prev; - l_node *next; - - /* invalid input */ - if (!l || !node) { - return NULL; - } - - /* empty list */ - if (!l->head) { - return NULL; - } - - /* node is head */ - if (l->head == node) { - l->head = node->next; - node->next = NULL; - return node; - } - - /* find the predecessor of node */ - for (prev = l->head; - prev->next && prev->next != node; prev = prev->next) ; - - /* node not in list */ - if (prev->next != node) { - return node; - } - - next = node->next; - prev->next = next; - - return node; -} - -l_node *l_init_node(void *data) -{ - l_node *node; - - node = malloc(sizeof(l_node)); - if (!node) { - return NULL; - } - - node->data = data; - node->next = NULL; - - return node; -} - -int l_length(list * l) -{ - l_node *iter; - int count; - - if (!l || !l->head) { - return 0; - } - - count = 0; - iter = l->head; - while (iter) { - count++; - iter = iter->next; - } - - return count; -} - -int l_is_empty(list * l) -{ - return l->head == NULL; -} - -int l_move(list * from, list * to, l_node * node) -{ - - if (!from || !to || !node) { - return -1; - } - node = l_node_remove(from, node); - return l_node_push(to, node); -} - -list *l_init(void) -{ - list *l = malloc(sizeof(list)); - l->head = NULL; - - return l; -} - -void l_sort(list * l, int (*f) (void *, void *)) -{ - list *old_list; - - if (!l || l_length(l) < 2) { - /* nothing to do */ - return; - } - - old_list = l_init(); - - old_list->head = l->head; - l->head = NULL; - - while (!l_is_empty(old_list)) { - l_node *iter; - l_node *max; - - /* find max in old_list */ - max = old_list->head; - for (iter = old_list->head; iter; iter = iter->next) { - if (f(max->data, iter->data) < 0) { - max = iter; - } - } - - l_move(old_list, l, max); - } - - free(old_list); -} - void n_stack_push(n_stack **s, notification *n) { if (!n || !s) @@ -288,6 +28,29 @@ notification *n_stack_pop(n_stack **s) return n; } +void n_stack_remove(n_stack **s, notification *n) +{ + if (!s || !*s || !n) + return; + + /* head is n */ + if ((*s)->n == n) { + n_stack *tmp = *s; + *s = (*s)->next; + free(tmp); + return; + } + + for (n_stack *iter = *s; iter->next; iter = iter->next) { + if (iter->next->n == n) { + n_stack *tmp = iter->next; + iter->next = iter->next->next; + free(tmp); + return; + } + } +} + int n_stack_len(n_stack **s) { if (!s || !*s) @@ -360,6 +123,11 @@ void n_queue_enqueue(n_queue **q, notification *n) cur->next = new; } +void n_queue_remove(n_queue **q, notification *n) +{ + n_stack_remove(q, n); +} + notification *n_queue_dequeue(n_queue **q) { return n_stack_pop(q); diff --git a/container.h b/container.h index e8386b2..9a16150 100644 --- a/container.h +++ b/container.h @@ -3,15 +3,6 @@ #include "dunst.h" -typedef struct _l_node { - struct _l_node *next; - void *data; -} l_node; - -typedef struct _list { - l_node *head; -} list; - typedef struct _n_stack { notification *n; struct _n_stack *next; @@ -21,52 +12,6 @@ typedef n_stack n_queue; int cmp_notification(notification *a, notification *b); -/* append to end of list */ -int l_push(list * l, void *data); - -/* same as append but with a l_node */ -int l_node_push(list * l, l_node * n); - -/* remove and return last element of list */ -void *l_pop(list * l); - -/* insert after node. */ -int l_insert(l_node * node, void *data); - -/* - * same as insert, but using a node_t - */ -int l_node_insert(l_node * node, l_node * to_be_inserted); - -/* - * remove l_node from list and return a pointer to its data - */ -void *l_remove(list * l, l_node * node); - -/* - * same as l_remove but returns the node instead of the data - */ -l_node *l_node_remove(list * l, l_node * node); - -/* - * initialize a node - */ -l_node *l_init_node(void *data); - -/* return the length of the list */ -int l_length(list * l); - -/* is list empty */ -int l_is_empty(list * l); - -/* move node from 'from' to 'to' */ -int l_move(list * from, list * to, l_node * node); - -void l_sort(list * l, int (*f) (void *, void *)); - -list *l_init(void); - - /************ * stack */ @@ -83,6 +28,12 @@ void n_stack_push(n_stack **s, notification *n); */ notification *n_stack_pop(n_stack **s); +/** + * remove notification from stack + */ + +void n_stack_remove(n_stack **q, notification *n); + /** * return length of stack */ @@ -107,6 +58,12 @@ void n_queue_enqueue(n_queue **q, notification *n); notification *n_queue_dequeue(n_queue **q); +/** + * remove notification from queue + */ + +void n_queue_remove(n_queue **q, notification *n); + /** * return length of queue */ diff --git a/dunst.c b/dunst.c index a6bce55..2835e14 100644 --- a/dunst.c +++ b/dunst.c @@ -80,7 +80,7 @@ int next_notification_id = 1; /* notification lists */ n_queue *queue = NULL; /* all new notifications get into here */ -list *displayed_notifications = NULL; /* currently displayed notifications */ +n_queue *displayed = NULL; /* currently displayed notifications */ n_stack *history = NULL; /* history of displayed notifications */ /* misc funtions */ @@ -96,7 +96,6 @@ void run(void); void setup(void); void update_screen_info(); void usage(int exit_status); -l_node *most_important(list * l); void draw_win(void); void hide_win(void); void move_all_to_history(void); @@ -216,42 +215,30 @@ void apply_rules(notification * n) void check_timeouts(void) { - l_node *iter; - notification *current; - l_node *next; - /* nothing to do */ - if (l_is_empty(displayed_notifications)) { + if (!displayed) return; - } - iter = displayed_notifications->head; - while (iter != NULL) { - current = (notification *) iter->data; + for (n_queue *iter = displayed; iter; iter = iter->next) { + notification *n = iter->n; /* don't timeout when user is idle */ if (is_idle()) { - current->start = now; - iter = iter->next; + n->start = now; continue; } /* skip hidden and sticky messages */ - if (current->start == 0 || current->timeout == 0) { - iter = iter->next; + if (n->start == 0 || n->timeout == 0) { continue; } /* remove old message */ - if (difftime(now, current->start) > current->timeout) { - /* l_move changes iter->next, so we need to store it beforehand */ - next = iter->next; - close_notification(current, 1); - iter = next; - continue; - - } else { - iter = iter->next; + if (difftime(now, n->start) > n->timeout) { + /* close_notification may conflict with iter, so restart */ + close_notification(n, 1); + check_timeouts(); + return; } } } @@ -263,8 +250,8 @@ void update_lists() check_timeouts(); if (pause_display) { - while (!l_is_empty(displayed_notifications)) { - notification *n = (notification *) l_remove(displayed_notifications, displayed_notifications->head); + while (displayed) { + notification *n = n_queue_dequeue(&displayed); n_queue_enqueue(&queue, n); } return; @@ -284,7 +271,7 @@ void update_lists() /* move notifications from queue to displayed */ while (queue) { - if (limit > 0 && l_length(displayed_notifications) >= limit) { + if (limit > 0 && n_queue_len(&displayed) >= limit) { /* the list is full */ break; } @@ -295,10 +282,7 @@ void update_lists() return; n->start = now; - l_push(displayed_notifications, n); - - l_sort(displayed_notifications, cmp_notification); - + n_queue_enqueue(&displayed, n); } } @@ -571,10 +555,8 @@ void move_and_map(int width, int height) void fill_line_cache(int width) { /* create cache with all lines */ - for (l_node * iter = displayed_notifications->head; iter; - iter = iter->next) { - notification *n = (notification *) iter->data; - add_notification_to_line_cache(n, width); + for (n_queue *iter = displayed; iter; iter = iter->next) { + add_notification_to_line_cache(iter->n, width); } assert(line_cache.count > 0); @@ -724,18 +706,16 @@ void handle_mouse_click(XEvent ev) if (ev.xbutton.button == Button1) { int y = 0; - notification *n; - l_node *iter = displayed_notifications->head; - assert(iter); - for (; iter; iter = iter->next) { - n = (notification *) iter->data; - int height = font_h * n->line_count; + notification *n = NULL; + for (n_queue *iter = displayed; iter; iter = iter->next) { + int height = font_h * iter->n->line_count; if (ev.xbutton.y > y && ev.xbutton.y < y + height) break; else y += height; } - close_notification(n, 2); + if (n) + close_notification(n, 2); } } @@ -767,10 +747,8 @@ void handleXEvents(void) if (close_ks.str && XLookupKeysym(&ev.xkey, 0) == close_ks.sym && close_ks.mask == ev.xkey.state) { - if (!l_is_empty(displayed_notifications)) { - notification *n = (notification *) - displayed_notifications->head->data; - close_notification(n, 2); + if (displayed) { + close_notification(displayed->n, 2); } } if (history_ks.str @@ -789,16 +767,11 @@ void handleXEvents(void) void move_all_to_history() { - l_node *node; - notification *n; - - while (!l_is_empty(displayed_notifications)) { - node = displayed_notifications->head; - n = (notification *) node->data; - close_notification(n, 2); + while (displayed) { + close_notification(displayed->n, 2); } - n = n_queue_dequeue(&queue); + notification *n = n_queue_dequeue(&queue); while (n) { n_stack_push(&history, n); n = n_queue_dequeue(&queue); @@ -885,9 +858,8 @@ int init_notification(notification * n, int id) } } - for (l_node * iter = displayed_notifications->head; iter; - iter = iter->next) { - notification *orig = (notification *) iter->data; + for (n_queue *iter = displayed; iter; iter = iter->next) { + notification *orig = iter->n; if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->msg, n->msg) == 0) { orig->dup_count++; @@ -952,22 +924,20 @@ int close_notification_by_id(int id, int reason) { notification *target = NULL; - for (l_node *iter = displayed_notifications->head; iter; iter = iter->next) { - notification *n = (notification *) iter->data; + for (n_queue *iter = displayed; iter; iter = iter->next) { + notification *n = iter->n; if (n->id == id) { - l_remove(displayed_notifications, iter); + n_queue_remove(&displayed, n); n_stack_push(&history, n); target = n; break; } } - for (n_queue *iter = queue; iter && iter->next; iter = iter->next) { + for (n_queue *iter = queue; iter; iter = iter->next) { notification *n = iter->next->n; if (n->id == id) { - n_queue *tmp = iter->next; - iter->next = iter->next->next; - free(tmp); + n_queue_remove(&queue, n); n_stack_push(&history, n); target = n; break; @@ -1098,7 +1068,7 @@ void run(void) /* move messages from notification_queue to displayed_notifications */ update_lists(); - if (l_length(displayed_notifications) > 0) { + if (displayed) { if (!visible) { map_win(); } else { @@ -1306,7 +1276,7 @@ void setup(void) void map_win(void) { /* window is already mapped or there's nothing to show */ - if (visible || l_is_empty(displayed_notifications)) { + if (visible || !displayed) { return; } @@ -1576,7 +1546,6 @@ int main(int argc, char *argv[]) { now = time(&now); - displayed_notifications = l_init(); r_line_cache_init(&line_cache);