#ifndef OUTPUTS_H_
#define OUTPUTS_H_
-#include "common.h"
#include <xcb/xcb.h>
-typedef struct i3_output_t i3_output;
+#include "common.h"
+#include "workspaces.h"
+
+typedef struct i3_output i3_output;
-i3_output* outputs;
+SLIST_HEAD(outputs_head, i3_output);
+struct outputs_head *outputs;
void parse_outputs_json(char* json);
void free_outputs();
i3_output* get_output_by_name(char* name);
-struct i3_output_t {
+struct i3_output {
char* name;
bool active;
int ws;
xcb_window_t bar;
xcb_gcontext_t bargc;
- i3_output* next;
+ struct ws_head *workspaces;
+
+ SLIST_ENTRY(i3_output) slist;
};
#endif
#ifndef UTIL_H_
#define UTIL_H_
+#include "queue.h"
+
/* Securely free p */
#define FREE(p) do { \
if (p != NULL) { \
} while (0)
/* Securely fee single-linked list */
-#define FREE_LIST(l, type) do { \
- type* FREE_LIST_TMP; \
- while (l != NULL) { \
- FREE_LIST_TMP = l; \
- free(l); \
- l = l->next; \
+#define FREE_SLIST(l, type) do { \
+ type *walk = SLIST_FIRST(l); \
+ while (!SLIST_EMPTY(l)) { \
+ SLIST_REMOVE_HEAD(l, slist); \
+ FREE(walk); \
+ walk = SLIST_FIRST(l); \
} \
} while (0)
#endif
+
+/* Securely fee tail-queues */
+#define FREE_TAILQ(l, type) do { \
+ type *walk = TAILQ_FIRST(l); \
+ while (!TAILQ_EMPTY(l)) { \
+ TAILQ_REMOVE(l, TAILQ_FIRST(l), tailq); \
+ FREE(walk); \
+ walk = TAILQ_FIRST(l); \
+ } \
+} while (0)
#include "common.h"
#include "outputs.h"
-typedef struct i3_ws_t i3_ws;
+typedef struct i3_ws i3_ws;
-i3_ws* workspaces;
+TAILQ_HEAD(ws_head, i3_ws);
void parse_workspaces_json();
void free_workspaces();
-struct i3_ws_t {
- int num;
- char* name;
- int name_width;
- bool visible;
- bool focused;
- bool urgent;
- rect rect;
- i3_output* output;
+struct i3_ws {
+ int num;
+ char *name;
+ int name_width;
+ bool visible;
+ bool focused;
+ bool urgent;
+ rect rect;
+ struct i3_output *output;
- i3_ws* next;
+ TAILQ_ENTRY(i3_ws) tailq;
};
#endif
void create_windows();
void draw_buttons();
int get_string_width(char *string);
+void handle_xcb_event(xcb_generic_event_t *event);
#endif
ev_default_destroy();
clean_xcb();
- free_outputs();
+
free_workspaces();
+ FREE_SLIST(outputs, i3_output);
return 0;
}
#include "ipc.h"
struct outputs_json_params {
- i3_output* outputs;
- i3_output* outputs_walk;
- char* cur_key;
- char* json;
+ struct outputs_head *outputs;
+ i3_output *outputs_walk;
+ char* cur_key;
+ char* json;
};
static int outputs_null_cb(void* params_) {
static int outputs_start_map_cb(void* params_) {
struct outputs_json_params* params = (struct outputs_json_params*) params_;
- i3_output* new_output = NULL;
+ i3_output *new_output = NULL;
if (params->cur_key == NULL) {
new_output = malloc(sizeof(i3_output));
new_output->name = NULL;
new_output->ws = 0,
memset(&new_output->rect, 0, sizeof(rect));
- new_output->next = NULL;
new_output->bar = XCB_NONE;
- if (params->outputs == NULL) {
- params->outputs = new_output;
- } else {
- params->outputs_walk->next = new_output;
- }
+ new_output->workspaces = malloc(sizeof(struct ws_head));
+ TAILQ_INIT(new_output->workspaces);
+
+ SLIST_INSERT_HEAD(params->outputs, new_output, slist);
+
+ params->outputs_walk = SLIST_FIRST(params->outputs);
- params->outputs_walk = new_output;
return 1;
}
/* FIXME: Fasciliate stream-processing, i.e. allow starting to interpret
* JSON in chunks */
struct outputs_json_params params;
- params.outputs = NULL;
+ printf(json);
+ params.outputs = malloc(sizeof(struct outputs_head));
+ SLIST_INIT(params.outputs);
+
params.outputs_walk = NULL;
params.cur_key = NULL;
params.json = json;
yajl_free(handle);
- free_outputs();
- outputs = params.outputs;
-}
-
-void free_outputs() {
- i3_output* tmp;
- while (outputs != NULL) {
- tmp = outputs;
- outputs = outputs->next;
- FREE(tmp->name);
- FREE(tmp);
+ if (outputs != NULL) {
+ FREE_SLIST(outputs, i3_output);
}
+
+ outputs = params.outputs;
}
i3_output* get_output_by_name(char* name) {
- if (outputs == NULL) {
- i3_send_msg(I3_IPC_MESSAGE_TYPE_GET_OUTPUTS, NULL);
- return NULL;
- }
-
- i3_output* walk;
-
- for (walk = outputs; walk != NULL; walk = walk->next) {
+ i3_output *walk;
+ SLIST_FOREACH(walk, outputs, slist) {
if (!strcmp(walk->name, name)) {
break;
}
#include "ipc.h"
struct workspaces_json_params {
- i3_ws* workspaces;
- i3_ws* workspaces_walk;
- char* cur_key;
- char* json;
+ struct ws_head *workspaces;
+ i3_ws *workspaces_walk;
+ char *cur_key;
+ char *json;
};
static int workspaces_null_cb(void* params_) {
strncpy(output_name, (const char*) val, len);
output_name[len] = '\0';
params->workspaces_walk->output = get_output_by_name(output_name);
- free(output_name);
+ TAILQ_INSERT_TAIL(params->workspaces_walk->output->workspaces,
+ params->workspaces_walk,
+ tailq);
+
+ free(output_name);
return 1;
}
static int workspaces_start_map_cb(void* params_) {
struct workspaces_json_params* params = (struct workspaces_json_params*) params_;
- i3_ws* new_workspace = NULL;
+
+ i3_ws *new_workspace = NULL;
if (params->cur_key == NULL) {
new_workspace = malloc(sizeof(i3_ws));
new_workspace->urgent = 0;
memset(&new_workspace->rect, 0, sizeof(rect));
new_workspace->output = NULL;
- new_workspace->next = NULL;
-
- if (params->workspaces == NULL) {
- params->workspaces = new_workspace;
- } else {
- params->workspaces_walk->next = new_workspace;
- }
params->workspaces_walk = new_workspace;
return 1;
/* FIXME: Fasciliate stream-processing, i.e. allow starting to interpret
* JSON in chunks */
struct workspaces_json_params params;
- params.workspaces = NULL;
+
+ free_workspaces();
+
params.workspaces_walk = NULL;
params.cur_key = NULL;
params.json = json;
}
yajl_free(handle);
-
- free_workspaces();
- workspaces = params.workspaces;
FREE(params.cur_key);
}
void free_workspaces() {
- i3_ws* tmp;
- while (workspaces != NULL) {
- tmp = workspaces;
- workspaces = workspaces->next;
- FREE(tmp->name);
- FREE(tmp);
+ i3_output *outputs_walk;
+ SLIST_FOREACH(outputs_walk, outputs, slist) {
+ if (outputs_walk->workspaces != NULL && !TAILQ_EMPTY(outputs_walk->workspaces)) {
+ FREE_TAILQ(outputs_walk->workspaces, i3_ws);
+ }
}
}
return (r << 16 | g << 8 | b);
}
-void handle_xcb_event(xcb_generic_event_t ev) {
+void handle_xcb_event(xcb_generic_event_t *event) {
switch (event->response_type & ~0x80) {
case XCB_EXPOSE:
draw_buttons();
}
void destroy_windows() {
- i3_output *walk = outputs;
- while(walk != NULL) {
+ i3_output *walk;
+ if (outputs == NULL) {
+ return;
+ }
+ SLIST_FOREACH(walk, outputs, slist) {
if (walk->bar == XCB_NONE) {
continue;
}
uint32_t mask;
uint32_t values[2];
- i3_output* walk = outputs;
- while (walk != NULL) {
+ i3_output *walk;
+ SLIST_FOREACH(walk, outputs, slist) {
if (!walk->active) {
- walk = walk->next;
continue;
}
printf("Creating Window for output %s\n", walk->name);
values);
xcb_map_window(xcb_connection, walk->bar);
- walk = walk->next;
}
xcb_flush(xcb_connection);
}
void draw_buttons() {
printf("Drawing Buttons...\n");
- i3_output *outputs_walk = outputs;
int i = 0;
- while (outputs_walk != NULL) {
+ i3_output *outputs_walk;
+ SLIST_FOREACH(outputs_walk, outputs, slist) {
if (!outputs_walk->active) {
printf("Output %s inactive, skipping...\n", outputs_walk->name);
- outputs_walk = outputs_walk->next;
continue;
}
if (outputs_walk->bar == XCB_NONE) {
outputs_walk->bargc,
1,
&rect);
- i3_ws *ws_walk = workspaces;
- while (ws_walk != NULL) {
- if (ws_walk->output != outputs_walk) {
- printf("WS %s on wrong output, skipping...\n", ws_walk->name);
- ws_walk = ws_walk->next;
- continue;
- }
+ i3_ws *ws_walk;
+ TAILQ_FOREACH(ws_walk, outputs_walk->workspaces, tailq) {
printf("Drawing Button for WS %s...\n", ws_walk->name);
uint32_t color = get_colorpixel("240000");
if (ws_walk->visible) {
color = get_colorpixel("480000");
}
if (ws_walk->urgent) {
+ printf("WS %s is urgent!\n", ws_walk->name);
color = get_colorpixel("002400");
}
xcb_change_gc(xcb_connection,
i + 5, font_height + 1,
ws_walk->name);
i += 10 + ws_walk->name_width;
- ws_walk = ws_walk->next;
}
- outputs_walk = outputs_walk->next;
i = 0;
}
xcb_flush(xcb_connection);