ecore_wl2: implement www extension for client-side use

handling for global binding and signal prop

Signed-off-by: Derek Foreman <derekf@osg.samsung.com>
This commit is contained in:
Mike Blumenkrantz 2016-03-24 12:19:42 -05:00
parent b132ce65ec
commit eb1a422d63
7 changed files with 294 additions and 1 deletions

View File

@ -12,6 +12,8 @@ lib/ecore_wl2/subsurface-client-protocol.h \
lib/ecore_wl2/subsurface-protocol.c \
lib/ecore_wl2/xdg-shell-client-protocol.h \
lib/ecore_wl2/xdg-shell-protocol.c \
lib/ecore_wl2/www-protocol.h \
lib/ecore_wl2/www-protocol.c \
lib/ecore_wl2/ecore_wl2_seat.c \
lib/ecore_wl2/ecore_wl2_subsurf.c \
lib/ecore_wl2/ecore_wl2_dnd.c \

View File

@ -27,6 +27,9 @@ EAPI int ECORE_WL2_EVENT_SELECTION_DATA_READY = 0;
EAPI int ECORE_WL2_EVENT_WINDOW_CONFIGURE = 0;
EAPI int ECORE_WL2_EVENT_SYNC_DONE = 0;
EAPI int _ecore_wl2_event_window_www = -1;
EAPI int _ecore_wl2_event_window_www_drag = -1;
/* public API functions */
EAPI int
ecore_wl2_init(void)
@ -77,6 +80,8 @@ ecore_wl2_init(void)
ECORE_WL2_EVENT_SELECTION_DATA_READY = ecore_event_type_new();
ECORE_WL2_EVENT_WINDOW_CONFIGURE = ecore_event_type_new();
ECORE_WL2_EVENT_SYNC_DONE = ecore_event_type_new();
_ecore_wl2_event_window_www = ecore_event_type_new();
_ecore_wl2_event_window_www_drag = ecore_event_type_new();
}
return _ecore_wl2_init_count;

View File

@ -119,6 +119,13 @@ _cb_global_add(void *data, struct wl_registry *registry, unsigned int id, const
EINA_INLIST_FOREACH(ewd->windows, window)
_ecore_wl2_window_shell_surface_init(window);
}
else if (eina_streq(interface, "www"))
{
Ecore_Wl2_Window *window;
ewd->wl.www = wl_registry_bind(registry, id, &www_interface, 1);
EINA_INLIST_FOREACH(ewd->windows, window)
_ecore_wl2_window_www_surface_init(window);
}
else if (!strcmp(interface, "wl_output"))
_ecore_wl2_output_add(ewd, id);
else if (!strcmp(interface, "wl_seat"))
@ -364,6 +371,7 @@ _ecore_wl2_display_cleanup(Ecore_Wl2_Display *ewd)
eina_hash_free(ewd->globals);
if (ewd->wl.www) www_destroy(ewd->wl.www);
if (ewd->wl.xdg_shell) xdg_shell_destroy(ewd->wl.xdg_shell);
if (ewd->wl.wl_shell) wl_shell_destroy(ewd->wl.wl_shell);
if (ewd->wl.shm) wl_shm_destroy(ewd->wl.shm);

View File

@ -4,6 +4,7 @@
# include <unistd.h>
# include "Ecore_Wl2.h"
# include "Ecore_Input.h"
# include "www-protocol.h"
/* NB: Test if subsurface protocol is part of wayland code, if not then
* include our own copy */
@ -16,6 +17,20 @@
extern int _ecore_wl2_log_dom;
# ifdef EAPI
# undef EAPI
# endif
# ifdef __GNUC__
# if __GNUC__ >= 4
# define EAPI __attribute__ ((visibility("default")))
# else
# define EAPI
# endif
# else
# define EAPI
# endif
# ifdef ECORE_WL2_DEFAULT_LOG_COLOR
# undef ECORE_WL2_DEFAULT_LOG_COLOR
# endif
@ -62,6 +77,7 @@ struct _Ecore_Wl2_Display
struct wl_shm *shm;
struct wl_shell *wl_shell;
struct xdg_shell *xdg_shell;
struct www *www;
int compositor_version;
} wl;
@ -117,6 +133,7 @@ struct _Ecore_Wl2_Window
struct wl_shell_surface *wl_shell_surface;
struct xdg_surface *xdg_surface;
struct xdg_popup *xdg_popup;
struct www_surface *www_surface;
uint32_t configure_serial;
void (*configure_ack)(struct xdg_surface *surface, uint32_t serial);
@ -405,4 +422,21 @@ void _ecore_wl2_dnd_del(Ecore_Wl2_Dnd_Source *source);
void _ecore_wl2_subsurf_free(Ecore_Wl2_Subsurface *subsurf);
void _ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window);
void _ecore_wl2_window_www_surface_init(Ecore_Wl2_Window *window);
typedef struct Ecore_Wl2_Event_Window_WWW
{
unsigned int window;
int x_rel;
int y_rel;
uint32_t timestamp;
} Ecore_Wl2_Event_Window_WWW;
typedef struct Ecore_Wl2_Event_Window_WWW_Drag
{
unsigned int window;
Eina_Bool dragging;
} Ecore_Wl2_Event_Window_WWW_Drag;
EAPI extern int _ecore_wl2_event_window_www;
EAPI extern int _ecore_wl2_event_window_www_drag;
#endif

View File

@ -215,6 +215,68 @@ _ecore_wl2_window_type_set(Ecore_Wl2_Window *win)
}
}
static void
_www_surface_end_drag(void *data, struct www_surface *www_surface EINA_UNUSED)
{
Ecore_Wl2_Window *window = data;
Ecore_Wl2_Event_Window_WWW_Drag *ev;
ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW_Drag));
EINA_SAFETY_ON_NULL_RETURN(ev);
ev->window = window->id;
ev->dragging = 0;
ecore_event_add(_ecore_wl2_event_window_www_drag, ev, NULL, NULL);
}
static void
_www_surface_start_drag(void *data, struct www_surface *www_surface EINA_UNUSED)
{
Ecore_Wl2_Window *window = data;
Ecore_Wl2_Event_Window_WWW_Drag *ev;
ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW_Drag));
EINA_SAFETY_ON_NULL_RETURN(ev);
ev->window = window->id;
ev->dragging = 1;
ecore_event_add(_ecore_wl2_event_window_www_drag, ev, NULL, NULL);
}
static void
_www_surface_status(void *data, struct www_surface *www_surface EINA_UNUSED, int32_t x_rel, int32_t y_rel, uint32_t timestamp)
{
Ecore_Wl2_Window *window = data;
Ecore_Wl2_Event_Window_WWW *ev;
ev = malloc(sizeof(Ecore_Wl2_Event_Window_WWW));
EINA_SAFETY_ON_NULL_RETURN(ev);
ev->window = window->id;
ev->x_rel = x_rel;
ev->y_rel = y_rel;
ev->timestamp = timestamp;
ecore_event_add(_ecore_wl2_event_window_www, ev, NULL, NULL);
}
static struct www_surface_listener _www_surface_listener =
{
.status = _www_surface_status,
.start_drag = _www_surface_start_drag,
.end_drag = _www_surface_end_drag,
};
void
_ecore_wl2_window_www_surface_init(Ecore_Wl2_Window *window)
{
if (!window->surface) return;
if (!window->display->wl.www) return;
if (window->www_surface) return;
window->www_surface = www_create(window->display->wl.www, window->surface);
www_surface_set_user_data(window->www_surface, window);
www_surface_add_listener(window->www_surface, &_www_surface_listener, window);
}
void
_ecore_wl2_window_shell_surface_init(Ecore_Wl2_Window *window)
{
@ -346,7 +408,10 @@ ecore_wl2_window_show(Ecore_Wl2_Window *window)
if ((window->type != ECORE_WL2_WINDOW_TYPE_DND) &&
(window->type != ECORE_WL2_WINDOW_TYPE_NONE))
_ecore_wl2_window_shell_surface_init(window);
{
_ecore_wl2_window_shell_surface_init(window);
_ecore_wl2_window_www_surface_init(window);
}
}
EAPI void
@ -364,6 +429,10 @@ ecore_wl2_window_hide(Ecore_Wl2_Window *window)
wl_shell_surface_destroy(window->wl_shell_surface);
window->wl_shell_surface = NULL;
if (window->www_surface)
www_surface_destroy(window->www_surface);
window->www_surface = NULL;
if (window->surface) wl_surface_destroy(window->surface);
window->surface = NULL;
}

View File

@ -0,0 +1,41 @@
#include <stdlib.h>
#include <stdint.h>
#include "wayland-util.h"
extern const struct wl_interface wl_surface_interface;
extern const struct wl_interface www_surface_interface;
static const struct wl_interface *types[] = {
NULL,
NULL,
NULL,
&www_surface_interface,
&wl_surface_interface,
};
static const struct wl_message www_requests[] = {
{ "create", "no", types + 3 },
};
WL_EXPORT const struct wl_interface www_interface = {
"www", 1,
1, www_requests,
0, NULL,
};
static const struct wl_message www_surface_requests[] = {
{ "destroy", "", types + 0 },
};
static const struct wl_message www_surface_events[] = {
{ "status", "iiu", types + 0 },
{ "start_drag", "", types + 0 },
{ "end_drag", "", types + 0 },
};
WL_EXPORT const struct wl_interface www_surface_interface = {
"www_surface", 1,
1, www_surface_requests,
3, www_surface_events,
};

View File

@ -0,0 +1,134 @@
#ifndef ZWP_WWW_CLIENT_PROTOCOL_H
#define ZWP_WWW_CLIENT_PROTOCOL_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stddef.h>
#include "wayland-client.h"
struct wl_client;
struct wl_resource;
struct wl_surface;
struct www;
struct www_surface;
extern const struct wl_interface www_interface;
extern const struct wl_interface www_surface_interface;
#define WWW_CREATE 0
#define WWW_CREATE_SINCE_VERSION 1
static inline void
www_set_user_data(struct www *www, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) www, user_data);
}
static inline void *
www_get_user_data(struct www *www)
{
return wl_proxy_get_user_data((struct wl_proxy *) www);
}
static inline uint32_t
www_get_version(struct www *www)
{
return wl_proxy_get_version((struct wl_proxy *) www);
}
static inline void
www_destroy(struct www *www)
{
wl_proxy_destroy((struct wl_proxy *) www);
}
static inline struct www_surface *
www_create(struct www *www, struct wl_surface *surface)
{
struct wl_proxy *id;
id = wl_proxy_marshal_constructor((struct wl_proxy *) www,
WWW_CREATE, &www_surface_interface, NULL, surface);
return (struct www_surface *) id;
}
struct www_surface_listener {
/**
* status - Status update on a www_surface
* @x_rel: (none)
* @y_rel: (none)
* @timestamp: (none)
*
*
*/
void (*status)(void *data,
struct www_surface *www_surface,
int32_t x_rel,
int32_t y_rel,
uint32_t timestamp);
/**
* start_drag - Drag has started
*
*
*/
void (*start_drag)(void *data,
struct www_surface *www_surface);
/**
* end_drag - Drag has ended
*
*
*/
void (*end_drag)(void *data,
struct www_surface *www_surface);
};
static inline int
www_surface_add_listener(struct www_surface *www_surface,
const struct www_surface_listener *listener, void *data)
{
return wl_proxy_add_listener((struct wl_proxy *) www_surface,
(void (**)(void)) listener, data);
}
#define WWW_SURFACE_DESTROY 0
#define WWW_SURFACE_DESTROY_SINCE_VERSION 1
static inline void
www_surface_set_user_data(struct www_surface *www_surface, void *user_data)
{
wl_proxy_set_user_data((struct wl_proxy *) www_surface, user_data);
}
static inline void *
www_surface_get_user_data(struct www_surface *www_surface)
{
return wl_proxy_get_user_data((struct wl_proxy *) www_surface);
}
static inline uint32_t
www_surface_get_version(struct www_surface *www_surface)
{
return wl_proxy_get_version((struct wl_proxy *) www_surface);
}
static inline void
www_surface_destroy(struct www_surface *www_surface)
{
wl_proxy_marshal((struct wl_proxy *) www_surface,
WWW_SURFACE_DESTROY);
wl_proxy_destroy((struct wl_proxy *) www_surface);
}
#ifdef __cplusplus
}
#endif
#endif