aboutsummaryrefslogtreecommitdiffstats
path: root/sway/ipc-json.c
blob: 09a32c1bdee7304a2b3a9ffbb484f874a2b1b3b5 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include <json-c/json.h>
#include <stdio.h>
#include <ctype.h>
#include "log.h"
#include "sway/ipc-json.h"
#include "sway/container.h"
#include "sway/output.h"
#include <wlr/types/wlr_box.h>
#include <wlr/types/wlr_output.h>

json_object *ipc_json_get_version() {
	int major = 0, minor = 0, patch = 0;
	json_object *version = json_object_new_object();

	sscanf(SWAY_VERSION, "%u.%u.%u", &major, &minor, &patch);

	json_object_object_add(version, "human_readable", json_object_new_string(SWAY_VERSION));
	json_object_object_add(version, "variant", json_object_new_string("sway"));
	json_object_object_add(version, "major", json_object_new_int(major));
	json_object_object_add(version, "minor", json_object_new_int(minor));
	json_object_object_add(version, "patch", json_object_new_int(patch));

	return version;
}

static json_object *ipc_json_create_rect(swayc_t *c) {
	json_object *rect = json_object_new_object();

	json_object_object_add(rect, "x", json_object_new_int((int32_t)c->x));
	json_object_object_add(rect, "y", json_object_new_int((int32_t)c->y));
	json_object_object_add(rect, "width", json_object_new_int((int32_t)c->width));
	json_object_object_add(rect, "height", json_object_new_int((int32_t)c->height));

	return rect;
}

static void ipc_json_describe_root(swayc_t *root, json_object *object) {
	json_object_object_add(object, "type", json_object_new_string("root"));
	json_object_object_add(object, "layout", json_object_new_string("splith"));
}

static const char *ipc_json_get_output_transform(enum wl_output_transform transform) {
	switch (transform) {
	case WL_OUTPUT_TRANSFORM_NORMAL:
		return "normal";
	case WL_OUTPUT_TRANSFORM_90:
		return "90";
	case WL_OUTPUT_TRANSFORM_180:
		return "180";
	case WL_OUTPUT_TRANSFORM_270:
		return "270";
	case WL_OUTPUT_TRANSFORM_FLIPPED:
		return "flipped";
	case WL_OUTPUT_TRANSFORM_FLIPPED_90:
		return "flipped-90";
	case WL_OUTPUT_TRANSFORM_FLIPPED_180:
		return "flipped-180";
	case WL_OUTPUT_TRANSFORM_FLIPPED_270:
		return "flipped-270";
	}
	return NULL;
}

static void ipc_json_describe_output(swayc_t *container, json_object *object) {
	struct wlr_output *wlr_output = container->sway_output->wlr_output;
	json_object_object_add(object, "type", json_object_new_string("output"));
	json_object_object_add(object, "active", json_object_new_boolean(true));
	json_object_object_add(object, "primary", json_object_new_boolean(false));
	json_object_object_add(object, "layout", json_object_new_string("output"));
	json_object_object_add(object, "make", json_object_new_string(wlr_output->make));
	json_object_object_add(object, "model", json_object_new_string(wlr_output->model));
	json_object_object_add(object, "serial", json_object_new_string(wlr_output->serial));
	json_object_object_add(object, "scale", json_object_new_double(wlr_output->scale));
	json_object_object_add(object, "refresh", json_object_new_int(wlr_output->refresh));
	json_object_object_add(object, "transform",
		json_object_new_string(ipc_json_get_output_transform(wlr_output->transform)));
	json_object_object_add(object, "current_workspace",
		(container->focused) ? json_object_new_string(container->focused->name) : NULL);
}

static void ipc_json_describe_workspace(swayc_t *workspace, json_object *object) {
	int num = (isdigit(workspace->name[0])) ? atoi(workspace->name) : -1;

	json_object_object_add(object, "num", json_object_new_int(num));
	json_object_object_add(object, "output", (workspace->parent) ? json_object_new_string(workspace->parent->name) : NULL);
	json_object_object_add(object, "type", json_object_new_string("workspace"));
}

static void ipc_json_describe_view(swayc_t *c, json_object *object) {
	json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL);
}

json_object *ipc_json_describe_container(swayc_t *c) {
	if (!(sway_assert(c, "Container must not be null."))) {
		return NULL;
	}

	json_object *object = json_object_new_object();

	json_object_object_add(object, "id", json_object_new_int((int)c->id));
	json_object_object_add(object, "name", (c->name) ? json_object_new_string(c->name) : NULL);
	json_object_object_add(object, "rect", ipc_json_create_rect(c));

	switch (c->type) {
	case C_ROOT:
		ipc_json_describe_root(c, object);
		break;

	case C_OUTPUT:
		ipc_json_describe_output(c, object);
		break;

	case C_CONTAINER:
	case C_VIEW:
		ipc_json_describe_view(c, object);
		break;

	case C_WORKSPACE:
		ipc_json_describe_workspace(c, object);
		break;

	case C_TYPES:
	default:
		break;
	}

	return object;
}

json_object *ipc_json_describe_container_recursive(swayc_t *c) {
	json_object *object = ipc_json_describe_container(c);
	int i;

	json_object *children = json_object_new_array();
	if (c->type != C_VIEW && c->children) {
		for (i = 0; i < c->children->length; ++i) {
			json_object_array_add(children, ipc_json_describe_container_recursive(c->children->items[i]));
		}
	}
	json_object_object_add(object, "nodes", children);

	return object;
}