diff --git a/i3-msg/main.c b/i3-msg/main.c index 5bc35b88..13cf0ccb 100644 --- a/i3-msg/main.c +++ b/i3-msg/main.c @@ -74,9 +74,11 @@ int main(int argc, char *argv[]) { message_type = I3_IPC_MESSAGE_TYPE_GET_TREE; else if (strcasecmp(optarg, "get_marks") == 0) message_type = I3_IPC_MESSAGE_TYPE_GET_MARKS; + else if (strcasecmp(optarg, "get_bar_config") == 0) + message_type = I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG; else { printf("Unknown message type\n"); - printf("Known types: command, get_workspaces, get_outputs, get_tree, get_marks\n"); + printf("Known types: command, get_workspaces, get_outputs, get_tree, get_marks, get_bar_config\n"); exit(EXIT_FAILURE); } } else if (o == 'q') { diff --git a/include/i3/ipc.h b/include/i3/ipc.h index 30b2d304..a12d5cd7 100644 --- a/include/i3/ipc.h +++ b/include/i3/ipc.h @@ -41,6 +41,9 @@ /** Request the current defined marks from i3 */ #define I3_IPC_MESSAGE_TYPE_GET_MARKS 5 +/** Request the configuration for a specific 'bar' */ +#define I3_IPC_MESSAGE_TYPE_GET_BAR_CONFIG 6 + /* * Messages from i3 to clients * @@ -61,9 +64,12 @@ /** Tree reply type */ #define I3_IPC_REPLY_TYPE_TREE 4 -/** Marks reply type*/ +/** Marks reply type */ #define I3_IPC_REPLY_TYPE_MARKS 5 +/** Bar config reply type */ +#define I3_IPC_REPLY_TYPE_BAR_CONFIG 6 + /* * Events from i3 to clients. Events have the first bit set high. * diff --git a/src/ipc.c b/src/ipc.c index eba778cd..60f55966 100644 --- a/src/ipc.c +++ b/src/ipc.c @@ -475,6 +475,120 @@ IPC_HANDLER(get_marks) { y(free); } +/* + * Formats the reply message for a GET_BAR_CONFIG request and sends it to the + * client. + * + */ +IPC_HANDLER(get_bar_config) { + /* To get a properly terminated buffer, we copy + * message_size bytes out of the buffer */ + char *bar_id = scalloc(message_size + 1); + strncpy(bar_id, (const char*)message, message_size); + LOG("IPC: looking for config for bar ID \"%s\"\n", bar_id); + Barconfig *current, *config = NULL; + SLIST_FOREACH(current, &barconfigs, configs) { + if (strcmp(current->id, bar_id) != 0) + continue; + + config = current; + break; + } + +#if YAJL_MAJOR >= 2 + yajl_gen gen = yajl_gen_alloc(NULL); +#else + yajl_gen gen = yajl_gen_alloc(NULL, NULL); +#endif + + y(map_open); + + if (!config) { + /* If we did not find a config for the given ID, the reply will contain + * a null 'id' field. */ + ystr("id"); + y(null); + } else { + ystr("id"); + ystr(config->id); + + if (config->num_outputs > 0) { + ystr("outputs"); + y(array_open); + for (int c = 0; c < config->num_outputs; c++) + ystr(config->outputs[c]); + y(array_close); + } + +#define YSTR_IF_SET(name) \ + do { \ + if (config->name) { \ + ystr( # name); \ + ystr(config->name); \ + } \ + } while (0) + + YSTR_IF_SET(tray_output); + YSTR_IF_SET(socket_path); + + ystr("mode"); + if (config->mode == M_HIDE) + ystr("hide"); + else ystr("dock"); + + ystr("position"); + if (config->position == P_BOTTOM) + ystr("bottom"); + else ystr("top"); + + YSTR_IF_SET(status_command); + YSTR_IF_SET(font); + + ystr("workspace_buttons"); + y(bool, !config->hide_workspace_buttons); + + ystr("verbose"); + y(bool, config->verbose); + +#undef YSTR_IF_SET +#define YSTR_IF_SET(name) \ + do { \ + if (config->colors.name) { \ + ystr( # name); \ + ystr(config->colors.name); \ + } \ + } while (0) + + ystr("colors"); + y(map_open); + YSTR_IF_SET(background); + YSTR_IF_SET(statusline); + YSTR_IF_SET(focused_workspace_text); + YSTR_IF_SET(focused_workspace_bg); + YSTR_IF_SET(active_workspace_text); + YSTR_IF_SET(active_workspace_bg); + YSTR_IF_SET(inactive_workspace_text); + YSTR_IF_SET(inactive_workspace_bg); + YSTR_IF_SET(urgent_workspace_text); + YSTR_IF_SET(urgent_workspace_bg); + +#undef YSTR_IF_SET + } + + y(map_close); + + const unsigned char *payload; +#if YAJL_MAJOR >= 2 + size_t length; +#else + unsigned int length; +#endif + y(get_buf, &payload, &length); + + ipc_send_message(fd, length, I3_IPC_REPLY_TYPE_BAR_CONFIG, payload); + y(free); +} + /* * Callback for the YAJL parser (will be called when a string is parsed). * @@ -560,13 +674,14 @@ IPC_HANDLER(subscribe) { /* The index of each callback function corresponds to the numeric * value of the message type (see include/i3/ipc.h) */ -handler_t handlers[6] = { +handler_t handlers[7] = { handle_command, handle_get_workspaces, handle_subscribe, handle_get_outputs, handle_tree, - handle_get_marks + handle_get_marks, + handle_get_bar_config }; /*