])
AM_CONDITIONAL([HAVE_WL_FB], [test "x${WL_FB}" = "xtrue"])
+define([CHECK_MODULE_WL_SCREENSHOT],
+[
+ if test "x${have_wayland_clients}" = "xyes" || test "x${e_cv_want_wayland_only}" = "xyes"; then
+ AC_E_CHECK_PKG(WL_SCREENSHOT, [ ecore >= $efl_version eina >= $efl_version ], [WL_SCREENSHOT=true], [WL_SCREENSHOT=false])
+ else
+ WL_SCREENSHOT=false
+ fi
+])
+AM_CONDITIONAL([HAVE_WL_SCREENSHOT], [test "x${WL_SCREENSHOT}" = "xtrue"])
+
define([CHECK_MODULE_WL_DRM],
[
if test "x${have_wayland}" = "xyes" ; then
AC_E_OPTIONAL_MODULE([wl_x11], $have_wayland, $wl_x11)
AC_E_OPTIONAL_MODULE([wl_fb], $have_wayland, [CHECK_MODULE_WL_FB])
AC_E_OPTIONAL_MODULE([wl_drm], $have_wayland, [CHECK_MODULE_WL_DRM])
-#AC_E_OPTIONAL_MODULE([wl_screenshot], true, [CHECK_MODULE_WL_SCREENSHOT])
+AC_E_OPTIONAL_MODULE([wl_screenshot], $have_wayland, [CHECK_MODULE_WL_SCREENSHOT])
AC_E_OPTIONAL_MODULE([policy_mobile], true)
HALT="/sbin/shutdown -h now"
include src/modules/Makefile_wl_fb.mk
-#if HAVE_WAYLAND_SCREENSHOT
-#include src/modules/Makefile_wl_screenshot.mk
+include src/modules/Makefile_wl_screenshot.mk
include src/modules/Makefile_policy_mobile.mk
EXTRA_DIST += src/modules/wl_screenshot/module.desktop.in \
src/modules/wl_screenshot/e-module-wl_screenshot.edj \
src/modules/wl_screenshot/e_screenshooter_client_protocol.h \
-src/modules/wl_screenshot/e_screenshooter_client_protocol.c
+src/modules/wl_screenshot/e_screenshooter_client_protocol.c \
+src/modules/wl_screenshot/e_screenshooter_server.h \
+src/modules/wl_screenshot/e_screenshooter_server.c \
+src/modules/wl_screenshot/e_screenshooter_server_protocol.h
+
if USE_MODULE_WL_SCREENSHOT
wl_screenshotdir = $(MDIR)/wl_screenshot
wl_screenshot_DATA = src/modules/wl_screenshot/e-module-wl_screenshot.edj \
wl_screenshotpkgdir = $(MDIR)/wl_screenshot/$(MODULE_ARCH)
wl_screenshotpkg_LTLIBRARIES = src/modules/wl_screenshot/module.la
-wl_screenshot_module_la_DEPENDENCIES = $(MDEPENDENCIES)
-wl_screenshot_module_la_CPPFLAGS = $(MOD_CPPFLAGS) @WL_SCREENSHOT_CFLAGS@ @WAYLAND_CFLAGS@
-wl_screenshot_module_la_LIBADD = $(MOD_LIBS) @WL_SCREENSHOT_LIBS@ @WAYLAND_LIBS@
-wl_screenshot_module_la_LDFLAGS = $(MOD_LDFLAGS) # @WL_SCREENSHOT_LDFLAGS@ @WAYLAND_LDFLAGS@
-wl_screenshot_module_la_SOURCES = src/modules/wl_screenshot/e_mod_main.c \
+src_modules_wl_screenshot_module_la_DEPENDENCIES = $(MDEPENDENCIES)
+src_modules_wl_screenshot_module_la_CPPFLAGS = $(MOD_CPPFLAGS) @WL_SCREENSHOT_CFLAGS@ @WAYLAND_CFLAGS@ -DNEED_WL
+src_modules_wl_screenshot_module_la_LIBADD = $(LIBS) @WL_SCREENSHOT_LIBS@ @WAYLAND_LIBS@
+src_modules_wl_screenshot_module_la_LDFLAGS = $(MOD_LDFLAGS)
+
+src_modules_wl_screenshot_module_la_SOURCES = src/modules/wl_screenshot/e_mod_main.c \
src/modules/wl_screenshot/e_mod_main.h \
src/modules/wl_screenshot/e_screenshooter_client_protocol.h \
- src/modules/wl_screenshot/e_screenshooter_client_protocol.c
+ src/modules/wl_screenshot/e_screenshooter_client_protocol.c \
+ src/modules/wl_screenshot/e_screenshooter_server.h \
+ src/modules/wl_screenshot/e_screenshooter_server.c \
+ src/modules/wl_screenshot/e_screenshooter_server_protocol.h
-PHONIES: wl_screenshot install-wl_screenshot
+PHONIES += wl_screenshot install-wl_screenshot
wl_screenshot: $(wl_screenshotpkg_LTLIBRARIES) $(wl_screenshot_DATA)
install-wl_screenshot: install-wl_screenshotDATA install-wl_screenshotpkgLTLIBRARIES
endif
#include <Ecore_Wayland.h>
#include <sys/mman.h>
#include "e_screenshooter_client_protocol.h"
+#include "e_screenshooter_server.h"
typedef struct _Instance Instance;
struct _Instance
struct wl_display *disp;
struct wl_registry *reg;
+ const char *engine_name;
+ EINA_SAFETY_ON_NULL_RETURN_VAL(e_comp, NULL);
+ engine_name = ecore_evas_engine_name_get(e_comp->ee);
+ if (!strncmp(engine_name, "drm", 3) || !strncmp(engine_name, "fb", 2))
+ return e_screenshooter_server_init(m);
+
if (!ecore_wl_init(NULL)) return NULL;
if (!(disp = ecore_wl_display_get()))
--- /dev/null
+#define E_COMP_WL
+#include "e.h"
+#include <wayland-server.h>
+#include <Ecore_Wayland.h>
+#include "e_screenshooter_server_protocol.h"
+#include "e_screenshooter_server.h"
+
+static void
+_e_screenshooter_center_rect (int src_w, int src_h, int dst_w, int dst_h, Eina_Rectangle *fit)
+{
+ float rw, rh;
+
+ if (src_w <= 0 || src_h <= 0 || dst_w <= 0 || dst_h <= 0 || !fit)
+ return;
+
+ rw = (float)src_w / dst_w;
+ rh = (float)src_h / dst_h;
+
+ if (rw > rh)
+ {
+ fit->w = dst_w;
+ fit->h = src_h * rw;
+ fit->x = 0;
+ fit->y = (dst_h - fit->h) / 2;
+ }
+ else if (rw < rh)
+ {
+ fit->w = src_w * rw;
+ fit->h = dst_h;
+ fit->x = (dst_w - fit->w) / 2;
+ fit->y = 0;
+ }
+ else
+ {
+ fit->w = dst_w;
+ fit->h = dst_h;
+ fit->x = 0;
+ fit->y = 0;
+ }
+}
+
+static void
+_e_screenshooter_shoot(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *output_resource,
+ struct wl_resource *buffer_resource)
+{
+ E_Comp_Wl_Output *output = wl_resource_get_user_data(output_resource);
+ struct wl_shm_buffer *shm_buffer = wl_shm_buffer_get(buffer_resource);
+ Eina_Rectangle center = {0,};
+ int32_t bw, bh, bs;
+ uint32_t bf;
+ void *bp;
+
+ if (!output || !shm_buffer)
+ {
+ wl_resource_post_error(resource, WL_DISPLAY_ERROR_INVALID_OBJECT,
+ "screenshooter failed: wrong %s resource",
+ (!output)?"output":"buffer");
+ return;
+ }
+
+ bw = wl_shm_buffer_get_width(shm_buffer);
+ bh = wl_shm_buffer_get_height(shm_buffer);
+ bf = wl_shm_buffer_get_format(shm_buffer);
+ bp = wl_shm_buffer_get_data(shm_buffer);
+ bs = wl_shm_buffer_get_stride(shm_buffer);
+
+ _e_screenshooter_center_rect(output->w, output->h, bw, bh, ¢er);
+printf ("@@@ %s(%d) %d, %d, %d, %x, s(%d,%d,%d,%d) d(%d,%d,%d,%d)\n", __FUNCTION__, __LINE__,
+ bs, bw, bh, bf,
+ output->x, output->y, output->w, output->h,
+ center.x, center.y, center.w, center.h);
+ /* do dump */
+ wl_shm_buffer_begin_access(shm_buffer);
+ evas_render_copy(e_comp->evas, bp, bs, bw, bh, bf,
+ output->x, output->y, output->w, output->h,
+ center.x, center.y, center.w, center.h);
+ wl_shm_buffer_end_access(shm_buffer);
+
+ /* done */
+ screenshooter_send_done(resource);
+}
+
+static const struct screenshooter_interface _e_screenshooter_interface =
+{
+ _e_screenshooter_shoot
+};
+
+static void
+_e_screenshooter_cb_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
+{
+ E_Comp_Data *cdata;
+ struct wl_resource *res;
+
+ if (!(cdata = data))
+ {
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ if (!(res = wl_resource_create(client, &screenshooter_interface, MIN(version, 1), id)))
+ {
+ ERR("Could not create screenshooter resource: %m");
+ wl_client_post_no_memory(client);
+ return;
+ }
+
+ wl_resource_set_implementation(res, &_e_screenshooter_interface, cdata, NULL);
+}
+
+void*
+e_screenshooter_server_init(E_Module *m)
+{
+ E_Comp_Data *cdata;
+
+ if (!e_comp) return EINA_FALSE;
+ if (!(cdata = e_comp->wl_comp_data)) return EINA_FALSE;
+ if (!cdata->wl.disp) return EINA_FALSE;
+
+ /* try to add screenshooter to wayland globals */
+ if (!wl_global_create(cdata->wl.disp, &screenshooter_interface, 1,
+ cdata, _e_screenshooter_cb_bind))
+ {
+ ERR("Could not add screenshooter to wayland globals: %m");
+ return EINA_FALSE;
+ }
+
+ return m;
+}
+
+int
+e_screenshooter_server_shutdown(E_Module *m)
+{
+ return 1;
+}
--- /dev/null
+#ifndef E_SCREENSHOOTER_SERVER_H
+#define E_SCREENSHOOTER_SERVER_H
+
+void* e_screenshooter_server_init(E_Module *m);
+int e_screenshooter_server_shutdown(E_Module *m);
+
+#endif
--- /dev/null
+#ifndef E_SCREENSHOOTER_SERVER_PROTOCOL_H
+#define E_SCREENSHOOTER_SERVER_PROTOCOL_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+#include <stddef.h>
+#include "wayland-util.h"
+
+struct wl_client;
+struct wl_resource;
+
+struct screenshooter;
+
+extern const struct wl_interface screenshooter_interface;
+
+struct screenshooter_interface {
+ /**
+ * shoot - (none)
+ * @output: (none)
+ * @buffer: (none)
+ */
+ void (*shoot)(struct wl_client *client,
+ struct wl_resource *resource,
+ struct wl_resource *output,
+ struct wl_resource *buffer);
+};
+
+#define SCREENSHOOTER_DONE 0
+
+#define SCREENSHOOTER_DONE_SINCE_VERSION 1
+
+static inline void
+screenshooter_send_done(struct wl_resource *resource_)
+{
+ wl_resource_post_event(resource_, SCREENSHOOTER_DONE);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif