summaryrefslogtreecommitdiffstats
path: root/swaylock
diff options
context:
space:
mode:
authorLibravatar Nuew <code@nuew.net>2016-03-24 18:02:34 -0400
committerLibravatar Nuew <code@nuew.net>2016-03-24 18:02:34 -0400
commit0aa4383c9a1b3b693ee771e7829ed84582b4577c (patch)
tree4bc6746cabaedeae60ffeeb0f082c4c850487062 /swaylock
parentMerge pull request #537 from mikkeloscar/exit-on-config-missing (diff)
downloadsway-0aa4383c9a1b3b693ee771e7829ed84582b4577c.tar.gz
sway-0aa4383c9a1b3b693ee771e7829ed84582b4577c.tar.zst
sway-0aa4383c9a1b3b693ee771e7829ed84582b4577c.zip
Add choice of display to --image.
Additionally - Made background colors display when an image is enabled if a --color is specified. - Link CJson to swaylock. - Add the --socket option to swaylock.
Diffstat (limited to 'swaylock')
-rw-r--r--swaylock/CMakeLists.txt2
-rw-r--r--swaylock/main.c155
-rw-r--r--swaylock/swaylock.1.txt12
3 files changed, 132 insertions, 37 deletions
diff --git a/swaylock/CMakeLists.txt b/swaylock/CMakeLists.txt
index 08c893ca..b290cd2f 100644
--- a/swaylock/CMakeLists.txt
+++ b/swaylock/CMakeLists.txt
@@ -4,6 +4,7 @@ include_directories(
4 ${CAIRO_INCLUDE_DIRS} 4 ${CAIRO_INCLUDE_DIRS}
5 ${PANGO_INCLUDE_DIRS} 5 ${PANGO_INCLUDE_DIRS}
6 ${PAM_INCLUDE_DIRS} 6 ${PAM_INCLUDE_DIRS}
7 ${JSONC_INCLUDE_DIRS}
7) 8)
8 9
9add_executable(swaylock 10add_executable(swaylock
@@ -18,6 +19,7 @@ target_link_libraries(swaylock
18 ${CAIRO_LIBRARIES} 19 ${CAIRO_LIBRARIES}
19 ${PANGO_LIBRARIES} 20 ${PANGO_LIBRARIES}
20 ${PAM_LIBRARIES} 21 ${PAM_LIBRARIES}
22 ${JSONC_LIBRARIES}
21 m 23 m
22) 24)
23 25
diff --git a/swaylock/main.c b/swaylock/main.c
index feb64975..7f4c424d 100644
--- a/swaylock/main.c
+++ b/swaylock/main.c
@@ -2,6 +2,7 @@
2#include <xkbcommon/xkbcommon.h> 2#include <xkbcommon/xkbcommon.h>
3#include <xkbcommon/xkbcommon-names.h> 3#include <xkbcommon/xkbcommon-names.h>
4#include <security/pam_appl.h> 4#include <security/pam_appl.h>
5#include <json-c/json.h>
5#include <stdio.h> 6#include <stdio.h>
6#include <stdlib.h> 7#include <stdlib.h>
7#include <string.h> 8#include <string.h>
@@ -11,6 +12,7 @@
11#include "client/window.h" 12#include "client/window.h"
12#include "client/registry.h" 13#include "client/registry.h"
13#include "client/cairo.h" 14#include "client/cairo.h"
15#include "ipc-client.h"
14#include "log.h" 16#include "log.h"
15 17
16list_t *surfaces; 18list_t *surfaces;
@@ -134,7 +136,6 @@ void notify_key(enum wl_keyboard_key_state state, xkb_keysym_t sym, uint32_t cod
134void render_color(struct window *window, uint32_t color) { 136void render_color(struct window *window, uint32_t color) {
135 cairo_set_source_u32(window->cairo, color); 137 cairo_set_source_u32(window->cairo, color);
136 cairo_paint(window->cairo); 138 cairo_paint(window->cairo);
137 window_render(window);
138} 139}
139 140
140void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) { 141void render_image(struct window *window, cairo_surface_t *image, enum scaling_mode scaling_mode) {
@@ -203,14 +204,35 @@ void render_image(struct window *window, cairo_surface_t *image, enum scaling_mo
203 } 204 }
204 205
205 cairo_paint(window->cairo); 206 cairo_paint(window->cairo);
207}
208
209cairo_surface_t *load_image(char *image_path) {
210 cairo_surface_t *image = NULL;
211
212#ifdef WITH_GDK_PIXBUF
213 GError *err = NULL;
214 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(image_path, &err);
215 if (!pixbuf) {
216 fprintf(stderr, "GDK Error: %s\n", err->message);
217 sway_abort("Failed to load background image.");
218 }
219 image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
220 g_object_unref(pixbuf);
221#else
222 image = cairo_image_surface_create_from_png(image_path);
223#endif //WITH_GDK_PIXBUF
224 if (!image) {
225 sway_abort("Failed to read background image.");
226 }
206 227
207 window_render(window); 228 return image;
208} 229}
209 230
210int main(int argc, char **argv) { 231int main(int argc, char **argv) {
211 char *image_path = NULL; 232 char *scaling_mode_str = "fit", *socket_path = NULL;
212 char *scaling_mode_str = "fit"; 233 int i, num_images = 0, color_set = 0;
213 uint32_t color = 0xFFFFFFFF; 234 uint32_t color = 0xFFFFFFFF;
235 void *images;
214 236
215 init_log(L_INFO); 237 init_log(L_INFO);
216 238
@@ -221,18 +243,22 @@ int main(int argc, char **argv) {
221 {"scaling", required_argument, NULL, 's'}, 243 {"scaling", required_argument, NULL, 's'},
222 {"tiling", no_argument, NULL, 't'}, 244 {"tiling", no_argument, NULL, 't'},
223 {"version", no_argument, NULL, 'v'}, 245 {"version", no_argument, NULL, 'v'},
246 {"socket", required_argument, NULL, 'p'},
224 {0, 0, 0, 0} 247 {0, 0, 0, 0}
225 }; 248 };
226 249
227 const char *usage = 250 const char *usage =
228 "Usage: swaylock [options...]\n" 251 "Usage: swaylock [options...]\n"
229 "\n" 252 "\n"
230 " -h, --help Show help message and quit.\n" 253 " -h, --help Show help message and quit.\n"
231 " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n" 254 " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n"
232 " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n" 255 " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n"
233 " -t, --tiling Same as --scaling=tile.\n" 256 " -t, --tiling Same as --scaling=tile.\n"
234 " -v, --version Show the version number and quit.\n" 257 " -v, --version Show the version number and quit.\n"
235 " -i, --image <path> Display the given image.\n"; 258 " -i, --image [<display>:]<path> Display the given image.\n"
259 " --socket <socket> Use the specified socket.\n";
260
261 registry = registry_poll();
236 262
237 int c; 263 int c;
238 while (1) { 264 while (1) {
@@ -250,6 +276,7 @@ int main(int argc, char **argv) {
250 exit(EXIT_FAILURE); 276 exit(EXIT_FAILURE);
251 } 277 }
252 color = strtol(optarg, NULL, 16); 278 color = strtol(optarg, NULL, 16);
279 color_set = 1;
253 280
254 if (colorlen == 6) { 281 if (colorlen == 6) {
255 color <<= 8; 282 color <<= 8;
@@ -259,14 +286,39 @@ int main(int argc, char **argv) {
259 break; 286 break;
260 } 287 }
261 case 'i': 288 case 'i':
262 image_path = optarg; 289 {
290 char *image_path = strchr(optarg, ':');
291 if (image_path == NULL) {
292 if (num_images == 0) {
293 images = load_image(optarg);
294 num_images = -1;
295 } else {
296 fprintf(stderr, "display must be defined for all --images or no --images.\n");
297 exit(EXIT_FAILURE);
298 }
299 } else {
300 if (num_images == 0) {
301 images = calloc(registry->outputs->length, sizeof(char*) * 2);
302 } else if (num_images == -1) {
303 fprintf(stderr, "display must be defined for all --images or no --images.\n");
304 exit(EXIT_FAILURE);
305 }
306
307 image_path[0] = '\0';
308 ((char**) images)[num_images * 2] = optarg;
309 ((char**) images)[num_images++ * 2 + 1] = ++image_path;
310 }
263 break; 311 break;
312 }
264 case 's': 313 case 's':
265 scaling_mode_str = optarg; 314 scaling_mode_str = optarg;
266 break; 315 break;
267 case 't': 316 case 't':
268 scaling_mode_str = "tile"; 317 scaling_mode_str = "tile";
269 break; 318 break;
319 case 'p':
320 socket_path = optarg;
321 break;
270 case 'v': 322 case 'v':
271#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE 323#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE
272 fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", SWAY_GIT_VERSION, SWAY_VERSION_DATE, SWAY_GIT_BRANCH); 324 fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", SWAY_GIT_VERSION, SWAY_VERSION_DATE, SWAY_GIT_BRANCH);
@@ -300,7 +352,12 @@ int main(int argc, char **argv) {
300 password = malloc(password_size); 352 password = malloc(password_size);
301 password[0] = '\0'; 353 password[0] = '\0';
302 surfaces = create_list(); 354 surfaces = create_list();
303 registry = registry_poll(); 355 if (!socket_path) {
356 socket_path = get_socketpath();
357 if (!socket_path) {
358 sway_abort("Unable to retrieve socket path");
359 }
360 }
304 361
305 if (!registry) { 362 if (!registry) {
306 sway_abort("Unable to connect to wayland compositor"); 363 sway_abort("Unable to connect to wayland compositor");
@@ -316,7 +373,6 @@ int main(int argc, char **argv) {
316 registry->pointer = NULL; 373 registry->pointer = NULL;
317 } 374 }
318 375
319 int i;
320 for (i = 0; i < registry->outputs->length; ++i) { 376 for (i = 0; i < registry->outputs->length; ++i) {
321 struct output_state *output = registry->outputs->items[i]; 377 struct output_state *output = registry->outputs->items[i];
322 struct window *window = window_setup(registry, output->width, output->height, true); 378 struct window *window = window_setup(registry, output->width, output->height, true);
@@ -328,23 +384,38 @@ int main(int argc, char **argv) {
328 384
329 registry->input->notify = notify_key; 385 registry->input->notify = notify_key;
330 386
331 cairo_surface_t *image = NULL; 387 if (num_images >= 1) {
332 388 char **displays_paths = images;
333 if (image_path) { 389 images = calloc(registry->outputs->length, sizeof(cairo_surface_t*));
334#ifdef WITH_GDK_PIXBUF 390
335 GError *err = NULL; 391 int socketfd = ipc_open_socket(socket_path);
336 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(image_path, &err); 392 uint32_t len = 0;
337 if (!pixbuf) { 393 char *outputs = ipc_single_command(socketfd, IPC_GET_OUTPUTS, "", &len);
338 sway_abort("Failed to load background image."); 394 struct json_object *json_outputs = json_tokener_parse(outputs);
339 } 395
340 image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf); 396 for (i = 0; i < registry->outputs->length; ++i) {
341 g_object_unref(pixbuf); 397 if (displays_paths[i * 2] != NULL) {
342#else 398 for (int j = 0;; ++j) {
343 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[1]); 399 if (j >= json_object_array_length(json_outputs)) {
344#endif //WITH_GDK_PIXBUF 400 fprintf(stderr, "%s is not an extant display\n", displays_paths[i * 2]);
345 if (!image) { 401 exit(EXIT_FAILURE);
346 sway_abort("Failed to read background image."); 402 }
403
404 struct json_object *dsp_name, *at_j = json_object_array_get_idx(json_outputs, j);
405 if (!json_object_object_get_ex(at_j, "name", &dsp_name)) {
406 sway_abort("display doesn't have a name field");
407 }
408 if (!strcmp(displays_paths[i * 2], json_object_get_string(dsp_name))) {
409 ((cairo_surface_t**) images)[j] = load_image(displays_paths[i * 2 + 1]);
410 break;
411 }
412 }
413 }
347 } 414 }
415
416 json_object_put(json_outputs);
417 close(socketfd);
418 free(displays_paths);
348 } 419 }
349 420
350 for (i = 0; i < surfaces->length; ++i) { 421 for (i = 0; i < surfaces->length; ++i) {
@@ -352,15 +423,31 @@ int main(int argc, char **argv) {
352 if (!window_prerender(window) || !window->cairo) { 423 if (!window_prerender(window) || !window->cairo) {
353 continue; 424 continue;
354 } 425 }
355 if (image) { 426
356 render_image(window, image, scaling_mode); 427 if (num_images == 0 || color_set) {
357 } else {
358 render_color(window, color); 428 render_color(window, color);
359 } 429 }
430
431 if (num_images == -1) {
432 render_image(window, images, scaling_mode);
433 } else if (num_images >= 1) {
434 if (((cairo_surface_t**) images)[i] != NULL) {
435 render_image(window, ((cairo_surface_t**) images)[i], scaling_mode);
436 }
437 }
438
439 window_render(window);
360 } 440 }
361 441
362 if (image) { 442 if (num_images == -1) {
363 cairo_surface_destroy(image); 443 cairo_surface_destroy((cairo_surface_t*) images);
444 } else if (num_images >= 1) {
445 for (i = 0; i < registry->outputs->length; ++i) {
446 if (((cairo_surface_t**) images)[i] != NULL) {
447 cairo_surface_destroy(((cairo_surface_t**) images)[i]);
448 }
449 }
450 free(images);
364 } 451 }
365 452
366 bool locked = false; 453 bool locked = false;
diff --git a/swaylock/swaylock.1.txt b/swaylock/swaylock.1.txt
index 04594fd0..724573ce 100644
--- a/swaylock/swaylock.1.txt
+++ b/swaylock/swaylock.1.txt
@@ -23,10 +23,11 @@ Options
23 Show help message and quit. 23 Show help message and quit.
24 24
25*-c, \--color* <rrggbb[aa]>:: 25*-c, \--color* <rrggbb[aa]>::
26 Turn the screen into the given color instead of white. 26 Turn the screen into the given color instead of white. If an image is in use,
27 also enables color display.
27 28
28*-i, \--image* <path>:: 29*-i, \--image* [<display>:]<path>::
29 Display the given image. 30 Display the given image, optionally only on the given display.
30 31
31*-s, \--scaling*:: 32*-s, \--scaling*::
32 Scaling mode for images: stretch, fill, fit, center, or tile. 33 Scaling mode for images: stretch, fill, fit, center, or tile.
@@ -37,6 +38,11 @@ Options
37*-v, \--version*:: 38*-v, \--version*::
38 Show the version number and quit. 39 Show the version number and quit.
39 40
41*--socket <path>*::
42 Use the specified socket path. Otherwise, swaymsg will ask sway where the
43 socket is (which is the value of $SWAYSOCK, then of $I3SOCK).
44
45
40Authors 46Authors
41------- 47-------
42 48