##// END OF EJS Templates
enable xwl
Tsuki -
r5:996174ee93eb default
parent child Browse files
Show More
@@ -1,6 +1,6
1 option(
1 option(
2 'xwayland',
2 'xwayland',
3 type: 'boolean',
3 type: 'boolean',
4 value: false,
4 value: true,
5 description: 'Enable XWayland support',
5 description: 'Enable XWayland support',
6 )
6 )
@@ -1,516 +1,516
1 #define _GNU_SOURCE
1 #define _GNU_SOURCE
2 #include "arg.h"
2 #include "arg.h"
3 #include <poll.h>
3 #include <poll.h>
4 #include <stdio.h>
4 #include <stdio.h>
5 #include <stdlib.h>
5 #include <stdlib.h>
6 #include <string.h>
6 #include <string.h>
7 #include <sys/socket.h>
7 #include <sys/socket.h>
8 #include <wayland-client.h>
8 #include <wayland-client.h>
9 #include <wayland-util.h>
9 #include <wayland-util.h>
10 #include "dwl-ipc-unstable-v2-protocol.h"
10 #include "dwl-ipc-unstable-v2-protocol.h"
11
11
12 #define die(fmt, ...) do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); } while (0)
12 #define die(fmt, ...) do { fprintf(stderr, fmt "\n", ##__VA_ARGS__); exit(EXIT_FAILURE); } while (0)
13
13
14 char *argv0;
14 char *argv0;
15
15
16 static enum {
16 static enum {
17 NONE = 0,
17 NONE = 0,
18 SET = 1<<0,
18 SET = 1<<0,
19 GET = 1<<1,
19 GET = 1<<1,
20 WATCH = 1<<2 | GET,
20 WATCH = 1<<2 | GET,
21 } mode = NONE;
21 } mode = NONE;
22
22
23 static int Oflag;
23 static int Oflag;
24 static int Tflag;
24 static int Tflag;
25 static int Lflag;
25 static int Lflag;
26 static int Pflag;
26 static int Pflag;
27 static int Fflag;
27 static int Fflag;
28 static int oflag;
28 static int oflag;
29 static int tflag;
29 static int tflag;
30 static int lflag;
30 static int lflag;
31 static int cflag;
31 static int cflag;
32 static int vflag;
32 static int vflag;
33 static int mflag;
33 static int mflag;
34 static int fflag;
34 static int fflag;
35
35
36 static uint32_t occ, seltags, sel, urg;
36 static uint32_t occ, seltags, sel, urg;
37
37
38 static char *output_name;
38 static char *output_name;
39 static char *focused_output;
39 static char *focused_output;
40 static uint32_t tagcount;
40 static uint32_t tagcount;
41 static char *tagset;
41 static char *tagset;
42 static char *layout_name;
42 static char *layout_name;
43 static size_t layoutcount, layout_idx;
43 static size_t layoutcount, layout_idx;
44 static char *client_tags;
44 static char *client_tags;
45
45
46 struct output {
46 struct output {
47 char *output_name;
47 char *output_name;
48 uint32_t name;
48 uint32_t name;
49 };
49 };
50 static size_t outputs_buflen = 4;
50 static size_t outputs_buflen = 4;
51 static struct output *outputs;
51 static struct output *outputs;
52 static size_t outputcount;
52 static size_t outputcount;
53
53
54 static struct wl_display *display;
54 static struct wl_display *display;
55 static struct wl_registry *registry;
55 static struct wl_registry *registry;
56 static struct zdwl_ipc_manager_v2 *dwl_ipc_manager;
56 static struct zdwl_ipc_manager_v2 *dwl_ipc_manager;
57
57
58 static void
58 static void
59 dwl_ipc_tags(void *data, struct zdwl_ipc_manager_v2 *dwl_ipc_manager, uint32_t count)
59 dwl_ipc_tags(void *data, struct zdwl_ipc_manager_v2 *dwl_ipc_manager, uint32_t count)
60 {
60 {
61 tagcount = count;
61 tagcount = count;
62 if (Tflag && mode & GET) printf("%d\n", tagcount);
62 if (Tflag && mode & GET) printf("%d\n", tagcount);
63 }
63 }
64
64
65 static void
65 static void
66 dwl_ipc_layout(void *data, struct zdwl_ipc_manager_v2 *dwl_ipc_manager, const char *name)
66 dwl_ipc_layout(void *data, struct zdwl_ipc_manager_v2 *dwl_ipc_manager, const char *name)
67 {
67 {
68 if (lflag && mode & SET && strcmp(layout_name, name) == 0)
68 if (lflag && mode & SET && strcmp(layout_name, name) == 0)
69 layout_idx = layoutcount;
69 layout_idx = layoutcount;
70 if (Lflag && mode & GET) printf("%s\n", name);
70 if (Lflag && mode & GET) printf("%s\n", name);
71 layoutcount++;
71 layoutcount++;
72 }
72 }
73
73
74 static const struct zdwl_ipc_manager_v2_listener dwl_ipc_listener = {
74 static const struct zdwl_ipc_manager_v2_listener dwl_ipc_listener = {
75 .tags = dwl_ipc_tags,
75 .tags = dwl_ipc_tags,
76 .layout = dwl_ipc_layout
76 .layout = dwl_ipc_layout
77 };
77 };
78
78
79 static void
79 static void
80 dwl_ipc_output_toggle_visibility(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output)
80 dwl_ipc_output_toggle_visibility(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output)
81 {
81 {
82 if (!vflag) return;
82 if (!vflag) return;
83 char *oname = data;
83 char *oname = data;
84 if (oname) printf("%s ", oname);
84 if (oname) printf("%s ", oname);
85 printf("toggle\n");
85 printf("toggle\n");
86 }
86 }
87
87
88 static void
88 static void
89 dwl_ipc_output_active(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
89 dwl_ipc_output_active(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
90 uint32_t active)
90 uint32_t active)
91 {
91 {
92 if (active && (!output_name || !*output_name))
92 if (active && (!output_name || !*output_name))
93 output_name = strdup(data);
93 output_name = strdup(data);
94 if (active) {
94 if (active) {
95 free(focused_output);
95 free(focused_output);
96 focused_output = data ? strdup(data) : NULL;
96 focused_output = data ? strdup(data) : NULL;
97 }
97 }
98 if (!oflag) return;
98 if (!oflag) return;
99 char *oname = data;
99 char *oname = data;
100 if (oname) printf("%s ", oname);
100 if (oname) printf("%s ", oname);
101 printf("selmon %u\n", !!active);
101 printf("selmon %u\n", !!active);
102 }
102 }
103
103
104 static void
104 static void
105 dwl_ipc_output_tag(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
105 dwl_ipc_output_tag(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
106 uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused)
106 uint32_t tag, uint32_t state, uint32_t clients, uint32_t focused)
107 {
107 {
108 if (!tflag) return;
108 if (!tflag) return;
109 if (state != ZDWL_IPC_OUTPUT_V2_TAG_STATE_NONE) seltags |= 1<<tag;
109 if (state != ZDWL_IPC_OUTPUT_V2_TAG_STATE_NONE) seltags |= 1<<tag;
110 if (state == ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE) urg |= 1<<tag;
110 if (state == ZDWL_IPC_OUTPUT_V2_TAG_STATE_ACTIVE) urg |= 1<<tag;
111 if (clients > 0) occ |= 1<<tag;
111 if (clients > 0) occ |= 1<<tag;
112 if (!(mode & GET)) return;
112 if (!(mode & GET)) return;
113 if (data) printf("%s ", (char *)data);
113 if (data) printf("%s ", (char *)data);
114 printf("tag %u %u %u %u\n", tag, state, clients, focused);
114 printf("tag %u %u %u %u\n", tag, state, clients, focused);
115 }
115 }
116
116
117 static void
117 static void
118 dwl_ipc_output_layout(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
118 dwl_ipc_output_layout(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
119 uint32_t layout)
119 uint32_t layout)
120 {
120 {
121 }
121 }
122
122
123 static void
123 static void
124 dwl_ipc_output_layout_symbol(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
124 dwl_ipc_output_layout_symbol(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
125 const char *layout)
125 const char *layout)
126 {
126 {
127 if (!(lflag && mode & GET)) return;
127 if (!(lflag && mode & GET)) return;
128 if (data) printf("%s ", (char *)data);
128 if (data) printf("%s ", (char *)data);
129 printf("layout %s\n", layout);
129 printf("layout %s\n", layout);
130 }
130 }
131
131
132 static void
132 static void
133 dwl_ipc_output_title(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
133 dwl_ipc_output_title(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
134 const char *title)
134 const char *title)
135 {
135 {
136 if (!(cflag && mode & GET)) return;
136 if (!(cflag && mode & GET)) return;
137 if (data) printf("%s ", (char *)data);
137 if (data) printf("%s ", (char *)data);
138 printf("title %s\n", title);
138 printf("title %s\n", title);
139 }
139 }
140
140
141 static void
141 static void
142 dwl_ipc_output_appid(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
142 dwl_ipc_output_appid(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
143 const char *appid)
143 const char *appid)
144 {
144 {
145 if (!(cflag && mode & GET)) return;
145 if (!(cflag && mode & GET)) return;
146 if (data) printf("%s ", (char *)data);
146 if (data) printf("%s ", (char *)data);
147 printf("appid %s\n", appid);
147 printf("appid %s\n", appid);
148 }
148 }
149
149
150 static void
150 static void
151 dwl_ipc_output_fullscreen(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
151 dwl_ipc_output_fullscreen(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
152 uint32_t is_fullscreen)
152 uint32_t is_fullscreen)
153 {
153 {
154 if (!mflag) return;
154 if (!mflag) return;
155 if (data) printf("%s ", (char *)data);
155 if (data) printf("%s ", (char *)data);
156 printf("fullscreen %u\n", is_fullscreen);
156 printf("fullscreen %u\n", is_fullscreen);
157 }
157 }
158
158
159 static void
159 static void
160 dwl_ipc_output_floating(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
160 dwl_ipc_output_floating(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output,
161 uint32_t is_floating)
161 uint32_t is_floating)
162 {
162 {
163 if (!fflag) return;
163 if (!fflag) return;
164 if (data) printf("%s ", (char *)data);
164 if (data) printf("%s ", (char *)data);
165 printf("floating %u\n", is_floating);
165 printf("floating %u\n", is_floating);
166 }
166 }
167
167
168 static void
168 static void
169 dwl_ipc_output_frame(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output)
169 dwl_ipc_output_frame(void *data, struct zdwl_ipc_output_v2 *dwl_ipc_output)
170 {
170 {
171 if (mode & SET) {
171 if (mode & SET) {
172 if (data && !(output_name && strcmp(output_name, (char *)data) == 0)) return;
172 if (data && !(output_name && strcmp(output_name, (char *)data) == 0)) return;
173 if (lflag) {
173 if (lflag) {
174 if (layout_idx == 0) {
174 if (layout_idx == 0) {
175 for (char *c = layout_name; *c; c++) {
175 for (char *c = layout_name; *c; c++) {
176 if (*c < '0' || *c > '9')
176 if (*c < '0' || *c > '9')
177 die("bad layout %s", layout_name);
177 die("bad layout %s", layout_name);
178 layout_idx = *c-'0' + layout_idx*10;
178 layout_idx = *c-'0' + layout_idx*10;
179 }
179 }
180 }
180 }
181 if (layout_idx >= layoutcount)
181 if (layout_idx >= layoutcount)
182 die("bad layout %s", layout_name);
182 die("bad layout %s", layout_name);
183 zdwl_ipc_output_v2_set_layout(dwl_ipc_output, layout_idx);
183 zdwl_ipc_output_v2_set_layout(dwl_ipc_output, layout_idx);
184 }
184 }
185 if (tflag) {
185 if (tflag) {
186 uint32_t mask = seltags;
186 uint32_t mask = seltags;
187 char *t = tagset;
187 char *t = tagset;
188 uint32_t i = 0;
188 uint32_t i = 0;
189 int toggle = 1;
189 int toggle = 1;
190
190
191 if (*t == '!') {
191 if (*t == '!') {
192 toggle = 0;
192 toggle = 0;
193 t++;
193 t++;
194 }
194 }
195
195
196 for (; *t && *t >= '0' && *t <= '9'; t++)
196 for (; *t && *t >= '0' && *t <= '9'; t++)
197 i = *t-'0' + i*10;
197 i = *t-'0' + i*10;
198
198
199 if (toggle && !*t) mask = 1<<i;
199 if (toggle && !*t) mask = 1<<i;
200
200
201 for (; *t; t++, i++) {
201 for (; *t; t++, i++) {
202 switch (*t) {
202 switch (*t) {
203 case '-':
203 case '-':
204 mask &= ~(1<<i);
204 mask &= ~(1<<i);
205 break;
205 break;
206 case '+':
206 case '+':
207 mask |= 1<<i;
207 mask |= 1<<i;
208 break;
208 break;
209 case '^':
209 case '^':
210 mask ^= 1<<i;
210 mask ^= 1<<i;
211 break;
211 break;
212 }
212 }
213 }
213 }
214
214
215 if (i > tagcount) die("bad tagset %s", tagset);
215 if (i > tagcount) die("bad tagset %s", tagset);
216
216
217 zdwl_ipc_output_v2_set_tags(dwl_ipc_output, mask, toggle);
217 zdwl_ipc_output_v2_set_tags(dwl_ipc_output, mask, toggle);
218 }
218 }
219 if (cflag) {
219 if (cflag) {
220 uint32_t and = ~0, xor = 0;
220 uint32_t and = ~0, xor = 0;
221 char *t = client_tags;
221 char *t = client_tags;
222 uint32_t i = 0;
222 uint32_t i = 0;
223
223
224 for (; *t && *t >= '0' && *t <= '9'; t++)
224 for (; *t && *t >= '0' && *t <= '9'; t++)
225 i = *t-'0' + i*10;
225 i = *t-'0' + i*10;
226
226
227 if (!*t) {
227 if (!*t) {
228 and = 0;
228 and = 0;
229 xor = 1<<i;
229 xor = 1<<i;
230 }
230 }
231
231
232 for (; *t; t++, i++) {
232 for (; *t; t++, i++) {
233 switch (*t) {
233 switch (*t) {
234 case '-':
234 case '-':
235 and &= ~(1<<i);
235 and &= ~(1<<i);
236 break;
236 break;
237 case '+':
237 case '+':
238 and &= ~(1<<i);
238 and &= ~(1<<i);
239 xor |= 1<<i;
239 xor |= 1<<i;
240 break;
240 break;
241 case '^':
241 case '^':
242 xor |= 1<<i;
242 xor |= 1<<i;
243 break;
243 break;
244 }
244 }
245 }
245 }
246 if (i > tagcount) die("bad client tagset %s", client_tags);
246 if (i > tagcount) die("bad client tagset %s", client_tags);
247
247
248 zdwl_ipc_output_v2_set_client_tags(dwl_ipc_output, and, xor);
248 zdwl_ipc_output_v2_set_client_tags(dwl_ipc_output, and, xor);
249 }
249 }
250 wl_display_flush(display);
250 wl_display_flush(display);
251 exit(0);
251 exit(0);
252 } else {
252 } else {
253 if (Fflag && mode == WATCH && focused_output)
253 if (Fflag && mode == WATCH && focused_output)
254 printf("focusmon %s\n", focused_output);
254 printf("focusmon %s\n", focused_output);
255 if (tflag) {
255 if (tflag) {
256 if (data) printf("%s ", (char *)data);
256 if (data) printf("%s ", (char *)data);
257 printf("tags %u %u %u %u\n", occ, seltags, sel, urg);
257 printf("tags %u %u %u %u\n", occ, seltags, sel, urg);
258 occ = seltags = sel = urg = 0;
258 occ = seltags = sel = urg = 0;
259 }
259 }
260 }
260 }
261 fflush(stdout);
261 fflush(stdout);
262 }
262 }
263
263
264 static const struct zdwl_ipc_output_v2_listener dwl_ipc_output_listener = {
264 static const struct zdwl_ipc_output_v2_listener dwl_ipc_output_listener = {
265 .toggle_visibility = dwl_ipc_output_toggle_visibility,
265 .toggle_visibility = dwl_ipc_output_toggle_visibility,
266 .active = dwl_ipc_output_active,
266 .active = dwl_ipc_output_active,
267 .tag = dwl_ipc_output_tag,
267 .tag = dwl_ipc_output_tag,
268 .layout = dwl_ipc_output_layout,
268 .layout = dwl_ipc_output_layout,
269 .title = dwl_ipc_output_title,
269 .title = dwl_ipc_output_title,
270 .appid = dwl_ipc_output_appid,
270 .appid = dwl_ipc_output_appid,
271 .layout_symbol = dwl_ipc_output_layout_symbol,
271 .layout_symbol = dwl_ipc_output_layout_symbol,
272 .fullscreen = dwl_ipc_output_fullscreen,
272 .fullscreen = dwl_ipc_output_fullscreen,
273 .floating = dwl_ipc_output_floating,
273 .floating = dwl_ipc_output_floating,
274 .frame = dwl_ipc_output_frame,
274 .frame = dwl_ipc_output_frame,
275 };
275 };
276
276
277 static void
277 static void
278 wl_output_name(void *data, struct wl_output *output, const char *name)
278 wl_output_name(void *data, struct wl_output *output, const char *name)
279 {
279 {
280 if (outputs) {
280 if (outputs) {
281 struct output *o = (struct output *)data;
281 struct output *o = (struct output *)data;
282 o->output_name = strdup(name);
282 o->output_name = strdup(name);
283 printf("+ ");
283 printf("+ ");
284 }
284 }
285 if (Oflag) printf("%s\n", name);
285 if (Oflag) printf("%s\n", name);
286 if (output_name && *output_name && strcmp(output_name, name) != 0) {
286 if (output_name && *output_name && strcmp(output_name, name) != 0) {
287 wl_output_release(output);
287 wl_output_release(output);
288 return;
288 return;
289 }
289 }
290 if (dwl_ipc_manager) {
290 if (dwl_ipc_manager) {
291 struct zdwl_ipc_output_v2 *dwl_ipc_output =
291 struct zdwl_ipc_output_v2 *dwl_ipc_output =
292 zdwl_ipc_manager_v2_get_output(dwl_ipc_manager, output);
292 zdwl_ipc_manager_v2_get_output(dwl_ipc_manager, output);
293 zdwl_ipc_output_v2_add_listener(dwl_ipc_output, &dwl_ipc_output_listener,
293 zdwl_ipc_output_v2_add_listener(dwl_ipc_output, &dwl_ipc_output_listener,
294 output_name && *output_name ? NULL : strdup(name));
294 output_name && *output_name ? NULL : strdup(name));
295 }
295 }
296 }
296 }
297
297
298 static void
298 static void
299 wl_output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t w, int32_t h, int32_t subpixel, const char *make, const char *model, int32_t transform) {
299 wl_output_geometry(void *data, struct wl_output *wl_output, int32_t x, int32_t y, int32_t w, int32_t h, int32_t subpixel, const char *make, const char *model, int32_t transform) {
300 }
300 }
301
301
302 static void
302 static void
303 wl_output_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh)
303 wl_output_mode(void *data, struct wl_output *wl_output, uint32_t flags, int32_t width, int32_t height, int32_t refresh)
304 {
304 {
305 }
305 }
306
306
307 static void
307 static void
308 wl_output_done(void *data, struct wl_output *wl_output)
308 wl_output_done(void *data, struct wl_output *wl_output)
309 {
309 {
310 }
310 }
311
311
312 static void
312 static void
313 wl_output_scale(void *data, struct wl_output *wl_output, int32_t factor)
313 wl_output_scale(void *data, struct wl_output *wl_output, int32_t factor)
314 {
314 {
315 }
315 }
316
316
317 static void
317 static void
318 wl_output_description(void *data, struct wl_output *output, const char *description)
318 wl_output_description(void *data, struct wl_output *output, const char *description)
319 {
319 {
320 }
320 }
321
321
322 static const struct wl_output_listener output_listener = {
322 static const struct wl_output_listener output_listener = {
323 .geometry = wl_output_geometry,
323 .geometry = wl_output_geometry,
324 .mode = wl_output_mode,
324 .mode = wl_output_mode,
325 .done = wl_output_done,
325 .done = wl_output_done,
326 .scale = wl_output_scale,
326 .scale = wl_output_scale,
327 .name = wl_output_name,
327 .name = wl_output_name,
328 .description = wl_output_description,
328 .description = wl_output_description,
329 };
329 };
330
330
331 static void
331 static void
332 global_add(void *data, struct wl_registry *wl_registry,
332 global_add(void *data, struct wl_registry *wl_registry,
333 uint32_t name, const char *interface, uint32_t version)
333 uint32_t name, const char *interface, uint32_t version)
334 {
334 {
335 if (strcmp(interface, wl_output_interface.name) == 0) {
335 if (strcmp(interface, wl_output_interface.name) == 0) {
336 struct wl_output *o = wl_registry_bind(
336 struct wl_output *o = wl_registry_bind(
337 wl_registry, name, &wl_output_interface,
337 wl_registry, name, &wl_output_interface,
338 WL_OUTPUT_NAME_SINCE_VERSION);
338 WL_OUTPUT_NAME_SINCE_VERSION);
339 wl_output_add_listener(o, &output_listener, outputs ? &outputs[outputcount] : NULL);
339 wl_output_add_listener(o, &output_listener, outputs ? &outputs[outputcount] : NULL);
340 if (!outputs) return;
340 if (!outputs) return;
341 if (outputcount >= outputs_buflen) {
341 if (outputcount >= outputs_buflen) {
342 outputs_buflen *= 2;
342 outputs_buflen *= 2;
343 outputs = reallocarray(outputs, outputs_buflen, sizeof(struct output));
343 outputs = reallocarray(outputs, outputs_buflen, sizeof(struct output));
344 }
344 }
345 outputs[outputcount].name = name;
345 outputs[outputcount].name = name;
346 outputcount++;
346 outputcount++;
347 } else if (strcmp(interface, zdwl_ipc_manager_v2_interface.name) == 0) {
347 } else if (strcmp(interface, zdwl_ipc_manager_v2_interface.name) == 0) {
348 dwl_ipc_manager = wl_registry_bind(wl_registry, name,
348 dwl_ipc_manager = wl_registry_bind(wl_registry, name,
349 &zdwl_ipc_manager_v2_interface, version < 2 ? version : 2);
349 &zdwl_ipc_manager_v2_interface, version < 2 ? version : 2);
350 zdwl_ipc_manager_v2_add_listener(dwl_ipc_manager, &dwl_ipc_listener, NULL);
350 zdwl_ipc_manager_v2_add_listener(dwl_ipc_manager, &dwl_ipc_listener, NULL);
351 }
351 }
352 }
352 }
353
353
354 static void
354 static void
355 global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
355 global_remove(void *data, struct wl_registry *wl_registry, uint32_t name)
356 {
356 {
357 if (!outputs) return;
357 if (!outputs) return;
358 for (size_t i = 0; i < outputcount; i++) {
358 for (size_t i = 0; i < outputcount; i++) {
359 if (outputs[i].name == name) {
359 if (outputs[i].name == name) {
360 printf("- %s\n", outputs[i].output_name);
360 printf("- %s\n", outputs[i].output_name);
361 free(outputs[i].output_name);
361 free(outputs[i].output_name);
362 outputs[i] = outputs[--outputcount];
362 outputs[i] = outputs[--outputcount];
363 }
363 }
364 }
364 }
365 }
365 }
366
366
367 static const struct wl_registry_listener registry_listener = {
367 static const struct wl_registry_listener registry_listener = {
368 .global = global_add,
368 .global = global_add,
369 .global_remove = global_remove,
369 .global_remove = global_remove,
370 };
370 };
371
371
372 static void
372 static void
373 usage(int code)
373 usage(int code)
374 {
374 {
375 fprintf(code ? stderr : stdout,
375 fprintf(code ? stderr : stdout,
376 "usage:"
376 "usage:"
377 "\t%1$s [-OTLPF]\n"
377 "\t%1$s [-OTLPF]\n"
378 "\t%1$s [-o <output>] -s [-t <tags>] [-l <layout>] [-c <tags>]\n"
378 "\t%1$s [-o <output>] -s [-t <tags>] [-l <layout>] [-c <tags>]\n"
379 "\t%1$s [-o <output>] (-g | -w) [-FOotlcvmf]\n",
379 "\t%1$s [-o <output>] (-g | -w) [-FOotlcvmf]\n",
380 argv0);
380 argv0);
381 exit(code);
381 exit(code);
382 }
382 }
383
383
384 int
384 int
385 main(int argc, char *argv[])
385 main(int argc, char *argv[])
386 {
386 {
387 ARGBEGIN {
387 ARGBEGIN {
388 case '?': case 'h':
388 case '?': case 'h':
389 usage(0); break;
389 usage(0); break;
390 case 's':
390 case 's':
391 if (mode != NONE) usage(1);
391 if (mode != NONE) usage(1);
392 mode = SET;
392 mode = SET;
393 break;
393 break;
394 case 'g':
394 case 'g':
395 if (mode != NONE) usage(1);
395 if (mode != NONE) usage(1);
396 mode = GET;
396 mode = GET;
397 break;
397 break;
398 case 'w':
398 case 'w':
399 if (mode != NONE) usage(1);
399 if (mode != NONE) usage(1);
400 mode = WATCH;
400 mode = WATCH;
401 break;
401 break;
402 case 'o':
402 case 'o':
403 if (mode & SET)
403 if (mode & SET)
404 output_name = EARGF(usage(1));
404 output_name = EARGF(usage(1));
405 else if (mode & GET || !(output_name = ARGF()))
405 else if (mode & GET || !(output_name = ARGF()))
406 oflag = 1;
406 oflag = 1;
407 break;
407 break;
408 case 't':
408 case 't':
409 tflag = 1;
409 tflag = 1;
410 if (mode & GET) break;
410 if (mode & GET) break;
411 mode = SET;
411 mode = SET;
412 tagset = EARGF(usage(1));
412 tagset = EARGF(usage(1));
413 break;
413 break;
414 case 'l':
414 case 'l':
415 lflag = 1;
415 lflag = 1;
416 if (mode & GET) break;
416 if (mode & GET) break;
417 mode = SET;
417 mode = SET;
418 layout_name = EARGF(usage(1));
418 layout_name = EARGF(usage(1));
419 break;
419 break;
420 case 'c':
420 case 'c':
421 cflag = 1;
421 cflag = 1;
422 if (mode & GET) break;
422 if (mode & GET) break;
423 mode = SET;
423 mode = SET;
424 client_tags = EARGF(usage(1));
424 client_tags = EARGF(usage(1));
425 break;
425 break;
426 case 'O':
426 case 'O':
427 Oflag = 1;
427 Oflag = 1;
428 if (mode & SET) usage(1);
428 if (mode & SET) usage(1);
429 if (mode & WATCH)
429 if (mode & WATCH)
430 outputs = malloc(outputs_buflen * sizeof(struct output));
430 outputs = malloc(outputs_buflen * sizeof(struct output));
431 else
431 else
432 mode = GET;
432 mode = GET;
433 break;
433 break;
434 case 'T':
434 case 'T':
435 Tflag = 1;
435 Tflag = 1;
436 if (mode && mode != GET) usage(1);
436 if (mode && mode != GET) usage(1);
437 mode = GET;
437 mode = GET;
438 break;
438 break;
439 case 'L':
439 case 'L':
440 Lflag = 1;
440 Lflag = 1;
441 if (mode && mode != GET) usage(1);
441 if (mode && mode != GET) usage(1);
442 mode = GET;
442 mode = GET;
443 break;
443 break;
444 case 'P':
444 case 'P':
445 Pflag = 1;
445 Pflag = 1;
446 if (mode && mode != GET) usage(1);
446 if (mode && mode != GET) usage(1);
447 mode = GET;
447 mode = GET;
448 break;
448 break;
449 case 'F':
449 case 'F':
450 Fflag = 1;
450 Fflag = 1;
451 if (mode && mode != GET) usage(1);
451 if (mode && mode != GET) usage(1);
452 mode = GET;
452 mode = GET;
453 break;
453 break;
454 case 'v':
454 case 'v':
455 vflag = 1;
455 vflag = 1;
456 if (mode & SET) usage(1);
456 if (mode & SET) usage(1);
457 mode |= GET;
457 mode |= GET;
458 break;
458 break;
459 case 'm':
459 case 'm':
460 mflag = 1;
460 mflag = 1;
461 if (mode & SET) usage(1);
461 if (mode & SET) usage(1);
462 mode |= GET;
462 mode |= GET;
463 break;
463 break;
464 case 'f':
464 case 'f':
465 fflag = 1;
465 fflag = 1;
466 if (mode & SET) usage(1);
466 if (mode & SET) usage(1);
467 mode |= GET;
467 mode |= GET;
468 break;
468 break;
469 default:
469 default:
470 fprintf(stderr, "%s: bad option: -%c\n", argv0, ARGC());
470 fprintf(stderr, "%s: bad option: -%c\n", argv0, ARGC());
471 usage(1);
471 usage(1);
472 } ARGEND
472 } ARGEND
473 if (argc > 0) {
473 if (argc > 0) {
474 fprintf(stderr, "%s: bad args:", argv0);
474 fprintf(stderr, "%s: bad args:", argv0);
475 for (; *argv; argv++)
475 for (; *argv; argv++)
476 fprintf(stderr, " %s", argv[0]);
476 fprintf(stderr, " %s", argv[0]);
477 fprintf(stderr, "\n");
477 fprintf(stderr, "\n");
478 usage(1);
478 usage(1);
479 }
479 }
480 if (mode == NONE) usage(1);
480 if (mode == NONE) usage(1);
481 if (mode & GET && !(oflag || tflag || lflag || Oflag || Tflag || Lflag || Pflag || Fflag || cflag || vflag || mflag || fflag))
481 if (mode & GET && !(oflag || tflag || lflag || Oflag || Tflag || Lflag || Pflag || Fflag || cflag || vflag || mflag || fflag))
482 oflag = tflag = lflag = cflag = vflag = mflag = fflag = Fflag = 1;
482 oflag = tflag = lflag = cflag = vflag = mflag = fflag = Fflag = 1;
483
483
484 display = wl_display_connect(NULL);
484 display = wl_display_connect(NULL);
485 if (!display) die("bad display");
485 if (!display) die("bad display");
486
486
487 if (Pflag) {
487 if (Pflag) {
488 int fd = wl_display_get_fd(display);
488 int fd = wl_display_get_fd(display);
489 struct ucred ucred;
489 struct ucred ucred;
490 socklen_t len = sizeof(struct ucred);
490 socklen_t len = sizeof(struct ucred);
491 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1)
491 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &len) == -1)
492 die("bad getsockopt");
492 die("bad getsockopt");
493 printf("%d\n", ucred.pid);
493 printf("%d\n", ucred.pid);
494 }
494 }
495
495
496 registry = wl_display_get_registry(display);
496 registry = wl_display_get_registry(display);
497 if (!registry) die("bad registry");
497 if (!registry) die("bad registry");
498
498
499 wl_registry_add_listener(registry, &registry_listener, NULL);
499 wl_registry_add_listener(registry, &registry_listener, NULL);
500
500
501 wl_display_dispatch(display);
501 wl_display_dispatch(display);
502 wl_display_roundtrip(display);
502 wl_display_roundtrip(display);
503
503
504 if (!dwl_ipc_manager && (mode & SET || tflag || lflag || Tflag || Lflag || cflag || vflag || mflag || fflag))
504 if (!dwl_ipc_manager && (mode & SET || tflag || lflag || Tflag || Lflag || cflag || vflag || mflag || fflag))
505 die("bad dwl-ipc protocol");
505 die("bad dwl-ipc protocol");
506
506
507 wl_display_roundtrip(display);
507 wl_display_roundtrip(display);
508
508
509 if (Fflag && !(mode == WATCH) && focused_output)
509 if (Fflag && !(mode == WATCH) && focused_output)
510 printf("focusmon %s\n", focused_output);
510 printf("focusmon %s\n", focused_output);
511
511
512 if (mode == WATCH)
512 if (mode == WATCH)
513 while (wl_display_dispatch(display) != -1);
513 while (wl_display_dispatch(display) != -1);
514
514
515 return 0;
515 return 0;
516 }
516 }
General Comments 0
You need to be logged in to leave comments. Login now