#include #include #include #include #include "common.h" #include "outputs.h" #include "ipc.h" struct outputs_json_params { i3_output* outputs; i3_output* outputs_walk; char* cur_key; char* json; void (*callback)(void*); void* cb_params; }; static int outputs_null_cb(void* params_) { struct outputs_json_params* params = (struct outputs_json_params*) params_; if (strcmp(params->cur_key, "current_workspace")) { return 0; } FREE(params->cur_key); return 1; } static int outputs_boolean_cb(void* params_, bool val) { struct outputs_json_params* params = (struct outputs_json_params*) params_; if (strcmp(params->cur_key, "active")) { return 0; } params->outputs_walk->active = val; FREE(params->cur_key); return 1; } static int outputs_integer_cb(void* params_, long val) { struct outputs_json_params* params = (struct outputs_json_params*) params_; if (!strcmp(params->cur_key, "current_workspace")) { params->outputs_walk->ws = (int) val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "x")) { params->outputs_walk->rect.x = (int) val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "y")) { params->outputs_walk->rect.y = (int) val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "width")) { params->outputs_walk->rect.w = (int) val; FREE(params->cur_key); return 1; } if (!strcmp(params->cur_key, "height")) { params->outputs_walk->rect.h = (int) val; FREE(params->cur_key); return 1; } return 0; } static int outputs_string_cb(void* params_, const unsigned char* val, unsigned int len) { struct outputs_json_params* params = (struct outputs_json_params*) params_; if (strcmp(params->cur_key, "name")) { return 0; } params->outputs_walk->name = malloc(sizeof(const unsigned char) * (len + 1)); strncpy(params->outputs_walk->name, (const char*) val, len); params->outputs_walk->name[len] = '\0'; FREE(params->cur_key); return 1; } static int outputs_start_map_cb(void* params_) { struct outputs_json_params* params = (struct outputs_json_params*) params_; 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; if (params->outputs == NULL) { params->outputs = new_output; } else { params->outputs_walk->next = new_output; } params->outputs_walk = new_output; return 1; } return 1; } static int outputs_map_key_cb(void* params_, const unsigned char* keyVal, unsigned int keyLen) { struct outputs_json_params* params = (struct outputs_json_params*) params_; FREE(params->cur_key); params->cur_key = malloc(sizeof(unsigned char) * (keyLen + 1)); strncpy(params->cur_key, (const char*) keyVal, keyLen); params->cur_key[keyLen] = '\0'; return 1; } yajl_callbacks outputs_callbacks = { &outputs_null_cb, &outputs_boolean_cb, &outputs_integer_cb, NULL, NULL, &outputs_string_cb, &outputs_start_map_cb, &outputs_map_key_cb, NULL, NULL, NULL }; void got_outputs_json_cb(char* json, void* params_) { /* FIXME: Fasciliate stream-processing, i.e. allow starting to interpret * JSON in chunks */ struct outputs_json_params* params = (struct outputs_json_params*) params_; yajl_handle handle; yajl_parser_config parse_conf = { 0, 0 }; yajl_status state; params->json = json; handle = yajl_alloc(&outputs_callbacks, &parse_conf, NULL, (void*) params); state = yajl_parse(handle, (const unsigned char*) json, strlen(json)); /* FIXME: Propper errorhandling for JSON-parsing */ switch (state) { case yajl_status_ok: break; case yajl_status_client_canceled: case yajl_status_insufficient_data: case yajl_status_error: printf("ERROR: Could not parse outputs-reply!\n"); exit(EXIT_FAILURE); break; } yajl_free(handle); free_outputs(); outputs = params->outputs; if (params->callback != NULL) { params->callback(params->cb_params); } FREE(params->json); FREE(params); } void refresh_outputs(void (*callback)(void*), void* cb_params) { struct outputs_json_params* params = malloc(sizeof(struct outputs_json_params)); params->outputs = NULL; params->outputs_walk = NULL; params->cur_key = NULL; params->json = NULL; params->callback = callback; params->cb_params = cb_params; get_outputs_json(&got_outputs_json_cb, params); } void free_outputs() { i3_output* tmp; while (outputs != NULL) { tmp = outputs; outputs = outputs->next; FREE(tmp->name); FREE(tmp); } } i3_output* get_output_by_name(char* name) { if (outputs == NULL) { refresh_outputs(NULL, NULL); return NULL; } i3_output* walk; for (walk = outputs; walk != NULL; walk = walk->next) { if (strcmp(walk->name, name)) { break; } } return walk; }