implementation wl_screenshooter server 58/38458/1
authorBoram Park <boram1288.park@samsung.com>
Fri, 17 Apr 2015 03:27:50 +0000 (12:27 +0900)
committerBoram Park <boram1288.park@samsung.com>
Tue, 21 Apr 2015 05:54:47 +0000 (14:54 +0900)
Change-Id: Iaf78519f3dc42eb63cb02f5ed6c8e19343c7b0ef

configure.ac
src/modules/Makefile.mk
src/modules/Makefile_wl_screenshot.mk
src/modules/wl_screenshot/e_mod_main.c
src/modules/wl_screenshot/e_screenshooter_server.c [new file with mode: 0644]
src/modules/wl_screenshot/e_screenshooter_server.h [new file with mode: 0644]
src/modules/wl_screenshot/e_screenshooter_server_protocol.h [new file with mode: 0644]

index fcb2fb0..ffd2ef4 100644 (file)
@@ -903,6 +903,16 @@ define([CHECK_MODULE_WL_FB],
 ])
 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
@@ -968,7 +978,7 @@ AC_E_OPTIONAL_MODULE([wl_desktop_shell], $have_wayland, [CHECK_MODULE_WL_DESKTOP
 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"
index 6efe674..27184a9 100644 (file)
@@ -129,7 +129,6 @@ include src/modules/Makefile_wl_x11.mk
 
 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
index 09ceb83..9be71cd 100644 (file)
@@ -1,7 +1,11 @@
 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 \
@@ -10,16 +14,20 @@ 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
index eadc89a..9a92fbf 100644 (file)
@@ -3,6 +3,7 @@
 #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
@@ -62,6 +63,12 @@ e_modapi_init(E_Module *m)
    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()))
diff --git a/src/modules/wl_screenshot/e_screenshooter_server.c b/src/modules/wl_screenshot/e_screenshooter_server.c
new file mode 100644 (file)
index 0000000..5baa362
--- /dev/null
@@ -0,0 +1,136 @@
+#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, &center);
+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;
+}
diff --git a/src/modules/wl_screenshot/e_screenshooter_server.h b/src/modules/wl_screenshot/e_screenshooter_server.h
new file mode 100644 (file)
index 0000000..3320797
--- /dev/null
@@ -0,0 +1,7 @@
+#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
diff --git a/src/modules/wl_screenshot/e_screenshooter_server_protocol.h b/src/modules/wl_screenshot/e_screenshooter_server_protocol.h
new file mode 100644 (file)
index 0000000..c0bc888
--- /dev/null
@@ -0,0 +1,45 @@
+#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