4 #include <xcb/xcb_event.h>
13 node_t *make_node(void)
15 node_t *n = malloc(sizeof(node_t));
16 n->parent = n->first_child = n->second_child = NULL;
17 n->split_ratio = split_ratio;
18 n->split_type = TYPE_VERTICAL;
19 n->birth_rotation = ROTATE_IDENTITY;
25 monitor_t *make_monitor(xcb_rectangle_t *rect)
27 monitor_t *m = malloc(sizeof(monitor_t));
28 snprintf(m->name, sizeof(m->name), "%s%02d", DEFAULT_MON_NAME, ++monitor_uid);
29 m->prev = m->next = NULL;
30 m->desk = m->last_desk = NULL;
34 warn("no rectangle was given for monitor '%s'\n", m->name);
35 m->top_padding = m->right_padding = m->bottom_padding = m->left_padding = 0;
40 monitor_t *find_monitor(char *name)
42 for (monitor_t *m = mon_head; m != NULL; m = m->next)
43 if (strcmp(m->name, name) == 0)
48 monitor_t *get_monitor_by_id(xcb_randr_output_t id)
50 for (monitor_t *m = mon_head; m != NULL; m = m->next)
56 monitor_t *add_monitor(xcb_rectangle_t *rect)
58 monitor_t *m = make_monitor(rect);
72 void remove_monitor(monitor_t *m)
74 while (m->desk_head != NULL)
75 remove_desktop(m, m->desk_head);
76 monitor_t *prev = m->prev;
77 monitor_t *next = m->next;
89 mon = (last_mon == NULL ? mon_head : last_mon);
94 void transfer_desktop(monitor_t *ms, monitor_t *md, desktop_t *d)
96 unlink_desktop(ms, d);
97 insert_desktop(md, d);
100 void merge_monitors(monitor_t *ms, monitor_t *md)
102 PRINTF("merge monitor %s into %s\n", ms->name, md->name);
105 for (node_t *n = first_extrema(ms->desk->root); n != NULL; n = next_leaf(n, ms->desk->root))
106 window_hide(n->client->window);
108 desktop_t *d = ms->desk_head;
110 desktop_t *next = d->next;
111 transfer_desktop(ms, md, d);
116 desktop_t *make_desktop(const char *name)
118 desktop_t *d = malloc(sizeof(desktop_t));
120 snprintf(d->name, sizeof(d->name), "%s%02d", DEFAULT_DESK_NAME, ++desktop_uid);
122 strncpy(d->name, name, sizeof(d->name));
123 d->layout = LAYOUT_TILED;
124 d->prev = d->next = NULL;
125 d->root = d->focus = NULL;
126 d->history = make_focus_history();
130 void insert_desktop(monitor_t *m, desktop_t *d)
132 if (m->desk == NULL) {
137 m->desk_tail->next = d;
138 d->prev = m->desk_tail;
143 void add_desktop(monitor_t *m, desktop_t *d)
145 PRINTF("add desktop %s\n", d->name);
147 insert_desktop(m, d);
149 ewmh_update_number_of_desktops();
150 ewmh_update_desktop_names();
154 void empty_desktop(desktop_t *d)
156 destroy_tree(d->root);
157 d->root = d->focus = NULL;
158 empty_history(d->history);
161 void unlink_desktop(monitor_t *m, desktop_t *d)
163 desktop_t *prev = d->prev;
164 desktop_t *next = d->next;
169 if (m->desk_head == d)
171 if (m->desk_tail == d)
173 if (m->last_desk == d)
176 m->desk = (m->last_desk == NULL ? m->desk_head : m->last_desk);
177 d->prev = d->next = NULL;
180 void remove_desktop(monitor_t *m, desktop_t *d)
182 PRINTF("remove desktop %s\n", d->name);
185 unlink_desktop(m, d);
189 ewmh_update_number_of_desktops();
190 ewmh_update_desktop_names();
194 client_t *make_client(xcb_window_t win)
196 client_t *c = malloc(sizeof(client_t));
197 strncpy(c->class_name, MISSING_VALUE, sizeof(c->class_name));
198 c->uid = ++client_uid;
199 c->border_width = border_width;
201 c->floating = c->transient = c->fullscreen = c->locked = c->urgent = false;
205 rule_t *make_rule(void)
207 rule_t *r = malloc(sizeof(rule_t));
209 r->effect.floating = false;
210 r->effect.follow = false;
211 r->effect.monitor = NULL;
212 r->effect.desktop = NULL;
218 pointer_state_t *make_pointer_state(void)
220 pointer_state_t *p = malloc(sizeof(pointer_state_t));
223 p->node = p->vertical_fence = p->horizontal_fence = NULL;
225 p->window = XCB_NONE;
229 focus_history_t *make_focus_history(void)
231 focus_history_t *f = malloc(sizeof(focus_history_t));
232 f->head = f->tail = NULL;
236 node_list_t *make_node_list(void)
238 node_list_t *n = malloc(sizeof(node_list_t));
240 n->prev = n->next = NULL;
245 void history_add(focus_history_t *f, node_t *n)
247 node_list_t *a = make_node_list();
249 if (f->head == NULL) {
250 f->head = f->tail = a;
251 } else if (f->head->node != n) {
252 for (node_list_t *b = f->head; b != NULL; b = b->next)
263 void history_remove(focus_history_t *f, node_t *n)
265 /* in order to maintain the `latest` node list state,
266 we remove node lists from head to tail */
267 node_list_t *b = f->head;
270 node_list_t *a = b->prev;
271 node_list_t *c = b->next;
273 /* remove duplicate entries */
274 while (c != NULL && c->node == a->node) {
275 node_list_t *d = c->next;
297 void empty_history(focus_history_t *f)
299 node_list_t *a = f->head;
301 node_list_t *b = a->next;
305 f->head = f->tail = NULL;
308 node_t *history_get(focus_history_t *f, int i)
310 node_list_t *a = f->head;
311 while (a != NULL && i > 0) {