diff options
Diffstat (limited to 'sway/ipc-json.c')
-rw-r--r-- | sway/ipc-json.c | 178 |
1 files changed, 151 insertions, 27 deletions
diff --git a/sway/ipc-json.c b/sway/ipc-json.c index e422b24d..81ca3483 100644 --- a/sway/ipc-json.c +++ b/sway/ipc-json.c | |||
@@ -3,7 +3,8 @@ | |||
3 | #include <json.h> | 3 | #include <json.h> |
4 | #include <libevdev/libevdev.h> | 4 | #include <libevdev/libevdev.h> |
5 | #include <stdio.h> | 5 | #include <stdio.h> |
6 | #include <wlr/backend/libinput.h> | 6 | #include <wlr/config.h> |
7 | #include <wlr/types/wlr_content_type_v1.h> | ||
7 | #include <wlr/types/wlr_output.h> | 8 | #include <wlr/types/wlr_output.h> |
8 | #include <xkbcommon/xkbcommon.h> | 9 | #include <xkbcommon/xkbcommon.h> |
9 | #include "config.h" | 10 | #include "config.h" |
@@ -20,6 +21,10 @@ | |||
20 | #include "wlr-layer-shell-unstable-v1-protocol.h" | 21 | #include "wlr-layer-shell-unstable-v1-protocol.h" |
21 | #include "sway/desktop/idle_inhibit_v1.h" | 22 | #include "sway/desktop/idle_inhibit_v1.h" |
22 | 23 | ||
24 | #if WLR_HAS_LIBINPUT_BACKEND | ||
25 | #include <wlr/backend/libinput.h> | ||
26 | #endif | ||
27 | |||
23 | static const int i3_output_id = INT32_MAX; | 28 | static const int i3_output_id = INT32_MAX; |
24 | static const int i3_scratch_id = INT32_MAX - 1; | 29 | static const int i3_scratch_id = INT32_MAX - 1; |
25 | 30 | ||
@@ -112,12 +117,43 @@ static const char *ipc_json_output_adaptive_sync_status_description( | |||
112 | return "disabled"; | 117 | return "disabled"; |
113 | case WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED: | 118 | case WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED: |
114 | return "enabled"; | 119 | return "enabled"; |
115 | case WLR_OUTPUT_ADAPTIVE_SYNC_UNKNOWN: | ||
116 | return "unknown"; | ||
117 | } | 120 | } |
118 | return NULL; | 121 | return NULL; |
119 | } | 122 | } |
120 | 123 | ||
124 | static const char *ipc_json_output_mode_aspect_ratio_description( | ||
125 | enum wlr_output_mode_aspect_ratio aspect_ratio) { | ||
126 | switch (aspect_ratio) { | ||
127 | case WLR_OUTPUT_MODE_ASPECT_RATIO_NONE: | ||
128 | return "none"; | ||
129 | case WLR_OUTPUT_MODE_ASPECT_RATIO_4_3: | ||
130 | return "4:3"; | ||
131 | case WLR_OUTPUT_MODE_ASPECT_RATIO_16_9: | ||
132 | return "16:9"; | ||
133 | case WLR_OUTPUT_MODE_ASPECT_RATIO_64_27: | ||
134 | return "64:27"; | ||
135 | case WLR_OUTPUT_MODE_ASPECT_RATIO_256_135: | ||
136 | return "256:135"; | ||
137 | } | ||
138 | return NULL; | ||
139 | } | ||
140 | |||
141 | static json_object *ipc_json_output_mode_description( | ||
142 | const struct wlr_output_mode *mode) { | ||
143 | const char *pic_ar = | ||
144 | ipc_json_output_mode_aspect_ratio_description(mode->picture_aspect_ratio); | ||
145 | json_object *mode_object = json_object_new_object(); | ||
146 | json_object_object_add(mode_object, "width", | ||
147 | json_object_new_int(mode->width)); | ||
148 | json_object_object_add(mode_object, "height", | ||
149 | json_object_new_int(mode->height)); | ||
150 | json_object_object_add(mode_object, "refresh", | ||
151 | json_object_new_int(mode->refresh)); | ||
152 | json_object_object_add(mode_object, "picture_aspect_ratio", | ||
153 | json_object_new_string(pic_ar)); | ||
154 | return mode_object; | ||
155 | } | ||
156 | |||
121 | #if HAVE_XWAYLAND | 157 | #if HAVE_XWAYLAND |
122 | static const char *ipc_json_xwindow_type_description(struct sway_view *view) { | 158 | static const char *ipc_json_xwindow_type_description(struct sway_view *view) { |
123 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; | 159 | struct wlr_xwayland_surface *surface = view->wlr_xwayland_surface; |
@@ -170,6 +206,20 @@ static const char *ipc_json_user_idle_inhibitor_description(enum sway_idle_inhib | |||
170 | return NULL; | 206 | return NULL; |
171 | } | 207 | } |
172 | 208 | ||
209 | static const char *ipc_json_content_type_description(enum wp_content_type_v1_type type) { | ||
210 | switch (type) { | ||
211 | case WP_CONTENT_TYPE_V1_TYPE_NONE: | ||
212 | return "none"; | ||
213 | case WP_CONTENT_TYPE_V1_TYPE_PHOTO: | ||
214 | return "photo"; | ||
215 | case WP_CONTENT_TYPE_V1_TYPE_VIDEO: | ||
216 | return "video"; | ||
217 | case WP_CONTENT_TYPE_V1_TYPE_GAME: | ||
218 | return "game"; | ||
219 | } | ||
220 | return NULL; | ||
221 | } | ||
222 | |||
173 | json_object *ipc_json_get_version(void) { | 223 | json_object *ipc_json_get_version(void) { |
174 | int major = 0, minor = 0, patch = 0; | 224 | int major = 0, minor = 0, patch = 0; |
175 | json_object *version = json_object_new_object(); | 225 | json_object *version = json_object_new_object(); |
@@ -238,14 +288,13 @@ static json_object *ipc_json_create_node(int id, const char* type, char *name, | |||
238 | json_object_object_add(object, "focus", focus); | 288 | json_object_object_add(object, "focus", focus); |
239 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); | 289 | json_object_object_add(object, "fullscreen_mode", json_object_new_int(0)); |
240 | json_object_object_add(object, "sticky", json_object_new_boolean(false)); | 290 | json_object_object_add(object, "sticky", json_object_new_boolean(false)); |
291 | json_object_object_add(object, "floating", NULL); | ||
292 | json_object_object_add(object, "scratchpad_state", NULL); | ||
241 | 293 | ||
242 | return object; | 294 | return object; |
243 | } | 295 | } |
244 | 296 | ||
245 | static void ipc_json_describe_output(struct sway_output *output, | 297 | static void ipc_json_describe_wlr_output(struct wlr_output *wlr_output, json_object *object) { |
246 | json_object *object) { | ||
247 | struct wlr_output *wlr_output = output->wlr_output; | ||
248 | |||
249 | json_object_object_add(object, "primary", json_object_new_boolean(false)); | 298 | json_object_object_add(object, "primary", json_object_new_boolean(false)); |
250 | json_object_object_add(object, "make", | 299 | json_object_object_add(object, "make", |
251 | json_object_new_string(wlr_output->make ? wlr_output->make : "Unknown")); | 300 | json_object_new_string(wlr_output->make ? wlr_output->make : "Unknown")); |
@@ -269,11 +318,17 @@ static void ipc_json_describe_output(struct sway_output *output, | |||
269 | json_object_object_add(object, "modes", modes_array); | 318 | json_object_object_add(object, "modes", modes_array); |
270 | } | 319 | } |
271 | 320 | ||
321 | static void ipc_json_describe_output(struct sway_output *output, | ||
322 | json_object *object) { | ||
323 | ipc_json_describe_wlr_output(output->wlr_output, object); | ||
324 | } | ||
325 | |||
272 | static void ipc_json_describe_enabled_output(struct sway_output *output, | 326 | static void ipc_json_describe_enabled_output(struct sway_output *output, |
273 | json_object *object) { | 327 | json_object *object) { |
274 | ipc_json_describe_output(output, object); | 328 | ipc_json_describe_output(output, object); |
275 | 329 | ||
276 | struct wlr_output *wlr_output = output->wlr_output; | 330 | struct wlr_output *wlr_output = output->wlr_output; |
331 | json_object_object_add(object, "non_desktop", json_object_new_boolean(false)); | ||
277 | json_object_object_add(object, "active", json_object_new_boolean(true)); | 332 | json_object_object_add(object, "active", json_object_new_boolean(true)); |
278 | json_object_object_add(object, "dpms", | 333 | json_object_object_add(object, "dpms", |
279 | json_object_new_boolean(wlr_output->enabled)); | 334 | json_object_new_boolean(wlr_output->enabled)); |
@@ -307,25 +362,26 @@ static void ipc_json_describe_enabled_output(struct sway_output *output, | |||
307 | json_object *modes_array = json_object_new_array(); | 362 | json_object *modes_array = json_object_new_array(); |
308 | struct wlr_output_mode *mode; | 363 | struct wlr_output_mode *mode; |
309 | wl_list_for_each(mode, &wlr_output->modes, link) { | 364 | wl_list_for_each(mode, &wlr_output->modes, link) { |
310 | json_object *mode_object = json_object_new_object(); | 365 | json_object *mode_object = |
311 | json_object_object_add(mode_object, "width", | 366 | ipc_json_output_mode_description(mode); |
312 | json_object_new_int(mode->width)); | ||
313 | json_object_object_add(mode_object, "height", | ||
314 | json_object_new_int(mode->height)); | ||
315 | json_object_object_add(mode_object, "refresh", | ||
316 | json_object_new_int(mode->refresh)); | ||
317 | json_object_array_add(modes_array, mode_object); | 367 | json_object_array_add(modes_array, mode_object); |
318 | } | 368 | } |
319 | 369 | ||
320 | json_object_object_add(object, "modes", modes_array); | 370 | json_object_object_add(object, "modes", modes_array); |
321 | 371 | ||
322 | json_object *current_mode_object = json_object_new_object(); | 372 | json_object *current_mode_object; |
323 | json_object_object_add(current_mode_object, "width", | 373 | if (wlr_output->current_mode != NULL) { |
324 | json_object_new_int(wlr_output->width)); | 374 | current_mode_object = |
325 | json_object_object_add(current_mode_object, "height", | 375 | ipc_json_output_mode_description(wlr_output->current_mode); |
326 | json_object_new_int(wlr_output->height)); | 376 | } else { |
327 | json_object_object_add(current_mode_object, "refresh", | 377 | current_mode_object = json_object_new_object(); |
328 | json_object_new_int(wlr_output->refresh)); | 378 | json_object_object_add(current_mode_object, "width", |
379 | json_object_new_int(wlr_output->width)); | ||
380 | json_object_object_add(current_mode_object, "height", | ||
381 | json_object_new_int(wlr_output->height)); | ||
382 | json_object_object_add(current_mode_object, "refresh", | ||
383 | json_object_new_int(wlr_output->refresh)); | ||
384 | } | ||
329 | json_object_object_add(object, "current_mode", current_mode_object); | 385 | json_object_object_add(object, "current_mode", current_mode_object); |
330 | 386 | ||
331 | struct sway_node *parent = node_get_parent(&output->node); | 387 | struct sway_node *parent = node_get_parent(&output->node); |
@@ -351,6 +407,7 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) { | |||
351 | 407 | ||
352 | ipc_json_describe_output(output, object); | 408 | ipc_json_describe_output(output, object); |
353 | 409 | ||
410 | json_object_object_add(object, "non_desktop", json_object_new_boolean(false)); | ||
354 | json_object_object_add(object, "type", json_object_new_string("output")); | 411 | json_object_object_add(object, "type", json_object_new_string("output")); |
355 | json_object_object_add(object, "name", | 412 | json_object_object_add(object, "name", |
356 | json_object_new_string(wlr_output->name)); | 413 | json_object_new_string(wlr_output->name)); |
@@ -372,6 +429,21 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) { | |||
372 | return object; | 429 | return object; |
373 | } | 430 | } |
374 | 431 | ||
432 | json_object *ipc_json_describe_non_desktop_output(struct sway_output_non_desktop *output) { | ||
433 | struct wlr_output *wlr_output = output->wlr_output; | ||
434 | |||
435 | json_object *object = json_object_new_object(); | ||
436 | |||
437 | ipc_json_describe_wlr_output(wlr_output, object); | ||
438 | |||
439 | json_object_object_add(object, "non_desktop", json_object_new_boolean(true)); | ||
440 | json_object_object_add(object, "type", json_object_new_string("output")); | ||
441 | json_object_object_add(object, "name", | ||
442 | json_object_new_string(wlr_output->name)); | ||
443 | |||
444 | return object; | ||
445 | } | ||
446 | |||
375 | static json_object *ipc_json_describe_scratchpad_output(void) { | 447 | static json_object *ipc_json_describe_scratchpad_output(void) { |
376 | struct wlr_box box; | 448 | struct wlr_box box; |
377 | root_get_box(root, &box); | 449 | root_get_box(root, &box); |
@@ -507,7 +579,7 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
507 | 579 | ||
508 | struct wlr_box window_box = { | 580 | struct wlr_box window_box = { |
509 | c->pending.content_x - c->pending.x, | 581 | c->pending.content_x - c->pending.x, |
510 | (c->current.border == B_PIXEL) ? c->current.border_thickness : 0, | 582 | (c->current.border == B_PIXEL) ? c->pending.content_y - c->pending.y : 0, |
511 | c->pending.content_width, | 583 | c->pending.content_width, |
512 | c->pending.content_height | 584 | c->pending.content_height |
513 | }; | 585 | }; |
@@ -551,6 +623,16 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
551 | 623 | ||
552 | json_object_object_add(object, "idle_inhibitors", idle_inhibitors); | 624 | json_object_object_add(object, "idle_inhibitors", idle_inhibitors); |
553 | 625 | ||
626 | enum wp_content_type_v1_type content_type = WP_CONTENT_TYPE_V1_TYPE_NONE; | ||
627 | if (c->view->surface != NULL) { | ||
628 | content_type = wlr_surface_get_content_type_v1(server.content_type_manager_v1, | ||
629 | c->view->surface); | ||
630 | } | ||
631 | if (content_type != WP_CONTENT_TYPE_V1_TYPE_NONE) { | ||
632 | json_object_object_add(object, "content_type", | ||
633 | json_object_new_string(ipc_json_content_type_description(content_type))); | ||
634 | } | ||
635 | |||
554 | #if HAVE_XWAYLAND | 636 | #if HAVE_XWAYLAND |
555 | if (c->view->type == SWAY_VIEW_XWAYLAND) { | 637 | if (c->view->type == SWAY_VIEW_XWAYLAND) { |
556 | json_object_object_add(object, "window", | 638 | json_object_object_add(object, "window", |
@@ -595,7 +677,8 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object | |||
595 | static void ipc_json_describe_container(struct sway_container *c, json_object *object) { | 677 | static void ipc_json_describe_container(struct sway_container *c, json_object *object) { |
596 | json_object_object_add(object, "name", | 678 | json_object_object_add(object, "name", |
597 | c->title ? json_object_new_string(c->title) : NULL); | 679 | c->title ? json_object_new_string(c->title) : NULL); |
598 | if (container_is_floating(c)) { | 680 | bool floating = container_is_floating(c); |
681 | if (floating) { | ||
599 | json_object_object_add(object, "type", | 682 | json_object_object_add(object, "type", |
600 | json_object_new_string("floating_con")); | 683 | json_object_new_string("floating_con")); |
601 | } | 684 | } |
@@ -613,9 +696,17 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o | |||
613 | json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); | 696 | json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); |
614 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); | 697 | json_object_object_add(object, "sticky", json_object_new_boolean(c->is_sticky)); |
615 | 698 | ||
699 | // sway doesn't track the floating reason, so we can't use "auto_on" or "user_off" | ||
700 | json_object_object_add(object, "floating", | ||
701 | json_object_new_string(floating ? "user_on" : "auto_off")); | ||
702 | |||
616 | json_object_object_add(object, "fullscreen_mode", | 703 | json_object_object_add(object, "fullscreen_mode", |
617 | json_object_new_int(c->pending.fullscreen_mode)); | 704 | json_object_new_int(c->pending.fullscreen_mode)); |
618 | 705 | ||
706 | // sway doesn't track if window was resized in scratchpad, so we can't use "changed" | ||
707 | json_object_object_add(object, "scratchpad_state", | ||
708 | json_object_new_string(!c->scratchpad ? "none" : "fresh")); | ||
709 | |||
619 | struct sway_node *parent = node_get_parent(&c->node); | 710 | struct sway_node *parent = node_get_parent(&c->node); |
620 | struct wlr_box parent_box = {0, 0, 0, 0}; | 711 | struct wlr_box parent_box = {0, 0, 0, 0}; |
621 | 712 | ||
@@ -771,6 +862,7 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) { | |||
771 | return object; | 862 | return object; |
772 | } | 863 | } |
773 | 864 | ||
865 | #if WLR_HAS_LIBINPUT_BACKEND | ||
774 | static json_object *describe_libinput_device(struct libinput_device *device) { | 866 | static json_object *describe_libinput_device(struct libinput_device *device) { |
775 | json_object *object = json_object_new_object(); | 867 | json_object *object = json_object_new_object(); |
776 | 868 | ||
@@ -854,6 +946,11 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
854 | case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: | 946 | case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: |
855 | accel_profile = "adaptive"; | 947 | accel_profile = "adaptive"; |
856 | break; | 948 | break; |
949 | #if HAVE_LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM | ||
950 | case LIBINPUT_CONFIG_ACCEL_PROFILE_CUSTOM: | ||
951 | accel_profile = "custom"; | ||
952 | break; | ||
953 | #endif | ||
857 | } | 954 | } |
858 | json_object_object_add(object, "accel_profile", | 955 | json_object_object_add(object, "accel_profile", |
859 | json_object_new_string(accel_profile)); | 956 | json_object_new_string(accel_profile)); |
@@ -933,6 +1030,17 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
933 | uint32_t button = libinput_device_config_scroll_get_button(device); | 1030 | uint32_t button = libinput_device_config_scroll_get_button(device); |
934 | json_object_object_add(object, "scroll_button", | 1031 | json_object_object_add(object, "scroll_button", |
935 | json_object_new_int(button)); | 1032 | json_object_new_int(button)); |
1033 | const char *lock = "unknown"; | ||
1034 | switch (libinput_device_config_scroll_get_button_lock(device)) { | ||
1035 | case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_ENABLED: | ||
1036 | lock = "enabled"; | ||
1037 | break; | ||
1038 | case LIBINPUT_CONFIG_SCROLL_BUTTON_LOCK_DISABLED: | ||
1039 | lock = "disabled"; | ||
1040 | break; | ||
1041 | } | ||
1042 | json_object_object_add(object, "scroll_button_lock", | ||
1043 | json_object_new_string(lock)); | ||
936 | } | 1044 | } |
937 | } | 1045 | } |
938 | 1046 | ||
@@ -949,6 +1057,19 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
949 | json_object_object_add(object, "dwt", json_object_new_string(dwt)); | 1057 | json_object_object_add(object, "dwt", json_object_new_string(dwt)); |
950 | } | 1058 | } |
951 | 1059 | ||
1060 | if (libinput_device_config_dwtp_is_available(device)) { | ||
1061 | const char *dwtp = "unknown"; | ||
1062 | switch (libinput_device_config_dwtp_get_enabled(device)) { | ||
1063 | case LIBINPUT_CONFIG_DWTP_ENABLED: | ||
1064 | dwtp = "enabled"; | ||
1065 | break; | ||
1066 | case LIBINPUT_CONFIG_DWTP_DISABLED: | ||
1067 | dwtp = "disabled"; | ||
1068 | break; | ||
1069 | } | ||
1070 | json_object_object_add(object, "dwtp", json_object_new_string(dwtp)); | ||
1071 | } | ||
1072 | |||
952 | if (libinput_device_config_calibration_has_matrix(device)) { | 1073 | if (libinput_device_config_calibration_has_matrix(device)) { |
953 | float matrix[6]; | 1074 | float matrix[6]; |
954 | libinput_device_config_calibration_get_matrix(device, matrix); | 1075 | libinput_device_config_calibration_get_matrix(device, matrix); |
@@ -963,6 +1084,7 @@ static json_object *describe_libinput_device(struct libinput_device *device) { | |||
963 | 1084 | ||
964 | return object; | 1085 | return object; |
965 | } | 1086 | } |
1087 | #endif | ||
966 | 1088 | ||
967 | json_object *ipc_json_describe_input(struct sway_input_device *device) { | 1089 | json_object *ipc_json_describe_input(struct sway_input_device *device) { |
968 | if (!(sway_assert(device, "Device must not be null"))) { | 1090 | if (!(sway_assert(device, "Device must not be null"))) { |
@@ -975,10 +1097,6 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
975 | json_object_new_string(device->identifier)); | 1097 | json_object_new_string(device->identifier)); |
976 | json_object_object_add(object, "name", | 1098 | json_object_object_add(object, "name", |
977 | json_object_new_string(device->wlr_device->name)); | 1099 | json_object_new_string(device->wlr_device->name)); |
978 | json_object_object_add(object, "vendor", | ||
979 | json_object_new_int(device->wlr_device->vendor)); | ||
980 | json_object_object_add(object, "product", | ||
981 | json_object_new_int(device->wlr_device->product)); | ||
982 | json_object_object_add(object, "type", | 1100 | json_object_object_add(object, "type", |
983 | json_object_new_string( | 1101 | json_object_new_string( |
984 | input_device_get_type(device))); | 1102 | input_device_get_type(device))); |
@@ -1026,12 +1144,18 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) { | |||
1026 | json_object_new_double(scroll_factor)); | 1144 | json_object_new_double(scroll_factor)); |
1027 | } | 1145 | } |
1028 | 1146 | ||
1147 | #if WLR_HAS_LIBINPUT_BACKEND | ||
1029 | if (wlr_input_device_is_libinput(device->wlr_device)) { | 1148 | if (wlr_input_device_is_libinput(device->wlr_device)) { |
1030 | struct libinput_device *libinput_dev; | 1149 | struct libinput_device *libinput_dev; |
1031 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); | 1150 | libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); |
1032 | json_object_object_add(object, "libinput", | 1151 | json_object_object_add(object, "libinput", |
1033 | describe_libinput_device(libinput_dev)); | 1152 | describe_libinput_device(libinput_dev)); |
1153 | json_object_object_add(object, "vendor", | ||
1154 | json_object_new_int(libinput_device_get_id_vendor(libinput_dev))); | ||
1155 | json_object_object_add(object, "product", | ||
1156 | json_object_new_int(libinput_device_get_id_product(libinput_dev))); | ||
1034 | } | 1157 | } |
1158 | #endif | ||
1035 | 1159 | ||
1036 | return object; | 1160 | return object; |
1037 | } | 1161 | } |