mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-11-24 06:59:45 -05:00
First attempt to implement screenshooter
This commit is contained in:
parent
1c8b72e0cd
commit
35f9700251
8 changed files with 360 additions and 1 deletions
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue