aboutsummaryrefslogtreecommitdiffstats
path: root/sway/ipc-json.c
diff options
context:
space:
mode:
Diffstat (limited to 'sway/ipc-json.c')
-rw-r--r--sway/ipc-json.c194
1 files changed, 162 insertions, 32 deletions
diff --git a/sway/ipc-json.c b/sway/ipc-json.c
index e682bc36..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
23static const int i3_output_id = INT32_MAX; 28static const int i3_output_id = INT32_MAX;
24static const int i3_scratch_id = INT32_MAX - 1; 29static 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
124static 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
141static 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
122static const char *ipc_json_xwindow_type_description(struct sway_view *view) { 158static 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
209static 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
173json_object *ipc_json_get_version(void) { 223json_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
245static void ipc_json_describe_output(struct sway_output *output, 297static 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,14 +318,22 @@ 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
321static 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
272static void ipc_json_describe_enabled_output(struct sway_output *output, 326static 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));
335 json_object_object_add(object, "power",
336 json_object_new_boolean(wlr_output->enabled));
280 json_object_object_add(object, "layout", json_object_new_string("output")); 337 json_object_object_add(object, "layout", json_object_new_string("output"));
281 json_object_object_add(object, "orientation", 338 json_object_object_add(object, "orientation",
282 json_object_new_string( 339 json_object_new_string(
@@ -305,25 +362,26 @@ static void ipc_json_describe_enabled_output(struct sway_output *output,
305 json_object *modes_array = json_object_new_array(); 362 json_object *modes_array = json_object_new_array();
306 struct wlr_output_mode *mode; 363 struct wlr_output_mode *mode;
307 wl_list_for_each(mode, &wlr_output->modes, link) { 364 wl_list_for_each(mode, &wlr_output->modes, link) {
308 json_object *mode_object = json_object_new_object(); 365 json_object *mode_object =
309 json_object_object_add(mode_object, "width", 366 ipc_json_output_mode_description(mode);
310 json_object_new_int(mode->width));
311 json_object_object_add(mode_object, "height",
312 json_object_new_int(mode->height));
313 json_object_object_add(mode_object, "refresh",
314 json_object_new_int(mode->refresh));
315 json_object_array_add(modes_array, mode_object); 367 json_object_array_add(modes_array, mode_object);
316 } 368 }
317 369
318 json_object_object_add(object, "modes", modes_array); 370 json_object_object_add(object, "modes", modes_array);
319 371
320 json_object *current_mode_object = json_object_new_object(); 372 json_object *current_mode_object;
321 json_object_object_add(current_mode_object, "width", 373 if (wlr_output->current_mode != NULL) {
322 json_object_new_int(wlr_output->width)); 374 current_mode_object =
323 json_object_object_add(current_mode_object, "height", 375 ipc_json_output_mode_description(wlr_output->current_mode);
324 json_object_new_int(wlr_output->height)); 376 } else {
325 json_object_object_add(current_mode_object, "refresh", 377 current_mode_object = json_object_new_object();
326 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 }
327 json_object_object_add(object, "current_mode", current_mode_object); 385 json_object_object_add(object, "current_mode", current_mode_object);
328 386
329 struct sway_node *parent = node_get_parent(&output->node); 387 struct sway_node *parent = node_get_parent(&output->node);
@@ -349,11 +407,13 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
349 407
350 ipc_json_describe_output(output, object); 408 ipc_json_describe_output(output, object);
351 409
410 json_object_object_add(object, "non_desktop", json_object_new_boolean(false));
352 json_object_object_add(object, "type", json_object_new_string("output")); 411 json_object_object_add(object, "type", json_object_new_string("output"));
353 json_object_object_add(object, "name", 412 json_object_object_add(object, "name",
354 json_object_new_string(wlr_output->name)); 413 json_object_new_string(wlr_output->name));
355 json_object_object_add(object, "active", json_object_new_boolean(false)); 414 json_object_object_add(object, "active", json_object_new_boolean(false));
356 json_object_object_add(object, "dpms", json_object_new_boolean(false)); 415 json_object_object_add(object, "dpms", json_object_new_boolean(false));
416 json_object_object_add(object, "power", json_object_new_boolean(false));
357 417
358 json_object_object_add(object, "current_workspace", NULL); 418 json_object_object_add(object, "current_workspace", NULL);
359 419
@@ -369,6 +429,21 @@ json_object *ipc_json_describe_disabled_output(struct sway_output *output) {
369 return object; 429 return object;
370} 430}
371 431
432json_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
372static json_object *ipc_json_describe_scratchpad_output(void) { 447static json_object *ipc_json_describe_scratchpad_output(void) {
373 struct wlr_box box; 448 struct wlr_box box;
374 root_get_box(root, &box); 449 root_get_box(root, &box);
@@ -455,7 +530,9 @@ static void ipc_json_describe_workspace(struct sway_workspace *workspace,
455 530
456static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) { 531static void get_deco_rect(struct sway_container *c, struct wlr_box *deco_rect) {
457 enum sway_container_layout parent_layout = container_parent_layout(c); 532 enum sway_container_layout parent_layout = container_parent_layout(c);
458 bool tab_or_stack = parent_layout == L_TABBED || parent_layout == L_STACKED; 533 list_t *siblings = container_get_siblings(c);
534 bool tab_or_stack = (parent_layout == L_TABBED || parent_layout == L_STACKED)
535 && ((siblings && siblings->length > 1) || !config->hide_lone_tab);
459 if (((!tab_or_stack || container_is_floating(c)) && 536 if (((!tab_or_stack || container_is_floating(c)) &&
460 c->current.border != B_NORMAL) || 537 c->current.border != B_NORMAL) ||
461 c->pending.fullscreen_mode != FULLSCREEN_NONE || 538 c->pending.fullscreen_mode != FULLSCREEN_NONE ||
@@ -502,7 +579,7 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
502 579
503 struct wlr_box window_box = { 580 struct wlr_box window_box = {
504 c->pending.content_x - c->pending.x, 581 c->pending.content_x - c->pending.x,
505 (c->current.border == B_PIXEL) ? c->current.border_thickness : 0, 582 (c->current.border == B_PIXEL) ? c->pending.content_y - c->pending.y : 0,
506 c->pending.content_width, 583 c->pending.content_width,
507 c->pending.content_height 584 c->pending.content_height
508 }; 585 };
@@ -546,6 +623,16 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
546 623
547 json_object_object_add(object, "idle_inhibitors", idle_inhibitors); 624 json_object_object_add(object, "idle_inhibitors", idle_inhibitors);
548 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
549#if HAVE_XWAYLAND 636#if HAVE_XWAYLAND
550 if (c->view->type == SWAY_VIEW_XWAYLAND) { 637 if (c->view->type == SWAY_VIEW_XWAYLAND) {
551 json_object_object_add(object, "window", 638 json_object_object_add(object, "window",
@@ -590,7 +677,8 @@ static void ipc_json_describe_view(struct sway_container *c, json_object *object
590static void ipc_json_describe_container(struct sway_container *c, json_object *object) { 677static void ipc_json_describe_container(struct sway_container *c, json_object *object) {
591 json_object_object_add(object, "name", 678 json_object_object_add(object, "name",
592 c->title ? json_object_new_string(c->title) : NULL); 679 c->title ? json_object_new_string(c->title) : NULL);
593 if (container_is_floating(c)) { 680 bool floating = container_is_floating(c);
681 if (floating) {
594 json_object_object_add(object, "type", 682 json_object_object_add(object, "type",
595 json_object_new_string("floating_con")); 683 json_object_new_string("floating_con"));
596 } 684 }
@@ -608,9 +696,17 @@ static void ipc_json_describe_container(struct sway_container *c, json_object *o
608 json_object_object_add(object, "urgent", json_object_new_boolean(urgent)); 696 json_object_object_add(object, "urgent", json_object_new_boolean(urgent));
609 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));
610 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
611 json_object_object_add(object, "fullscreen_mode", 703 json_object_object_add(object, "fullscreen_mode",
612 json_object_new_int(c->pending.fullscreen_mode)); 704 json_object_new_int(c->pending.fullscreen_mode));
613 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
614 struct sway_node *parent = node_get_parent(&c->node); 710 struct sway_node *parent = node_get_parent(&c->node);
615 struct wlr_box parent_box = {0, 0, 0, 0}; 711 struct wlr_box parent_box = {0, 0, 0, 0};
616 712
@@ -766,6 +862,7 @@ json_object *ipc_json_describe_node_recursive(struct sway_node *node) {
766 return object; 862 return object;
767} 863}
768 864
865#if WLR_HAS_LIBINPUT_BACKEND
769static json_object *describe_libinput_device(struct libinput_device *device) { 866static json_object *describe_libinput_device(struct libinput_device *device) {
770 json_object *object = json_object_new_object(); 867 json_object *object = json_object_new_object();
771 868
@@ -849,6 +946,11 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
849 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE: 946 case LIBINPUT_CONFIG_ACCEL_PROFILE_ADAPTIVE:
850 accel_profile = "adaptive"; 947 accel_profile = "adaptive";
851 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
852 } 954 }
853 json_object_object_add(object, "accel_profile", 955 json_object_object_add(object, "accel_profile",
854 json_object_new_string(accel_profile)); 956 json_object_new_string(accel_profile));
@@ -928,6 +1030,17 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
928 uint32_t button = libinput_device_config_scroll_get_button(device); 1030 uint32_t button = libinput_device_config_scroll_get_button(device);
929 json_object_object_add(object, "scroll_button", 1031 json_object_object_add(object, "scroll_button",
930 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));
931 } 1044 }
932 } 1045 }
933 1046
@@ -944,6 +1057,19 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
944 json_object_object_add(object, "dwt", json_object_new_string(dwt)); 1057 json_object_object_add(object, "dwt", json_object_new_string(dwt));
945 } 1058 }
946 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
947 if (libinput_device_config_calibration_has_matrix(device)) { 1073 if (libinput_device_config_calibration_has_matrix(device)) {
948 float matrix[6]; 1074 float matrix[6];
949 libinput_device_config_calibration_get_matrix(device, matrix); 1075 libinput_device_config_calibration_get_matrix(device, matrix);
@@ -958,6 +1084,7 @@ static json_object *describe_libinput_device(struct libinput_device *device) {
958 1084
959 return object; 1085 return object;
960} 1086}
1087#endif
961 1088
962json_object *ipc_json_describe_input(struct sway_input_device *device) { 1089json_object *ipc_json_describe_input(struct sway_input_device *device) {
963 if (!(sway_assert(device, "Device must not be null"))) { 1090 if (!(sway_assert(device, "Device must not be null"))) {
@@ -970,19 +1097,16 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
970 json_object_new_string(device->identifier)); 1097 json_object_new_string(device->identifier));
971 json_object_object_add(object, "name", 1098 json_object_object_add(object, "name",
972 json_object_new_string(device->wlr_device->name)); 1099 json_object_new_string(device->wlr_device->name));
973 json_object_object_add(object, "vendor",
974 json_object_new_int(device->wlr_device->vendor));
975 json_object_object_add(object, "product",
976 json_object_new_int(device->wlr_device->product));
977 json_object_object_add(object, "type", 1100 json_object_object_add(object, "type",
978 json_object_new_string( 1101 json_object_new_string(
979 input_device_get_type(device))); 1102 input_device_get_type(device)));
980 1103
981 if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) { 1104 if (device->wlr_device->type == WLR_INPUT_DEVICE_KEYBOARD) {
982 struct wlr_keyboard *keyboard = device->wlr_device->keyboard; 1105 struct wlr_keyboard *keyboard =
1106 wlr_keyboard_from_input_device(device->wlr_device);
983 struct xkb_keymap *keymap = keyboard->keymap; 1107 struct xkb_keymap *keymap = keyboard->keymap;
984 struct xkb_state *state = keyboard->xkb_state; 1108 struct xkb_state *state = keyboard->xkb_state;
985 1109
986 json_object_object_add(object, "repeat_delay", 1110 json_object_object_add(object, "repeat_delay",
987 json_object_new_int(keyboard->repeat_info.delay)); 1111 json_object_new_int(keyboard->repeat_info.delay));
988 json_object_object_add(object, "repeat_rate", 1112 json_object_object_add(object, "repeat_rate",
@@ -1012,20 +1136,26 @@ json_object *ipc_json_describe_input(struct sway_input_device *device) {
1012 if (device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) { 1136 if (device->wlr_device->type == WLR_INPUT_DEVICE_POINTER) {
1013 struct input_config *ic = input_device_get_config(device); 1137 struct input_config *ic = input_device_get_config(device);
1014 float scroll_factor = 1.0f; 1138 float scroll_factor = 1.0f;
1015 if (ic != NULL && !isnan(ic->scroll_factor) && 1139 if (ic != NULL && !isnan(ic->scroll_factor) &&
1016 ic->scroll_factor != FLT_MIN) { 1140 ic->scroll_factor != FLT_MIN) {
1017 scroll_factor = ic->scroll_factor; 1141 scroll_factor = ic->scroll_factor;
1018 } 1142 }
1019 json_object_object_add(object, "scroll_factor", 1143 json_object_object_add(object, "scroll_factor",
1020 json_object_new_double(scroll_factor)); 1144 json_object_new_double(scroll_factor));
1021 } 1145 }
1022 1146
1147#if WLR_HAS_LIBINPUT_BACKEND
1023 if (wlr_input_device_is_libinput(device->wlr_device)) { 1148 if (wlr_input_device_is_libinput(device->wlr_device)) {
1024 struct libinput_device *libinput_dev; 1149 struct libinput_device *libinput_dev;
1025 libinput_dev = wlr_libinput_get_device_handle(device->wlr_device); 1150 libinput_dev = wlr_libinput_get_device_handle(device->wlr_device);
1026 json_object_object_add(object, "libinput", 1151 json_object_object_add(object, "libinput",
1027 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)));
1028 } 1157 }
1158#endif
1029 1159
1030 return object; 1160 return object;
1031} 1161}