Implement swaygrab for still images

master
Drew DeVault 9 years ago
parent 062c74b7d0
commit f05b6cd55c

@ -81,4 +81,4 @@ source contributors. For more information about sway development, see
See Also See Also
-------- --------
**sway**(5) **sway**(5) **swaymsg**(1) **swaygrab**(1)

@ -31,6 +31,15 @@ Options
Use the specified socket path. Otherwise, swaymsg will ask sway where the Use the specified socket path. Otherwise, swaymsg will ask sway where the
socket is (which is the value of $SWAYSOCK, then of $I3SOCK). socket is (which is the value of $SWAYSOCK, then of $I3SOCK).
Examples
--------
swaygrab HDMI-A-1 output.png::
Grab the contents of HDMI-A-1 and write to output.png.
swaygrab -c HDMI-A-1 output.webm::
Capture a webm of HDMI-A-1.
Authors Authors
------- -------

@ -1,5 +1,9 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include <unistd.h>
#include <math.h>
#include "log.h" #include "log.h"
#include "ipc-client.h" #include "ipc-client.h"
@ -7,8 +11,42 @@ void sway_terminate(void) {
exit(1); exit(1);
} }
int main(int argc, const char **argv) { int numlen(int n) {
int capture; if (n >= 1000000) return 7;
if (n >= 100000) return 6;
if (n >= 10000) return 5;
if (n >= 1000) return 4;
if (n >= 100) return 3;
if (n >= 10) return 2;
return 1;
}
void grab_and_apply_magick(const char *file, const char *output, int socketfd) {
uint32_t len = strlen(output);
char *pixels = ipc_single_command(socketfd,
IPC_SWAY_GET_PIXELS, output, &len);
uint32_t *u32pixels = (uint32_t *)(pixels + 1);
uint32_t width = u32pixels[0];
uint32_t height = u32pixels[1];
pixels += 9;
if (width == 0 || height == 0) {
sway_abort("Unknown output %s.", output);
}
const char *fmt = "convert -depth 8 -size %dx%d+0 rgba:- -flip %s";
char *cmd = malloc(strlen(fmt) - 6 /*args*/
+ numlen(width) + numlen(height) + strlen(file) + 1);
sprintf(cmd, fmt, width, height, file);
FILE *f = popen(cmd, "w");
fwrite(pixels, 1, len, f);
fflush(f);
fclose(f);
}
int main(int argc, char **argv) {
static int capture = 0;
char *socket_path = NULL; char *socket_path = NULL;
init_log(L_INFO); init_log(L_INFO);
@ -51,15 +89,21 @@ int main(int argc, const char **argv) {
} }
} }
if (optind >= argc) { if (optind >= argc - 1) {
sway_abort("Expected output file on command line. See `man swaygrab`"); sway_abort("Expected output and file on command line. See `man swaygrab`");
} }
char *out = argv[optind]; char *file = argv[optind + 1];
char *output = argv[optind];
int socketfd = ipc_open_socket(socket_path); int socketfd = ipc_open_socket(socket_path);
free(socket_path); free(socket_path);
if (!capture) {
grab_and_apply_magick(file, output, socketfd);
} else {
sway_abort("Capture is not yet supported");
}
close(socketfd); close(socketfd);
free(out);
return 0; return 0;
} }

Loading…
Cancel
Save