aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2015-08-20 15:16:38 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2015-08-20 15:16:38 -0400
commit1100335ea01ecd56df68568622580db14e72b6c7 (patch)
tree783cf48873e5a3944cf670461bed69b140e56fc9
parentMerge pull request #102 from taiyu-len/master (diff)
parentadded IPC messages get_workspaces and get_outputs (diff)
downloadsway-1100335ea01ecd56df68568622580db14e72b6c7.tar.gz
sway-1100335ea01ecd56df68568622580db14e72b6c7.tar.zst
sway-1100335ea01ecd56df68568622580db14e72b6c7.zip
Merge pull request #104 from minus7/ipc-get-messages
added IPC messages get_workspaces and get_outputs
-rw-r--r--include/stringop.h1
-rw-r--r--sway/ipc.c92
-rw-r--r--sway/stringop.c39
3 files changed, 132 insertions, 0 deletions
diff --git a/include/stringop.h b/include/stringop.h
index a5346829..4300f9ed 100644
--- a/include/stringop.h
+++ b/include/stringop.h
@@ -10,5 +10,6 @@ char *code_strchr(const char *string, char delimiter);
10char *code_strstr(const char *haystack, const char *needle); 10char *code_strstr(const char *haystack, const char *needle);
11int unescape_string(char *string); 11int unescape_string(char *string);
12char *join_args(char **argv, int argc); 12char *join_args(char **argv, int argc);
13char *join_list(list_t *list, char *separator);
13 14
14#endif 15#endif
diff --git a/sway/ipc.c b/sway/ipc.c
index 505c17f8..39e580cd 100644
--- a/sway/ipc.c
+++ b/sway/ipc.c
@@ -11,10 +11,13 @@
11#include <stropts.h> 11#include <stropts.h>
12#include <sys/ioctl.h> 12#include <sys/ioctl.h>
13#include <fcntl.h> 13#include <fcntl.h>
14#include <ctype.h>
14#include "ipc.h" 15#include "ipc.h"
15#include "log.h" 16#include "log.h"
16#include "config.h" 17#include "config.h"
17#include "commands.h" 18#include "commands.h"
19#include "list.h"
20#include "stringop.h"
18 21
19static int ipc_socket = -1; 22static int ipc_socket = -1;
20static struct wlc_event_source *ipc_event_source = NULL; 23static struct wlc_event_source *ipc_event_source = NULL;
@@ -37,6 +40,10 @@ int ipc_client_handle_readable(int client_fd, uint32_t mask, void *data);
37void ipc_client_disconnect(struct ipc_client *client); 40void ipc_client_disconnect(struct ipc_client *client);
38void ipc_client_handle_command(struct ipc_client *client); 41void ipc_client_handle_command(struct ipc_client *client);
39bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length); 42bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t payload_length);
43void ipc_get_workspaces_callback(swayc_t *container, void *data);
44void ipc_get_outputs_callback(swayc_t *container, void *data);
45
46char *json_list(list_t *items);
40 47
41void ipc_init(void) { 48void ipc_init(void) {
42 ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0); 49 ipc_socket = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 0);
@@ -195,6 +202,26 @@ void ipc_client_handle_command(struct ipc_client *client) {
195 ipc_send_reply(client, reply, (uint32_t) length); 202 ipc_send_reply(client, reply, (uint32_t) length);
196 break; 203 break;
197 } 204 }
205 case IPC_GET_WORKSPACES:
206 {
207 list_t *workspaces = create_list();
208 container_map(&root_container, ipc_get_workspaces_callback, workspaces);
209 char *json = json_list(workspaces);
210 free_flat_list(workspaces);
211 ipc_send_reply(client, json, strlen(json));
212 free(json);
213 break;
214 }
215 case IPC_GET_OUTPUTS:
216 {
217 list_t *outputs = create_list();
218 container_map(&root_container, ipc_get_outputs_callback, outputs);
219 char *json = json_list(outputs);
220 free_flat_list(outputs);
221 ipc_send_reply(client, json, strlen(json));
222 free(json);
223 break;
224 }
198 default: 225 default:
199 sway_log(L_INFO, "Unknown IPC command type %i", client->current_command); 226 sway_log(L_INFO, "Unknown IPC command type %i", client->current_command);
200 ipc_client_disconnect(client); 227 ipc_client_disconnect(client);
@@ -227,3 +254,68 @@ bool ipc_send_reply(struct ipc_client *client, const char *payload, uint32_t pay
227 254
228 return true; 255 return true;
229} 256}
257
258char *json_list(list_t *items) {
259 char *json_elements = join_list(items, ",");
260 size_t len = strlen(json_elements);
261 char *json = malloc(len + 3);
262 json[0] = '[';
263 memcpy(json + 1, json_elements, len);
264 json[len+1] = ']';
265 json[len+2] = '\0';
266 free(json_elements);
267 return json;
268}
269
270void ipc_get_workspaces_callback(swayc_t *container, void *data) {
271 if (container->type == C_WORKSPACE) {
272 char *json = malloc(512); // Output should usually be around 180 chars
273 int num = isdigit(container->name[0]) ? atoi(container->name) : -1;
274 // TODO: escape the name (quotation marks, unicode)
275 sprintf(json,
276 "{"
277 "\"num\":%d,"
278 "\"name\":\"%s\","
279 "\"visible\":%s,"
280 "\"focused\":%s,"
281 "\"rect\":{"
282 "\"x\":%d,"
283 "\"y\":%d,"
284 "\"width\":%d,"
285 "\"height\":%d"
286 "},"
287 "\"output\":\"%s\","
288 "\"urgent\":%s"
289 "}",
290 num, container->name, container->visible ? "true" : "false", container->is_focused ? "true" : "false",
291 container->x, container->y, container->width, container->height,
292 container->parent->name, "false" // TODO: urgent hint
293 );
294 list_add((list_t *)data, json);
295 }
296}
297
298void ipc_get_outputs_callback(swayc_t *container, void *data) {
299 if (container->type == C_OUTPUT) {
300 char *json = malloc(512); // Output should usually be around 130 chars
301 // TODO: escape the name (quotation marks, unicode)
302 sprintf(json,
303 "{"
304 "\"name\":\"%s\","
305 "\"active\":%s,"
306 "\"primary\":%s,"
307 "\"rect\":{"
308 "\"x\":%d,"
309 "\"y\":%d,"
310 "\"width\":%d,"
311 "\"height\":%d"
312 "},"
313 "\"current_workspace\":\"%s\""
314 "}",
315 container->name, "true", "false", // TODO: active, primary
316 container->x, container->y, container->width, container->height,
317 container->focused ? container->focused->name : ""
318 );
319 list_add((list_t *)data, json);
320 }
321}
diff --git a/sway/stringop.c b/sway/stringop.c
index 1dff97bf..c39e2c34 100644
--- a/sway/stringop.c
+++ b/sway/stringop.c
@@ -4,6 +4,7 @@
4#include "string.h" 4#include "string.h"
5#include "list.h" 5#include "list.h"
6#include <strings.h> 6#include <strings.h>
7#include <log.h>
7 8
8/* Note: This returns 8 characters for trimmed_start per tab character. */ 9/* Note: This returns 8 characters for trimmed_start per tab character. */
9char *strip_whitespace(char *_str, int *trimmed_start) { 10char *strip_whitespace(char *_str, int *trimmed_start) {
@@ -197,3 +198,41 @@ char *join_args(char **argv, int argc) {
197 res[len - 1] = '\0'; 198 res[len - 1] = '\0';
198 return res; 199 return res;
199} 200}
201
202/*
203 * Join a list of strings, adding separator in between. Separator can be NULL.
204 */
205char *join_list(list_t *list, char *separator) {
206 if (!sway_assert(list != NULL, "list != NULL") || list->length == 0) {
207 return NULL;
208 }
209
210 size_t len = 1; // NULL terminator
211 size_t sep_len = 0;
212 if (separator != NULL) {
213 sep_len = strlen(separator);
214 len += (list->length - 1) * sep_len;
215 }
216
217 for (int i = 0; i < list->length; i++) {
218 len += strlen(list->items[i]);
219 }
220
221 char *res = malloc(len);
222
223 char *p = res + strlen(list->items[0]);
224 strcpy(res, list->items[0]);
225
226 for (int i = 1; i < list->length; i++) {
227 if (sep_len) {
228 memcpy(p, separator, sep_len);
229 p += sep_len;
230 }
231 strcpy(p, list->items[i]);
232 p += strlen(list->items[i]);
233 }
234
235 *p = '\0';
236
237 return res;
238}