summaryrefslogtreecommitdiff
path: root/src/modules/ecore_evas
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/ecore_evas')
-rw-r--r--src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c142
-rw-r--r--src/modules/ecore_evas/engines/drm/ecore_evas_drm.c43
-rw-r--r--src/modules/ecore_evas/engines/drm/meson.build4
-rw-r--r--src/modules/ecore_evas/engines/extn/ecore_evas_extn.c6
-rw-r--r--src/modules/ecore_evas/engines/extn/ecore_evas_extn_buf.c2
-rw-r--r--src/modules/ecore_evas/engines/extn/meson.build1
-rw-r--r--src/modules/ecore_evas/engines/fb/ecore_evas_fb.c4
-rw-r--r--src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c3
-rw-r--r--src/modules/ecore_evas/engines/sdl/meson.build1
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c886
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c2
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h22
-rw-r--r--src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c2
-rw-r--r--src/modules/ecore_evas/engines/wayland/meson.build2
-rw-r--r--src/modules/ecore_evas/engines/win32/ecore_evas_win32.c383
-rw-r--r--src/modules/ecore_evas/engines/win32/meson.build1
-rw-r--r--src/modules/ecore_evas/engines/x/ecore_evas_x.c950
-rw-r--r--src/modules/ecore_evas/engines/x/meson.build2
-rw-r--r--src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c6
19 files changed, 2094 insertions, 368 deletions
diff --git a/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c b/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c
index e1c5a66670..7018a66691 100644
--- a/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c
+++ b/src/modules/ecore_evas/engines/cocoa/ecore_evas_cocoa.c
@@ -34,6 +34,11 @@ static Ecore_Event_Handler *ecore_evas_event_handlers[4];
static const char *_iface_name = "opengl_cocoa";
static const int _iface_version = 1;
+typedef struct {
+ Ecore_Evas_Selection_Callbacks clipboard;
+ Eina_Future *delivery;
+} Ecore_Evas_Cocoa_Engine_Data;
+
static inline Ecore_Evas *
_ecore_evas_cocoa_match(Ecore_Cocoa_Object *cocoa_win)
{
@@ -422,6 +427,130 @@ _ecore_evas_callback_delete_request_set(Ecore_Evas *ee, Ecore_Evas_Event_Cb func
ee->func.fn_delete_request = func;
}
+static Eina_Value
+_delivery(void *data, const Eina_Value value EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Evas_Cocoa_Engine_Data *edata = ee->engine.data;
+ Eina_Rw_Slice slice;
+ const char *mime_type = NULL;
+
+ EINA_SAFETY_ON_NULL_GOTO(edata->delivery, end);
+
+ for (unsigned int i = 0; i < eina_array_count(edata->clipboard.available_types); ++i)
+ {
+ mime_type = eina_array_data_get(edata->clipboard.available_types, i);
+ if (!strncmp("text/", mime_type, strlen("text/")))
+ break;
+ }
+ if (mime_type)
+ {
+ edata->clipboard.delivery(ee, 1, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER, mime_type, &slice);
+ EINA_SAFETY_ON_FALSE_GOTO(ecore_cocoa_clipboard_set(slice.mem, slice.len, mime_type), end);
+ }
+ else
+ {
+ ERR("No compatible mime type found");
+ }
+
+end:
+ return EINA_VALUE_EMPTY;
+}
+
+static Eina_Bool
+_ecore_evas_cocoa_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
+{
+ if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ return EINA_FALSE;
+
+ if (!delivery && !cancel)
+ {
+ ecore_cocoa_clipboard_clear();
+ return EINA_TRUE;
+ }
+ else
+ {
+ Ecore_Evas_Cocoa_Engine_Data *edata = ee->engine.data;
+
+ if (edata->clipboard.cancel)
+ {
+ edata->clipboard.cancel(ee, seat, selection);
+ eina_array_free(edata->clipboard.available_types);
+ }
+
+ edata->delivery = efl_loop_job(efl_main_loop_get());
+ eina_future_then(edata->delivery, _delivery, ee);
+ edata->clipboard.delivery = delivery;
+ edata->clipboard.cancel = cancel;
+ edata->clipboard.available_types = available_types;
+ return EINA_TRUE;
+ }
+}
+
+Eina_Future*
+_ecore_evas_cocoa_selection_request(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_type)
+{
+ Eina_Future *future;
+ Eina_Promise *promise;
+ const char *mime_type;
+
+ if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ return eina_future_rejected(efl_loop_future_scheduler_get(efl_main_loop_get()), ecore_evas_no_selection);
+
+ promise = efl_loop_promise_new(efl_main_loop_get());
+ future = eina_future_new(promise);
+
+ for (unsigned int i = 0; i < eina_array_count(acceptable_type); ++i)
+ {
+ mime_type = eina_array_data_get(acceptable_type, i);
+ if (!strncmp("text/", mime_type, strlen("text/")))
+ break;
+ }
+ if (!mime_type)
+ {
+ eina_promise_reject(promise, ecore_evas_no_matching_type);
+ }
+ else
+ {
+ int size;
+ void *data;
+ Eina_Content *content = NULL;
+ Eina_Rw_Slice slice;
+
+ data = ecore_cocoa_clipboard_get(&size, mime_type);
+
+ if (eina_str_has_prefix(mime_type,"text"))
+ {
+ //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
+ slice.len = size + 1;
+ slice.mem = eina_memdup(data, size, EINA_TRUE);
+ free(data);
+ }
+ else
+ {
+ slice.len = size;
+ slice.mem = data;
+ }
+ if (slice.mem)
+ content = eina_content_new(eina_rw_slice_slice_get(slice), mime_type);
+ free(slice.mem); //memory got duplicated in eina_content_new
+ if (!content) // construction can fail because of some validation reasons
+ eina_promise_reject(promise, ecore_evas_no_matching_type);
+ else
+ eina_promise_resolve(promise, eina_value_content_init(content));
+
+ }
+ return future;
+}
+
+static Eina_Bool
+_ecore_evas_cocoa_selection_has_owner(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection EINA_UNUSED)
+{
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ return ecore_cocoa_clipboard_exists();
+ return EINA_FALSE;
+}
+
static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
{
_ecore_evas_cocoa_free,
@@ -508,6 +637,11 @@ static Ecore_Evas_Engine_Func _ecore_cocoa_engine_func =
NULL, //fn_pointer_device_xy_get
NULL, //fn_prepare
NULL, //fn_last_tick_get
+ _ecore_evas_cocoa_selection_claim, //fn_selection_claim
+ _ecore_evas_cocoa_selection_has_owner, //fn_selection_has_owner
+ _ecore_evas_cocoa_selection_request, //fn_selection_request
+ NULL, //fn_dnd_start
+ NULL, //fn_dnd_stop
};
static Ecore_Cocoa_Window *
@@ -517,11 +651,11 @@ _ecore_evas_cocoa_window_get(const Ecore_Evas *ee)
return (Ecore_Cocoa_Window *)(ee->prop.window);
}
-
EAPI Ecore_Evas *
ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int y, int w, int h)
{
Ecore_Evas *ee;
+ Ecore_Evas_Cocoa_Engine_Data *edata;
Ecore_Evas_Interface_Cocoa *iface;
if (!ecore_cocoa_init())
@@ -532,6 +666,10 @@ ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int
ee = calloc(1, sizeof(Ecore_Evas));
if (!ee)
goto shutdown_ecore_cocoa;
+ edata = calloc(1, sizeof(Ecore_Evas_Cocoa_Engine_Data));
+ if (!edata)
+ goto shutdown_ecore_cocoa_engine_data;
+ ee->engine.data = edata;
ECORE_MAGIC_SET(ee, ECORE_MAGIC_EVAS);
@@ -606,6 +744,8 @@ ecore_evas_cocoa_new_internal(Ecore_Cocoa_Window *parent EINA_UNUSED, int x, int
free(ee->name);
//free_ee:
_ecore_evas_cocoa_shutdown();
+ free(edata);
+ shutdown_ecore_cocoa_engine_data:
free(ee);
shutdown_ecore_cocoa:
ecore_cocoa_shutdown();
diff --git a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
index 35eadc002b..c8f0eb8c24 100644
--- a/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
+++ b/src/modules/ecore_evas/engines/drm/ecore_evas_drm.c
@@ -142,9 +142,8 @@ _drm_device_change(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
static int
_ecore_evas_drm_init(Ecore_Evas *ee, Ecore_Evas_Engine_Drm_Data *edata, const char *device)
{
- // XXX: this is broken. we init once but in a per ecore evas struct so
- // we assume there will be only 1 of these drm ecore evas's ever...
- if (++_drm_init_count != 1) return _drm_init_count;
+ _drm_init_count++;
+ if (_drm_init_count > 1) return _drm_init_count;
if (!ecore_drm2_init())
{
@@ -201,24 +200,31 @@ static int
_ecore_evas_drm_shutdown(Ecore_Evas_Engine_Drm_Data *edata)
{
Ecore_Event_Handler *h;
- if (--_drm_init_count != 0) return _drm_init_count;
- if (edata->focus_job)
+ _drm_init_count--;
+ if (_drm_init_count == 0)
{
- ecore_job_del(edata->focus_job);
- edata->focus_job = NULL;
- }
- if (edata->dev)
- {
- ecore_drm2_outputs_destroy(edata->dev);
- ecore_drm2_device_close(edata->dev);
- edata->dev = NULL;
+ if (edata->focus_job)
+ {
+ ecore_job_del(edata->focus_job);
+ edata->focus_job = NULL;
+ }
+
+ if (edata->dev)
+ {
+ ecore_drm2_outputs_destroy(edata->dev);
+ ecore_drm2_device_close(edata->dev);
+ edata->dev = NULL;
+ }
+
+ ecore_drm2_shutdown();
+ ecore_event_evas_shutdown();
+
+ EINA_LIST_FREE(handlers, h)
+ ecore_event_handler_del(h);
}
- ecore_drm2_shutdown();
- ecore_event_evas_shutdown();
- EINA_LIST_FREE(handlers, h)
- ecore_event_handler_del(h);
+ if (_drm_init_count < 0) _drm_init_count = 0;
return _drm_init_count;
}
@@ -398,8 +404,6 @@ _drm_show(Ecore_Evas *ee)
if (ee->func.fn_state_change) ee->func.fn_state_change(ee);
}
- if (ee->visible) return;
-
ee->visible = 1;
if (ee->func.fn_show) ee->func.fn_show(ee);
@@ -717,6 +721,7 @@ _cb_pageflip(int fd EINA_UNUSED, unsigned int frame EINA_UNUSED, unsigned int se
ecore_drm2_output_info_get(output, &x, &y, &w, &h, NULL);
if (!edata->once) t = ecore_time_get();
+// printf("ECORE_EVAS: drm tick %1.5f @ %1.5f\n", t, ecore_time_get());
ecore_evas_animator_tick(ee, &(Eina_Rectangle){x, y, w, h},
t - edata->offset);
}
diff --git a/src/modules/ecore_evas/engines/drm/meson.build b/src/modules/ecore_evas/engines/drm/meson.build
index 584cc56159..58071010d0 100644
--- a/src/modules/ecore_evas/engines/drm/meson.build
+++ b/src/modules/ecore_evas/engines/drm/meson.build
@@ -1,7 +1,3 @@
-if get_option('opengl') != 'none'
- config_h.set('BUILD_ECORE_EVAS_GL_DRM', '1')
-endif
-
engine_src = files(['ecore_evas_drm.c'])
engine_deps = [ecore_drm2, ecore_input, eeze, elput, libdrm, engine_drm]
diff --git a/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c b/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c
index 28f743ae71..37963fe664 100644
--- a/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c
+++ b/src/modules/ecore_evas/engines/extn/ecore_evas_extn.c
@@ -753,7 +753,7 @@ _ecore_evas_extn_cb_focus_in(void *data, Evas *e EINA_UNUSED, Evas_Object *obj E
Extn *extn;
Evas_Device *dev;
- dev = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_TYPE_SEAT);
+ dev = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT);
if (ecore_evas_focus_device_get(ee, dev)) return;
ee->prop.focused_by = eina_list_append(ee->prop.focused_by, dev);
extn = bdata->data;
@@ -770,7 +770,7 @@ _ecore_evas_extn_cb_focus_out(void *data, Evas *e EINA_UNUSED, Evas_Object *obj
Extn *extn;
ee->prop.focused_by = eina_list_remove(ee->prop.focused_by,
- evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_TYPE_SEAT));
+ evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_SEAT));
extn = bdata->data;
if (!extn) return;
if (!extn->ipc.server) return;
@@ -1030,7 +1030,7 @@ _ipc_server_data(void *data, int type EINA_UNUSED, void *event)
Ipc_Data_Update *ipc;
int n = e->response;
- /* b->lockfd is not enough to ensure the size is same
+ /* b->lockfd is not enough to ensure the size is same
* between what server knows, and client knows.
* So should check file lock also. */
if ((n >= 0) && (n < NBUF))
diff --git a/src/modules/ecore_evas/engines/extn/ecore_evas_extn_buf.c b/src/modules/ecore_evas/engines/extn/ecore_evas_extn_buf.c
index 986dde06ff..055e744c6f 100644
--- a/src/modules/ecore_evas/engines/extn/ecore_evas_extn_buf.c
+++ b/src/modules/ecore_evas/engines/extn/ecore_evas_extn_buf.c
@@ -86,7 +86,7 @@ _extnbuf_free(Extnbuf *b)
if (b->file) shm_unlink(b->file);
if (b->lock) unlink(b->lock);
}
-
+
if (b->addr != MAP_FAILED) munmap(b->addr, b->size);
if (b->fd >= 0) close(b->fd);
if (b->lockfd >= 0) close(b->lockfd);
diff --git a/src/modules/ecore_evas/engines/extn/meson.build b/src/modules/ecore_evas/engines/extn/meson.build
index 901a126f52..4a912b4fbd 100644
--- a/src/modules/ecore_evas/engines/extn/meson.build
+++ b/src/modules/ecore_evas/engines/extn/meson.build
@@ -2,6 +2,7 @@ engine_src = files(['ecore_evas_extn.c', 'ecore_evas_extn_buf.c', 'ecore_evas_ex
engine_deps = [ecore_input, ecore_ipc]
shared_module(mod_full_name, engine_src,
+ c_args : package_c_args,
include_directories : config_dir + [engine_include_dir],
dependencies : [eina, ecore_evas, ecore_input_evas, rt] + engine_deps,
install : true,
diff --git a/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c b/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c
index 17bf83f7c1..ce671e2e3e 100644
--- a/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c
+++ b/src/modules/ecore_evas/engines/fb/ecore_evas_fb.c
@@ -61,7 +61,7 @@ _ecore_evas_mouse_move_process_fb(Ecore_Evas *ee, int x, int y)
ecore_fb_size_get(&fbw, &fbh);
- pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_TYPE_MOUSE);
+ pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
pointer = evas_device_parent_get(pointer);
cursor = eina_hash_find(ee->prop.cursors, &pointer);
EINA_SAFETY_ON_NULL_RETURN(cursor);
@@ -330,7 +330,7 @@ _ecore_evas_rotation_set(Ecore_Evas *ee, int rotation, int resize EINA_UNUSED)
Evas_Engine_Info_FB *einfo;
int rot_dif;
- pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_TYPE_MOUSE);
+ pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
pointer = evas_device_parent_get(pointer);
cursor = eina_hash_find(ee->prop.cursors, &pointer);
EINA_SAFETY_ON_NULL_RETURN(cursor);
diff --git a/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c b/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c
index 8abc7401b6..ef4ba057b9 100644
--- a/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c
+++ b/src/modules/ecore_evas/engines/sdl/ecore_evas_sdl.c
@@ -455,6 +455,9 @@ static Ecore_Evas_Engine_Func _ecore_sdl_engine_func =
NULL, //fn_pointer_device_xy_get
NULL, //fn_prepare
NULL, //fn_last_tick_get
+ NULL, //fn_selection_claim
+ NULL, //fn_selection_has_owner
+ NULL, //fn_selection_request
};
static Ecore_Evas*
diff --git a/src/modules/ecore_evas/engines/sdl/meson.build b/src/modules/ecore_evas/engines/sdl/meson.build
index 94b990df92..030ca6561a 100644
--- a/src/modules/ecore_evas/engines/sdl/meson.build
+++ b/src/modules/ecore_evas/engines/sdl/meson.build
@@ -2,6 +2,7 @@ engine_src = files(['ecore_evas_sdl.c'])
engine_deps = [ecore_sdl, ecore_input, ecore, dependency('sdl2')]
shared_module(mod_full_name, engine_src,
+ c_args : package_c_args,
include_directories : config_dir + [engine_include_dir],
dependencies : [eina, ecore_evas, ecore_input_evas] + engine_deps,
install : true,
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
index ad922474cd..1cec016ebc 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_common.c
@@ -4,9 +4,10 @@
#include "ecore_evas_wayland_private.h"
#include <Evas_Engine_Wayland.h>
+#include "ecore_wl2_internal.h"
-extern EAPI Eina_List *_evas_canvas_image_data_unset(Evas *eo_e);
-extern EAPI void _evas_canvas_image_data_regenerate(Eina_List *list);
+EAPI extern Eina_List *_evas_canvas_image_data_unset(Evas *eo_e);
+EAPI extern void _evas_canvas_image_data_regenerate(Eina_List *list);
#define _smart_frame_type "ecore_evas_wl_frame"
@@ -32,19 +33,27 @@ static Eina_Array *_ecore_evas_wl_event_hdls;
static void _ecore_evas_wayland_resize(Ecore_Evas *ee, int location);
static void _ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize);
+static void _ecore_evas_wl_selection_init(Ecore_Evas *ee);
/* local functions */
static void
-_anim_cb_tick(Ecore_Wl2_Window *win EINA_UNUSED, uint32_t timestamp EINA_UNUSED, void *data)
+_anim_cb_tick(Ecore_Wl2_Window *win EINA_UNUSED, uint32_t timestamp, void *data)
{
Ecore_Evas *ee = data;
Ecore_Evas_Engine_Wl_Data *edata;
+ double t;//, rt;
+ /* static double pt = 0.0, prt = 0.0; */
edata = ee->engine.data;
if (!edata->ticking) return;
-
- ecore_evas_animator_tick(ee, NULL, ecore_loop_time_get());
+ t = ((double)timestamp / 1000.0);
+ ecore_loop_time_set(t);
+ /* rt = ecore_time_get(); */
+ /* printf("ECORE_EVAS: wl client anim tick %p | %p - %1.5f @ %1.5f delt=%1.5f | %1.5f\n", ee, edata, t, ecore_time_get(), t - pt, rt - prt); */
+ ecore_evas_animator_tick(ee, NULL, t);
+ /* pt = t; */
+ /* prt = rt; */
}
static void
@@ -57,8 +66,8 @@ _ecore_evas_wl_common_animator_register(Ecore_Evas *ee)
EINA_SAFETY_ON_TRUE_RETURN(edata->ticking);
EINA_SAFETY_ON_TRUE_RETURN(edata->frame != NULL);
- edata->frame = ecore_wl2_window_frame_callback_add(edata->win,
- _anim_cb_tick, ee);
+ edata->frame =
+ ecore_wl2_window_frame_callback_add(edata->win, _anim_cb_tick, ee);
if (!ecore_wl2_window_pending_get(edata->win) && !ee->in_async_render &&
!ee->animator_ticked && !ee->animator_ran && !ee->draw_block)
ecore_wl2_window_false_commit(edata->win);
@@ -112,7 +121,7 @@ _ecore_evas_wl_common_cb_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED,
Ecore_Evas *ee;
Ecore_Event_Mouse_IO *ev;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
ev = event;
ee = ecore_event_window_match((Ecore_Window)ev->window);
@@ -133,12 +142,13 @@ _ecore_evas_wl_common_cb_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED,
Ecore_Evas *ee;
Ecore_Event_Mouse_IO *ev;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
ev = event;
ee = ecore_event_window_match((Ecore_Window)ev->window);
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
- if ((Ecore_Window)ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+ if ((Ecore_Window)ev->window != ee->prop.window)
+ return ECORE_CALLBACK_PASS_ON;
if (!_ecore_evas_mouse_in_check(ee, ev->dev)) return ECORE_CALLBACK_PASS_ON;
ecore_event_evas_seat_modifier_lock_update(ee->evas,
@@ -155,12 +165,13 @@ _ecore_evas_wl_common_cb_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED,
Ecore_Evas *ee;
Ecore_Wl2_Event_Focus_In *ev;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
ev = event;
ee = ecore_event_window_match((Ecore_Window)ev->window);
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
- if ((Ecore_Window)ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+ if ((Ecore_Window)ev->window != ee->prop.window)
+ return ECORE_CALLBACK_PASS_ON;
_ecore_evas_focus_device_set(ee, ev->dev, EINA_TRUE);
return ECORE_CALLBACK_PASS_ON;
}
@@ -171,12 +182,13 @@ _ecore_evas_wl_common_cb_focus_out(void *data EINA_UNUSED, int type EINA_UNUSED,
Ecore_Evas *ee;
Ecore_Wl2_Event_Focus_Out *ev;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
ev = event;
ee = ecore_event_window_match((Ecore_Window)ev->window);
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
- if ((Ecore_Window)ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
+ if ((Ecore_Window)ev->window != ee->prop.window)
+ return ECORE_CALLBACK_PASS_ON;
_ecore_evas_focus_device_set(ee, ev->dev, EINA_FALSE);
return ECORE_CALLBACK_PASS_ON;
}
@@ -282,9 +294,7 @@ _ecore_evas_wayland_window_update(Ecore_Evas *ee, Ecore_Evas_Engine_Wl_Data *wda
*/
else if (!ee->alpha)
{
- ecore_wl2_window_opaque_region_set(wdata->win,
- 0, 0,
- fullw, fullh);
+ ecore_wl2_window_opaque_region_set(wdata->win, 0, 0, fullw, fullh);
}
/* alpha is set and we might use it, so we'd better clear the
* opaque region, let the compositor blend it all.
@@ -302,9 +312,9 @@ _ecore_evas_wayland_window_update(Ecore_Evas *ee, Ecore_Evas_Engine_Wl_Data *wda
if (!change) return;
if (ECORE_EVAS_PORTRAIT(ee))
- evas_damage_rectangle_add(ee->evas, 0, 0, fullw, fullh);
+ evas_damage_rectangle_add(ee->evas, 0, 0, fullw, fullh);
else
- evas_damage_rectangle_add(ee->evas, 0, 0, fullh, fullw);
+ evas_damage_rectangle_add(ee->evas, 0, 0, fullh, fullw);
ee->shadow.changed = EINA_FALSE;
}
@@ -313,10 +323,10 @@ static void
_ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- int ow, oh, ew, eh;
+ int ow, oh, ew, eh, fw, fh, ww, hh;
int diff = 0;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
@@ -326,6 +336,8 @@ _ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
ee->req.w = w;
ee->req.h = h;
+ evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
+
/* TODO: wayland client can resize the ecore_evas directly.
* In the future, we will remove ee->req value in wayland backend */
ew = ee->w;
@@ -333,85 +345,81 @@ _ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
ee->w = w;
ee->h = h;
- if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel && wdata->win->pending.min)
+ if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel &&
+ wdata->win->pending.min)
{
- wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, ee->prop.min.w, ee->prop.min.h);
+ ww = ee->prop.min.w + fw;
+ hh = ee->prop.min.h + fh;
+ if (ww < 1) ww = 1;
+ if (hh < 1) hh = 1;
+ wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, ww, hh);
wdata->win->pending.min = 0;
}
- if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel && wdata->win->pending.max)
+ if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel &&
+ wdata->win->pending.max)
{
- wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, ee->prop.max.w, ee->prop.max.h);
+ ww = ee->prop.max.w + fw;
+ hh = ee->prop.max.h + fh;
+ if (ww < 0) ww = 0;
+ if (hh < 0) hh = 0;
+ wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, ww, hh);
wdata->win->pending.max = 0;
}
- if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel && wdata->win->pending.min)
+ if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel &&
+ wdata->win->pending.min)
{
- wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, ee->prop.min.w, ee->prop.min.h);
+ ww = ee->prop.min.w + fw;
+ hh = ee->prop.min.h + fh;
+ if (ww < 1) ww = 1;
+ if (hh < 1) hh = 1;
+ wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, ww, hh);
wdata->win->pending.min = 0;
}
- if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel && wdata->win->pending.max)
+ if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel &&
+ wdata->win->pending.max)
{
- wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, ee->prop.max.w, ee->prop.max.h);
+ ww = ee->prop.max.w + fw;
+ hh = ee->prop.max.h + fh;
+ if (ww < 0) ww = 0;
+ if (hh < 0) hh = 0;
+ wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, ww, hh);
wdata->win->pending.max = 0;
}
if (!ee->prop.fullscreen)
{
- int fw = 0, fh = 0;
int maxw = 0, maxh = 0;
int minw = 0, minh = 0;
- evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
-
- if (ECORE_EVAS_PORTRAIT(ee))
- {
- if (ee->prop.min.w > 0)
- minw = (ee->prop.min.w - fw);
- if (ee->prop.min.h > 0)
- minh = (ee->prop.min.h - fh);
- if (ee->prop.max.w > 0)
- maxw = (ee->prop.max.w + fw);
- if (ee->prop.max.h > 0)
- maxh = (ee->prop.max.h + fh);
- }
- else
- {
- if (ee->prop.min.w > 0)
- minw = (ee->prop.min.w - fh);
- if (ee->prop.min.h > 0)
- minh = (ee->prop.min.h - fw);
- if (ee->prop.max.w > 0)
- maxw = (ee->prop.max.w + fh);
- if (ee->prop.max.h > 0)
- maxh = (ee->prop.max.h + fw);
- }
+ if (ee->prop.min.w > 0) minw = (ee->prop.min.w);
+ if (ee->prop.min.h > 0) minh = (ee->prop.min.h);
+ if (ee->prop.max.w > 0) maxw = (ee->prop.max.w);
+ if (ee->prop.max.h > 0) maxh = (ee->prop.max.h);
- if ((maxw > 0) && (w > maxw))
- w = maxw;
- else if (w < minw)
- w = minw;
+ if ((maxw > 0) && (w > maxw)) w = maxw;
+ else if (w < minw) w = minw;
- if ((maxh > 0) && (h > maxh))
- h = maxh;
- else if (h < minh)
- h = minh;
+ if ((maxh > 0) && (h > maxh)) h = maxh;
+ else if (h < minh) h = minh;
if (!ee->prop.maximized)
{
/* calc new size using base size & step size */
if (ee->prop.step.w > 1)
{
- int bw = ee->prop.base.w ?: minw;
+ int bw = ee->prop.base.w;
w = (bw + (((w - bw) / ee->prop.step.w) * ee->prop.step.w));
}
if (ee->prop.step.h > 1)
{
- int bh = ee->prop.base.h ?: minh;
+ int bh = ee->prop.base.h;
h = (bh + (((h - bh) / ee->prop.step.h) * ee->prop.step.h));
}
- if (!wdata->win->display->wl.efl_hints && EINA_DBL_NONZERO(ee->prop.aspect))
+ if (!wdata->win->display->wl.efl_hints &&
+ EINA_DBL_NONZERO(ee->prop.aspect))
{
/* copied from e_client.c */
Evas_Aspect_Control aspect;
@@ -479,9 +487,9 @@ _ecore_evas_wl_common_resize(Ecore_Evas *ee, int w, int h)
}
if (ECORE_EVAS_PORTRAIT(ee))
- evas_output_size_get(ee->evas, &ow, &oh);
+ evas_output_size_get(ee->evas, &ow, &oh);
else
- evas_output_size_get(ee->evas, &oh, &ow);
+ evas_output_size_get(ee->evas, &oh, &ow);
if (ECORE_EVAS_PORTRAIT(ee) && ((ow != w) || (oh != h)))
diff = 1;
@@ -589,7 +597,7 @@ _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_
int framew, frameh;
Eina_Bool active, prev_max, prev_full, state_change = EINA_FALSE;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
ev = event;
ee = ecore_event_window_match((Ecore_Window)ev->win);
@@ -605,9 +613,11 @@ _ecore_evas_wl_common_cb_window_configure(void *data EINA_UNUSED, int type EINA_
prev_max = ee->prop.maximized;
prev_full = ee->prop.fullscreen;
ee->prop.maximized =
- (ev->states & ECORE_WL2_WINDOW_STATE_MAXIMIZED) == ECORE_WL2_WINDOW_STATE_MAXIMIZED;
+ (ev->states & ECORE_WL2_WINDOW_STATE_MAXIMIZED) ==
+ ECORE_WL2_WINDOW_STATE_MAXIMIZED;
ee->prop.fullscreen =
- (ev->states & ECORE_WL2_WINDOW_STATE_FULLSCREEN) == ECORE_WL2_WINDOW_STATE_FULLSCREEN;
+ (ev->states & ECORE_WL2_WINDOW_STATE_FULLSCREEN) ==
+ ECORE_WL2_WINDOW_STATE_FULLSCREEN;
active = wdata->activated;
wdata->activated = ecore_wl2_window_activated_get(wdata->win);
@@ -718,7 +728,7 @@ _ecore_evas_wl_common_cb_window_configure_complete(void *data EINA_UNUSED, int t
Evas_Engine_Info_Wayland *einfo;
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
ev = event;
ee = ecore_event_window_match((Ecore_Window)ev->win);
@@ -771,8 +781,10 @@ _ecore_evas_wl_common_cb_aux_hint_supported(void *data EINA_UNUSED, int type EI
if (!ee) return ECORE_CALLBACK_PASS_ON;
if ((Ecore_Window)ev->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
wdata = ee->engine.data;
- EINA_LIST_FREE(ee->prop.aux_hint.supported_list, hint) eina_stringshare_del(hint);
- ee->prop.aux_hint.supported_list = ecore_wl2_window_aux_hints_supported_get(wdata->win);
+ EINA_LIST_FREE(ee->prop.aux_hint.supported_list, hint)
+ eina_stringshare_del(hint);
+ ee->prop.aux_hint.supported_list =
+ ecore_wl2_window_aux_hints_supported_get(wdata->win);
return ECORE_CALLBACK_RENEW;
}
@@ -811,7 +823,7 @@ _ecore_evas_wl_common_cb_window_rotate(void *data EINA_UNUSED, int type EINA_UNU
Ecore_Evas *ee;
Ecore_Wl2_Event_Window_Rotation *ev;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
ev = event;
ee = ecore_event_window_match((Ecore_Window)ev->win);
@@ -882,14 +894,14 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
{
/* resize the canvas */
evas_output_size_set(ee->evas, ee->req.w, ee->req.h);
- evas_output_viewport_set(ee->evas, 0, 0,
+ evas_output_viewport_set(ee->evas, 0, 0,
ee->req.w, ee->req.h);
}
else
{
/* resize the canvas */
evas_output_size_set(ee->evas, ee->req.h, ee->req.w);
- evas_output_viewport_set(ee->evas, 0, 0,
+ evas_output_viewport_set(ee->evas, 0, 0,
ee->req.h, ee->req.w);
}
}
@@ -975,43 +987,6 @@ _rotation_do(Ecore_Evas *ee, int rotation, int resize)
}
}
-static Eina_Bool
-_ecore_evas_wl_common_cb_www_drag(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
-{
- Ecore_Wl2_Event_Window_WWW_Drag *ev = event;
- Ecore_Evas_Engine_Wl_Data *wdata;
- Ecore_Evas *ee;
-
- ee = ecore_event_window_match((Ecore_Window)ev->window);
- if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
- if ((Ecore_Window)ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
-
- wdata = ee->engine.data;
- wdata->dragging = !!ev->dragging;
- if (!ev->dragging)
- evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
- return ECORE_CALLBACK_RENEW;
-}
-
-static Eina_Bool
-_ecore_evas_wl_common_cb_www(void *d EINA_UNUSED, int t EINA_UNUSED, void *event)
-{
- Ecore_Wl2_Event_Window_WWW *ev = event;
- Ecore_Evas_Engine_Wl_Data *wdata;
- Ecore_Evas *ee;
-
- ee = ecore_event_window_match((Ecore_Window)ev->window);
- if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON;
- if ((Ecore_Window)ev->window != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
-
- wdata = ee->engine.data;
- wdata->x_rel += ev->x_rel;
- wdata->y_rel += ev->y_rel;
- wdata->timestamp = ev->timestamp;
- evas_damage_rectangle_add(ee->evas, 0, 0, ee->w, ee->h);
- return ECORE_CALLBACK_RENEW;
-}
-
static void
_ecore_evas_wl_common_cb_device_event_free(void *user_data, void *func_data)
{
@@ -1081,7 +1056,7 @@ _ecore_evas_wl_common_cb_global_added(void *d EINA_UNUSED, int t EINA_UNUSED, vo
EE_Wl_Device *device;
if ((!ev->interface) || (strcmp(ev->interface, "wl_seat")))
- return ECORE_CALLBACK_PASS_ON;
+ return ECORE_CALLBACK_PASS_ON;
EINA_LIST_FOREACH(ee_list, l, ee)
{
@@ -1130,7 +1105,7 @@ _ecore_evas_wl_common_cb_global_removed(void *d EINA_UNUSED, int t EINA_UNUSED,
Eina_List *l, *ll;
if ((!ev->interface) || (strcmp(ev->interface, "wl_seat")))
- return ECORE_CALLBACK_PASS_ON;
+ return ECORE_CALLBACK_PASS_ON;
EINA_LIST_FOREACH(ee_list, l, ee)
{
@@ -1320,7 +1295,7 @@ static int
_ecore_evas_wl_common_init(void)
{
Ecore_Event_Handler *h;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (++_ecore_evas_wl_init_count != 1)
return _ecore_evas_wl_init_count;
@@ -1347,14 +1322,6 @@ _ecore_evas_wl_common_init(void)
_ecore_evas_wl_common_cb_window_configure, NULL);
eina_array_push(_ecore_evas_wl_event_hdls, h);
- h = ecore_event_handler_add(_ecore_wl2_event_window_www,
- _ecore_evas_wl_common_cb_www, NULL);
- eina_array_push(_ecore_evas_wl_event_hdls, h);
-
- h = ecore_event_handler_add(_ecore_wl2_event_window_www_drag,
- _ecore_evas_wl_common_cb_www_drag, NULL);
- eina_array_push(_ecore_evas_wl_event_hdls, h);
-
h = ecore_event_handler_add(ECORE_WL2_EVENT_DISCONNECT,
_ecore_evas_wl_common_cb_disconnect, NULL);
eina_array_push(_ecore_evas_wl_event_hdls, h);
@@ -1409,7 +1376,7 @@ _ecore_evas_wl_common_init(void)
static int
_ecore_evas_wl_common_shutdown(void)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (--_ecore_evas_wl_init_count != 0)
return _ecore_evas_wl_init_count;
@@ -1430,7 +1397,7 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
Ecore_Evas_Engine_Wl_Data *wdata;
EE_Wl_Device *device;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
@@ -1441,6 +1408,15 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
if (wdata->frame) ecore_wl2_window_frame_callback_del(wdata->frame);
wdata->frame = NULL;
ecore_event_handler_del(wdata->sync_handler);
+ ecore_event_handler_del(wdata->changed_handler);
+ ecore_event_handler_del(wdata->send_handler);
+ ecore_event_handler_del(wdata->offer_handler);
+ ecore_event_handler_del(wdata->dnd_leave_handler);
+ ecore_event_handler_del(wdata->dnd_enter_handler);
+ ecore_event_handler_del(wdata->dnd_motion_handler);
+ ecore_event_handler_del(wdata->dnd_drop_handler);
+ ecore_event_handler_del(wdata->dnd_end_handler);
+
if (wdata->win)
{
ecore_wl2_window_close_callback_set(wdata->win, NULL, NULL);
@@ -1450,7 +1426,7 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
ecore_wl2_display_disconnect(wdata->display);
EINA_LIST_FREE(wdata->devices_list, device)
- free(device);
+ free(device);
free(wdata);
@@ -1464,7 +1440,7 @@ _ecore_evas_wl_common_free(Ecore_Evas *ee)
static void
_ecore_evas_wl_common_move_resize(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED, int w, int h)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if ((ee->w != w) || (ee->h != h))
@@ -1526,10 +1502,12 @@ _ecore_evas_wl_common_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_C
Ecore_Evas_Engine_Wl_Data *wdata;
Ecore_Wl2_Input *input;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
wdata = ee->engine.data;
- input = ecore_wl2_display_input_find_by_name(ecore_wl2_window_display_get(wdata->win), "default");
+ input =
+ ecore_wl2_display_input_find_by_name
+ (ecore_wl2_window_display_get(wdata->win), "default");
if (input) ecore_wl2_input_pointer_xy_get(input, x, y);
}
@@ -1601,12 +1579,14 @@ _ecore_evas_wl_common_pointer_device_xy_get(const Ecore_Evas *ee, const Efl_Inpu
Ecore_Wl2_Input *input;
const Eo *seat;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
wdata = ee->engine.data;
seat = evas_device_parent_get(pointer);
EINA_SAFETY_ON_NULL_RETURN(seat);
- input = ecore_wl2_display_input_find(ecore_wl2_window_display_get(wdata->win), evas_device_seat_id_get(seat));
+ input =
+ ecore_wl2_display_input_find
+ (ecore_wl2_window_display_get(wdata->win), evas_device_seat_id_get(seat));
EINA_SAFETY_ON_NULL_RETURN(input);
ecore_wl2_input_pointer_xy_get(input, x, y);
}
@@ -1616,11 +1596,12 @@ _ecore_evas_wl_common_aux_hints_supported_update(Ecore_Evas *ee)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
wdata = ee->engine.data;
- ee->prop.aux_hint.supported_list = ecore_wl2_window_aux_hints_supported_get(wdata->win);
+ ee->prop.aux_hint.supported_list =
+ ecore_wl2_window_aux_hints_supported_get(wdata->win);
}
static void
@@ -1628,7 +1609,7 @@ _ecore_evas_wl_common_title_set(Ecore_Evas *ee, const char *title)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (eina_streq(ee->prop.title, title)) return;
@@ -1647,7 +1628,7 @@ _ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
wdata = ee->engine.data;
@@ -1671,8 +1652,9 @@ _ecore_evas_wl_common_name_class_set(Ecore_Evas *ee, const char *n, const char *
static void
_ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h)
{
+ int fw, fh, ww, hh;
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
@@ -1682,14 +1664,23 @@ _ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h)
ee->prop.min.w = w;
ee->prop.min.h = h;
wdata = ee->engine.data;
+ evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel)
{
- wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, w, h);
+ ww = w + fw;
+ hh = h + fh;
+ if (ww < 1) ww = 1;
+ if (hh < 1) hh = 1;
+ wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, ww, hh);
wdata->win->pending.min = 0;
}
if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel)
{
- wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, w, h);
+ ww = w + fw;
+ hh = h + fh;
+ if (ww < 1) ww = 1;
+ if (hh < 1) hh = 1;
+ wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, ww, hh);
wdata->win->pending.min = 0;
}
else
@@ -1700,8 +1691,9 @@ _ecore_evas_wl_common_size_min_set(Ecore_Evas *ee, int w, int h)
static void
_ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h)
{
+ int fw, fh, ww, hh;
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (w < 0) w = 0;
@@ -1710,14 +1702,23 @@ _ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h)
ee->prop.max.w = w;
ee->prop.max.h = h;
wdata = ee->engine.data;
+ evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel)
{
- wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, w, h);
+ ww = w + fw;
+ hh = h + fh;
+ if (ww < 0) ww = 0;
+ if (hh < 0) hh = 0;
+ wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, ww, hh);
wdata->win->pending.max = 0;
}
if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel)
{
- wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, w, h);
+ ww = w + fw;
+ hh = h + fh;
+ if (ww < 0) ww = 0;
+ if (hh < 0) hh = 0;
+ wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, ww, hh);
wdata->win->pending.max = 0;
}
else
@@ -1728,7 +1729,7 @@ _ecore_evas_wl_common_size_max_set(Ecore_Evas *ee, int w, int h)
static void
_ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (w < 0) w = 0;
@@ -1742,7 +1743,7 @@ _ecore_evas_wl_common_size_base_set(Ecore_Evas *ee, int w, int h)
static void
_ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (w < 0) w = 0;
@@ -1756,7 +1757,7 @@ _ecore_evas_wl_common_size_step_set(Ecore_Evas *ee, int w, int h)
static void
_ecore_evas_wl_common_aspect_set(Ecore_Evas *ee, double aspect)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (EINA_FLT_EQ(ee->prop.aspect, aspect)) return;
@@ -1784,14 +1785,16 @@ _ecore_evas_wl_common_object_cursor_set(Ecore_Evas *ee, Evas_Object *obj, int la
wdata = ee->engine.data;
if (obj == _ecore_evas_default_cursor_image_get(ee)) return;
- input = ecore_wl2_display_input_find_by_name(ecore_wl2_window_display_get(wdata->win), "default");
+ input =
+ ecore_wl2_display_input_find_by_name
+ (ecore_wl2_window_display_get(wdata->win), "default");
if (input) ecore_wl2_input_pointer_set(input, NULL, hot_x, hot_y);
}
static void
_ecore_evas_wl_common_layer_set(Ecore_Evas *ee, int layer)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (ee->prop.layer == layer) return;
@@ -1806,7 +1809,7 @@ _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, Eina_Bool on)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
ee->prop.iconified = on;
@@ -1818,7 +1821,7 @@ _ecore_evas_wl_common_iconified_set(Ecore_Evas *ee, Eina_Bool on)
static void
_ecore_evas_wl_common_borderless_set(Ecore_Evas *ee, Eina_Bool on)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (ee->prop.borderless == on) return;
@@ -1832,7 +1835,7 @@ _ecore_evas_wl_common_maximized_set(Ecore_Evas *ee, Eina_Bool on)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (ee->prop.maximized == on) return;
@@ -1846,7 +1849,7 @@ _ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (ee->prop.fullscreen == on) return;
@@ -1858,7 +1861,7 @@ _ecore_evas_wl_common_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
static void
_ecore_evas_wl_common_ignore_events_set(Ecore_Evas *ee, int ignore)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
ee->ignore_events = ignore;
@@ -1923,7 +1926,7 @@ _ecore_evas_wayland_alpha_do(Ecore_Evas *ee, int alpha)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (ee->alpha == alpha) return;
@@ -1973,7 +1976,7 @@ _ecore_evas_wl_common_prepare(Ecore_Evas *ee)
static void
_ecore_evas_wl_common_withdrawn_set(Ecore_Evas *ee, Eina_Bool on)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (ee->prop.withdrawn == on) return;
@@ -1992,7 +1995,7 @@ _ecore_evas_wl_common_screen_geometry_get(const Ecore_Evas *ee, int *x, int *y,
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (x) *x = 0;
if (y) *y = 0;
@@ -2008,7 +2011,7 @@ _ecore_evas_wl_common_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi)
Ecore_Wl2_Output *output;
int dpi = 0;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
if (xdpi) *xdpi = 0;
@@ -2029,7 +2032,7 @@ _ecore_evas_wayland_resize(Ecore_Evas *ee, int location)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
wdata = ee->engine.data;
@@ -2042,7 +2045,7 @@ _ecore_evas_wayland_move(Ecore_Evas *ee, int x EINA_UNUSED, int y EINA_UNUSED)
{
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!ee) return;
wdata = ee->engine.data;
@@ -2136,8 +2139,9 @@ _ecore_evas_wl_common_show(Ecore_Evas *ee)
{
Evas_Engine_Info_Wayland *einfo;
Ecore_Evas_Engine_Wl_Data *wdata;
+ int ww, hh;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if ((!ee) || (ee->visible)) return;
@@ -2153,31 +2157,50 @@ _ecore_evas_wl_common_show(Ecore_Evas *ee)
{
int fw, fh;
- if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel && wdata->win->pending.min)
+ evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
+ if (wdata->win->xdg_set_min_size && wdata->win->xdg_toplevel &&
+ wdata->win->pending.min)
{
- wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, ee->prop.min.w, ee->prop.min.h);
+ ww = ee->prop.min.w + fw;
+ hh = ee->prop.min.h + fh;
+ if (ww < 1) ww = 1;
+ if (hh < 1) hh = 1;
+ wdata->win->xdg_set_min_size(wdata->win->xdg_toplevel, ww, hh);
wdata->win->pending.min = 0;
}
- if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel && wdata->win->pending.max)
+ if (wdata->win->xdg_set_max_size && wdata->win->xdg_toplevel &&
+ wdata->win->pending.max)
{
- wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, ee->prop.max.w, ee->prop.max.h);
+ ww = ee->prop.max.w + fw;
+ hh = ee->prop.max.h + fh;
+ if (ww < 0) ww = 0;
+ if (hh < 0) hh = 0;
+ wdata->win->xdg_set_max_size(wdata->win->xdg_toplevel, ww, hh);
wdata->win->pending.max = 0;
}
- if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel && wdata->win->pending.min)
+ if (wdata->win->zxdg_set_min_size && wdata->win->zxdg_toplevel &&
+ wdata->win->pending.min)
{
- wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, ee->prop.min.w, ee->prop.min.h);
+ ww = ee->prop.min.w + fw;
+ hh = ee->prop.min.h + fh;
+ if (ww < 1) ww = 1;
+ if (hh < 1) hh = 1;
+ wdata->win->zxdg_set_min_size(wdata->win->zxdg_toplevel, ww, hh);
wdata->win->pending.min = 0;
}
- if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel && wdata->win->pending.max)
+ if (wdata->win->zxdg_set_max_size && wdata->win->zxdg_toplevel &&
+ wdata->win->pending.max)
{
- wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, ee->prop.max.w, ee->prop.max.h);
+ ww = ee->prop.max.w + fw;
+ hh = ee->prop.max.h + fh;
+ if (ww < 0) ww = 0;
+ if (hh < 0) hh = 0;
+ wdata->win->zxdg_set_max_size(wdata->win->zxdg_toplevel, ww, hh);
wdata->win->pending.max = 0;
}
_ecore_evas_wayland_window_update(ee, wdata, ee->alpha);
- evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
-
ecore_wl2_window_show(wdata->win);
einfo = (Evas_Engine_Info_Wayland *)evas_engine_info_get(ee->evas);
if (einfo)
@@ -2185,7 +2208,6 @@ _ecore_evas_wl_common_show(Ecore_Evas *ee)
einfo->info.destination_alpha = ee_needs_alpha(ee);
einfo->info.wl2_win = wdata->win;
einfo->info.hidden = wdata->win->pending.configure; //EINA_FALSE;
- einfo->www_avail = !!wdata->win->www_surface;
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
ERR("Failed to set Evas Engine Info for '%s'", ee->driver);
if (ECORE_EVAS_PORTRAIT(ee))
@@ -2208,7 +2230,7 @@ _ecore_evas_wl_common_hide(Ecore_Evas *ee)
Evas_Engine_Info_Wayland *einfo;
Ecore_Evas_Engine_Wl_Data *wdata;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if ((!ee) || (!ee->visible)) return;
wdata = ee->engine.data;
@@ -2257,7 +2279,7 @@ _ecore_evas_wl_common_alpha_set(Ecore_Evas *ee, int alpha)
static void
_ecore_evas_wl_common_rotation_set(Ecore_Evas *ee, int rotation, int resize)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (ee->rotation == rotation) return;
@@ -2387,6 +2409,518 @@ _ecore_wl2_devices_setup(Ecore_Evas *ee, Ecore_Wl2_Display *display)
return r;
}
+static void
+_reeval_seat(unsigned int *seat, Ecore_Evas *ee)
+{
+ if (*seat == 0)
+ {
+ *seat =
+ evas_device_seat_id_get(evas_default_device_get
+ (ee->evas, EVAS_DEVICE_CLASS_SEAT));
+ }
+}
+
+static inline void
+_clear_selection(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection)
+{
+ Ecore_Evas_Engine_Wl_Data *edata = ee->engine.data;
+ Ecore_Evas_Selection_Callbacks *cbs;
+
+ cbs = &edata->selection_data[selection].callbacks;
+ EINA_SAFETY_ON_FALSE_RETURN(cbs->cancel);
+
+ cbs->cancel(ee, seat, selection);
+ eina_array_free(cbs->available_types);
+ memset(cbs, 0, sizeof(Ecore_Evas_Selection_Callbacks));
+}
+
+static void
+_store_selection_cbs(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
+{
+ Ecore_Evas_Wl_Selection_Data *sdata;
+ Ecore_Evas_Engine_Wl_Data *edata;
+ Ecore_Evas_Selection_Callbacks *cbs;
+
+ edata = ee->engine.data;
+ sdata = &edata->selection_data[selection];
+ cbs = &sdata->callbacks;
+
+ if (cbs->cancel)
+ {
+ _clear_selection(ee, seat, selection);
+ }
+
+ cbs->delivery = delivery;
+ cbs->cancel = cancel;
+ cbs->available_types = available_types;
+}
+
+static inline Ecore_Wl2_Input*
+_fetch_input(Ecore_Evas *ee, unsigned int seat)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ return ecore_wl2_display_input_find(ecore_wl2_window_display_get(wdata->win), seat);
+}
+
+static Eina_Bool
+_ecore_evas_wl_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
+ char *tmp_array[eina_array_count(available_types) + 1];
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
+ {
+ _store_selection_cbs(ee, seat, selection, available_types,
+ delivery, cancel);
+ return EINA_TRUE;
+ }
+
+ _reeval_seat(&seat, ee);
+ _store_selection_cbs(ee, seat, selection, available_types, delivery, cancel);
+
+ for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
+ {
+ tmp_array[i] = eina_array_data_get(available_types, i);
+ }
+ tmp_array[eina_array_count(available_types)] = NULL;
+
+ data->sent_serial =
+ ecore_wl2_dnd_selection_set(_fetch_input(ee, seat),
+ (const char**)tmp_array);
+ return EINA_TRUE;
+}
+
+
+static Eina_Future*
+_ecore_evas_wl_selection_request(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_types)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
+ Ecore_Wl2_Input *input;
+ Ecore_Wl2_Offer *offer = NULL;
+ Eina_Future *future;
+
+ _reeval_seat(&seat, ee);
+ input = _fetch_input(ee, seat);
+
+ if (data->delivery)
+ {
+ eina_promise_reject(data->delivery, ecore_evas_request_replaced);
+ data->delivery = NULL;
+ }
+ data->delivery = efl_loop_promise_new(efl_main_loop_get());
+ future = eina_future_new(data->delivery);
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ {
+ offer = data->offer = wdata->external_offer;
+ }
+ else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ {
+ offer = data->offer = ecore_wl2_dnd_selection_get(input);
+ }
+
+ if (!offer)
+ {
+ eina_promise_reject(data->delivery, ecore_evas_no_selection);
+ data->delivery = NULL;
+ }
+ else
+ {
+ Eina_Array *available_types = ecore_wl2_offer_mimes_get(offer);
+ char *selected_type = NULL;
+
+ for (unsigned int i = 0; i < eina_array_count(available_types) && !selected_type; ++i)
+ {
+ char *available_type = eina_array_data_get(available_types, i);
+ for (unsigned int j = 0; j < eina_array_count(acceptable_types) && !selected_type; ++j)
+ {
+ Eina_Iterator *convertions;
+ const char *convert_available_type;
+ char *acceptable_type;
+
+ acceptable_type = eina_array_data_get(acceptable_types, j);
+ if (eina_streq(acceptable_type, available_type))
+ {
+ selected_type = available_type;
+ data->later_convert = NULL;
+ break;
+ }
+
+ convertions =
+ eina_content_converter_possible_conversions(available_type);
+
+ EINA_ITERATOR_FOREACH(convertions, convert_available_type)
+ {
+ if (eina_streq(convert_available_type, acceptable_type))
+ {
+ selected_type = available_type;
+ data->later_convert = acceptable_type;
+ }
+ }
+ eina_iterator_free(convertions);
+ }
+
+ }
+ if (selected_type)
+ {
+ ecore_wl2_offer_receive(offer, selected_type);
+ ecore_wl2_display_flush(ecore_wl2_input_display_get(input));
+ }
+ else
+ {
+ eina_promise_reject(data->delivery, ecore_evas_no_matching_type);
+ data->delivery = NULL;
+ }
+ }
+
+ return future;
+}
+
+static Eina_Bool
+_ecore_evas_wl_selection_has_owner(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection EINA_UNUSED)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Wl2_Input *input;
+
+ _reeval_seat(&seat, ee);
+ input = _fetch_input(ee, seat);
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER )
+ return !!ecore_wl2_dnd_selection_get(input);
+ else if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ {
+ Ecore_Evas_Wl_Selection_Data *data = &wdata->selection_data[selection];
+ return !!data->offer;
+ }
+
+ return EINA_FALSE; //the selection buffer is not supportet in wayland
+}
+
+static Eina_Bool
+_wl_selection_changed(void *data, int type EINA_UNUSED, void *event EINA_UNUSED)
+{
+ Ecore_Wl2_Event_Seat_Selection *sel = event;
+ Ecore_Evas *ee = data;
+ Ecore_Wl2_Input *input;
+ unsigned int seat = sel->seat;
+
+ _reeval_seat(&seat, ee);
+ input = _fetch_input(ee, seat);
+ if (!ecore_wl2_dnd_selection_get(input))
+ return ECORE_CALLBACK_PASS_ON;
+
+ if (ee->func.fn_selection_changed)
+ {
+ ee->func.fn_selection_changed
+ (ee, 0, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER);
+ }
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+typedef struct
+{
+ Eina_Rw_Slice slice;
+ unsigned int written_bytes;
+} Delayed_Writing;
+
+static Eina_Bool
+_write_to_fd(void *data, Ecore_Fd_Handler *fd_handler)
+{
+ int fd;
+ size_t len;
+ Delayed_Writing *slice = data;
+
+ fd = ecore_main_fd_handler_fd_get(fd_handler);
+ if (fd < 0) goto end;
+
+ len = write(fd, (char*)slice->slice.mem + slice->written_bytes,
+ slice->slice.len - slice->written_bytes);
+
+ slice->written_bytes += len;
+ if (slice->written_bytes != slice->slice.len)
+ {
+ return EINA_TRUE;
+ }
+ else
+ {
+end:
+ ecore_main_fd_handler_del(fd_handler);
+ free(slice->slice.mem);
+ free(slice);
+ if (fd > -1) close(fd);
+ return EINA_FALSE;
+ }
+}
+
+static Eina_Bool
+_wl_interaction_send(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Wl2_Event_Data_Source_Send *ev = event;
+ Ecore_Evas *ee = data;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Evas_Wl_Selection_Data *selection = NULL;
+ Delayed_Writing *forign_slice = calloc(1, sizeof(Delayed_Writing));
+ Ecore_Evas_Selection_Buffer buffer = ECORE_EVAS_SELECTION_BUFFER_LAST;
+
+ if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER].sent_serial)
+ buffer = ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER;
+ else if (ev->serial == wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].sent_serial)
+ {
+ buffer = ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER;
+ ee->drag.accepted = EINA_TRUE;
+ }
+
+ if (buffer == ECORE_EVAS_SELECTION_BUFFER_LAST)
+ {
+ //silent return, this send request was *not* for this window
+ goto end;
+ }
+
+ selection = &wdata->selection_data[buffer];
+ EINA_SAFETY_ON_NULL_GOTO(selection, end);
+ EINA_SAFETY_ON_NULL_GOTO(selection->callbacks.delivery, end);
+ EINA_SAFETY_ON_FALSE_GOTO(selection->callbacks.delivery
+ (ee, ev->seat, buffer, ev->type,
+ &forign_slice->slice), end);
+ ecore_main_fd_handler_add(ev->fd, ECORE_FD_WRITE, _write_to_fd,
+ forign_slice, NULL, NULL);
+
+ return ECORE_CALLBACK_PASS_ON;
+
+end:
+ free(forign_slice);
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_wl_selection_receive(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Ecore_Wl2_Event_Offer_Data_Ready *ready = event;
+ Ecore_Evas_Selection_Buffer selection = ECORE_EVAS_SELECTION_BUFFER_LAST;
+
+ if ((!ready->data) || (ready->len < 1))
+ {
+ ERR("no selection data");
+ return ECORE_CALLBACK_PASS_ON;
+ }
+ for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
+ {
+ if (wdata->selection_data[i].offer == ready->offer)
+ {
+ selection = i;
+ break;
+ }
+ }
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_LAST)
+ return ECORE_CALLBACK_PASS_ON;
+
+ //Now deliver the content
+ Eina_Slice slice;
+
+ if (eina_str_has_prefix(ready->mimetype,"text"))
+ {
+ //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
+ slice.len = ready->len + 1;
+ slice.mem =
+ eina_memdup((unsigned char*)ready->data, ready->len, EINA_TRUE);
+ }
+ else
+ {
+ slice.len = ready->len;
+ slice.mem = ready->data;
+ }
+
+ Eina_Content *content = eina_content_new(slice, ready->mimetype);
+
+ if (wdata->selection_data[selection].later_convert)
+ {
+ Eina_Content *tmp;
+
+ tmp = eina_content_convert(content, wdata->selection_data[selection].later_convert);
+ wdata->selection_data[selection].later_convert = NULL;
+ eina_content_free(content);
+ content = tmp;
+ }
+
+ eina_promise_resolve(wdata->selection_data[selection].delivery,
+ eina_value_content_init(content));
+ wdata->selection_data[selection].delivery = NULL;
+ eina_content_free(content);
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_wl_selection_dnd_leave(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Evas *ee = data;
+ Eina_Position2D cpos;
+ Eina_Position2D fpos = EINA_POSITION2D(0, 0);
+ Ecore_Wl2_Event_Dnd_Leave *ev = event;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+
+ if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
+
+ //evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
+ ecore_wl2_input_pointer_xy_get(ecore_wl2_display_input_find
+ (ev->display, ev->seat), &cpos.x, &cpos.y);
+ ecore_evas_dnd_leave(data, ev->seat, EINA_POSITION2D(cpos.x - fpos.x,
+ cpos.y - fpos.y));
+ wdata->external_offer = NULL;
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_wl_selection_dnd_motion(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Wl2_Event_Dnd_Motion *ev = event;
+ Eina_Position2D fpos = EINA_POSITION2D(0, 0);
+
+ if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
+
+ evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
+ ecore_evas_dnd_position_set(data, ev->seat,
+ EINA_POSITION2D(ev->x - fpos.x, ev->y - fpos.y));
+ return ECORE_CALLBACK_PASS_ON;
+}
+static Eina_Bool
+_wl_selection_dnd_enter(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Wl2_Event_Dnd_Enter *ev = event;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ Eina_Position2D fpos = EINA_POSITION2D(0, 0);
+
+ if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
+
+ evas_output_framespace_get(ee->evas, &fpos.x, &fpos.y, NULL, NULL);
+ ecore_evas_dnd_enter(data, ev->seat,
+ eina_array_iterator_new
+ (ecore_wl2_offer_mimes_get(ev->offer)),
+ EINA_POSITION2D(ev->x - fpos.x, ev->y - fpos.y));
+ ecore_wl2_offer_mimes_set(ev->offer, ecore_wl2_offer_mimes_get(ev->offer));
+ wdata->external_offer = ev->offer;
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_wl_selection_dnd_drop(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Wl2_Event_Dnd_Drop *ev = event;
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
+ wdata = ee->engine.data;
+
+ if (ee->func.fn_dnd_drop)
+ {
+ ee->func.fn_dnd_drop(ee, ev->seat,
+ ecore_evas_dnd_pos_get(ee, ev->seat), "ask");
+ }
+
+ ecore_wl2_dnd_drag_end(_fetch_input(ee, ev->seat));
+ wdata->external_offer = NULL;
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+static Eina_Bool
+_wl_selection_dnd_end(void *data, int type EINA_UNUSED, void *event)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Wl2_Event_Dnd_End *ev = event;
+
+ if (ee->prop.window != (Ecore_Window)ev->win) return ECORE_CALLBACK_PASS_ON;
+
+
+ if (ee->drag.free)
+ ee->drag.free(ee, ev->seat, ee->drag.data, ee->drag.accepted);
+ ee->drag.free = NULL;
+ //we got dropped, we should call
+
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_ecore_evas_wl_selection_init(Ecore_Evas *ee)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+
+ wdata->changed_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_SEAT_SELECTION,
+ _wl_selection_changed, ee);
+ wdata->send_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_SEND,
+ _wl_interaction_send, ee);
+ wdata->offer_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_OFFER_DATA_READY,
+ _wl_selection_receive, ee);
+ wdata->dnd_leave_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_DND_LEAVE,
+ _wl_selection_dnd_leave, ee);
+ wdata->dnd_motion_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_DND_MOTION,
+ _wl_selection_dnd_motion, ee);
+ wdata->dnd_enter_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_DND_ENTER,
+ _wl_selection_dnd_enter, ee);
+ wdata->dnd_drop_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_DND_DROP,
+ _wl_selection_dnd_drop, ee);
+ wdata->dnd_end_handler =
+ ecore_event_handler_add(ECORE_WL2_EVENT_DATA_SOURCE_END,
+ _wl_selection_dnd_end, ee);
+
+ for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
+ {
+ wdata->selection_data[i].callbacks.available_types = NULL;
+ wdata->selection_data[i].callbacks.delivery = NULL;
+ wdata->selection_data[i].callbacks.cancel = NULL;
+ }
+}
+
+static Eina_Bool
+_ecore_evas_wl_dnd_start(Ecore_Evas *ee, unsigned int seat, Eina_Array *available_types, Ecore_Evas *drag_rep, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel, const char *action EINA_UNUSED)
+{
+ Ecore_Evas_Engine_Wl_Data *wdata = ee->engine.data;
+ const char *tmp_array[eina_array_count(available_types) + 1];
+
+ _reeval_seat(&seat, ee);
+ _store_selection_cbs(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER,
+ available_types, delivery, cancel);
+
+ for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
+ {
+ tmp_array[i] = eina_array_data_get(available_types, i);
+ }
+ tmp_array[eina_array_count(available_types)] = NULL;
+
+ ecore_wl2_dnd_drag_types_set(_fetch_input(ee, seat),
+ (const char**)tmp_array);
+ wdata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].sent_serial =
+ ecore_wl2_dnd_drag_start(_fetch_input(ee, seat),
+ _ecore_evas_wayland_window_get(ee),
+ _ecore_evas_wayland_window_get(drag_rep));
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecore_evas_wl_dnd_stop(Ecore_Evas *ee, unsigned int seat)
+{
+ _clear_selection(ee, seat, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER);
+ _reeval_seat(&seat, ee);
+ ecore_wl2_dnd_drag_end(_fetch_input(ee, seat));
+ return EINA_TRUE;
+}
+
static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
{
_ecore_evas_wl_common_free,
@@ -2472,6 +3006,11 @@ static Ecore_Evas_Engine_Func _ecore_wl_engine_func =
_ecore_evas_wl_common_pointer_device_xy_get,
_ecore_evas_wl_common_prepare,
NULL, //fn_last_tick_get
+ _ecore_evas_wl_selection_claim, //fn_selection_claim
+ _ecore_evas_wl_selection_has_owner, //fn_selection_has_owner
+ _ecore_evas_wl_selection_request, //fn_selection_request
+ _ecore_evas_wl_dnd_start, //fn_dnd_start
+ _ecore_evas_wl_dnd_stop, //fn_dnd_stop
};
static void
@@ -2496,7 +3035,7 @@ _ecore_evas_wl_common_new_internal(const char *disp_name, Ecore_Window parent, i
Ecore_Evas *ee = NULL;
int method = 0;
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
if (!(method = evas_render_method_lookup(engine_name)))
{
@@ -2648,6 +3187,7 @@ _ecore_evas_wl_common_new_internal(const char *disp_name, Ecore_Window parent, i
}
_ecore_evas_wl_common_wm_rotation_protocol_set(ee);
+ _ecore_evas_wl_selection_init(ee);
ecore_evas_done(ee, EINA_FALSE);
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
index f5530bc61d..fd9415de41 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_egl.c
@@ -31,7 +31,7 @@
EAPI Ecore_Evas *
ecore_evas_wayland_egl_new_internal(const char *disp_name, Ecore_Window parent, int x, int y, int w, int h, Eina_Bool frame, const int *opt)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
return _ecore_evas_wl_common_new_internal(disp_name, parent,
x, y, w, h, frame,
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
index e69970f262..8213dc2b32 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_private.h
@@ -11,10 +11,10 @@
//#define LOGFNS 1
# ifdef LOGFNS
# include <stdio.h>
-# define LOGFN(fl, ln, fn) \
- printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", fl, ln, fn);
+# define LOGFN \
+ printf("-ECORE_EVAS-WL: %25s: %5i - %s\n", __FILE__, __LINE__, __func__)
# else
-# define LOGFN(fl, ln, fn)
+# define LOGFN
# endif
# include <Eina.h>
@@ -34,12 +34,23 @@
typedef struct _Ecore_Evas_Engine_Wl_Data Ecore_Evas_Engine_Wl_Data;
+typedef struct _Ecore_Evas_Wl_Selection_Data Ecore_Evas_Wl_Selection_Data;
+
+struct _Ecore_Evas_Wl_Selection_Data
+{
+ Ecore_Evas_Selection_Callbacks callbacks;
+ Eina_Promise *delivery;
+ Ecore_Wl2_Offer *offer;
+ const char *later_convert;
+ uint32_t sent_serial; //The serial of the last sent selection op
+};
+
struct _Ecore_Evas_Engine_Wl_Data
{
Ecore_Wl2_Display *display;
Eina_List *regen_objs;
Ecore_Wl2_Window *parent, *win;
- Ecore_Event_Handler *sync_handler;
+ Ecore_Event_Handler *sync_handler, *changed_handler, *end_handler, *send_handler, *offer_handler, *dnd_leave_handler, *dnd_motion_handler, *dnd_enter_handler, *dnd_drop_handler, *dnd_end_handler;
int fx, fy, fw, fh;
Ecore_Wl2_Frame_Cb_Handle *frame;
int x_rel;
@@ -47,7 +58,8 @@ struct _Ecore_Evas_Engine_Wl_Data
uint32_t timestamp;
Eina_List *devices_list;
int cw, ch;
-
+ Ecore_Evas_Wl_Selection_Data selection_data[ECORE_EVAS_SELECTION_BUFFER_LAST];
+ Ecore_Wl2_Offer *external_offer;
struct
{
Eina_Bool supported : 1;
diff --git a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c
index 252b1ffa02..1481bf6f2b 100644
--- a/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c
+++ b/src/modules/ecore_evas/engines/wayland/ecore_evas_wayland_shm.c
@@ -31,7 +31,7 @@
EAPI Ecore_Evas *
ecore_evas_wayland_shm_new_internal(const char *disp_name, Ecore_Window parent, int x, int y, int w, int h, Eina_Bool frame)
{
- LOGFN(__FILE__, __LINE__, __FUNCTION__);
+ LOGFN;
return _ecore_evas_wl_common_new_internal(disp_name, parent, x, y, w, h,
frame, NULL, "wayland_shm");
diff --git a/src/modules/ecore_evas/engines/wayland/meson.build b/src/modules/ecore_evas/engines/wayland/meson.build
index fbc27a396b..259d8bcdd8 100644
--- a/src/modules/ecore_evas/engines/wayland/meson.build
+++ b/src/modules/ecore_evas/engines/wayland/meson.build
@@ -11,7 +11,7 @@ engine_src = files([
'ecore_evas_wayland_private.h'
])
-engine_deps = [ecore_wl2, ecore_input]
+engine_deps = [ecore_wl2, ecore_input] + ecore_wl2_ext_deps
engine_include_dir += include_directories(join_paths('..', '..', '..', 'evas', 'engines', 'wayland_common'))
diff --git a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c
index 39def9d49f..623515da95 100644
--- a/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c
+++ b/src/modules/ecore_evas/engines/win32/ecore_evas_win32.c
@@ -54,6 +54,8 @@
#define ECORE_EVAS_EVENT_COUNT 11
+#define EE_SZ(sz_) (ee->sz_ == 0) ? 1 : (ee->sz_)
+
static int _ecore_evas_init_count = 0;
static Ecore_Event_Handler *ecore_evas_event_handlers[ECORE_EVAS_EVENT_COUNT];
@@ -62,11 +64,16 @@ static const int interface_win32_version = 1;
typedef struct _Ecore_Evas_Engine_Data_Win32 Ecore_Evas_Engine_Data_Win32;
-struct _Ecore_Evas_Engine_Data_Win32 {
+struct _Ecore_Evas_Engine_Data_Win32
+{
Ecore_Win32_Window *parent;
- struct {
- unsigned char region : 1;
- unsigned char fullscreen : 1;
+ Ecore_Evas_Selection_Callbacks clipboard;
+ Eina_Future *delivery;
+ struct
+ {
+ unsigned char region : 1;
+ unsigned char fullscreen : 1;
+ unsigned char maximized : 1;
} state;
};
@@ -94,6 +101,7 @@ static Eina_Bool _ecore_evas_win32_event_window_delete_request(void *data EINA_U
static Eina_Bool _ecore_evas_win32_event_window_property_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event);
+
/* Private functions */
static int
@@ -370,13 +378,13 @@ _ecore_evas_win32_event_window_configure(void *data EINA_UNUSED, int type EINA_U
if (ECORE_EVAS_PORTRAIT(ee))
{
- evas_output_size_set(ee->evas, ee->w, ee->h);
- evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_output_size_set(ee->evas, EE_SZ(w), EE_SZ(h));
+ evas_output_viewport_set(ee->evas, 0, 0, EE_SZ(w), EE_SZ(h));
}
else
{
- evas_output_size_set(ee->evas, ee->h, ee->w);
- evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ evas_output_size_set(ee->evas, EE_SZ(h), EE_SZ(w));
+ evas_output_viewport_set(ee->evas, 0, 0, EE_SZ(h), EE_SZ(w));
}
if (ee->prop.avoid_damage)
{
@@ -427,9 +435,11 @@ _ecore_evas_win32_event_window_property_change(void *data EINA_UNUSED, int type
{
struct {
struct {
+ unsigned char maximized : 1;
unsigned char fullscreen : 1;
} win32;
struct {
+ Eina_Bool maximized : 1;
Eina_Bool fullscreen : 1;
} prop;
} prev;
@@ -449,12 +459,16 @@ _ecore_evas_win32_event_window_property_change(void *data EINA_UNUSED, int type
wdata = ee->engine.data;
prev.win32.fullscreen = wdata->state.fullscreen;
+ prev.win32.maximized = wdata->state.maximized;
prev.prop.fullscreen = ee->prop.fullscreen;
+ prev.prop.maximized = ee->prop.maximized;
wdata->state.fullscreen = 0;
+ wdata->state.maximized = 0;
ee->prop.fullscreen = EINA_FALSE;
+ ee->prop.maximized = EINA_FALSE;
/* we get the states status */
ecore_win32_window_state_get(e->window, &state, &num);
@@ -468,6 +482,10 @@ _ecore_evas_win32_event_window_property_change(void *data EINA_UNUSED, int type
ee->prop.fullscreen = 1;
wdata->state.fullscreen = 1;
break;
+ case ECORE_WIN32_WINDOW_STATE_MAXIMIZED:
+ ee->prop.maximized = 1;
+ wdata->state.maximized = 1;
+ break;
default:
break;
}
@@ -476,7 +494,9 @@ _ecore_evas_win32_event_window_property_change(void *data EINA_UNUSED, int type
}
if ((prev.win32.fullscreen != wdata->state.fullscreen) ||
- (prev.prop.fullscreen != ee->prop.fullscreen))
+ (prev.prop.fullscreen != ee->prop.fullscreen) ||
+ (prev.win32.maximized != wdata->state.maximized) ||
+ (prev.prop.maximized != ee->prop.maximized))
{
if (ee->func.fn_state_change)
ee->func.fn_state_change(ee);
@@ -501,6 +521,8 @@ _ecore_evas_win32_state_update(Ecore_Evas *ee)
state[num++] = ECORE_WIN32_WINDOW_STATE_MAXIMIZED_VERT;
if (ee->prop.maximized)
state[num++] = ECORE_WIN32_WINDOW_STATE_MAXIMIZED_HORZ;
+ if (ee->prop.maximized)
+ state[num++] = ECORE_WIN32_WINDOW_STATE_MAXIMIZED;
// if (bd->client.netwm.state.shaded)
// state[num++] = ECORE_WIN32_WINDOW_STATE_SHADED;
/* if (ee->prop.focus_skip) */
@@ -599,13 +621,13 @@ _ecore_evas_win32_move_resize(Ecore_Evas *ee, int x, int y, int width, int heigh
x, y, width, height);
if (ECORE_EVAS_PORTRAIT(ee))
{
- evas_output_size_set(ee->evas, ee->w, ee->h);
- evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_output_size_set(ee->evas, EE_SZ(w), EE_SZ(h));
+ evas_output_viewport_set(ee->evas, 0, 0, EE_SZ(w), EE_SZ(h));
}
else
{
- evas_output_size_set(ee->evas, ee->h, ee->w);
- evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ evas_output_size_set(ee->evas, EE_SZ(h), EE_SZ(w));
+ evas_output_viewport_set(ee->evas, 0, 0, EE_SZ(h), EE_SZ(w));
}
if (ee->prop.avoid_damage)
{
@@ -664,13 +686,13 @@ _ecore_evas_win32_rotation_set_internal(Ecore_Evas *ee, int rotation)
h, w);
if (ECORE_EVAS_PORTRAIT(ee))
{
- evas_output_size_set(ee->evas, ee->w, ee->h);
- evas_output_viewport_set(ee->evas, 0, 0, ee->w, ee->h);
+ evas_output_size_set(ee->evas, EE_SZ(w), EE_SZ(h));
+ evas_output_viewport_set(ee->evas, 0, 0, EE_SZ(w), EE_SZ(h));
}
else
{
- evas_output_size_set(ee->evas, ee->h, ee->w);
- evas_output_viewport_set(ee->evas, 0, 0, ee->h, ee->w);
+ evas_output_size_set(ee->evas, EE_SZ(h), EE_SZ(w));
+ evas_output_viewport_set(ee->evas, 0, 0, EE_SZ(h), EE_SZ(w));
}
if (ee->func.fn_resize) ee->func.fn_resize(ee);
}
@@ -824,7 +846,8 @@ _ecore_evas_win32_activate(Ecore_Evas *ee)
{
INF("ecore evas activate");
- ecore_win32_window_focus((Ecore_Win32_Window *)ee->prop.window);
+ ecore_evas_show(ee);
+ ecore_win32_window_activate((Ecore_Win32_Window *)ee->prop.window);
}
static void
@@ -967,6 +990,30 @@ _ecore_evas_win32_override_set(Ecore_Evas *ee, Eina_Bool on)
}
static void
+_ecore_evas_win32_maximized_set(Ecore_Evas *ee, Eina_Bool on)
+{
+ Ecore_Evas_Engine_Data_Win32 *wdata = ee->engine.data;
+
+ INF("ecore evas maximized set");
+
+ wdata->state.maximized = !!on;
+ if (ee->should_be_visible)
+ {
+ struct _Ecore_Win32_Window *window;
+
+ window = (Ecore_Win32_Window *)ee->prop.window;
+ ecore_win32_window_maximized_set(window, on);
+ }
+ else
+ {
+ if (ee->prop.maximized == on) return;
+ ee->prop.maximized = on;
+ wdata->state.maximized = on;
+ _ecore_evas_win32_state_update(ee);
+ }
+}
+
+static void
_ecore_evas_win32_fullscreen_set(Ecore_Evas *ee, Eina_Bool on)
{
Ecore_Evas_Engine_Data_Win32 *wdata = ee->engine.data;
@@ -1197,93 +1244,225 @@ _ecore_evas_win32_screen_dpi_get(const Ecore_Evas *ee, int *xdpi, int *ydpi)
*ydpi = y_dpi;
}
+static Eina_Value
+_delivery(void *data, const Eina_Value value EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Evas_Engine_Data_Win32 *edata = ee->engine.data;
+ Eina_Rw_Slice slice;
+ const char *mime_type = NULL;
+
+ EINA_SAFETY_ON_NULL_GOTO(edata->delivery, end);
+
+ for (unsigned int i = 0; i < eina_array_count(edata->clipboard.available_types); ++i)
+ {
+ mime_type = eina_array_data_get(edata->clipboard.available_types, i);
+ if (eina_str_has_prefix(mime_type, "text/"))
+ break;
+ }
+ if (mime_type)
+ {
+ edata->clipboard.delivery(ee, 1, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER, mime_type, &slice);
+ EINA_SAFETY_ON_FALSE_GOTO(ecore_win32_clipboard_set((Ecore_Win32_Window *)ee->prop.window, slice.mem, slice.len, mime_type), end);
+ }
+ else
+ {
+ ERR("No compatible mime type found");
+ }
+
+end:
+ return EINA_VALUE_EMPTY;
+}
+
+static Eina_Bool
+_ecore_evas_win32_selection_claim(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
+{
+ Ecore_Evas_Engine_Data_Win32 *edata = ee->engine.data;
+
+ if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ return EINA_FALSE;
+
+ if (!delivery && !cancel)
+ {
+ edata->clipboard.delivery = NULL;
+ edata->clipboard.cancel = NULL;
+ eina_array_clean(edata->clipboard.available_types);
+ ecore_win32_clipboard_clear((Ecore_Win32_Window *)ee->prop.window);
+ return EINA_TRUE;
+ }
+ else
+ {
+ if (edata->clipboard.cancel)
+ {
+ edata->clipboard.cancel(ee, seat, selection);
+ eina_array_free(edata->clipboard.available_types);
+ }
+
+ edata->delivery = efl_loop_job(efl_main_loop_get());
+ eina_future_then(edata->delivery, _delivery, ee);
+ edata->clipboard.delivery = delivery;
+ edata->clipboard.cancel = cancel;
+ edata->clipboard.available_types = available_types;
+ return EINA_TRUE;
+ }
+}
+
+Eina_Future*
+_ecore_evas_win32_selection_request(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_type)
+{
+ Eina_Future *future;
+ Eina_Promise *promise;
+ const char *mime_type = NULL;
+
+ if (selection != ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ return eina_future_rejected(efl_loop_future_scheduler_get(efl_main_loop_get()), ecore_evas_no_selection);
+
+ promise = efl_loop_promise_new(efl_main_loop_get());
+ future = eina_future_new(promise);
+
+ for (unsigned int i = 0; i < eina_array_count(acceptable_type); ++i)
+ {
+ mime_type = eina_array_data_get(acceptable_type, i);
+ if (eina_str_has_prefix(mime_type, "text/"))
+ break;
+ }
+ if (!mime_type)
+ {
+ eina_promise_reject(promise, ecore_evas_no_matching_type);
+ }
+ else
+ {
+ size_t size;
+ void *data;
+ Eina_Content *content;
+ Eina_Rw_Slice slice;
+
+ data = ecore_win32_clipboard_get((Ecore_Win32_Window *)ee->prop.window, &size, mime_type);
+ if (size != 0)
+ {
+ if (eina_str_has_prefix(mime_type, "text/"))
+ {
+ //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
+ slice.len = size + 1;
+ slice.mem = eina_memdup(data, size, EINA_TRUE);
+ free(data);
+ }
+ else
+ {
+ slice.len = size;
+ slice.mem = data;
+ }
+ content = eina_content_new(eina_rw_slice_slice_get(slice), mime_type);
+ free(slice.mem); //memory got duplicated in eina_content_new
+ if (!content) // construction can fail because of some validation reasons
+ eina_promise_reject(promise, ecore_evas_no_matching_type);
+ else
+ eina_promise_resolve(promise, eina_value_content_init(content));
+ }
+ else
+ eina_promise_reject(promise, ecore_evas_no_matching_type);
+ }
+ return future;
+}
+
+static Eina_Bool
+_ecore_evas_win32_selection_has_owner(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection)
+{
+ return (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER);
+}
+
static Ecore_Evas_Engine_Func _ecore_win32_engine_func =
{
_ecore_evas_win32_free,
- NULL,
- NULL,
- NULL,
- NULL,
- _ecore_evas_win32_callback_delete_request_set,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- _ecore_evas_win32_move,
- NULL,
- _ecore_evas_win32_resize,
- _ecore_evas_win32_move_resize,
- _ecore_evas_win32_rotation_set,
- _ecore_evas_win32_shaped_set,
- _ecore_evas_win32_show,
- _ecore_evas_win32_hide,
- _ecore_evas_win32_raise,
- _ecore_evas_win32_lower,
- _ecore_evas_win32_activate,
- _ecore_evas_win32_title_set,
- NULL, /* _ecore_evas_x_name_class_set */
- _ecore_evas_win32_size_min_set,
- _ecore_evas_win32_size_max_set,
- _ecore_evas_win32_size_base_set,
- _ecore_evas_win32_size_step_set,
- _ecore_evas_win32_object_cursor_set,
- _ecore_evas_win32_object_cursor_unset,
- NULL, /* _ecore_evas_x_layer_set */
- _ecore_evas_win32_focus_set,
- _ecore_evas_win32_iconified_set,
- _ecore_evas_win32_borderless_set,
- _ecore_evas_win32_override_set,
- NULL,
- _ecore_evas_win32_fullscreen_set,
- NULL, /* _ecore_evas_x_avoid_damage_set */
- NULL, /* _ecore_evas_x_withdrawn_set */
- NULL, /* _ecore_evas_x_sticky_set */
- NULL, /* _ecore_evas_x_ignore_events_set */
- _ecore_evas_win32_alpha_set,
- NULL, //transparent
- NULL, // profiles_set
- NULL, // profile_set
-
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
-
- NULL, // render
- _ecore_evas_win32_screen_geometry_get,
- _ecore_evas_win32_screen_dpi_get,
- NULL,
- NULL, // msg_send
-
- NULL, // pointer_xy_get
- NULL, // pointer_warp
-
- NULL, // wm_rot_preferred_rotation_set
- NULL, // wm_rot_available_rotations_set
- NULL, // wm_rot_manual_rotation_done_set
- NULL, // wm_rot_manual_rotation_done
-
- NULL, // aux_hints_set
-
- NULL, // fn_animator_register
- NULL, // fn_animator_unregister
-
- NULL, // fn_evas_changed
- NULL, //fn_focus_device_set
- NULL, //fn_callback_focus_device_in_set
- NULL, //fn_callback_focus_device_out_set
- NULL, //fn_callback_device_mouse_in_set
- NULL, //fn_callback_device_mouse_out_set
- NULL, //fn_pointer_device_xy_get
- NULL, //fn_prepare
- NULL, //fn_last_tick_get
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_win32_callback_delete_request_set,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ _ecore_evas_win32_move,
+ NULL,
+ _ecore_evas_win32_resize,
+ _ecore_evas_win32_move_resize,
+ _ecore_evas_win32_rotation_set,
+ _ecore_evas_win32_shaped_set,
+ _ecore_evas_win32_show,
+ _ecore_evas_win32_hide,
+ _ecore_evas_win32_raise,
+ _ecore_evas_win32_lower,
+ _ecore_evas_win32_activate,
+ _ecore_evas_win32_title_set,
+ NULL, /* _ecore_evas_x_name_class_set */
+ _ecore_evas_win32_size_min_set,
+ _ecore_evas_win32_size_max_set,
+ _ecore_evas_win32_size_base_set,
+ _ecore_evas_win32_size_step_set,
+ _ecore_evas_win32_object_cursor_set,
+ _ecore_evas_win32_object_cursor_unset,
+ NULL, /* _ecore_evas_x_layer_set */
+ _ecore_evas_win32_focus_set,
+ _ecore_evas_win32_iconified_set,
+ _ecore_evas_win32_borderless_set,
+ _ecore_evas_win32_override_set,
+ _ecore_evas_win32_maximized_set,
+ _ecore_evas_win32_fullscreen_set,
+ NULL, /* _ecore_evas_x_avoid_damage_set */
+ NULL, /* _ecore_evas_x_withdrawn_set */
+ NULL, /* _ecore_evas_x_sticky_set */
+ NULL, /* _ecore_evas_x_ignore_events_set */
+ _ecore_evas_win32_alpha_set,
+ NULL, //transparent
+ NULL, // profiles_set
+ NULL, // profile_set
+
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+
+ NULL, // render
+ _ecore_evas_win32_screen_geometry_get,
+ _ecore_evas_win32_screen_dpi_get,
+ NULL,
+ NULL, // msg_send
+
+ NULL, // pointer_xy_get
+ NULL, // pointer_warp
+
+ NULL, // wm_rot_preferred_rotation_set
+ NULL, // wm_rot_available_rotations_set
+ NULL, // wm_rot_manual_rotation_done_set
+ NULL, // wm_rot_manual_rotation_done
+
+ NULL, // aux_hints_set
+
+ NULL, // fn_animator_register
+ NULL, // fn_animator_unregister
+
+ NULL, // fn_evas_changed
+ NULL, //fn_focus_device_set
+ NULL, //fn_callback_focus_device_in_set
+ NULL, //fn_callback_focus_device_out_set
+ NULL, //fn_callback_device_mouse_in_set
+ NULL, //fn_callback_device_mouse_out_set
+ NULL, //fn_pointer_device_xy_get
+ NULL, //fn_prepare
+ NULL, //fn_last_tick_get
+ _ecore_evas_win32_selection_claim, //fn_selection_claim
+ _ecore_evas_win32_selection_has_owner, //fn_selection_has_owner
+ _ecore_evas_win32_selection_request, //fn_selection_request
+ NULL, //fn_dnd_start
+ NULL, //fn_dnd_stop
};
#endif /* BUILD_ECORE_EVAS_WIN32 */
diff --git a/src/modules/ecore_evas/engines/win32/meson.build b/src/modules/ecore_evas/engines/win32/meson.build
index 65fbfc1bb1..197f306e83 100644
--- a/src/modules/ecore_evas/engines/win32/meson.build
+++ b/src/modules/ecore_evas/engines/win32/meson.build
@@ -6,6 +6,7 @@ config_h.set('BUILD_ECORE_EVAS_SOFTWARE_GDI', '1')
engine_deps = [engine_software_ddraw, engine_software_gdi]
shared_module(mod_full_name, engine_src,
+ c_args : package_c_args,
include_directories : config_dir + [engine_include_dir],
dependencies : [eina, ecore_win32, ecore_input, ecore_evas, ecore_input_evas] + engine_deps,
install : true,
diff --git a/src/modules/ecore_evas/engines/x/ecore_evas_x.c b/src/modules/ecore_evas/engines/x/ecore_evas_x.c
index 97e5fb2d10..bb5f02c853 100644
--- a/src/modules/ecore_evas/engines/x/ecore_evas_x.c
+++ b/src/modules/ecore_evas/engines/x/ecore_evas_x.c
@@ -13,6 +13,7 @@
#include <Ecore_X.h>
#include <Ecore_X_Atoms.h>
+#include <Efreet.h>
#ifdef BUILD_ECORE_EVAS_SOFTWARE_X11
# include <Evas_Engine_Software_X11.h>
@@ -48,6 +49,8 @@
# endif
#endif /* ! _WIN32 */
+#define ECORE_EVAS_X11_SELECTION 0x7F
+
#define EDBG(...) \
EINA_LOG(_ecore_evas_log_dom, EINA_LOG_LEVEL_DBG + 1, __VA_ARGS__);
@@ -73,6 +76,17 @@ static Eina_Bool wm_exists;
typedef struct _Ecore_Evas_Engine_Data_X11 Ecore_Evas_Engine_Data_X11;
+typedef struct {
+ EINA_MAGIC;
+ Ecore_Evas_Selection_Callbacks callbacks;
+ Ecore_Evas_Selection_Buffer buffer;
+ Ecore_Evas *ee;
+ Eina_Promise *delivery;
+ Eina_Array *acceptable_type;
+ Eina_Stringshare *requested_type;
+ Eina_Stringshare *later_conversion;
+} Ecore_Evas_X11_Selection_Data;
+
struct _Ecore_Evas_Engine_Data_X11 {
Ecore_X_Window win_root;
Eina_List *win_extra;
@@ -128,6 +142,11 @@ struct _Ecore_Evas_Engine_Data_X11 {
void *visual; // store visual used to create pixmap
unsigned long colormap; // store colormap used to create pixmap
} pixmap;
+ Ecore_Evas_X11_Selection_Data selection_data[ECORE_EVAS_SELECTION_BUFFER_LAST];
+ Eina_Array *xserver_atom_name_during_dnd;
+ Ecore_Event_Handler *mouse_up_handler;
+ Ecore_Job *init_job;
+ int skip_clean_event;
Eina_Bool destroyed : 1; // X window has been deleted and cannot be used
Eina_Bool fully_obscured : 1; // X window is fully obscured
Eina_Bool configured : 1; // X window has been configured
@@ -151,6 +170,8 @@ static void _alpha_do(Ecore_Evas *, int);
static void _transparent_do(Ecore_Evas *, int);
static void _avoid_damage_do(Ecore_Evas *, int);
static void _rotation_do(Ecore_Evas *, int, int);
+static void _ecore_evas_x_selection_init(void);
+static void _ecore_evas_x_selection_window_init(Ecore_Evas *ee);
#define SWAP_INT(a, b) do { a ^= b; b ^= a; a ^= b; } while (0)
@@ -361,7 +382,7 @@ _ecore_evas_x_aux_hints_supported_update(Ecore_Evas *ee)
for (i = 0; i < num; i++)
{
hint = eina_stringshare_add(str[i]);
- ee->prop.aux_hint.supported_list =
+ ee->prop.aux_hint.supported_list =
eina_list_append(ee->prop.aux_hint.supported_list, hint);
}
@@ -414,7 +435,7 @@ _ecore_evas_x_gl_window_new(Ecore_Evas *ee, Ecore_X_Window parent, int x, int y,
op++;
einfo->vsync = opt[op];
}
-#ifdef EVAS_ENGINE_GL_X11_SWAP_MODE_EXISTS
+#ifdef EVAS_ENGINE_GL_X11_SWAP_MODE_EXISTS
else if (opt[op] == ECORE_EVAS_GL_X11_OPT_SWAP_MODE)
{
op++;
@@ -768,7 +789,12 @@ _resize_shape_do(Ecore_Evas *ee)
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
- if (edata->mask) ecore_x_pixmap_free(edata->mask);
+ if (edata->mask)
+ {
+ ecore_x_pixmap_free(edata->mask);
+ edata->mask = 0;
+ }
+ if (!ee->shaped) return;
edata->mask = ecore_x_pixmap_new(ee->prop.window, ee->w + fw, ee->h + fh, 1);
foreground = 0;
gc = ecore_x_gc_new(edata->mask,
@@ -845,7 +871,7 @@ _ecore_evas_x_event_property_change(void *data EINA_UNUSED, int type EINA_UNUSED
Eina_Bool focus_skip : 1;
} prop;
} prev;
-
+
prev.x.modal = edata->state.modal;
prev.x.sticky = edata->state.sticky;
prev.x.maximized_v = edata->state.maximized_v;
@@ -856,7 +882,7 @@ _ecore_evas_x_event_property_change(void *data EINA_UNUSED, int type EINA_UNUSED
prev.x.fullscreen = edata->state.fullscreen;
prev.x.above = edata->state.above;
prev.x.below = edata->state.below;
-
+
prev.prop.modal = ee->prop.modal;
prev.prop.maximized = ee->prop.maximized;
prev.prop.sticky = ee->prop.sticky;
@@ -879,7 +905,7 @@ _ecore_evas_x_event_property_change(void *data EINA_UNUSED, int type EINA_UNUSED
ee->prop.sticky = EINA_FALSE;
ee->prop.fullscreen = EINA_FALSE;
// ee->prop.focus_skip = EINA_FALSE;
-
+
ecore_x_netwm_window_state_get(e->win, &state, &num);
if (state)
{
@@ -1253,7 +1279,7 @@ _ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
edata = ee->engine.data;
-/*
+/*
{
time_t t;
char *ct;
@@ -1304,7 +1330,7 @@ _ecore_evas_x_event_mouse_in(void *data EINA_UNUSED, int type EINA_UNUSED, void
edata->outdelay = NULL;
_fake_out(ee);
}
-
+
/* if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0; */
if (!_ecore_evas_mouse_in_check(ee, NULL))
{
@@ -1388,7 +1414,7 @@ _ecore_evas_x_event_mouse_out(void *data EINA_UNUSED, int type EINA_UNUSED, void
ecore_timer_del(edata->outdelay);
edata->outdelay = NULL;
}
-
+
// if (e->mode != ECORE_X_EVENT_MODE_NORMAL) return 0;
// printf("OUT: ee->in=%i, e->mode=%i, e->detail=%i, dount_count=%i\n",
// ee->in, e->mode, e->detail, evas_event_down_count_get(ee->evas));
@@ -1417,7 +1443,7 @@ _ecore_evas_x_event_window_focus_in(void *data EINA_UNUSED, int type EINA_UNUSED
ee = ecore_event_window_match(e->win);
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
-//xx// filtering with these doesnt help
+//xx// filtering with these doesnt help
//xx// if (e->mode == ECORE_X_EVENT_MODE_UNGRAB) return ECORE_CALLBACK_PASS_ON;
_ecore_evas_focus_device_set(ee, NULL, EINA_TRUE);
return ECORE_CALLBACK_PASS_ON;
@@ -1433,7 +1459,7 @@ _ecore_evas_x_event_window_focus_out(void *data EINA_UNUSED, int type EINA_UNUSE
ee = ecore_event_window_match(e->win);
if ((!ee) || (ee->ignore_events)) return ECORE_CALLBACK_PASS_ON; /* pass on event */
if (e->win != ee->prop.window) return ECORE_CALLBACK_PASS_ON;
-//xx// filtering with these doesnt help
+//xx// filtering with these doesnt help
//xx// if (e->mode == ECORE_X_EVENT_MODE_GRAB) return ECORE_CALLBACK_PASS_ON;
// if (ee->prop.fullscreen)
@@ -1534,6 +1560,8 @@ _ecore_evas_x_shadow_update(Ecore_Evas *ee)
ECORE_X_ATOM_CARDINAL, 32, shadow, 4);
}
+static void _ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee);
+
static Eina_Bool
_ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSED, void *event)
{
@@ -1568,7 +1596,7 @@ _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSE
}
if (edata->direct_resize) return ECORE_CALLBACK_PASS_ON;
- pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_TYPE_MOUSE);
+ pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
pointer = evas_device_parent_get(pointer);
cursor = eina_hash_find(ee->prop.cursors, &pointer);
EINA_SAFETY_ON_NULL_RETURN_VAL(cursor, ECORE_CALLBACK_PASS_ON);
@@ -1672,6 +1700,8 @@ _ecore_evas_x_event_window_configure(void *data EINA_UNUSED, int type EINA_UNUSE
}
}
}
+ if (framespace_resized)
+ _ecore_evas_x_size_pos_hints_update(ee);
}
return ECORE_CALLBACK_PASS_ON;
}
@@ -1763,15 +1793,19 @@ _ecore_evas_x_event_window_hide(void *data EINA_UNUSED, int type EINA_UNUSED, vo
static void
_ecore_evas_x_size_pos_hints_update(Ecore_Evas *ee)
{
+ int fw, fh;
+
+ fw = ee->framespace.w;
+ fh = ee->framespace.h;
ecore_x_icccm_size_pos_hints_set(ee->prop.window,
ee->prop.request_pos /*request_pos */,
ECORE_X_GRAVITY_NW /* gravity */,
- ee->prop.min.w /* min_w */,
- ee->prop.min.h /* min_h */,
- ee->prop.max.w /* max_w */,
- ee->prop.max.h /* max_h */,
- ee->prop.base.w /* base_w */,
- ee->prop.base.h /* base_h */,
+ ee->prop.min.w + fw /* min_w */,
+ ee->prop.min.h + fh /* min_h */,
+ ee->prop.max.w + fw /* max_w */,
+ ee->prop.max.h + fh /* max_h */,
+ ee->prop.base.w + fw /* base_w */,
+ ee->prop.base.h + fh /* base_h */,
ee->prop.step.w /* step_x */,
ee->prop.step.h /* step_y */,
ee->prop.aspect /* min_aspect */,
@@ -1962,6 +1996,7 @@ _ecore_evas_x_init(void)
ecore_event_handler_add(ECORE_X_EVENT_WINDOW_CREATE,
_ecore_evas_x_event_window_create, NULL);
ecore_event_evas_init();
+ _ecore_evas_x_selection_init();
return _ecore_evas_init_count;
}
@@ -1989,6 +2024,7 @@ _ecore_evas_x_free(Ecore_Evas *ee)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
+ ecore_job_del(edata->init_job);
if (edata->pixmap.back)
ecore_x_pixmap_free(edata->pixmap.back);
if (edata->pixmap.front)
@@ -2137,7 +2173,7 @@ _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
}
/* check for valid property window
- *
+ *
* NB: If we do not have one, check for valid pixmap rendering */
if (!ee->prop.window)
{
@@ -2145,7 +2181,7 @@ _ecore_evas_x_resize(Ecore_Evas *ee, int w, int h)
if ((edata->pixmap.w != vw) || (edata->pixmap.h != vh))
{
/* free the backing pixmap */
- if (edata->pixmap.back)
+ if (edata->pixmap.back)
ecore_x_pixmap_free(edata->pixmap.back);
}
}
@@ -2294,7 +2330,7 @@ _ecore_evas_x_rotation_set_internal(Ecore_Evas *ee, int rotation, int resize,
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
int fw = 0, fh = 0;
- pointer = evas_default_device_get(ee->evas, EFL_INPUT_DEVICE_TYPE_MOUSE);
+ pointer = evas_default_device_get(ee->evas, EVAS_DEVICE_CLASS_MOUSE);
pointer = evas_device_parent_get(pointer);
cursor = eina_hash_find(ee->prop.cursors, &pointer);
EINA_SAFETY_ON_NULL_RETURN(cursor);
@@ -2688,6 +2724,7 @@ _alpha_do(Ecore_Evas *ee, int alpha)
_ecore_evas_x_aux_hints_supported_update(ee);
_ecore_evas_x_aux_hints_update(ee);
_ecore_evas_x_size_pos_hints_update(ee);
+ _ecore_evas_x_selection_window_init(ee);
#endif /* BUILD_ECORE_EVAS_SOFTWARE_X11 */
if ((id = getenv("DESKTOP_STARTUP_ID")))
{
@@ -2842,6 +2879,7 @@ _ecore_evas_x_alpha_set(Ecore_Evas *ee, int alpha)
_ecore_evas_x_aux_hints_supported_update(ee);
_ecore_evas_x_aux_hints_update(ee);
_ecore_evas_x_size_pos_hints_update(ee);
+ _ecore_evas_x_selection_window_init(ee);
#endif /* BUILD_ECORE_EVAS_OPENGL_X11 */
if ((id = getenv("DESKTOP_STARTUP_ID")))
{
@@ -2910,7 +2948,7 @@ _ecore_evas_x_aspect_set(Ecore_Evas *ee, double aspect)
ee->prop.aspect = aspect;
_ecore_evas_x_size_pos_hints_update(ee);
-// netwm state
+// netwm state
// if (ee->should_be_visible)
// ecore_x_netwm_state_request_send(ee->prop.window, ee->engine.x.win_root,
// ECORE_X_WINDOW_STATE_STICKY, -1, sticky);
@@ -3265,20 +3303,21 @@ _ecore_evas_x_maximized_set(Ecore_Evas *ee, Eina_Bool on)
{
Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
- if (ee->prop.maximized == on) return;
- ee->prop.maximized = 1;
- edata->state.maximized_h = 1;
- edata->state.maximized_v = 1;
-// ee->prop.maximized = on;
if (ee->should_be_visible)
{
ecore_x_netwm_state_request_send(ee->prop.window, edata->win_root,
- ECORE_X_WINDOW_STATE_MAXIMIZED_VERT, -1, on);
- ecore_x_netwm_state_request_send(ee->prop.window, edata->win_root,
- ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ, -1, on);
+ ECORE_X_WINDOW_STATE_MAXIMIZED_VERT,
+ ECORE_X_WINDOW_STATE_MAXIMIZED_HORZ,
+ on);
}
else
- _ecore_evas_x_state_update(ee);
+ {
+ if (ee->prop.maximized == on) return;
+ ee->prop.maximized = on;
+ edata->state.maximized_h = on;
+ edata->state.maximized_v = on;
+ _ecore_evas_x_state_update(ee);
+ }
}
static void
@@ -3537,14 +3576,14 @@ norandr:
if (!found) goto norandr;
}
-static void
+static void
_ecore_evas_x_pointer_xy_get(const Ecore_Evas *ee, Evas_Coord *x, Evas_Coord *y)
{
if (ee->prop.window)
ecore_x_pointer_xy_get(ee->prop.window, x, y);
}
-static Eina_Bool
+static Eina_Bool
_ecore_evas_x_pointer_warp(const Ecore_Evas *ee, Evas_Coord x, Evas_Coord y)
{
return ecore_x_pointer_warp(ee->prop.window, x, y);
@@ -3659,6 +3698,804 @@ _ecore_evas_x_aux_hints_set(Ecore_Evas *ee, const char *hints)
(ee->prop.window, ECORE_X_ATOM_E_WINDOW_AUX_HINT);
}
+static Ecore_X_Atom ecore_evas_selection_to_atom[] = {0, 0, 0, 0};
+static Ecore_Event_Handler *ecore_evas_selection_handlers[8];
+
+static inline Ecore_Evas_Selection_Buffer
+_atom_to_selection(Ecore_X_Atom atom)
+{
+ for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
+ {
+ if (ecore_evas_selection_to_atom[i] == atom)
+ return i;
+ }
+ return ECORE_EVAS_SELECTION_BUFFER_LAST;
+}
+
+static Eina_Stringshare*
+_decrypt_type(const char *target)
+{
+ // reference https://tronche.com/gui/x/icccm/sec-2.html
+ if (eina_streq(target, "TEXT")) return eina_stringshare_add("text/plain");
+ //FIXME no support in eina_content for that so far
+ if (eina_streq(target, "COMPOUND_TEXT")) return eina_stringshare_add("text/plain");
+ // reference https://tronche.com/gui/x/icccm/sec-2.html
+ if (eina_streq(target, "STRING")) return eina_stringshare_add("text/plain;charset=iso-8859-1");
+ if (eina_streq(target, "UTF8_STRING")) return eina_stringshare_add("text/plain;charset=utf-8");
+
+ return eina_stringshare_add(target);
+}
+
+static Eina_Stringshare*
+_mime_to_xserver_type(const char *target)
+{
+ // FIXME // reference https://tronche.com/gui/x/icccm/sec-2.html says it is in the owners choice of encoding, not sure what this means directly here
+ if (eina_streq(target, "text/plain")) return eina_stringshare_add("TEXT");
+ // reference https://tronche.com/gui/x/icccm/sec-2.html
+ if (eina_streq(target, "text/plain;charset=iso-8859-1")) return eina_stringshare_add("STRING");
+ if (eina_streq(target, "text/plain;charset=utf-8")) return eina_stringshare_add("UTF8_STRING");
+
+ return eina_stringshare_add(target);
+}
+
+static inline void
+_clear_selection(Ecore_Evas *ee, Ecore_Evas_Selection_Buffer selection)
+{
+ Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
+ Ecore_Evas_Selection_Callbacks *cbs = &edata->selection_data[selection].callbacks;
+
+ EINA_SAFETY_ON_FALSE_RETURN(cbs->cancel);
+
+ cbs->cancel(ee, 1, selection);
+ eina_array_free(cbs->available_types);
+
+ cbs->delivery = NULL;
+ cbs->cancel = NULL;
+ cbs->available_types = NULL;
+}
+
+static void
+_clear_selection_delivery(Ecore_Evas *ee, Ecore_Evas_Selection_Buffer selection)
+{
+ Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
+ eina_stringshare_replace(&edata->selection_data[selection].requested_type, NULL);
+ eina_stringshare_replace(&edata->selection_data[selection].later_conversion, NULL);
+ edata->selection_data[selection].delivery = NULL;
+ eina_array_free(edata->selection_data[selection].acceptable_type);
+ edata->selection_data[selection].acceptable_type = NULL;
+}
+
+static void
+_ecore_x_selection_request(Ecore_X_Window win, Ecore_Evas_Selection_Buffer selection, const char *type)
+{
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
+ ecore_x_selection_primary_request(win, type);
+ else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ ecore_x_selection_clipboard_request(win, type);
+ else
+ ecore_x_selection_xdnd_request(win, type);
+}
+
+static void
+_search_fitting_type(Ecore_Evas *ee, Ecore_Evas_Engine_Data_X11 *edata, Ecore_Evas_Selection_Buffer selection, Eina_Array *arr)
+{
+ Eina_Stringshare *mime_type;
+ Eina_Bool found_conversion = EINA_FALSE;
+
+#define HANDLE_TYPE() \
+ { \
+ edata->selection_data[selection].requested_type = eina_stringshare_add(x11_name); \
+ edata->selection_data[selection].later_conversion = eina_stringshare_add(acceptable_type);\
+ found_conversion = EINA_TRUE; \
+ break; \
+ }
+
+ EINA_SAFETY_ON_NULL_RETURN(edata->selection_data[selection].acceptable_type);
+
+ for (unsigned int i = 0; i < eina_array_count(arr) && !found_conversion; ++i)
+ {
+ const char *x11_name = eina_array_data_get(arr, i);
+ mime_type = _decrypt_type(x11_name);
+
+ for (unsigned int j = 0; j < eina_array_count(edata->selection_data[selection].acceptable_type) && !found_conversion; ++j)
+ {
+ const char *acceptable_type = (const char*) eina_array_data_get(edata->selection_data[selection].acceptable_type, j);
+
+ if (mime_type == acceptable_type)
+ HANDLE_TYPE()
+
+ //if there is no available type yet, check if we can convert to the desired type via this type
+ if (!found_conversion)
+ {
+ const char *convertion_type = NULL;
+ Eina_Iterator *iter = eina_content_converter_possible_conversions(mime_type);
+ EINA_ITERATOR_FOREACH(iter, convertion_type)
+ {
+ if (convertion_type == acceptable_type)
+ HANDLE_TYPE()
+ }
+ eina_iterator_free(iter);
+ }
+ }
+ eina_stringshare_del(mime_type);
+ }
+ if (found_conversion)
+ {
+ _ecore_x_selection_request(ee->prop.window, selection, edata->selection_data[selection].requested_type);
+ }
+ else
+ {
+ eina_promise_resolve(edata->selection_data[selection].delivery, eina_value_error_init(ecore_evas_no_matching_type));
+ _clear_selection_delivery(ee, selection);
+ }
+
+#undef HANDLE_TYPE
+}
+
+static void
+_search_fitting_type_from_event(Ecore_Evas *ee, Ecore_Evas_Engine_Data_X11 *edata, Ecore_Evas_Selection_Buffer selection, Ecore_X_Event_Selection_Notify *ev)
+{
+ Ecore_X_Atom *available_atoms;
+ Ecore_X_Selection_Data_Targets *targets;
+ Eina_Array *tmp = eina_array_new(10);
+
+ targets = ev->data;
+ available_atoms = (Ecore_X_Atom *)targets->data.data;
+ for (int i = 0; i < targets->data.length; ++i)
+ {
+ Ecore_X_Atom atom = available_atoms[i];
+ eina_array_push(tmp, ecore_x_atom_name_get(atom));
+ }
+ _search_fitting_type(ee, edata, selection, tmp);
+ eina_array_free(tmp);
+}
+
+static Eina_Content*
+_create_delivery_content(unsigned long int size, const void *mem, const char *mime_type)
+{
+ Eina_Content *content;
+
+ content = eina_content_new((Eina_Slice){.len = size, .mem = mem}, mime_type);
+
+ return content;
+}
+
+static void
+_deliver_content(Ecore_Evas *ee, Ecore_Evas_Engine_Data_X11 *edata, Ecore_Evas_Selection_Buffer selection, Ecore_X_Event_Selection_Notify *ev)
+{
+ Eina_Content *result = NULL;
+ Eina_Stringshare *mime_type = _decrypt_type(edata->selection_data[selection].requested_type);
+
+ EINA_SAFETY_ON_NULL_GOTO(ev->data, err);
+ if (eina_streq(mime_type, "text/uri-list"))
+ {
+ Ecore_X_Selection_Data_Files *files = ev->data;
+ Efreet_Uri *uri;
+ Eina_Strbuf *strbuf;
+ int i;
+
+ strbuf = eina_strbuf_new();
+
+ for (i = 0; i < files->num_files ; i++)
+ {
+ uri = efreet_uri_decode(files->files[i]);
+ if (uri)
+ {
+ eina_strbuf_append(strbuf, uri->path);
+ efreet_uri_free(uri);
+ }
+ else
+ {
+ eina_strbuf_append(strbuf, files->files[i]);
+ }
+ if (i < (files->num_files - 1))
+ eina_strbuf_append(strbuf, "\n");
+ }
+ result = _create_delivery_content(eina_strbuf_length_get(strbuf) + 1, eina_strbuf_string_get(strbuf), mime_type);
+ eina_strbuf_free(strbuf);
+ }
+ else if (eina_str_has_prefix(mime_type,"text"))
+ {
+ Ecore_X_Selection_Data *x11_data = ev->data;
+ //ensure that we always have a \0 at the end, there is no assertion that \0 is included here.
+ void *null_terminated = eina_memdup(x11_data->data, x11_data->length, EINA_TRUE);
+
+ result = _create_delivery_content(x11_data->length + 1, null_terminated, mime_type);
+ free(null_terminated);
+ }
+ else if (eina_str_has_prefix(mime_type,"image"))
+ {
+ Ecore_X_Selection_Data *x11_data = ev->data;
+ Eina_Content *tmp_container = eina_content_new((Eina_Slice){.len = x11_data->length, .mem = x11_data->data}, mime_type);
+ const char *file = eina_content_as_file(tmp_container);
+
+ result = _create_delivery_content(strlen(file), file, mime_type);
+ eina_content_free(tmp_container);
+ }
+ else
+ {
+ Ecore_X_Selection_Data *x11_data = ev->data;
+ result = _create_delivery_content(x11_data->length, x11_data->data, mime_type);
+ }
+ EINA_SAFETY_ON_NULL_GOTO(result, err);
+
+ //ensure that we deliver the correct type, we might have choosen a convertion before
+ if (edata->selection_data[selection].later_conversion != mime_type)
+ {
+ Eina_Content *tmp = eina_content_convert(result, edata->selection_data[selection].later_conversion);
+ eina_content_free(result);
+ result = tmp;
+ }
+
+ eina_promise_resolve(edata->selection_data[selection].delivery, eina_value_content_init(result));
+ eina_content_free(result);
+ _clear_selection_delivery(ee, selection);
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ ecore_x_dnd_send_finished();
+ return;
+err:
+ eina_promise_reject(edata->selection_data[selection].delivery, ecore_evas_no_selection);
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ ecore_x_dnd_send_finished();
+}
+
+static Eina_Bool
+_ecore_evas_x_selection_notify(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Selection_Notify *ev = event;
+ Ecore_Evas_Selection_Buffer selection;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Ecore_Evas *ee;
+
+ ee = ecore_event_window_match(ev->win);
+ selection = _atom_to_selection(ev->atom);
+ EINA_SAFETY_ON_FALSE_GOTO(!!ee, end);
+ EINA_SAFETY_ON_FALSE_GOTO(selection != ECORE_EVAS_SELECTION_BUFFER_LAST, end);
+ edata = ee->engine.data;
+
+ //if dnd drops above us, and even if we did not request anything, we are getting notified, refuse to do anything
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER &&
+ !edata->selection_data[selection].later_conversion)
+ {
+ ecore_x_dnd_send_finished();
+ }
+ else
+ {
+ if (eina_streq(ev->target, "TARGETS") || eina_streq(ev->target, "ATOMS"))
+ {
+ //This will decide for a type, and will sent that via _ecore_x_selection_request
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(!edata->selection_data[selection].later_conversion, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(!edata->selection_data[selection].requested_type, EINA_FALSE);
+ _search_fitting_type_from_event(ee, edata, selection, ev);
+ }
+ else
+ {
+ //This will read the data, fill it into a Eina_Content apply all conversions required.
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(edata->selection_data[selection].later_conversion, EINA_FALSE);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(edata->selection_data[selection].requested_type, EINA_FALSE);
+ _deliver_content(ee, edata, selection, ev);
+ }
+ }
+end:
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_ecore_evas_x_selection_clear(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Selection_Clear *ev = event;
+ Ecore_Evas_Selection_Callbacks *cbs;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Ecore_Evas_Selection_Buffer selection;
+ Ecore_Evas *ee;
+
+ ee = ecore_event_window_match(ev->win);
+ selection = _atom_to_selection(ev->atom);
+ EINA_SAFETY_ON_FALSE_GOTO(ee, end);
+ EINA_SAFETY_ON_FALSE_GOTO(selection != ECORE_EVAS_SELECTION_BUFFER_LAST, end);
+ edata = ee->engine.data;
+ cbs = &edata->selection_data[selection].callbacks;
+
+ //skip clean event
+ if (edata->skip_clean_event)
+ {
+ edata->skip_clean_event --;
+ goto end;
+ }
+
+ if (cbs->cancel)
+ _clear_selection(ee, selection);
+end:
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_force_stop_self_dnd(Ecore_Evas *ee)
+{
+ Ecore_Evas_Engine_Data_X11 *edata;
+
+ EINA_SAFETY_ON_NULL_RETURN(ee);
+ edata = ee->engine.data;
+ EINA_SAFETY_ON_NULL_RETURN(edata);
+
+ //Never clear the buffer for selection here.
+ //Selection buffer is freed as a response to the FINISHED event.
+ ecore_x_pointer_ungrab();
+ ecore_x_dnd_self_drop();
+ ecore_x_dnd_aware_set(ee->prop.window, EINA_FALSE);
+ ecore_event_handler_del(edata->mouse_up_handler);
+ edata->mouse_up_handler = NULL;
+
+ if (ee->drag.free)
+ ee->drag.free(ee, 1, ee->drag.data, ee->drag.accepted);
+ ee->drag.free = NULL;
+}
+
+static Eina_Bool
+_ecore_evas_x_selection_fixes_notify(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Fixes_Selection_Notify *ev = event;
+ Ecore_Evas *ee;
+ Ecore_Evas_Selection_Buffer selection;
+
+ ee = ecore_event_window_match(ev->win);
+ selection = _atom_to_selection(ev->atom);
+ EINA_SAFETY_ON_FALSE_GOTO(!!ee, end);
+ EINA_SAFETY_ON_FALSE_GOTO(selection != ECORE_EVAS_SELECTION_BUFFER_LAST, end);
+
+ //notify that the selection has changed on this ecore evas
+ if (ee->func.fn_selection_changed)
+ ee->func.fn_selection_changed(ee, 0, selection);
+end:
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_eina_content_converter(char *target, void *data, int size EINA_UNUSED, void **data_ret, int *size_ret, Ecore_X_Atom *ttype, int *typesize)
+{
+ Ecore_Evas_X11_Selection_Data *sdata = data;
+ Eina_Bool ret = EINA_FALSE;;
+
+ if (size != sizeof(Ecore_Evas_X11_Selection_Data)) return EINA_FALSE;
+
+ if (!EINA_MAGIC_CHECK(sdata, ECORE_EVAS_X11_SELECTION)) return EINA_FALSE;
+
+ if (eina_streq(target, "TARGETS") || eina_streq(target, "ATOM"))
+ {
+ //list all available types that we have currently
+ Ecore_X_Atom *result = calloc(eina_array_count(sdata->callbacks.available_types), sizeof(Ecore_X_Atom));
+ for (unsigned int i = 0; i < eina_array_count(sdata->callbacks.available_types); ++i)
+ {
+ result[i] = ecore_x_atom_get(eina_array_data_get(sdata->callbacks.available_types, i));
+ }
+ *size_ret = eina_array_count(sdata->callbacks.available_types);
+ *data_ret = result;
+ *ttype = ECORE_X_ATOM_ATOM;
+ *typesize = 32; /* urk */
+ ret = EINA_TRUE;
+ }
+ else
+ {
+ const char *mime_type = _decrypt_type(target);
+ for (unsigned int i = 0; i < eina_array_count(sdata->callbacks.available_types); ++i)
+ {
+ if (mime_type == eina_array_data_get(sdata->callbacks.available_types, i))
+ {
+ Eina_Rw_Slice slice;
+ sdata->callbacks.delivery(sdata->ee, 1, sdata->buffer, mime_type, &slice);
+ *size_ret = slice.len;
+ *data_ret = slice.mem;
+ *ttype = ecore_x_atom_get(target); //use here target in order to get the correct atom
+ //FIXME in selection manager we never set here the typesize, isn't that weird ?
+ ret = EINA_TRUE;
+ // XXX: fixup for strings to not include nul byte if last
+ // byte is nul byte
+ if (((!strncmp(target, "text/", 5)) ||
+ (!strcmp(target, "tex")) ||
+ (!strcmp(target, "TEXT")) ||
+ (!strcmp(target, "COMPOUND_TEXT")) ||
+ (!strcmp(target, "STRING")) ||
+ (!strcmp(target, "UTF8_STRING"))) &&
+ (slice.len > 0) && (slice.bytes[slice.len - 1] == '\0'))
+ {
+ *size_ret = *size_ret - 1;
+ }
+ break;
+ }
+ }
+ eina_stringshare_del(mime_type);
+ }
+
+ return ret;
+}
+
+static Eina_Bool
+_ecore_evas_x_dnd_enter(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Xdnd_Enter *enter = event;
+ Eina_Array *mime_tmp;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Ecore_Evas *ee;
+
+ mime_tmp = eina_array_new(10);
+ ee = ecore_event_window_match(enter->win);
+ EINA_SAFETY_ON_NULL_GOTO(ee, end);
+ edata = ee->engine.data;
+ edata->xserver_atom_name_during_dnd = eina_array_new(10);
+ for (int i = 0; i < enter->num_types; ++i)
+ {
+ const char *mime_type = _decrypt_type(enter->types[i]);
+ eina_array_push(mime_tmp, mime_type);
+ eina_array_push(edata->xserver_atom_name_during_dnd, eina_stringshare_add(enter->types[i]));
+ }
+ ecore_evas_dnd_enter(ee, 1, eina_array_iterator_new(mime_tmp), EINA_POSITION2D(0,0)); //FIXME
+
+end:
+ eina_array_free(mime_tmp);
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_ecore_evas_x_dnd_leave(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Xdnd_Leave *leave = event;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Ecore_Evas *ee;
+
+ ee = ecore_event_window_match(leave->win);
+ EINA_SAFETY_ON_NULL_GOTO(ee, end);
+ edata = ee->engine.data;
+ ecore_evas_dnd_leave(ee, 1, EINA_POSITION2D(0,0));
+ for (unsigned int i = 0; i < eina_array_count(edata->xserver_atom_name_during_dnd); ++i)
+ {
+ eina_stringshare_del(eina_array_data_get(edata->xserver_atom_name_during_dnd, i));
+ }
+ eina_array_free(edata->xserver_atom_name_during_dnd);
+ edata->xserver_atom_name_during_dnd = NULL;
+end:
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Ecore_X_Atom
+_x11_dnd_action_rev_map(const char* action)
+{
+ if (eina_streq(action, "copy")) return ECORE_X_ATOM_XDND_ACTION_COPY;
+ if (eina_streq(action, "move")) return ECORE_X_ATOM_XDND_ACTION_MOVE;
+ else if (eina_streq(action, "privat")) return ECORE_X_ATOM_XDND_ACTION_PRIVATE;
+ else if (eina_streq(action, "ask")) return ECORE_X_ATOM_XDND_ACTION_ASK;
+ else if (eina_streq(action, "list")) return ECORE_X_ATOM_XDND_ACTION_LIST;
+ else if (eina_streq(action, "link")) return ECORE_X_ATOM_XDND_ACTION_LINK;
+ else if (eina_streq(action, "description")) return ECORE_X_ATOM_XDND_ACTION_DESCRIPTION;
+ return 0;
+}
+
+static const char*
+_x11_dnd_action_map(Ecore_X_Atom action)
+{
+ if (action == ECORE_X_DND_ACTION_COPY) return "copy";
+ if (action == ECORE_X_ATOM_XDND_ACTION_MOVE) return "move";
+ if (action == ECORE_X_ATOM_XDND_ACTION_PRIVATE) return "privat";
+ if (action == ECORE_X_ATOM_XDND_ACTION_ASK) return "ask";
+ if (action == ECORE_X_ATOM_XDND_ACTION_LIST) return "list";
+ if (action == ECORE_X_ATOM_XDND_ACTION_LINK) return "link";
+ if (action == ECORE_X_ATOM_XDND_ACTION_DESCRIPTION) return "description";
+
+ return "unknown";
+}
+
+static Eina_Bool
+_ecore_evas_x_dnd_position(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Xdnd_Position *pos = event;
+ int x, y, w, h;
+ Ecore_Evas *ee;
+
+ ee = ecore_event_window_match(pos->win);
+ EINA_SAFETY_ON_NULL_GOTO(ee, end);
+ ecore_evas_geometry_get(ee, &x, &y, &w, &h);
+ Eina_Bool used = ecore_evas_dnd_position_set(ee, 1, EINA_POSITION2D(pos->position.x - x, pos->position.y - y));
+ ecore_x_dnd_send_status(used, EINA_FALSE, (Ecore_X_Rectangle){x,y,w,h}, pos->action);
+end:
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_ecore_evas_x_dnd_drop(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Xdnd_Drop *drop = event;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Ecore_Evas *ee;
+
+ ee = ecore_event_window_match(drop->win);
+ EINA_SAFETY_ON_NULL_GOTO(ee, end);
+ edata = ee->engine.data;
+ if (ee->func.fn_dnd_drop)
+ ee->func.fn_dnd_drop(ee, 1, ecore_evas_dnd_pos_get(ee, 1), _x11_dnd_action_map(drop->action));
+ if (edata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].delivery &&
+ !edata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER].requested_type)
+ {
+ //only abort dnd if we have something to deliver here, otherwise some other dnd implementation in our own window is handling that
+ ecore_x_dnd_send_finished();
+ }
+ ecore_evas_dnd_leave(ee, 1, EINA_POSITION2D(drop->position.x ,drop->position.y));
+ eina_array_free(edata->xserver_atom_name_during_dnd);
+ edata->xserver_atom_name_during_dnd = NULL;
+end:
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static Eina_Bool
+_ecore_evas_x_finished(void *udata EINA_UNUSED, int type EINA_UNUSED, void *event)
+{
+ Ecore_X_Event_Xdnd_Finished *finished = event;
+ Ecore_Evas *ee;
+
+ ee = ecore_event_window_match(finished->win);
+ EINA_SAFETY_ON_NULL_GOTO(ee, end);
+
+ _clear_selection(ee, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER);
+end:
+ return ECORE_CALLBACK_PASS_ON;
+}
+
+static void
+_ecore_evas_x_selection_init(void)
+{
+ Ecore_X_Atom _ecore_evas_selection_to_atom[] = {ECORE_X_ATOM_SELECTION_PRIMARY, ECORE_X_ATOM_SELECTION_CLIPBOARD, ECORE_X_ATOM_SELECTION_XDND};
+
+ for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
+ {
+ ecore_evas_selection_to_atom[i] = _ecore_evas_selection_to_atom[i];
+ }
+
+ ecore_evas_selection_handlers[0] =
+ ecore_event_handler_add(ECORE_X_EVENT_SELECTION_NOTIFY,
+ _ecore_evas_x_selection_notify, NULL);
+ ecore_evas_selection_handlers[1] =
+ ecore_event_handler_add(ECORE_X_EVENT_SELECTION_CLEAR,
+ _ecore_evas_x_selection_clear, NULL);
+ if (ECORE_X_EVENT_FIXES_SELECTION_NOTIFY)
+ ecore_evas_selection_handlers[2] =
+ ecore_event_handler_add(ECORE_X_EVENT_FIXES_SELECTION_NOTIFY,
+ _ecore_evas_x_selection_fixes_notify, NULL);
+
+ ecore_evas_selection_handlers[3] = ecore_event_handler_add(ECORE_X_EVENT_XDND_ENTER,
+ _ecore_evas_x_dnd_enter, NULL);
+ ecore_evas_selection_handlers[4] = ecore_event_handler_add(ECORE_X_EVENT_XDND_LEAVE,
+ _ecore_evas_x_dnd_leave, NULL);
+ ecore_evas_selection_handlers[5] = ecore_event_handler_add(ECORE_X_EVENT_XDND_POSITION,
+ _ecore_evas_x_dnd_position, NULL);
+ ecore_evas_selection_handlers[6] = ecore_event_handler_add(ECORE_X_EVENT_XDND_DROP,
+ _ecore_evas_x_dnd_drop, NULL);
+ ecore_evas_selection_handlers[7] = ecore_event_handler_add(ECORE_X_EVENT_XDND_FINISHED,
+ _ecore_evas_x_finished, NULL);
+ /* for us known type */
+ char *supported_types[] = {
+ "text/plain",
+ "text/plain;charset=utf-8",
+ "image/png",
+ "image/jpeg",
+ "image/x-ms-bmp",
+ "image/gif",
+ "image/tiff",
+ "image/svg+xml",
+ "image/x-xpixmap",
+ "image/x-tga",
+ "image/x-portable-pixmap",
+ "TEXT",
+ "COMPOUND_TEXT",
+ "STRING",
+ "UTF8_STRING",
+ "text/x-vcard",
+ "text/uri-list",
+ "application/x-elementary-markup",
+ "ATOM",
+ "TARGETS",
+ NULL
+ };
+ for (int i = 0; supported_types[i]; ++i)
+ {
+ ecore_x_selection_converter_add(supported_types[i], _eina_content_converter);
+ }
+}
+
+static Eina_Bool
+_ecore_evas_x_selection_has_owner(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection)
+{
+ return !!ecore_x_selection_owner_get(ecore_evas_selection_to_atom[selection]);
+}
+
+static void
+_deliver_selection_changed(void *data)
+{
+ Ecore_Evas *ee = data;
+ Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
+
+ if (!ee->func.fn_selection_changed)
+ goto end;
+
+ if (_ecore_evas_x_selection_has_owner(ee, 1, ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER))
+ ee->func.fn_selection_changed(ee, 1, ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER);
+ if (_ecore_evas_x_selection_has_owner(ee, 1, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER))
+ ee->func.fn_selection_changed(ee, 1, ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER);
+ if (_ecore_evas_x_selection_has_owner(ee, 1, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER))
+ ee->func.fn_selection_changed(ee, 1, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER);
+end:
+ edata->init_job = NULL;
+}
+
+static void
+_ecore_evas_x_selection_window_init(Ecore_Evas *ee)
+{
+ Ecore_Evas_Engine_Data_X11 *edata = ee->engine.data;
+ for (int i = 0; i < ECORE_EVAS_SELECTION_BUFFER_LAST; ++i)
+ {
+ ecore_x_fixes_window_selection_notification_request(ee->prop.window, ecore_evas_selection_to_atom[i]);
+ edata->selection_data[i].ee = ee;
+ edata->selection_data[i].buffer = i;
+ EINA_MAGIC_SET(&edata->selection_data[i], ECORE_EVAS_X11_SELECTION);
+ }
+ ecore_x_dnd_aware_set(ee->prop.window, EINA_TRUE);
+ edata->init_job = ecore_job_add(_deliver_selection_changed, ee);
+}
+
+static void
+_store_selection_cbs(Ecore_Evas *ee, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Eina_Bool (*delivery)(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer, const char *type, Eina_Rw_Slice *slice), void (*cancel)(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer))
+{
+ Ecore_Evas_X11_Selection_Data *sdata;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Ecore_Evas_Selection_Callbacks *cbs;
+
+ edata = ee->engine.data;
+ sdata = &edata->selection_data[selection];
+ cbs = &sdata->callbacks;
+
+ if (cbs->cancel)
+ {
+ _clear_selection(ee, selection);
+ edata->skip_clean_event ++; //we are going to overwrite our own selection, this will emit a clean event, but we already freed it.
+ }
+
+ cbs->delivery = delivery;
+ cbs->cancel = cancel;
+ cbs->available_types = available_types;
+}
+
+static Eina_Bool
+_ecore_evas_x_selection_claim(Ecore_Evas *ee, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection, Eina_Array *available_types, Ecore_Evas_Selection_Internal_Delivery delivery, Ecore_Evas_Selection_Internal_Cancel cancel)
+{
+ Ecore_Evas_X11_Selection_Data *sdata;
+ Ecore_Evas_Engine_Data_X11 *edata;
+
+ edata = ee->engine.data;
+ sdata = &edata->selection_data[selection];
+
+ _store_selection_cbs(ee, selection, available_types, delivery, cancel);
+
+ if (eina_array_count(available_types) > 0)
+ {
+ //the commands below will *copy* the content of sdata, this you have to ensure that clear is called when sdata is changed.
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
+ ecore_x_selection_primary_set(ee->prop.window, sdata, sizeof(Ecore_Evas_X11_Selection_Data));
+ else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ ecore_x_selection_clipboard_set(ee->prop.window, sdata, sizeof(Ecore_Evas_X11_Selection_Data));
+ }
+ else
+ {
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_SELECTION_BUFFER)
+ ecore_x_selection_primary_clear();
+ else if (selection == ECORE_EVAS_SELECTION_BUFFER_COPY_AND_PASTE_BUFFER)
+ ecore_x_selection_clipboard_clear();
+ }
+
+ //for drag and drop, we are not calling anything in here
+
+ return EINA_TRUE;
+}
+
+Eina_Future*
+_ecore_evas_x_selection_request(Ecore_Evas *ee EINA_UNUSED, unsigned int seat EINA_UNUSED, Ecore_Evas_Selection_Buffer selection, Eina_Array *acceptable_type)
+{
+ Ecore_Evas_X11_Selection_Data *sdata;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Eina_Future *future;
+
+ edata = ee->engine.data;
+ sdata = &edata->selection_data[selection];
+
+ if (sdata->delivery)
+ {
+ eina_promise_reject(sdata->delivery, ecore_evas_request_replaced);
+ _clear_selection_delivery(ee, selection);
+ }
+ sdata->delivery = efl_loop_promise_new(efl_main_loop_get());
+ sdata->acceptable_type = acceptable_type;
+ future = eina_future_new(sdata->delivery);
+
+ if (selection == ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER)
+ {
+ //when in dnd - we are requesting out of the set that we know from the enter event
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(!edata->selection_data[selection].later_conversion, NULL);
+ EINA_SAFETY_ON_FALSE_RETURN_VAL(!edata->selection_data[selection].requested_type, NULL);
+ _search_fitting_type(ee, edata, selection, edata->xserver_atom_name_during_dnd);
+ }
+ else
+ {
+ //when not dnd - we are first wanting to know what is available
+ _ecore_x_selection_request(ee->prop.window, selection, ECORE_X_SELECTION_TARGET_TARGETS);
+ }
+
+ return future;
+}
+
+static void
+_x11_drag_move(void *data, Ecore_X_Xdnd_Position *pos)
+{
+ Ecore_Evas *ee = data;
+ Eina_Rect rect;
+
+ ecore_evas_geometry_get(ee->drag.rep, &rect.x, &rect.y, &rect.w, &rect.h);
+
+ ecore_evas_move(ee->drag.rep, pos->position.x - rect.w / 2, pos->position.y - rect.h/2);
+}
+
+static Eina_Bool
+_x11_drag_mouse_up(void *data, int etype EINA_UNUSED, void *event EINA_UNUSED)
+{
+ Ecore_Evas *ee = data;
+
+ _force_stop_self_dnd(ee);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecore_evas_x_dnd_start(Ecore_Evas *ee, unsigned int seat EINA_UNUSED, Eina_Array *available_types, Ecore_Evas *drag_rep, Eina_Bool (*delivery)(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer, const char *type, Eina_Rw_Slice *slice), void (*cancel)(Ecore_Evas *ee, unsigned int seat, Ecore_Evas_Selection_Buffer buffer), const char* action)
+{
+ Ecore_Evas_X11_Selection_Data *sdata;
+ Ecore_Evas_Engine_Data_X11 *edata;
+ Ecore_X_Atom actx;
+
+ edata = ee->engine.data;
+ sdata = &edata->selection_data[ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER];
+ _store_selection_cbs(ee, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER, available_types, delivery, cancel);
+
+ //first set all types we have
+ ecore_x_dnd_types_set(ee->prop.window, NULL, 0);
+ for (unsigned int i = 0; i < eina_array_count(available_types); ++i)
+ {
+ const char *xserver_mime_type = _mime_to_xserver_type(eina_array_data_get(available_types, i));
+ ecore_x_dnd_type_set(ee->prop.window, xserver_mime_type, EINA_TRUE);
+ eina_stringshare_del(xserver_mime_type);
+ }
+ ecore_x_dnd_aware_set(ee->prop.window, EINA_TRUE);
+ ecore_x_dnd_callback_pos_update_set(_x11_drag_move, ee);
+ ecore_x_dnd_self_begin(ee->prop.window, (unsigned char*)sdata, sizeof(Ecore_Evas_X11_Selection_Data));
+ actx = _x11_dnd_action_rev_map(action);
+ ecore_x_dnd_source_action_set(actx);
+ ecore_x_pointer_grab(ee->prop.window);
+
+ ecore_x_window_ignore_set(drag_rep->prop.window, EINA_TRUE);
+
+ if (edata->mouse_up_handler)
+ ecore_event_handler_del(edata->mouse_up_handler);
+ edata->mouse_up_handler = ecore_event_handler_add(ECORE_EVENT_MOUSE_BUTTON_UP,
+ _x11_drag_mouse_up, ee);
+
+ return EINA_TRUE;
+}
+
+static Eina_Bool
+_ecore_evas_x_dnd_stop(Ecore_Evas *ee, unsigned int seat EINA_UNUSED)
+{
+ _force_stop_self_dnd(ee);
+ _clear_selection(ee, ECORE_EVAS_SELECTION_BUFFER_DRAG_AND_DROP_BUFFER);
+ ecore_x_selection_xdnd_clear(); //This is needed otherwise a outdated sdata struct will be accessed
+ return EINA_TRUE;
+}
+
static Ecore_Evas_Engine_Func _ecore_x_engine_func =
{
_ecore_evas_x_free,
@@ -3746,6 +4583,11 @@ static Ecore_Evas_Engine_Func _ecore_x_engine_func =
NULL, //fn_pointer_device_xy_get
NULL, //fn_prepare
NULL, //fn_last_tick_get
+ _ecore_evas_x_selection_claim, //fn_selection_claim
+ _ecore_evas_x_selection_has_owner, //fn_selection_has_owner
+ _ecore_evas_x_selection_request, //fn_selection_request
+ _ecore_evas_x_dnd_start, //fn_dnd_start
+ _ecore_evas_x_dnd_stop, //fn_dnd_stop
};
/*
@@ -3764,19 +4606,19 @@ _ecore_evas_x_render_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_
/* printf("\tPixman Size: %d %d\n", edata->pixmap.w, edata->pixmap.h); */
/* printf("\tEE Size: %d %d\n", ee->w, ee->h); */
- /* before rendering to the back buffer pixmap, we should check the
- * size. If the back buffer is not the proper size, destroy it and
+ /* before rendering to the back buffer pixmap, we should check the
+ * size. If the back buffer is not the proper size, destroy it and
* create a new one at the proper size */
if ((edata->pixmap.w != ee->w) || (edata->pixmap.h != ee->h))
{
int fw = 0, fh = 0;
/* free the backing pixmap */
- if (edata->pixmap.back)
+ if (edata->pixmap.back)
ecore_x_pixmap_free(edata->pixmap.back);
- edata->pixmap.back =
- ecore_x_pixmap_new(edata->win_root, ee->w, ee->h,
+ edata->pixmap.back =
+ ecore_x_pixmap_new(edata->win_root, ee->w, ee->h,
edata->pixmap.depth);
evas_output_framespace_get(ee->evas, NULL, NULL, &fw, &fh);
@@ -3795,7 +4637,7 @@ _ecore_evas_x_render_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
{
- ERR("evas_engine_info_set() init engine '%s' failed.",
+ ERR("evas_engine_info_set() init engine '%s' failed.",
ee->driver);
}
}
@@ -3813,7 +4655,7 @@ _ecore_evas_x_render_pre(void *data, Evas *e EINA_UNUSED, void *event_info EINA_
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
{
- ERR("evas_engine_info_set() init engine '%s' failed.",
+ ERR("evas_engine_info_set() init engine '%s' failed.",
ee->driver);
}
}
@@ -3836,8 +4678,8 @@ _ecore_evas_x_flush_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_
/* printf("\tBack Pixmap: %d\n", edata->pixmap.back); */
/* printf("\tFront Pixmap: %d\n", edata->pixmap.front); */
- /* done drawing to the back buffer. flip it to the front so that
- * any calls to "fetch pixmap" will return the front buffer already
+ /* done drawing to the back buffer. flip it to the front so that
+ * any calls to "fetch pixmap" will return the front buffer already
* pre-rendered */
/* record the current front buffer */
@@ -3862,7 +4704,7 @@ _ecore_evas_x_flush_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
{
- ERR("evas_engine_info_set() init engine '%s' failed.",
+ ERR("evas_engine_info_set() init engine '%s' failed.",
ee->driver);
}
}
@@ -3880,7 +4722,7 @@ _ecore_evas_x_flush_post(void *data, Evas *e EINA_UNUSED, void *event_info EINA_
if (!evas_engine_info_set(ee->evas, (Evas_Engine_Info *)einfo))
{
- ERR("evas_engine_info_set() init engine '%s' failed.",
+ ERR("evas_engine_info_set() init engine '%s' failed.",
ee->driver);
}
}
@@ -4109,6 +4951,7 @@ ecore_evas_software_x11_new_internal(const char *disp_name, Ecore_X_Window paren
_ecore_evas_x_wm_rotation_protocol_set(ee);
_ecore_evas_x_aux_hints_supported_update(ee);
_ecore_evas_x_aux_hints_update(ee);
+ _ecore_evas_x_selection_window_init(ee);
ee->engine.func->fn_render = _ecore_evas_x_render;
ee->draw_block = EINA_TRUE;
@@ -4299,9 +5142,9 @@ ecore_evas_software_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Windo
edata->pixmap.colormap = einfo->info.colormap;
/* create front and back pixmaps for double-buffer rendering */
- edata->pixmap.front =
+ edata->pixmap.front =
ecore_x_pixmap_new(parent, w, h, edata->pixmap.depth);
- edata->pixmap.back =
+ edata->pixmap.back =
ecore_x_pixmap_new(parent, w, h, edata->pixmap.depth);
einfo->info.drawable = edata->pixmap.back;
@@ -4314,7 +5157,7 @@ ecore_evas_software_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Windo
}
}
- /* FIXME: Allow of these set properties or do something with the
+ /* FIXME: Allow of these set properties or do something with the
* ee->prop.window (x window), which we do not have in pixmap case */
/* _ecore_evas_x_hints_update(ee); */
@@ -4362,7 +5205,7 @@ _ecore_evas_software_x11_pixmap_visual_get(const Ecore_Evas *ee)
return edata->pixmap.visual;
}
-static unsigned long
+static unsigned long
_ecore_evas_software_x11_pixmap_colormap_get(const Ecore_Evas *ee)
{
if (!(!strcmp(ee->driver, "software_x11"))) return 0;
@@ -4370,7 +5213,7 @@ _ecore_evas_software_x11_pixmap_colormap_get(const Ecore_Evas *ee)
return edata->pixmap.colormap;
}
-static int
+static int
_ecore_evas_software_x11_pixmap_depth_get(const Ecore_Evas *ee)
{
if (!(!strcmp(ee->driver, "software_x11"))) return 0;
@@ -4545,6 +5388,7 @@ ecore_evas_gl_x11_options_new_internal(const char *disp_name, Ecore_X_Window par
_ecore_evas_x_wm_rotation_protocol_set(ee);
_ecore_evas_x_aux_hints_supported_update(ee);
_ecore_evas_x_aux_hints_update(ee);
+ _ecore_evas_x_selection_window_init(ee);
ee->draw_block = 1;
if (!wm_exists) edata->configured = 1;
@@ -4711,9 +5555,9 @@ ecore_evas_gl_x11_pixmap_new_internal(const char *disp_name, Ecore_X_Window pare
edata->pixmap.colormap = einfo->info.colormap;
/* create front and back pixmaps for double-buffer rendering */
- edata->pixmap.front =
+ edata->pixmap.front =
ecore_x_pixmap_new(parent, w, h, edata->pixmap.depth);
- edata->pixmap.back =
+ edata->pixmap.back =
ecore_x_pixmap_new(parent, w, h, edata->pixmap.depth);
einfo->info.drawable = edata->pixmap.back;
@@ -4771,7 +5615,7 @@ _ecore_evas_gl_x11_pixmap_visual_get(const Ecore_Evas *ee)
return edata->pixmap.visual;
}
-static unsigned long
+static unsigned long
_ecore_evas_gl_x11_pixmap_colormap_get(const Ecore_Evas *ee)
{
if (!(!strcmp(ee->driver, "opengl_x11"))) return 0;
@@ -4779,7 +5623,7 @@ _ecore_evas_gl_x11_pixmap_colormap_get(const Ecore_Evas *ee)
return edata->pixmap.colormap;
}
-static int
+static int
_ecore_evas_gl_x11_pixmap_depth_get(const Ecore_Evas *ee)
{
if (!(!strcmp(ee->driver, "opengl_x11"))) return 0;
diff --git a/src/modules/ecore_evas/engines/x/meson.build b/src/modules/ecore_evas/engines/x/meson.build
index 582a782115..1108f9c755 100644
--- a/src/modules/ecore_evas/engines/x/meson.build
+++ b/src/modules/ecore_evas/engines/x/meson.build
@@ -14,7 +14,7 @@ endif
shared_module(mod_full_name, engine_src,
include_directories : config_dir + [engine_include_dir],
- dependencies : [eina, ecore_evas, ecore_input_evas] + engine_deps,
+ dependencies : [eina, ecore_evas, ecore_input_evas, efreet] + engine_deps,
install : true,
install_dir : mod_install_dir,
name_suffix : sys_mod_extension
diff --git a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c
index 636026f4b1..85110d4d7f 100644
--- a/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c
+++ b/src/modules/ecore_evas/vnc_server/ecore_evas_vnc_server_fb_keymap.c
@@ -1,4 +1,8 @@
-#include <linux/input-event-codes.h>
+#if defined(__linux__)
+ #include <linux/input-event-codes.h>
+#elif defined(__FreeBSD__)
+ #include <dev/evdev/input-event-codes.h>
+#endif
#include <rfb/keysym.h>
#include <stdlib.h>
#include <limits.h>