|  |  |  | @ -3,12 +3,18 @@ | 
			
		
	
		
			
				
					|  |  |  |  | // Any value will hide SOCK_CLOEXEC on FreeBSD (__BSD_VISIBLE=0)
 | 
			
		
	
		
			
				
					|  |  |  |  | #define _XOPEN_SOURCE 700 | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | #ifdef __linux__ | 
			
		
	
		
			
				
					|  |  |  |  | #include <linux/input-event-codes.h> | 
			
		
	
		
			
				
					|  |  |  |  | #elif __FreeBSD__ | 
			
		
	
		
			
				
					|  |  |  |  | #include <dev/evdev/input-event-codes.h> | 
			
		
	
		
			
				
					|  |  |  |  | #endif | 
			
		
	
		
			
				
					|  |  |  |  | #include <assert.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <errno.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <fcntl.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <json-c/json.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <stdbool.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <stdint.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <stdio.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <stdlib.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <string.h> | 
			
		
	
		
			
				
					|  |  |  |  | #include <sys/socket.h> | 
			
		
	
	
		
			
				
					|  |  |  | @ -28,6 +34,7 @@ | 
			
		
	
		
			
				
					|  |  |  |  | #include "sway/tree/view.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "list.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "log.h" | 
			
		
	
		
			
				
					|  |  |  |  | #include "util.h" | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | static int ipc_socket = -1; | 
			
		
	
		
			
				
					|  |  |  |  | static struct wl_event_source *ipc_event_source =  NULL; | 
			
		
	
	
		
			
				
					|  |  |  | @ -367,6 +374,75 @@ void ipc_event_shutdown(const char *reason) { | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_put(json); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | void ipc_event_binding(struct sway_binding *binding) { | 
			
		
	
		
			
				
					|  |  |  |  | 	if (!ipc_has_event_listeners(IPC_EVENT_BINDING)) { | 
			
		
	
		
			
				
					|  |  |  |  | 		return; | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	wlr_log(WLR_DEBUG, "Sending binding event"); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object *json_binding = json_object_new_object(); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json_binding, "command", json_object_new_string(binding->command)); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	const char *names[10]; | 
			
		
	
		
			
				
					|  |  |  |  | 	int len = get_modifier_names(names, binding->modifiers); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object *modifiers = json_object_new_array(); | 
			
		
	
		
			
				
					|  |  |  |  | 	for (int i = 0; i < len; ++i) { | 
			
		
	
		
			
				
					|  |  |  |  | 		json_object_array_add(modifiers, json_object_new_string(names[i])); | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json_binding, "event_state_mask", modifiers); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object *input_codes = json_object_new_array(); | 
			
		
	
		
			
				
					|  |  |  |  | 	int input_code = 0; | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object *symbols = json_object_new_array(); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object *symbol = NULL; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	if (binding->type == BINDING_KEYCODE) { // bindcode: populate input_codes
 | 
			
		
	
		
			
				
					|  |  |  |  | 		uint32_t keycode; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i < binding->keys->length; ++i) { | 
			
		
	
		
			
				
					|  |  |  |  | 			keycode = *(uint32_t *)binding->keys->items[i]; | 
			
		
	
		
			
				
					|  |  |  |  | 			json_object_array_add(input_codes, json_object_new_int(keycode)); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (i == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 				input_code = keycode; | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} else { // bindsym/mouse: populate symbols
 | 
			
		
	
		
			
				
					|  |  |  |  | 		uint32_t keysym; | 
			
		
	
		
			
				
					|  |  |  |  | 		char buffer[64]; | 
			
		
	
		
			
				
					|  |  |  |  | 		for (int i = 0; i < binding->keys->length; ++i) { | 
			
		
	
		
			
				
					|  |  |  |  | 			keysym = *(uint32_t *)binding->keys->items[i]; | 
			
		
	
		
			
				
					|  |  |  |  | 			if (keysym >= BTN_LEFT && keysym <= BTN_LEFT + 8) { | 
			
		
	
		
			
				
					|  |  |  |  | 				snprintf(buffer, 64, "button%u", keysym - BTN_LEFT + 1); | 
			
		
	
		
			
				
					|  |  |  |  | 			} else if (xkb_keysym_get_name(keysym, buffer, 64) < 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 				continue; | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 			json_object *str = json_object_new_string(buffer); | 
			
		
	
		
			
				
					|  |  |  |  | 			if (i == 0) { | 
			
		
	
		
			
				
					|  |  |  |  | 				// str is owned by both symbol and symbols. Make sure
 | 
			
		
	
		
			
				
					|  |  |  |  | 				// to bump the ref count.
 | 
			
		
	
		
			
				
					|  |  |  |  | 				json_object_array_add(symbols, json_object_get(str)); | 
			
		
	
		
			
				
					|  |  |  |  | 				symbol = str; | 
			
		
	
		
			
				
					|  |  |  |  | 			} else { | 
			
		
	
		
			
				
					|  |  |  |  | 				json_object_array_add(symbols, str); | 
			
		
	
		
			
				
					|  |  |  |  | 			} | 
			
		
	
		
			
				
					|  |  |  |  | 		} | 
			
		
	
		
			
				
					|  |  |  |  | 	} | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json_binding, "input_codes", input_codes); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json_binding, "input_code", json_object_new_int(input_code)); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json_binding, "symbols", symbols); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json_binding, "symbol", symbol); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json_binding, "input_type", binding->type == BINDING_MOUSE ? | 
			
		
	
		
			
				
					|  |  |  |  | 			json_object_new_string("mouse") : json_object_new_string("keyboard")); | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object *json = json_object_new_object(); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json, "change", json_object_new_string("run")); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_object_add(json, "binding", json_binding); | 
			
		
	
		
			
				
					|  |  |  |  | 	const char *json_string = json_object_to_json_string(json); | 
			
		
	
		
			
				
					|  |  |  |  | 	ipc_send_event(json_string, IPC_EVENT_BINDING); | 
			
		
	
		
			
				
					|  |  |  |  | 	json_object_put(json); | 
			
		
	
		
			
				
					|  |  |  |  | } | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
		
			
				
					|  |  |  |  | int ipc_client_handle_writable(int client_fd, uint32_t mask, void *data) { | 
			
		
	
		
			
				
					|  |  |  |  | 	struct ipc_client *client = data; | 
			
		
	
		
			
				
					|  |  |  |  | 
 | 
			
		
	
	
		
			
				
					|  |  |  | 
 |