From f214d9d73b4d2d634ce608d183a007bc7690664e Mon Sep 17 00:00:00 2001 From: Chris Michael Date: Wed, 8 Jul 2015 15:04:49 -0400 Subject: [PATCH] e-comp-wl: Create compositor screenshooter global and add function to actually handle taking shots Signed-off-by: Chris Michael --- src/bin/e_comp_wl.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/src/bin/e_comp_wl.c b/src/bin/e_comp_wl.c index 8b6060d..2fa8a56 100644 --- a/src/bin/e_comp_wl.c +++ b/src/bin/e_comp_wl.c @@ -1,5 +1,6 @@ #define E_COMP_WL #include "e.h" +#include "e_comp_wl_screenshooter_server.h" /* handle include for printing uint64_t */ #define __STDC_FORMAT_MACROS @@ -1636,6 +1637,9 @@ _e_comp_wl_compositor_cb_del(void *data EINA_UNUSED) cdata = e_comp->wl_comp_data; + if (cdata->screenshooter.global) + wl_global_destroy(cdata->screenshooter.global); + EINA_LIST_FREE(cdata->outputs, output) { if (output->id) eina_stringshare_del(output->id); @@ -2074,6 +2078,87 @@ _e_comp_wl_subcompositor_cb_bind(struct wl_client *client, void *data EINA_UNUSE } static void +_e_comp_wl_screenshooter_cb_shoot(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource, struct wl_resource *buffer_resource) +{ + E_Comp_Wl_Output *output; + E_Comp_Wl_Buffer *buffer; + struct wl_shm_buffer *shm_buffer; + int stride; + void *pixels, *d; + + output = wl_resource_get_user_data(output_resource); + buffer = e_comp_wl_buffer_get(buffer_resource); + + if (!buffer) + { + wl_resource_post_no_memory(resource); + return; + } + + if ((buffer->w < output->w) || (buffer->h < output->h)) + { + ERR("Buffer size less than output"); + /* send done with bad buffer error */ + return; + } + + stride = buffer->w * sizeof(int); + + pixels = malloc(stride * buffer->h); + if (!pixels) + { + /* send done with bad buffer error */ + ERR("Could not allocate space for destination"); + return; + } + + if (e_comp->wl_comp_data->screenshooter.read_pixels) + e_comp->wl_comp_data->screenshooter.read_pixels(output, pixels); + + shm_buffer = wl_shm_buffer_get(buffer->resource); + if (!shm_buffer) + { + ERR("Could not get shm_buffer from resource"); + return; + } + + stride = wl_shm_buffer_get_stride(shm_buffer); + d = wl_shm_buffer_get_data(shm_buffer); + if (!d) + { + ERR("Could not get buffer data"); + return; + } + + wl_shm_buffer_begin_access(shm_buffer); + memcpy(d, pixels, buffer->h * stride); + wl_shm_buffer_end_access(shm_buffer); + + screenshooter_send_done(resource); +} + +static const struct screenshooter_interface _e_screenshooter_interface = +{ + _e_comp_wl_screenshooter_cb_shoot +}; + +static void +_e_comp_wl_screenshooter_cb_bind(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id) +{ + struct wl_resource *res; + + res = wl_resource_create(client, &screenshooter_interface, 1, id); + if (!res) + { + ERR("Could not create screenshooter resource: %m"); + wl_client_post_no_memory(client); + return; + } + + wl_resource_set_implementation(res, &_e_screenshooter_interface, data, NULL); +} + +static void _e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec) { uint64_t win; @@ -2474,6 +2559,15 @@ _e_comp_wl_compositor_create(void) goto comp_global_err; } + cdata->screenshooter.global = + wl_global_create(cdata->wl.disp, &screenshooter_interface, 1, + e_comp, _e_comp_wl_screenshooter_cb_bind); + if (!cdata->screenshooter.global) + { + ERR("Could not create screenshooter global: %m"); + goto comp_global_err; + } + /* _e_comp_wl_cb_randr_change(NULL, 0, NULL); */ /* try to init data manager */ -- 2.7.4