From 621ee205102ec735352416b58434dd5e843eae4c Mon Sep 17 00:00:00 2001 From: Dmitry Kovalenko Date: Fri, 27 May 2016 13:39:24 +0300 Subject: [PATCH] [FIX] Enable UIHV for Tizen 3.0 Fix UIHV library access rights return index_prop.priority field Change-Id: Ib3c0c7004662c606deb62b87c6f4cd16882ea57b Signed-off-by: Dmitry Kovalenko --- daemon/threads.c | 2 +- packaging/swap-manager.spec | 14 ++ swap-manager.manifest | 3 + ui_viewer/Makefile | 3 +- ui_viewer/ui_viewer_data.c | 8 +- ui_viewer/ui_viewer_screenshot.c | 429 +++++++++++++++++++++++++++------------ ui_viewer/ui_viewer_utils.h | 3 +- ui_viewer/wayland-api.c | 26 +++ ui_viewer/wayland-api.h | 69 +++++++ 9 files changed, 422 insertions(+), 135 deletions(-) create mode 100644 ui_viewer/wayland-api.c create mode 100644 ui_viewer/wayland-api.h diff --git a/daemon/threads.c b/daemon/threads.c index 938569c..55cc7b1 100644 --- a/daemon/threads.c +++ b/daemon/threads.c @@ -67,7 +67,7 @@ static int chsmack(const char *filename) break; case 0: /* child */ - snprintf(cmd, sizeof(cmd), "chsmack -a sdbd \"%s\"", filename); + snprintf(cmd, sizeof(cmd), "chsmack -a \"*\" \"%s\"", filename); execl(SHELL_CMD, SHELL_CMD, "-c", cmd, NULL); /* exec fail */ diff --git a/packaging/swap-manager.spec b/packaging/swap-manager.spec index fb9c869..71012fd 100644 --- a/packaging/swap-manager.spec +++ b/packaging/swap-manager.spec @@ -11,7 +11,11 @@ Source: %{name}_%{version}.tar.gz %define NSP_SUPPORT 0 %define WSP_SUPPORT 0 %define WSI_SUPPORT 0 +%define WAYLAND_SUPPORT 0 +%if "%{_with_wayland}" == "1" +%define WAYLAND_SUPPORT 1 +%endif # _with_wayland ExcludeArch: aarch64 x86_64 BuildRequires: smack-devel @@ -35,6 +39,12 @@ BuildRequires: swap-probe-devel BuildRequires: swap-probe-elf BuildRequires: pkgconfig(libtzplatform-config) +# graphic support +%if %{WAYLAND_SUPPORT} +BuildRequires: pkgconfig(gles20) +BuildRequires: pkgconfig(wayland-egl) +BuildRequires: pkgconfig(egl) +%endif %define NSP_SUPPORT 1 # FIXME: add WSP_SUPPORT wrt webkit2-efl and webkit2-efl-debuginfo @@ -53,6 +63,10 @@ This binary will be installed in target. %setup -q -n %{name}_%{version} %build +%if %{WSI_SUPPORT} +export WAYLAND_SUPPORT=y +%endif + pushd scripts echo "__tizen_profile_name__="%{?tizen_profile_name} > dyn_vars echo "__tizen_product_tv__="%{?TIZEN_PRODUCT_TV} >> dyn_vars diff --git a/swap-manager.manifest b/swap-manager.manifest index a76fdba..37a5bde 100644 --- a/swap-manager.manifest +++ b/swap-manager.manifest @@ -2,4 +2,7 @@ + + + diff --git a/ui_viewer/Makefile b/ui_viewer/Makefile index 765c0aa..212203d 100644 --- a/ui_viewer/Makefile +++ b/ui_viewer/Makefile @@ -77,10 +77,11 @@ LDFLAGS := \ SRC_C := \ + wayland-api.c \ ui_viewer_lib.c \ ui_viewer_utils.c \ ui_viewer_data.c \ -# ui_viewer_screenshot.c + ui_viewer_screenshot.c TARGET = da_ui_viewer.so diff --git a/ui_viewer/ui_viewer_data.c b/ui_viewer/ui_viewer_data.c index 600740f..91350f9 100644 --- a/ui_viewer/ui_viewer_data.c +++ b/ui_viewer/ui_viewer_data.c @@ -1705,6 +1705,7 @@ static void pack_ui_obj_prop(int file, Evas_Object *obj, const char *type_name) index_prop.omit_enabled = elm_index_omit_enabled_get(obj); /* TODO: Port this to Tizen 3.0 */ /* index_prop.priority = elm_index_priority_get(obj); */ + index_prop.priority = 0; index_prop.horizontal = elm_index_horizontal_get(obj); index_prop.change_time = elm_index_delay_change_time_get(obj); index_prop.indicator_disabled = elm_index_indicator_disabled_get(obj); @@ -1943,12 +1944,7 @@ char *pack_ui_obj_screenshot(char *to, Evas_Object *obj) evas_object_ref(obj); evas = evas_object_evas_get(obj); evas_event_freeze(evas); - /* win_id = _get_win_id(evas); */ - /* win_focus = elm_win_focus_get(win_id); */ - - /* if (win_focus || _get_shot_in_bg(obj)) */ - /* ui_viewer_capture_screen(screenshot, obj); */ - /* else */ + if (ui_viewer_capture_screen(screenshot, obj) != 0) err_code = ERR_UI_OBJ_SCREENSHOT_FAILED; evas_event_thaw(evas); evas_object_unref(obj); diff --git a/ui_viewer/ui_viewer_screenshot.c b/ui_viewer/ui_viewer_screenshot.c index 60cc97d..a8719c0 100644 --- a/ui_viewer/ui_viewer_screenshot.c +++ b/ui_viewer/ui_viewer_screenshot.c @@ -24,113 +24,322 @@ * */ -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include +#include // for system +#include // for stat, getpid +#include // fot stat, chmod +#include // fot stat, getpid +#include // for mutex +#include // MIN, MAX +#include // mmap #include #include #include #include +#include +#include "wayland-api.h" + #include "ui_viewer_utils.h" -typedef struct _screenshot_data -{ - XImage* ximage; - Display* dpy; - XShmSegmentInfo x_shm_info; -} screenshot_data; +#define MAX_HEIGHT 720 +#define CAPTURE_TIMEOUT 2.0 +#define MAX_PATH_LENGTH 256 static int screenshotIndex = 0; static pthread_mutex_t captureScreenLock = PTHREAD_MUTEX_INITIALIZER; -static char* captureScreenShotX(screenshot_data* sdata) +struct screenshot_data { + struct wl_shm *shm; + struct screenshooter *screenshooter; + struct wl_list output_list; + int min_x, min_y, max_x, max_y; + int buffer_copy_done; +}; + +struct screenshooter_output { + struct wl_output *output; + struct wl_buffer *buffer; + int width, height, offset_x, offset_y; + void *data; + struct wl_list link; +}; + +static void +display_handle_geometry(void __attribute__((unused)) *data, + struct wl_output *wl_output, + int x, + int y, + int __attribute__((unused)) physical_width, + int __attribute__((unused)) physical_height, + int __attribute__((unused)) subpixel, + const char __attribute__((unused)) *make, + const char __attribute__((unused)) *model, + int __attribute__((unused)) transform) { - Window root; - int width, height; + struct screenshooter_output *output; - sdata->dpy = XOpenDisplay(NULL); - if(sdata->dpy == NULL) - { - ui_viewer_log("ERROR: XOpenDisplay failed\n"); - return NULL; + output = wl_output_get_user_data(wl_output); + + if (wl_output == output->output) { + output->offset_x = x; + output->offset_y = y; } +} - width = DisplayWidth(sdata->dpy, DefaultScreen(sdata->dpy)); - height = DisplayHeight(sdata->dpy, DefaultScreen(sdata->dpy)); +static void +display_handle_mode(void __attribute__((unused)) *data, + struct wl_output *wl_output, uint32_t flags, int width, + int height, int __attribute__((unused)) refresh) +{ + struct screenshooter_output *output; - root = RootWindow(sdata->dpy, DefaultScreen(sdata->dpy)); + output = wl_output_get_user_data(wl_output); - sdata->ximage = XShmCreateImage(sdata->dpy, DefaultVisualOfScreen (DefaultScreenOfDisplay (sdata->dpy)), 24, - ZPixmap, NULL, &sdata->x_shm_info, (unsigned int)width, (unsigned int)height); + if ((wl_output == output->output) && (flags & WL_OUTPUT_MODE_CURRENT)) { + output->width = width; + output->height = height; + } +} - if (sdata->ximage != NULL) - { - sdata->x_shm_info.shmid = shmget(IPC_PRIVATE, sdata->ximage->bytes_per_line * sdata->ximage->height, IPC_CREAT | 0777); - sdata->x_shm_info.shmaddr = sdata->ximage->data = shmat(sdata->x_shm_info.shmid, 0, 0); - sdata->x_shm_info.readOnly = False; +static const struct wl_output_listener output_listener = { + display_handle_geometry, + display_handle_mode, + NULL, + NULL +}; - if (XShmAttach(sdata->dpy, &sdata->x_shm_info)) - { - if (XShmGetImage(sdata->dpy, root, sdata->ximage, 0, 0, AllPlanes)) - { - XSync(sdata->dpy, False); - return sdata->ximage->data; - } - else - { - ui_viewer_log("ERROR: XShmGetImage failed\n"); - } +static void +screenshot_done(void *data, + struct screenshooter __attribute__((unused)) *screenshooter) +{ + struct screenshot_data *sdata = data; + sdata->buffer_copy_done = 1; +} + +static const struct screenshooter_listener screenshooter_listener = { + screenshot_done +}; - XShmDetach(sdata->dpy, &sdata->x_shm_info); +static void +handle_global(void *data, struct wl_registry *registry, + uint32_t name, const char *interface, + uint32_t __attribute__((unused)) version) +{ + struct screenshot_data *sdata = data; + + if (strcmp(interface, "wl_output") == 0) { + struct screenshooter_output *output = malloc(sizeof(*output)); + + if (output) { + PRINTMSG("allocate %p", output); + output->output = wl_registry_bind(registry, name, + &wl_output_interface, + 1); + wl_list_insert(&sdata->output_list, &output->link); + wl_output_add_listener(output->output, + &output_listener, output); } - else - { - ui_viewer_log("ERROR: XShmAttach failed\n"); + } else if (strcmp(interface, "wl_shm") == 0) { + sdata->shm = wl_registry_bind(registry, name, + &wl_shm_interface, 1); + } else if (strcmp(interface, "screenshooter") == 0) { + sdata->screenshooter = wl_registry_bind(registry, name, + &screenshooter_interface, + 1); + } +} + +static const struct wl_registry_listener registry_listener = { + handle_global, + NULL +}; + +static struct wl_buffer *create_shm_buffer(struct wl_shm *shm, int width, + int height, void **data_out) +{ + char filename[] = "/tmp/wayland-shm-XXXXXX"; + struct wl_shm_pool *pool; + struct wl_buffer *buffer; + int fd, size, stride; + void *data; + + stride = width * 4; + size = stride * height; + + fd = mkstemp(filename); + if (fd < 0) + return NULL; + + if (ftruncate(fd, size) < 0) { + close(fd); + return NULL; + } + + data = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + unlink(filename); + + if (data == MAP_FAILED) { + close(fd); + return NULL; + } + + pool = wl_shm_create_pool(shm, fd, size); + close(fd); + buffer = wl_shm_pool_create_buffer(pool, 0, width, height, stride, + WL_SHM_FORMAT_XRGB8888); + wl_shm_pool_destroy(pool); + *data_out = data; + + return buffer; +} + +static void *__screenshot_to_buf(struct screenshot_data *sdata, int x, int y, + int width, int height) +{ + int dest_stride, src_stride, i; + void *data, *dest, *src; + struct screenshooter_output *output, *next; + dest_stride = width * 4; + + data = malloc(width * height * 4); + if (!data) + return NULL; + + wl_list_for_each_safe(output, next, &sdata->output_list, link) { + src_stride = output->width * 4; + dest = data; + if (y + height <= output->height) { + src = output->data + y * src_stride + x * 4; + + for (i = 0; i < height; i++) { + memcpy(dest, src, dest_stride); + dest += dest_stride; + src += src_stride; + } + } else { + PRINTERR("Cannot get screenshot. wrong height." + "src_height=%d [y=%d, h=%d]", output->height, + y, height); + memset(dest, 0xab, height * width * 4); } - shmdt (sdata->x_shm_info.shmaddr); - shmctl (sdata->x_shm_info.shmid, IPC_RMID, NULL); - XDestroyImage(sdata->ximage); - sdata->ximage = NULL; + wl_list_remove(&output->link); + free(output); + } + + return data; +} + +static int +set_buffer_size(struct screenshot_data *sdata, int *width, int *height) +{ + struct screenshooter_output *output; + + sdata->min_x = sdata->min_y = INT_MAX; + sdata->max_x = sdata->max_y = INT_MIN; + int position = 0; + + wl_list_for_each_reverse(output, &sdata->output_list, link) { + output->offset_x = position; + position += output->width; } - else - { - ui_viewer_log("ERROR: XShmCreateImage failed\n"); + + wl_list_for_each(output, &sdata->output_list, link) { + sdata->min_x = MIN(sdata->min_x, output->offset_x); + sdata->min_y = MIN(sdata->min_y, output->offset_y); + sdata->max_x = MAX(sdata->max_x, + output->offset_x + output->width); + sdata->max_y = MAX(sdata->max_y, + output->offset_y + output->height); } - return NULL; + if (sdata->max_x <= sdata->min_x || sdata->max_y <= sdata->min_y) + return -1; + + *width = sdata->max_x - sdata->min_x; + *height = sdata->max_y - sdata->min_y; + + return 0; } -static void releaseScreenShotX(screenshot_data* sdata) +static void *__capture_screnshot_wayland(int x, int y, int width, int height) { - if(sdata->ximage) - { - XShmDetach(sdata->dpy, &sdata->x_shm_info); - shmdt (sdata->x_shm_info.shmaddr); - shmctl (sdata->x_shm_info.shmid, IPC_RMID, NULL); - XDestroyImage(sdata->ximage); + struct wl_display *display = NULL; + struct wl_registry *registry; + struct screenshooter_output *output; + void *buf = NULL; + struct screenshot_data *sdata; + const char *wayland_socket = NULL; + + wayland_socket = getenv("WAYLAND_SOCKET"); + if (!wayland_socket) + wayland_socket = getenv("WAYLAND_DISPLAY"); + + if (!wayland_socket) { + PRINTERR("must be launched by wayland"); + return NULL; } - else { } - if(sdata->dpy) - { - XCloseDisplay(sdata->dpy); + sdata = malloc(sizeof(*sdata)); + if (!sdata) + return NULL; + + sdata->shm = NULL; + sdata->screenshooter = NULL; + wl_list_init(&sdata->output_list); + sdata->min_x = 0; + sdata->min_y = 0; + sdata->max_x = 0; + sdata->max_y = 0; + sdata->buffer_copy_done = 0; + + display = wl_display_connect(wayland_socket); + if (display == NULL) + goto out; + + /* wl_list_init(&output_list); */ + registry = wl_display_get_registry(display); + wl_registry_add_listener(registry, ®istry_listener, sdata); + wl_display_dispatch(display); + wl_display_roundtrip(display); + + if (sdata->screenshooter == NULL) { + PRINTERR("display doesn't support screenshooter"); + return NULL; } + + screenshooter_add_listener(sdata->screenshooter, + &screenshooter_listener, sdata); + + int buf_width, buf_height; + if (set_buffer_size(sdata, &buf_width, &buf_height)) + return NULL; + + wl_list_for_each(output, &sdata->output_list, link) { + output->buffer = create_shm_buffer(sdata->shm, output->width, + output->height, + &output->data); + screenshooter_shoot(sdata->screenshooter, output->output, + output->buffer); + sdata->buffer_copy_done = 0; + while (!sdata->buffer_copy_done) { + wl_display_roundtrip(display); + } + } + + buf = __screenshot_to_buf(sdata, x, y, width, height); + +out: + if (display) + wl_display_disconnect(display); + free(sdata); + return buf; } static int capture_object(char *screenshot_path, int width, int height, - Evas_Object *obj, const char *type_name) { + Evas_Object *obj, const char *type_name) +{ char dstpath[MAX_PATH_LENGTH]; Evas_Object *img; Evas *canvas, *sub_canvas; @@ -151,7 +360,7 @@ static int capture_object(char *screenshot_path, int width, int height, ecore_evas_resize(sub_ee, width, height); if (!strcmp(type_name, "rectangle")) { - Evas_Object* rect; + Evas_Object *rect; int r, g, b, a; rect = evas_object_rectangle_add(sub_canvas); @@ -174,62 +383,25 @@ static int capture_object(char *screenshot_path, int width, int height, evas_object_show(image); } else { - char* scrimage; - screenshot_data sdata; int x, y; - int screen_w; Evas_Object *image; - int i, j; - int bytes_per_pixel; evas_object_geometry_get(obj, &x, &y, NULL, NULL); - - sdata.ximage = NULL; - scrimage = captureScreenShotX(&sdata); - if (!scrimage) { - ui_viewer_log("ERROR: capture_object : no scrimage\n"); - ret = -1; - goto finish; - } - bytes_per_pixel = sdata.ximage->bits_per_pixel / 8; - screen_w = sdata.ximage->width; - - image_data = malloc(width * height * bytes_per_pixel); - if (!image_data) { - ui_viewer_log("ERROR: capture_object : can't allocate %d bytes\n", - width * height * bytes_per_pixel); - ret = -1; + image_data = __capture_screnshot_wayland(x, y, width, height); + if (image_data == NULL) goto finish; - } - - // remove invisible image parts - if (x < 0) - x = 0; - - if (y < 0) - y = 0; - - // crop image - for (j = 0; j < height; j++) { - for (i = 0; i < width * bytes_per_pixel; i++) { - image_data[i + j * width * bytes_per_pixel] = - scrimage[(i + x * bytes_per_pixel) + (j + y) * screen_w * bytes_per_pixel]; - } - } - image = evas_object_image_filled_add(sub_canvas); evas_object_image_size_set(image, width, height); evas_object_image_data_set(image, image_data); evas_object_image_data_update_add(image, 0, 0, width, height); evas_object_resize(image, width, height); evas_object_show(image); -finish: - releaseScreenShotX(&sdata); } +finish: ecore_evas_manual_render(sub_ee); - snprintf(dstpath, sizeof(dstpath), TMP_DIR"/%d_%d.png", _getpid(), + snprintf(dstpath, sizeof(dstpath), TMP_DIR "/%d_%d.png", _getpid(), screenshotIndex); if (evas_object_image_save(img, dstpath, NULL, "compress=5") != 0) { @@ -254,7 +426,7 @@ int ui_viewer_capture_screen(char *screenshot_path, Evas_Object *obj) char type_name[MAX_PATH_LENGTH]; if (!screenshot_path) { - ui_viewer_log("ui_viewer_capture_screen : no screenshot path\n"); + ui_viewer_log("ui_viewer_capture_screen: no screenshot path\n"); ret = -1; return ret; } @@ -268,8 +440,8 @@ int ui_viewer_capture_screen(char *screenshot_path, Evas_Object *obj) evas_object_geometry_get(obj, &obj_x, &obj_y, &obj_w, &obj_h); if (obj_w == 0 || obj_h == 0) { - ui_viewer_log("ui_viewer_capture_screen : object %p[%d,%d] has zero width or height\n", - obj, obj_w, obj_h); + ui_viewer_log("ui_viewer_capture_screen : object %p[%d,%d]" + "has zero width or height\n", obj, obj_w, obj_h); ret = -1; } else if (!strcmp(type_name, "rectangle")) { int width, height; @@ -278,27 +450,31 @@ int ui_viewer_capture_screen(char *screenshot_path, Evas_Object *obj) width = (obj_w <= view_w) ? obj_w : view_w; height = (obj_h <= view_h) ? obj_h : view_h; - ret = capture_object(screenshot_path, width, height, obj, type_name); + ret = capture_object(screenshot_path, width, height, obj, + type_name); } else if (!strcmp(type_name, "image")) { - ret = capture_object(screenshot_path, obj_w, obj_h, obj, type_name); + ret = capture_object(screenshot_path, obj_w, obj_h, obj, + type_name); } else if (!strcmp(type_name, "vectors")) { ret = -1; } else if (!strcmp(type_name, "elm_image") || - !strcmp(type_name, "elm_icon")) { + !strcmp(type_name, "elm_icon")) { Evas_Object *internal_img; int img_w, img_h; internal_img = elm_image_object_get(obj); - evas_object_geometry_get(internal_img, NULL, NULL, &img_w, &img_h); + evas_object_geometry_get(internal_img, NULL, NULL, &img_w, + &img_h); - ret = capture_object(screenshot_path, img_w, img_h, internal_img, type_name); + ret = capture_object(screenshot_path, img_w, img_h, + internal_img, type_name); } else if (obj_x > view_w || obj_y > view_h) { - ui_viewer_log("ui_viewer_capture_screen : object %p lies beside view area\n", - obj); + ui_viewer_log("ui_viewer_capture_screen:" + "object %p lies beside view area\n", obj); ret = -1; } else if (!evas_object_visible_get(obj)) { - ui_viewer_log("ui_viewer_capture_screen : object %p is unvisible\n", - obj); + ui_viewer_log("ui_viewer_capture_screen:" + "object %p is unvisible\n", obj); ret = -1; } else { int width, height; @@ -307,7 +483,8 @@ int ui_viewer_capture_screen(char *screenshot_path, Evas_Object *obj) width = (view_w < obj_w + obj_x) ? (view_w - obj_x) : obj_w; height = (view_h < obj_h + obj_y) ? (view_h - obj_y) : obj_h; - ret = capture_object(screenshot_path, width, height, obj, type_name); + ret = capture_object(screenshot_path, width, height, obj, + type_name); } if (ret) diff --git a/ui_viewer/ui_viewer_utils.h b/ui_viewer/ui_viewer_utils.h index 3a3d2e4..a712b85 100644 --- a/ui_viewer/ui_viewer_utils.h +++ b/ui_viewer/ui_viewer_utils.h @@ -29,6 +29,7 @@ #include #include +#include #include "app_protocol.h" /* from swap-probe-devel package */ @@ -83,7 +84,7 @@ bool print_log_ui_obj_screenshot(Evas_Object *obj); bool printLog(log_t* log, int msgType); void raise_app_window(void); -/* int ui_viewer_capture_screen(char *screenshot_path, Evas_Object *obj); */ +int ui_viewer_capture_screen(char *screenshot_path, Evas_Object *obj); void ui_viewer_clean_log(void); void ui_viewer_log(const char *format, ...); diff --git a/ui_viewer/wayland-api.c b/ui_viewer/wayland-api.c new file mode 100644 index 0000000..5a3a8fb --- /dev/null +++ b/ui_viewer/wayland-api.c @@ -0,0 +1,26 @@ +#include +#include +#include "wayland-util.h" + +extern const struct wl_interface wl_buffer_interface; +extern const struct wl_interface wl_output_interface; + +static const struct wl_interface *types[] = { + &wl_output_interface, + &wl_buffer_interface, +}; + +static const struct wl_message screenshooter_requests[] = { + { "shoot", "oo", types + 0 }, +}; + +static const struct wl_message screenshooter_events[] = { + { "done", "", types + 0 }, +}; + +WL_EXPORT const struct wl_interface screenshooter_interface = { + "screenshooter", 1, + 1, screenshooter_requests, + 1, screenshooter_events, +}; + diff --git a/ui_viewer/wayland-api.h b/ui_viewer/wayland-api.h new file mode 100644 index 0000000..755c245 --- /dev/null +++ b/ui_viewer/wayland-api.h @@ -0,0 +1,69 @@ +#ifndef SCREENSHOOTER_CLIENT_PROTOCOL_H +#define SCREENSHOOTER_CLIENT_PROTOCOL_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include "wayland-client.h" + +struct wl_client; +struct wl_resource; + +struct screenshooter; +struct wl_buffer; +struct wl_output; + +extern const struct wl_interface screenshooter_interface; + +struct screenshooter_listener { + /** + * done - (none) + */ + void (*done)(void *data, struct screenshooter *screenshooter); +}; + +static inline int +screenshooter_add_listener(struct screenshooter *screenshooter, + const struct screenshooter_listener *listener, + void *data) +{ + return wl_proxy_add_listener((struct wl_proxy *)screenshooter, + (void (**)(void))listener, data); +} + +#define SCREENSHOOTER_SHOOT 0 + +static inline void +screenshooter_set_user_data(struct screenshooter *screenshooter, void *user_data) +{ + wl_proxy_set_user_data((struct wl_proxy *)screenshooter, user_data); +} + +static inline void * +screenshooter_get_user_data(struct screenshooter *screenshooter) +{ + return wl_proxy_get_user_data((struct wl_proxy *)screenshooter); +} + +static inline void +screenshooter_destroy(struct screenshooter *screenshooter) +{ + wl_proxy_destroy((struct wl_proxy *)screenshooter); +} + +static inline void +screenshooter_shoot(struct screenshooter *screenshooter, + struct wl_output *output, struct wl_buffer *buffer) +{ + wl_proxy_marshal((struct wl_proxy *)screenshooter, SCREENSHOOTER_SHOOT, + output, buffer); +} + +#ifdef __cplusplus +} +#endif + +#endif -- 2.7.4