list.c (2936B)
1 /* 2 * kbgwm, a sucklessy floating window manager 3 * Copyright (c) 2020-2021, Kebigon <git@kebigon.xyz> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 18 #include "list.h" 19 20 #include <stdio.h> 21 #include <stdlib.h> 22 23 #include "xcbutils.h" 24 25 // Internal use only 26 void list_remove_item(struct item **list, struct item *item) 27 { 28 if (item->previous != NULL) 29 item->previous->next = item->next; 30 if (item->next != NULL) 31 item->next->previous = item->previous; 32 if (item == *list) 33 *list = item->next; 34 } 35 36 struct item *list_tail(struct item **list) 37 { 38 if (list_is_empty(list)) 39 return NULL; 40 struct item *item = *list; 41 42 while (item->next != NULL) 43 item = item->next; 44 return item; 45 } 46 47 void list_move_to_head(struct item **list, struct item *item) 48 { 49 if (list_is_empty(list)) 50 return; 51 52 list_remove_item(list, item); 53 54 item->previous = NULL; 55 item->next = *list; 56 item->next->previous = item; 57 *list = item; 58 } 59 60 void list_move_to_tail(struct item **list, struct item *item) 61 { 62 struct item *tail = list_tail(list); 63 if (tail == NULL) 64 return; 65 66 list_remove_item(list, item); 67 68 item->next = NULL; 69 tail->next = item; 70 item->previous = tail; 71 } 72 73 // Add a client to the head of the list 74 void list_add(struct item **list, void *e) 75 { 76 struct item *item = emalloc(sizeof(struct item)); 77 item->data = e; 78 item->previous = NULL; 79 item->next = *list; 80 81 if (item->next != NULL) 82 item->next->previous = item; 83 84 *list = item; 85 } 86 87 // Remove an item from the list 88 void *list_remove(struct item **list, struct item *item) 89 { 90 if (list_is_empty(list)) 91 return NULL; 92 93 list_remove_item(list, item); 94 95 struct client *data = item->data; 96 free(item); 97 return data; 98 } 99 100 // Remove the client from the head of the list 101 void *list_remove_head(struct item **list) 102 { 103 return list_is_empty(list) ? NULL : list_remove(list, *list); 104 } 105 106 struct item *list_find_client(struct item **list, xcb_window_t id) 107 { 108 if (list_is_empty(list)) 109 return NULL; 110 111 struct item *item = *list; 112 113 do 114 { 115 if (((struct client *)item->data)->id == id) 116 return item; 117 } while ((item = item->next) != NULL); 118 119 return NULL; 120 }