-rw-r--r-- src/ipc.c
1 #include <sys/socket.h> 2 #include <sys/un.h> 3 #include <unistd.h> 4 5 #include "action.h" 6 #include "config.h" 7 #include "ipc.h" 8 #include "keybind.h" 9 10 #define SOCKET_PATH "/tmp/wimpy-sock-%s" 11 12 13 void close_ipc(const char *display) { 14 char path[1024]; 15 snprintf(path, sizeof(path), SOCKET_PATH, display); 16 unlink(path); 17 } 18 19 20 static void handle_message(char *message, char *response) { 21 char *s = strtok(message, " \t\n\r"); 22 23 // set <option> <value> 24 if (!strcasecmp(s, "set")) { 25 set_configurable(s, response); 26 } 27 28 // bind [<modifiers>] <key> <action> 29 else if (!strcasecmp(s, "bind")) { 30 add_binding(s, response); 31 } 32 33 // <action> <data> 34 else { 35 if (!do_action(message, response)) { 36 sprintf(response, "Sorry, I don't recognise that command."); 37 } 38 } 39 } 40 41 42 static int dispatch(int sock, unsigned int mask, void *data) { 43 char message[1024]; 44 char response[1024] = {0}; 45 46 if (mask & WL_EVENT_READABLE) { 47 int fd = accept(sock, NULL, NULL); 48 if (fd == -1) { 49 wlr_log(WLR_ERROR, "Failed to accept connection from client."); 50 return 0; 51 } 52 ssize_t len = recv(fd, message, sizeof(message) - 1, 0); 53 message[len] = '\0'; 54 handle_message(message, response); 55 if (response[0]) { 56 send(fd, response, strlen(response), 0); 57 } 58 close(fd); 59 } 60 61 return 0; 62 } 63 64 65 void set_up_defaults(){ 66 char defaults[][64] = { 67 "set desks 2", 68 "set desk 2 background #3e3e73", 69 "set desk 2 borders normal #31475c", 70 "set desk 2 corners normal #3e5973", 71 "set mark_indicator #47315c", 72 "set snap_box 47315c66", 73 "set mod Logo", 74 "set vt_switching on", 75 "set bind_marks on", 76 "bind Ctrl Escape terminate", 77 }; 78 for (size_t i = 0; i < sizeof(defaults) / sizeof(defaults[0]); i++) { 79 handle_message(defaults[i], NULL); 80 } 81 } 82 83 84 bool start_ipc(const char *display) { 85 int sock; 86 if ((sock = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { 87 wlr_log(WLR_ERROR, "Failed to create IPC socket."); 88 return false; 89 } 90 91 struct sockaddr_un addr; 92 snprintf(addr.sun_path, sizeof(addr.sun_path), SOCKET_PATH, display); 93 addr.sun_family = AF_UNIX; 94 unlink(addr.sun_path); 95 96 if (bind(sock, (struct sockaddr *) &addr, sizeof(addr)) == -1) { 97 wlr_log(WLR_ERROR, "Failed to bind IPC socket."); 98 return false; 99 } 100 101 if (listen(sock, SOMAXCONN) == -1) { 102 wlr_log(WLR_ERROR, "Failed to listen on IPC socket."); 103 return false; 104 } 105 106 struct wl_event_loop *event_loop = wl_display_get_event_loop(wimp.display); 107 wl_event_loop_add_fd(event_loop, sock, WL_EVENT_READABLE, &dispatch, NULL); 108 109 return true; 110 } 111