First attempt to implement screenshooter

This commit is contained in:
emersion 2017-09-08 18:09:09 +02:00
parent 1c8b72e0cd
commit 35f9700251
No known key found for this signature in database
GPG key ID: 0FDE7BE0E88F5E48
8 changed files with 360 additions and 1 deletions

View file

@ -247,3 +247,9 @@ uint16_t wlr_output_get_gamma_size(struct wlr_output *output) {
}
return output->impl->get_gamma_size(output);
}
void wlr_output_read_pixels(struct wlr_output *output, void *out_data) {
if (output->impl->read_pixels) {
output->impl->read_pixels(output, out_data);
}
}

View file

@ -6,9 +6,44 @@
#include <wlr/util/log.h>
#include "screenshooter-protocol.h"
struct screenshot_state {
struct wl_shm_buffer *shm_buffer;
struct wlr_output *output;
struct wlr_screenshot *screenshot;
struct wl_listener frame_listener;
};
static void output_frame_notify(struct wl_listener *listener, void *_data) {
struct screenshot_state *state = wl_container_of(listener, state, frame_listener);
void *data = wl_shm_buffer_get_data(state->shm_buffer);
wl_shm_buffer_begin_access(state->shm_buffer);
wlr_output_read_pixels(state->output, data);
wl_shm_buffer_end_access(state->shm_buffer);
wl_list_remove(&listener->link);
orbital_screenshot_send_done(state->screenshot->resource);
// TODO: free(state)
}
static void screenshooter_shoot(struct wl_client *client,
struct wl_resource *_screenshooter, uint32_t id,
struct wl_resource *_output, struct wl_resource *_buffer) {
struct wlr_output *output = wl_resource_get_user_data(_output);
if (!wl_shm_buffer_get(_buffer)) {
wlr_log(L_ERROR, "Invalid buffer: not a shared memory buffer");
return;
}
struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(_buffer);
int32_t width = wl_shm_buffer_get_width(shm_buffer);
int32_t height = wl_shm_buffer_get_height(shm_buffer);
// TODO: int32_t stride = wl_shm_buffer_get_stride(shm_buffer);
if (width < output->width || height < output->height) {
wlr_log(L_ERROR, "Invalid buffer: too small");
return;
}
struct wlr_screenshot *screenshot;
if (!(screenshot = calloc(1, sizeof(struct wlr_screenshot)))) {
return;
@ -18,7 +53,13 @@ static void screenshooter_shoot(struct wl_client *client,
&orbital_screenshot_interface, wl_resource_get_version(_screenshooter), id);
wlr_log(L_DEBUG, "new screenshot %p (res %p)", screenshot, screenshot->resource);
wl_resource_set_implementation(screenshot->resource, NULL, screenshot, NULL);
// TODO: orbital_screenshot_send_done(screenshot->resource);
struct screenshot_state *state = calloc(1, sizeof(struct screenshot_state));
state->shm_buffer = shm_buffer;
state->output = output;
state->screenshot = screenshot;
state->frame_listener.notify = output_frame_notify;
wl_signal_add(&output->events.frame, &state->frame_listener);
}
static struct orbital_screenshooter_interface screenshooter_impl = {