From 34714fe1f9ffabdb9ac3590c1e4b4d2c41f4e2af Mon Sep 17 00:00:00 2001 From: Sascha Kruse Date: Sat, 16 Feb 2013 05:25:51 +0100 Subject: [PATCH] replaced stack/queue with GList/GQueue --- container.c | 134 -------------------------------------------------- container.h | 67 ------------------------- dunst.c | 137 +++++++++++++++++++++++++++++++--------------------- 3 files changed, 82 insertions(+), 256 deletions(-) diff --git a/container.c b/container.c index a6d469d..76c5cd1 100644 --- a/container.c +++ b/container.c @@ -4,140 +4,6 @@ #include "container.h" -void n_stack_push(n_stack **s, notification *n) -{ - if (!n || !s) - return; - - n_stack *new = malloc(sizeof(n_stack)); - new->n = n; - new->next = *s; - *s = new; -} - -notification *n_stack_pop(n_stack **s) -{ - if (!s || !*s) - return NULL; - - n_stack *head = *s; - *s = (*s)->next; - - notification *n = head->n; - free(head); - - 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) - return 0; - - n_stack *cur = *s; - int count = 0; - - while (cur) { - cur = cur->next; - count++; - } - - return count; -} - -int cmp_notification(notification *a, notification *b) -{ - if (a == NULL && b == NULL) - return 0; - else if (a == NULL) - return -1; - else if (b == NULL) - return 1; - - if (a->urgency != b->urgency) { - return a->urgency - b->urgency; - } else { - return b->timestamp - a->timestamp; - } -} - -void n_queue_enqueue(n_queue **q, notification *n) -{ - if (!n || !q) - return; - - - n_queue *new = malloc(sizeof(n_queue)); - new->n = n; - new->next = NULL; - - if (!(*q)) { - /* queue was empty */ - *q = new; - return; - } - - - /* new head */ - if (cmp_notification(new->n, (*q)->n) > 0) { - new->next = *q; - *q = new; - return; - } - - /* in between */ - n_queue *cur = *q; - while (cur->next) { - if (cmp_notification(new->n, cur->next->n) > 0) { - new->next = cur->next; - cur->next = new; - return; - } - - cur = cur->next; - } - - /* last */ - 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); -} - -int n_queue_len(n_queue **q) -{ - return n_stack_len(q); -} str_array *str_array_malloc(void) { diff --git a/container.h b/container.h index 1e8e0b5..265b8dc 100644 --- a/container.h +++ b/container.h @@ -3,13 +3,6 @@ #include "dunst.h" -typedef struct _n_stack { - notification *n; - struct _n_stack *next; -} n_stack; - -typedef n_stack n_queue; - typedef struct _str_array { int count; char **strs; @@ -20,65 +13,5 @@ void str_array_dup_append(str_array *a, const char *str); void str_array_append(str_array *a, char *str); void str_array_deep_free(str_array *a); -int cmp_notification(notification *a, notification *b); - -/************ - * stack - */ - -/** - * push notification onto stack - * creates a new stack if *s == NULL - */ -void n_stack_push(n_stack **s, notification *n); - -/** - * remove and return notification from stack - * sets *s to NULL if stack is empty - */ -notification *n_stack_pop(n_stack **s); - -/** - * remove notification from stack - */ - -void n_stack_remove(n_stack **q, notification *n); - -/** - * return length of stack - */ - -int n_stack_len(n_stack **s); - -/*************** - * queue - */ - -/** - * enqueue notification into queue - * creates a new queue if *q == NULL - */ - -void n_queue_enqueue(n_queue **q, notification *n); - -/** - * dequeues the next element from the queue. - * returns NULL if queue is empty - */ - -notification *n_queue_dequeue(n_queue **q); - -/** - * remove notification from queue - */ - -void n_queue_remove(n_queue **q, notification *n); - -/** - * return length of queue - */ - -int n_queue_len(n_queue **q); - #endif /* vim: set ts=8 sw=8 tw=0: */ diff --git a/dunst.c b/dunst.c index c095b4e..e4bcff1 100644 --- a/dunst.c +++ b/dunst.c @@ -84,12 +84,14 @@ bool dunst_grab_errored = false; int next_notification_id = 1; /* notification lists */ -n_queue *queue = NULL; /* all new notifications get into here */ -n_queue *displayed = NULL; /* currently displayed notifications */ -n_stack *history = NULL; /* history of displayed notifications */ +GQueue *queue = NULL; /* all new notifications get into here */ +GQueue *displayed = NULL; /* currently displayed notifications */ +GQueue *history = NULL; /* history of displayed notifications */ /* misc funtions */ void apply_rules(notification * n); +int cmp_notification(const void *a, const void *b); +int cmp_notification_data(const void *va, const void *vb, void *data); void check_timeouts(void); char *fix_markup(char *str); void handle_mouse_click(XEvent ev); @@ -116,6 +118,33 @@ void r_line_cache_reset(r_line_cache *c); void init_shortcut(keyboard_shortcut * shortcut); KeySym string_to_mask(char *str); +int cmp_notification(const void *va, const void *vb) +{ + notification *a = (notification*) va; + notification *b = (notification*) vb; + if (!sort) + return 1; + + if (a == NULL && b == NULL) + return 1; + else if (a == NULL) + return 1; + else if (b == NULL) + return -1; + + if (a->urgency != b->urgency) { + return b->urgency - a->urgency; + } else { + return a->timestamp - b->timestamp; + } +} + +int cmp_notification_data(const void *va, const void *vb, void *data) +{ + return cmp_notification(va, vb); +} + + str_array *extract_urls( const char * to_match) { static bool is_initialized = false; @@ -164,16 +193,14 @@ str_array *extract_urls( const char * to_match) void context_menu(void) { char *dmenu_input = NULL; - n_queue *iter = displayed; - - while (iter) { - for (int i = 0; i < iter->n->urls->count; i++) { + for (GList *iter = g_queue_peek_head_link(displayed); iter; iter = iter->next) { + for (int i = 0; i < ((notification*)iter->data)->urls->count; i++) { dmenu_input = string_append(dmenu_input, - (iter->n->urls->strs)[i], "\n"); + (((notification*)iter->data)->urls->strs)[i], "\n"); } - iter = iter->next; } + if (!dmenu_input) return; @@ -409,11 +436,11 @@ void apply_rules(notification * n) void check_timeouts(void) { /* nothing to do */ - if (!displayed) + if (displayed->length == 0) return; - for (n_queue *iter = displayed; iter; iter = iter->next) { - notification *n = iter->n; + for (GList *iter = g_queue_peek_head_link(displayed); iter; iter = iter->next) { + notification *n = iter->data; /* don't timeout when user is idle */ if (is_idle()) { @@ -443,9 +470,8 @@ void update_lists() check_timeouts(); if (pause_display) { - while (displayed) { - notification *n = n_queue_dequeue(&displayed); - n_queue_enqueue(&queue, n); + while (displayed->length > 0) { + g_queue_insert_sorted(queue, g_queue_pop_head(queue), cmp_notification_data, NULL); } return; } @@ -462,14 +488,14 @@ void update_lists() /* move notifications from queue to displayed */ - while (queue) { + while (queue->length > 0) { - if (limit > 0 && n_queue_len(&displayed) >= limit) { + if (limit > 0 && displayed->length >= limit) { /* the list is full */ break; } - notification *n = n_queue_dequeue(&queue); + notification *n = g_queue_pop_head(queue); if (!n) return; @@ -478,7 +504,7 @@ void update_lists() run_script(n); } - n_queue_enqueue(&displayed, n); + g_queue_insert_sorted(displayed, n, cmp_notification_data, NULL); } } @@ -736,18 +762,17 @@ void move_and_map(int width, int height) void fill_line_cache(int width) { /* create cache with all lines */ - for (n_queue *iter = displayed; iter; iter = iter->next) { - add_notification_to_line_cache(iter->n, width); + for (GList *iter = g_queue_peek_head_link(displayed); iter; iter = iter->next) { + add_notification_to_line_cache(iter->data, width); } assert(line_cache.count > 0); /* add (x more) */ - int queue_cnt = n_queue_len(&queue); - if (indicate_hidden && queue_cnt > 0) { + if (indicate_hidden && queue->length > 0) { if (geometry.h != 1) { char *tmp; - tmp = g_strdup_printf("(%d more)", queue_cnt); + tmp = g_strdup_printf("(%d more)", queue->length); ColorSet *last_colors = line_cache.lines[line_cache.count-1].colors; r_line_cache_append(&line_cache, tmp, last_colors, true, true); @@ -755,7 +780,7 @@ void fill_line_cache(int width) } else { char *old = line_cache.lines[0].str; char *new; - new = g_strdup_printf("%s (%d more)", old, queue_cnt); + new = g_strdup_printf("%s (%d more)", old, queue->length); free(old); line_cache.lines[0].str = new; } @@ -795,9 +820,9 @@ void draw_win(void) /* resize dc to correct width */ int height = (line_cache.count * line_height) - + n_queue_len(&displayed) * 2 * padding - + ((indicate_hidden && n_queue_len(&queue) > 0) ? 2 * padding : 0) - + (separator_height * (n_queue_len(&displayed) - 1)) + + displayed->length * 2 * padding + + ((indicate_hidden && queue->length > 0) ? 2 * padding : 0) + + (separator_height * (displayed->length - 1)) + (2 * frame_width); @@ -923,8 +948,8 @@ void handle_mouse_click(XEvent ev) if (ev.xbutton.button == Button1) { int y = separator_height; notification *n = NULL; - for (n_queue *iter = displayed; iter; iter = iter->next) { - n = iter->n; + for (GList *iter = g_queue_peek_head_link(displayed); iter; iter = iter->next) { + n = iter->data; int text_h = MAX(font_h, line_height) * n->line_count; int padding = 2 * h_padding; @@ -969,7 +994,7 @@ void handleXEvents(void) && XLookupKeysym(&ev.xkey, 0) == close_ks.sym && close_ks.mask == ev.xkey.state) { if (displayed) { - close_notification(displayed->n, 2); + close_notification(g_queue_peek_head_link(displayed)->data, 2); } } if (history_ks.str @@ -993,28 +1018,28 @@ void handleXEvents(void) void move_all_to_history() { - while (displayed) { - close_notification(displayed->n, 2); + while (displayed->length > 0) { + close_notification(g_queue_peek_head_link(displayed)->data, 2); } - notification *n = n_queue_dequeue(&queue); + notification *n = g_queue_pop_head(queue); while (n) { - n_stack_push(&history, n); - n = n_queue_dequeue(&queue); + g_queue_push_tail(history, n); + n = g_queue_pop_head(queue); } } void history_pop(void) { - if (!history) + if (g_queue_is_empty(history)) return; - notification *n = n_stack_pop(&history); + notification *n = g_queue_pop_tail(history); n->redisplayed = true; n->start = 0; n->timeout = sticky_history ? 0 : n->timeout; - n_queue_enqueue(&queue, n); + g_queue_push_head(queue, n); if (!visible) { map_win(); @@ -1088,8 +1113,8 @@ int init_notification(notification * n, int id) n->dup_count = 0; /* check if n is a duplicate */ - for (n_queue *iter = queue; iter; iter = iter->next) { - notification *orig = iter->n; + for (GList *iter = g_queue_peek_head_link(queue); iter; iter = iter->next) { + notification *orig = iter->data; if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->msg, n->msg) == 0) { orig->dup_count++; @@ -1098,8 +1123,8 @@ int init_notification(notification * n, int id) } } - for (n_queue *iter = displayed; iter; iter = iter->next) { - notification *orig = iter->n; + for (GList *iter = g_queue_peek_head_link(displayed); iter; iter = iter->next) { + notification *orig = iter->data; if (strcmp(orig->appname, n->appname) == 0 && strcmp(orig->msg, n->msg) == 0) { orig->dup_count++; @@ -1144,7 +1169,7 @@ int init_notification(notification * n, int id) close_notification(n, 2); printf("skipping notification: %s %s\n", n->body, n->summary); } else { - n_queue_enqueue(&queue, n); + g_queue_insert_sorted(queue, n, cmp_notification_data, NULL); } char *tmp = g_strconcat(n->summary, " ", n->body, NULL); @@ -1171,21 +1196,21 @@ int close_notification_by_id(int id, int reason) { notification *target = NULL; - for (n_queue *iter = displayed; iter; iter = iter->next) { - notification *n = iter->n; + for (GList *iter = g_queue_peek_head_link(displayed); iter; iter = iter->next) { + notification *n = iter->data; if (n->id == id) { - n_queue_remove(&displayed, n); - n_stack_push(&history, n); + g_queue_remove(displayed, n); + g_queue_push_tail(history, n); target = n; break; } } - for (n_queue *iter = queue; iter; iter = iter->next) { - notification *n = iter->n; + for (GList *iter = g_queue_peek_head_link(queue); iter; iter = iter->next) { + notification *n = iter->data; if (n->id == id) { - n_queue_remove(&queue, n); - n_stack_push(&history, n); + g_queue_remove(queue, n); + g_queue_push_tail(history, n); target = n; break; } @@ -1315,7 +1340,7 @@ void run(void) /* move messages from notification_queue to displayed_notifications */ update_lists(); - if (displayed) { + if (displayed->length > 0) { if (!visible) { map_win(); } else { @@ -1535,7 +1560,7 @@ void setup(void) void map_win(void) { /* window is already mapped or there's nothing to show */ - if (visible || !displayed) { + if (visible || g_queue_is_empty(displayed)) { return; } @@ -1843,7 +1868,9 @@ int main(int argc, char *argv[]) now = time(&now); r_line_cache_init(&line_cache); - + history = g_queue_new(); + displayed = g_queue_new(); + queue = g_queue_new(); rules.count = LENGTH(default_rules); rules.rules = calloc(rules.count, sizeof(rule_t));