Merge pull request #104 from minus7/ipc-get-messages
added IPC messages get_workspaces and get_outputs
This commit is contained in:
commit
1100335ea0
|
@ -10,5 +10,6 @@ char *code_strchr(const char *string, char delimiter);
|
||||||
char *code_strstr(const char *haystack, const char *needle);
|
char *code_strstr(const char *haystack, const char *needle);
|
||||||
int unescape_string(char *string);
|
int unescape_string(char *string);
|
||||||
char *join_args(char **argv, int argc);
|
char *join_args(char **argv, int argc);
|
||||||
|
char *join_list(list_t *list, char *separator);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
92
sway/ipc.c
92
sway/ipc.c
|
@ -11,10 +11,13 @@
|
||||||
#include <stropts.h>
|
#include <stropts.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include "ipc.h"
|
#include "ipc.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "commands.h"
|
#include "commands.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "stringop.h"
|
||||||
|
|
||||||
static int ipc_socket = -1;
|
static int ipc_socket = -1;
|
||||||
static struct wlc_event_source *ipc_event_source = NULL;
|
static struct wlc_event_source *ipc_event_source = NULL;
|
||||||
|
@ -37,6 +40,10 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
|
||||||
void ipc_client_disconnect(struct ipc_client *client);
|
void ipc_client_disconnect(struct ipc_client *client);
|
||||||
void ipc_client_handle_command(struct ipc_client *client);
|
void ipc_client_handle_command(struct ipc_client *client);
|
||||||
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
|
bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
|
||||||
|
void ipc_get_workspaces_callback(swayc_t *container, void *data);
|
||||||
|
void ipc_get_outputs_callback(swayc_t *container, void *data);
|
||||||
|
|
||||||
|
char *json_list(list_t *items);
|
||||||
|
|
||||||
void ipc_init(void) {
|
void ipc_init(void) {
|
||||||
ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
|
||||||
|
@ -195,6 +202,26 @@ void ipc_client_handle_command(struct ipc_client *client) {
|
||||||
ipc_send_reply(client, reply, (uint32_t) length);
|
ipc_send_reply(client, reply, (uint32_t) length);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case IPC_GET_WORKSPACES:
|
||||||
|
{
|
||||||
|
list_t *workspaces = create_list();
|
||||||
|
container_map(&root_container, ipc_get_workspaces_callback, workspaces);
|
||||||
|
char *json = json_list(workspaces);
|
||||||
|
free_flat_list(workspaces);
|
||||||
|
ipc_send_reply(client, json, strlen(json));
|
||||||
|
free(json);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IPC_GET_OUTPUTS:
|
||||||
|
{
|
||||||
|
list_t *outputs = create_list();
|
||||||
|
container_map(&root_container, ipc_get_outputs_callback, outputs);
|
||||||
|
char *json = json_list(outputs);
|
||||||
|
free_flat_list(outputs);
|
||||||
|
ipc_send_reply(client, json, strlen(json));
|
||||||
|
free(json);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
sway_log(L_INFO, "Unknown IPC command type %i", client->current_command);
|
sway_log(L_INFO, "Unknown IPC command type %i", client->current_command);
|
||||||
ipc_client_disconnect(client);
|
ipc_client_disconnect(client);
|
||||||
|
@ -227,3 +254,68 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *json_list(list_t *items) {
|
||||||
|
char *json_elements = join_list(items, ",");
|
||||||
|
size_t len = strlen(json_elements);
|
||||||
|
char *json = malloc(len + 3);
|
||||||
|
json[0] = '[';
|
||||||
|
memcpy(json + 1, json_elements, len);
|
||||||
|
json[len+1] = ']';
|
||||||
|
json[len+2] = '\0';
|
||||||
|
free(json_elements);
|
||||||
|
return json;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_get_workspaces_callback(swayc_t *container, void *data) {
|
||||||
|
if (container->type == C_WORKSPACE) {
|
||||||
|
char *json = malloc(512); // Output should usually be around 180 chars
|
||||||
|
int num = isdigit(container->name[0]) ? atoi(container->name) : -1;
|
||||||
|
// TODO: escape the name (quotation marks, unicode)
|
||||||
|
sprintf(json,
|
||||||
|
"{"
|
||||||
|
"\"num\":%d,"
|
||||||
|
"\"name\":\"%s\","
|
||||||
|
"\"visible\":%s,"
|
||||||
|
"\"focused\":%s,"
|
||||||
|
"\"rect\":{"
|
||||||
|
"\"x\":%d,"
|
||||||
|
"\"y\":%d,"
|
||||||
|
"\"width\":%d,"
|
||||||
|
"\"height\":%d"
|
||||||
|
"},"
|
||||||
|
"\"output\":\"%s\","
|
||||||
|
"\"urgent\":%s"
|
||||||
|
"}",
|
||||||
|
num, container->name, container->visible ? "true" : "false", container->is_focused ? "true" : "false",
|
||||||
|
container->x, container->y, container->width, container->height,
|
||||||
|
container->parent->name, "false" // TODO: urgent hint
|
||||||
|
);
|
||||||
|
list_add((list_t *)data, json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipc_get_outputs_callback(swayc_t *container, void *data) {
|
||||||
|
if (container->type == C_OUTPUT) {
|
||||||
|
char *json = malloc(512); // Output should usually be around 130 chars
|
||||||
|
// TODO: escape the name (quotation marks, unicode)
|
||||||
|
sprintf(json,
|
||||||
|
"{"
|
||||||
|
"\"name\":\"%s\","
|
||||||
|
"\"active\":%s,"
|
||||||
|
"\"primary\":%s,"
|
||||||
|
"\"rect\":{"
|
||||||
|
"\"x\":%d,"
|
||||||
|
"\"y\":%d,"
|
||||||
|
"\"width\":%d,"
|
||||||
|
"\"height\":%d"
|
||||||
|
"},"
|
||||||
|
"\"current_workspace\":\"%s\""
|
||||||
|
"}",
|
||||||
|
container->name, "true", "false", // TODO: active, primary
|
||||||
|
container->x, container->y, container->width, container->height,
|
||||||
|
container->focused ? container->focused->name : ""
|
||||||
|
);
|
||||||
|
list_add((list_t *)data, json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include <strings.h>
|
#include <strings.h>
|
||||||
|
#include <log.h>
|
||||||
|
|
||||||
/* Note: This returns 8 characters for trimmed_start per tab character. */
|
/* Note: This returns 8 characters for trimmed_start per tab character. */
|
||||||
char *strip_whitespace(char *_str, int *trimmed_start) {
|
char *strip_whitespace(char *_str, int *trimmed_start) {
|
||||||
|
@ -197,3 +198,41 @@ char *join_args(char **argv, int argc) {
|
||||||
res[len - 1] = '\0';
|
res[len - 1] = '\0';
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Join a list of strings, adding separator in between. Separator can be NULL.
|
||||||
|
*/
|
||||||
|
char *join_list(list_t *list, char *separator) {
|
||||||
|
if (!sway_assert(list != NULL, "list != NULL") || list->length == 0) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t len = 1; // NULL terminator
|
||||||
|
size_t sep_len = 0;
|
||||||
|
if (separator != NULL) {
|
||||||
|
sep_len = strlen(separator);
|
||||||
|
len += (list->length - 1) * sep_len;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < list->length; i++) {
|
||||||
|
len += strlen(list->items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
char *res = malloc(len);
|
||||||
|
|
||||||
|
char *p = res + strlen(list->items[0]);
|
||||||
|
strcpy(res, list->items[0]);
|
||||||
|
|
||||||
|
for (int i = 1; i < list->length; i++) {
|
||||||
|
if (sep_len) {
|
||||||
|
memcpy(p, separator, sep_len);
|
||||||
|
p += sep_len;
|
||||||
|
}
|
||||||
|
strcpy(p, list->items[i]);
|
||||||
|
p += strlen(list->items[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
*p = '\0';
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue