summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Drew DeVault <sir@cmpwn.com>2016-03-24 20:06:43 -0400
committerLibravatar Drew DeVault <sir@cmpwn.com>2016-03-24 20:06:43 -0400
commit56838587e1db6ba9b1143dea6559734abf4ddbbe (patch)
tree12cb9bfc354f7783f678ab29e9e0d3fda90d5530
parentCMake: add missing wlc include dir for common and swaygrab (diff)
parentReplace with in swaylock (diff)
downloadsway-56838587e1db6ba9b1143dea6559734abf4ddbbe.tar.gz
sway-56838587e1db6ba9b1143dea6559734abf4ddbbe.tar.zst
sway-56838587e1db6ba9b1143dea6559734abf4ddbbe.zip
Merge pull request #538 from nuew/display-images
Add choice of display to --image.
-rw-r--r--swaylock/CMakeLists.txt2
-rw-r--r--swaylock/main.c156
-rw-r--r--swaylock/swaylock.1.txt12
3 files changed, 132 insertions, 38 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..8f0eddb3 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,34 @@ 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 sway_abort("Failed to load background image: %s", err->message);
217 }
218 image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf);
219 g_object_unref(pixbuf);
220#else
221 image = cairo_image_surface_create_from_png(image_path);
222#endif //WITH_GDK_PIXBUF
223 if (!image) {
224 sway_abort("Failed to read background image.");
225 }
206 226
207 window_render(window); 227 return image;
208} 228}
209 229
210int main(int argc, char **argv) { 230int main(int argc, char **argv) {
211 char *image_path = NULL; 231 char *scaling_mode_str = "fit", *socket_path = NULL;
212 char *scaling_mode_str = "fit"; 232 int i, num_images = 0, color_set = 0;
213 uint32_t color = 0xFFFFFFFF; 233 uint32_t color = 0xFFFFFFFF;
234 void *images;
214 235
215 init_log(L_INFO); 236 init_log(L_INFO);
216 237
@@ -221,18 +242,22 @@ int main(int argc, char **argv) {
221 {"scaling", required_argument, NULL, 's'}, 242 {"scaling", required_argument, NULL, 's'},
222 {"tiling", no_argument, NULL, 't'}, 243 {"tiling", no_argument, NULL, 't'},
223 {"version", no_argument, NULL, 'v'}, 244 {"version", no_argument, NULL, 'v'},
245 {"socket", required_argument, NULL, 'p'},
224 {0, 0, 0, 0} 246 {0, 0, 0, 0}
225 }; 247 };
226 248
227 const char *usage = 249 const char *usage =
228 "Usage: swaylock [options...]\n" 250 "Usage: swaylock [options...]\n"
229 "\n" 251 "\n"
230 " -h, --help Show help message and quit.\n" 252 " -h, --help Show help message and quit.\n"
231 " -c, --color <rrggbb[aa]> Turn the screen into the given color instead of white.\n" 253 " -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" 254 " -s, --scaling Scaling mode: stretch, fill, fit, center, tile.\n"
233 " -t, --tiling Same as --scaling=tile.\n" 255 " -t, --tiling Same as --scaling=tile.\n"
234 " -v, --version Show the version number and quit.\n" 256 " -v, --version Show the version number and quit.\n"
235 " -i, --image <path> Display the given image.\n"; 257 " -i, --image [<output>:]<path> Display the given image.\n"
258 " --socket <socket> Use the specified socket.\n";
259
260 registry = registry_poll();
236 261
237 int c; 262 int c;
238 while (1) { 263 while (1) {
@@ -246,10 +271,11 @@ int main(int argc, char **argv) {
246 { 271 {
247 int colorlen = strlen(optarg); 272 int colorlen = strlen(optarg);
248 if (colorlen < 6 || colorlen == 7 || colorlen > 8) { 273 if (colorlen < 6 || colorlen == 7 || colorlen > 8) {
249 fprintf(stderr, "color must be specified in 3 or 4 byte format, e.g. ff0000 or ff0000ff\n"); 274 sway_log(L_ERROR, "color must be specified in 3 or 4 byte format, e.g. ff0000 or ff0000ff");
250 exit(EXIT_FAILURE); 275 exit(EXIT_FAILURE);
251 } 276 }
252 color = strtol(optarg, NULL, 16); 277 color = strtol(optarg, NULL, 16);
278 color_set = 1;
253 279
254 if (colorlen == 6) { 280 if (colorlen == 6) {
255 color <<= 8; 281 color <<= 8;
@@ -259,14 +285,39 @@ int main(int argc, char **argv) {
259 break; 285 break;
260 } 286 }
261 case 'i': 287 case 'i':
262 image_path = optarg; 288 {
289 char *image_path = strchr(optarg, ':');
290 if (image_path == NULL) {
291 if (num_images == 0) {
292 images = load_image(optarg);
293 num_images = -1;
294 } else {
295 sway_log(L_ERROR, "output must be defined for all --images or no --images");
296 exit(EXIT_FAILURE);
297 }
298 } else {
299 if (num_images == 0) {
300 images = calloc(registry->outputs->length, sizeof(char*) * 2);
301 } else if (num_images == -1) {
302 sway_log(L_ERROR, "output must be defined for all --images or no --images");
303 exit(EXIT_FAILURE);
304 }
305
306 image_path[0] = '\0';
307 ((char**) images)[num_images * 2] = optarg;
308 ((char**) images)[num_images++ * 2 + 1] = ++image_path;
309 }
263 break; 310 break;
311 }
264 case 's': 312 case 's':
265 scaling_mode_str = optarg; 313 scaling_mode_str = optarg;
266 break; 314 break;
267 case 't': 315 case 't':
268 scaling_mode_str = "tile"; 316 scaling_mode_str = "tile";
269 break; 317 break;
318 case 'p':
319 socket_path = optarg;
320 break;
270 case 'v': 321 case 'v':
271#if defined SWAY_GIT_VERSION && defined SWAY_GIT_BRANCH && defined SWAY_VERSION_DATE 322#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); 323 fprintf(stdout, "swaylock version %s (%s, branch \"%s\")\n", SWAY_GIT_VERSION, SWAY_VERSION_DATE, SWAY_GIT_BRANCH);
@@ -300,7 +351,12 @@ int main(int argc, char **argv) {
300 password = malloc(password_size); 351 password = malloc(password_size);
301 password[0] = '\0'; 352 password[0] = '\0';
302 surfaces = create_list(); 353 surfaces = create_list();
303 registry = registry_poll(); 354 if (!socket_path) {
355 socket_path = get_socketpath();
356 if (!socket_path) {
357 sway_abort("Unable to retrieve socket path");
358 }
359 }
304 360
305 if (!registry) { 361 if (!registry) {
306 sway_abort("Unable to connect to wayland compositor"); 362 sway_abort("Unable to connect to wayland compositor");
@@ -316,7 +372,6 @@ int main(int argc, char **argv) {
316 registry->pointer = NULL; 372 registry->pointer = NULL;
317 } 373 }
318 374
319 int i;
320 for (i = 0; i < registry->outputs->length; ++i) { 375 for (i = 0; i < registry->outputs->length; ++i) {
321 struct output_state *output = registry->outputs->items[i]; 376 struct output_state *output = registry->outputs->items[i];
322 struct window *window = window_setup(registry, output->width, output->height, true); 377 struct window *window = window_setup(registry, output->width, output->height, true);
@@ -328,23 +383,38 @@ int main(int argc, char **argv) {
328 383
329 registry->input->notify = notify_key; 384 registry->input->notify = notify_key;
330 385
331 cairo_surface_t *image = NULL; 386 if (num_images >= 1) {
332 387 char **displays_paths = images;
333 if (image_path) { 388 images = calloc(registry->outputs->length, sizeof(cairo_surface_t*));
334#ifdef WITH_GDK_PIXBUF 389
335 GError *err = NULL; 390 int socketfd = ipc_open_socket(socket_path);
336 GdkPixbuf *pixbuf = gdk_pixbuf_new_from_file(image_path, &err); 391 uint32_t len = 0;
337 if (!pixbuf) { 392 char *outputs = ipc_single_command(socketfd, IPC_GET_OUTPUTS, "", &len);
338 sway_abort("Failed to load background image."); 393 struct json_object *json_outputs = json_tokener_parse(outputs);
339 } 394
340 image = gdk_cairo_image_surface_create_from_pixbuf(pixbuf); 395 for (i = 0; i < registry->outputs->length; ++i) {
341 g_object_unref(pixbuf); 396 if (displays_paths[i * 2] != NULL) {
342#else 397 for (int j = 0;; ++j) {
343 cairo_surface_t *image = cairo_image_surface_create_from_png(argv[1]); 398 if (j >= json_object_array_length(json_outputs)) {
344#endif //WITH_GDK_PIXBUF 399 sway_log(L_ERROR, "%s is not an extant output", displays_paths[i * 2]);
345 if (!image) { 400 exit(EXIT_FAILURE);
346 sway_abort("Failed to read background image."); 401 }
402
403 struct json_object *dsp_name, *at_j = json_object_array_get_idx(json_outputs, j);
404 if (!json_object_object_get_ex(at_j, "name", &dsp_name)) {
405 sway_abort("output doesn't have a name field");
406 }
407 if (!strcmp(displays_paths[i * 2], json_object_get_string(dsp_name))) {
408 ((cairo_surface_t**) images)[j] = load_image(displays_paths[i * 2 + 1]);
409 break;
410 }
411 }
412 }
347 } 413 }
414
415 json_object_put(json_outputs);
416 close(socketfd);
417 free(displays_paths);
348 } 418 }
349 419
350 for (i = 0; i < surfaces->length; ++i) { 420 for (i = 0; i < surfaces->length; ++i) {
@@ -352,15 +422,31 @@ int main(int argc, char **argv) {
352 if (!window_prerender(window) || !window->cairo) { 422 if (!window_prerender(window) || !window->cairo) {
353 continue; 423 continue;
354 } 424 }
355 if (image) { 425
356 render_image(window, image, scaling_mode); 426 if (num_images == 0 || color_set) {
357 } else {
358 render_color(window, color); 427 render_color(window, color);
359 } 428 }
429
430 if (num_images == -1) {
431 render_image(window, images, scaling_mode);
432 } else if (num_images >= 1) {
433 if (((cairo_surface_t**) images)[i] != NULL) {
434 render_image(window, ((cairo_surface_t**) images)[i], scaling_mode);
435 }
436 }
437
438 window_render(window);
360 } 439 }
361 440
362 if (image) { 441 if (num_images == -1) {
363 cairo_surface_destroy(image); 442 cairo_surface_destroy((cairo_surface_t*) images);
443 } else if (num_images >= 1) {
444 for (i = 0; i < registry->outputs->length; ++i) {
445 if (((cairo_surface_t**) images)[i] != NULL) {
446 cairo_surface_destroy(((cairo_surface_t**) images)[i]);
447 }
448 }
449 free(images);
364 } 450 }
365 451
366 bool locked = false; 452 bool locked = false;
diff --git a/swaylock/swaylock.1.txt b/swaylock/swaylock.1.txt
index 04594fd0..c30e8d3d 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* [<output>:]<path>::
29 Display the given image. 30 Display the given image, optionally only on the given output.
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