2014-10-14 10:52:26 -07:00
|
|
|
#define E_COMP_WL
|
|
|
|
#include "e.h"
|
2015-07-08 12:04:49 -07:00
|
|
|
#include "e_comp_wl_screenshooter_server.h"
|
2014-10-14 10:52:26 -07:00
|
|
|
|
2014-10-17 01:39:58 -07:00
|
|
|
/* handle include for printing uint64_t */
|
|
|
|
#define __STDC_FORMAT_MACROS
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
2014-10-14 10:52:26 -07:00
|
|
|
#define COMPOSITOR_VERSION 3
|
|
|
|
|
2014-10-15 03:53:45 -07:00
|
|
|
/* Resource Data Mapping: (wl_resource_get_user_data)
|
2015-02-24 14:34:20 -08:00
|
|
|
*
|
2014-10-14 23:47:56 -07:00
|
|
|
* wl_surface == e_pixmap
|
2014-10-16 08:28:24 -07:00
|
|
|
* wl_region == eina_tiler
|
2014-11-03 08:27:17 -08:00
|
|
|
* wl_subsurface == e_client
|
2015-02-24 14:34:20 -08:00
|
|
|
*
|
2014-10-14 23:47:56 -07:00
|
|
|
*/
|
|
|
|
|
2014-11-03 09:50:07 -08:00
|
|
|
static void _e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized);
|
|
|
|
|
2014-10-15 03:57:16 -07:00
|
|
|
/* local variables */
|
2014-10-31 09:33:09 -07:00
|
|
|
/* static Eina_Hash *clients_win_hash = NULL; */
|
2014-10-16 09:18:50 -07:00
|
|
|
static Eina_List *handlers = NULL;
|
2015-01-26 11:50:58 -08:00
|
|
|
static double _last_event_time = 0.0;
|
2014-10-15 03:57:16 -07:00
|
|
|
|
2014-10-14 11:03:15 -07:00
|
|
|
/* local functions */
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-17 02:16:30 -07:00
|
|
|
_e_comp_wl_focus_down_set(E_Client *ec)
|
|
|
|
{
|
|
|
|
Ecore_Window win = 0;
|
|
|
|
|
|
|
|
win = e_client_util_pwin_get(ec);
|
|
|
|
e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, win);
|
|
|
|
e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, win);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2015-03-18 14:30:49 -07:00
|
|
|
_e_comp_wl_focus_check(void)
|
2014-10-17 02:16:30 -07:00
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
if (stopping) return;
|
|
|
|
ec = e_client_focused_get();
|
2015-06-25 16:55:37 -07:00
|
|
|
if ((!ec) || e_pixmap_is_x(ec->pixmap))
|
2015-03-18 14:30:49 -07:00
|
|
|
e_grabinput_focus(e_comp->ee_win, E_FOCUS_METHOD_PASSIVE);
|
2014-10-17 02:16:30 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 11:07:38 -07:00
|
|
|
_e_comp_wl_log_cb_print(const char *format, va_list args)
|
|
|
|
{
|
2014-10-14 12:12:17 -07:00
|
|
|
EINA_LOG_DOM_INFO(e_log_dom, format, args);
|
2014-10-14 11:07:38 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static Eina_Bool
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_cb_read(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
2014-10-14 11:40:02 -07:00
|
|
|
{
|
|
|
|
/* dispatch pending wayland events */
|
2015-05-18 06:08:52 -07:00
|
|
|
wl_event_loop_dispatch(e_comp->wl_comp_data->wl.loop, 0);
|
2014-10-14 11:40:02 -07:00
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_cb_prepare(void *data EINA_UNUSED, Ecore_Fd_Handler *hdlr EINA_UNUSED)
|
2014-10-14 11:40:02 -07:00
|
|
|
{
|
|
|
|
/* flush pending client events */
|
2015-05-18 06:08:52 -07:00
|
|
|
wl_display_flush_clients(e_comp->wl_comp_data->wl.disp);
|
2014-10-14 11:40:02 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static Eina_Bool
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_cb_module_idle(void *data EINA_UNUSED)
|
2014-10-14 11:44:21 -07:00
|
|
|
{
|
2015-04-28 10:38:26 -07:00
|
|
|
const char **m, *mods[] =
|
|
|
|
{
|
|
|
|
"wl_desktop_shell",
|
|
|
|
"xwayland",
|
|
|
|
NULL
|
|
|
|
};
|
2014-10-14 11:44:21 -07:00
|
|
|
|
|
|
|
/* check if we are still loading modules */
|
|
|
|
if (e_module_loading_get()) return ECORE_CALLBACK_RENEW;
|
|
|
|
|
2015-04-28 10:38:26 -07:00
|
|
|
for (m = mods; *m; m++)
|
2014-10-14 11:44:21 -07:00
|
|
|
{
|
2015-04-28 10:38:26 -07:00
|
|
|
E_Module *mod = e_module_find(*m);
|
2014-10-14 11:44:21 -07:00
|
|
|
|
2015-04-28 10:38:26 -07:00
|
|
|
if (!mod)
|
|
|
|
mod = e_module_new(*m);
|
2014-10-14 11:44:21 -07:00
|
|
|
|
2015-04-28 10:38:26 -07:00
|
|
|
if (mod)
|
|
|
|
e_module_enable(mod);
|
2014-10-14 11:44:21 -07:00
|
|
|
}
|
|
|
|
|
2015-04-28 10:38:26 -07:00
|
|
|
/* FIXME: NB:
|
|
|
|
* Do we need to dispatch pending wl events here ?? */
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_CANCEL;
|
2014-10-14 11:44:21 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 09:25:59 -07:00
|
|
|
_e_comp_wl_evas_cb_show(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec, *tmp;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
2015-08-04 15:41:31 -07:00
|
|
|
if (e_object_is_del(data)) return;
|
2014-10-16 09:25:59 -07:00
|
|
|
|
|
|
|
if (!ec->override) e_hints_window_visible_set(ec);
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
if ((!ec->override) && (!ec->re_manage) && (!ec->comp_data->reparented) &&
|
2015-01-09 09:45:03 -08:00
|
|
|
(!ec->comp_data->need_reparent))
|
|
|
|
{
|
|
|
|
ec->comp_data->need_reparent = EINA_TRUE;
|
|
|
|
ec->visible = EINA_TRUE;
|
2015-02-10 16:15:22 -08:00
|
|
|
}
|
|
|
|
if (!e_client_util_ignored_get(ec))
|
|
|
|
{
|
|
|
|
ec->take_focus = !starting;
|
2015-01-09 09:45:03 -08:00
|
|
|
EC_CHANGED(ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ec->comp_data->need_reparent)
|
|
|
|
{
|
|
|
|
if ((ec->hidden) || (ec->iconic))
|
|
|
|
{
|
|
|
|
evas_object_hide(ec->frame);
|
|
|
|
e_comp_object_damage(ec->frame, 0, 0, ec->w, ec->h);
|
|
|
|
}
|
|
|
|
else if (!ec->internal_elm_win)
|
|
|
|
evas_object_show(ec->frame);
|
|
|
|
}
|
|
|
|
|
2014-10-16 09:25:59 -07:00
|
|
|
EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp)
|
|
|
|
evas_object_show(tmp->frame);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 09:28:37 -07:00
|
|
|
_e_comp_wl_evas_cb_hide(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec, *tmp;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ec->e.state.video_child, l, tmp)
|
|
|
|
evas_object_hide(tmp->frame);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 09:56:40 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
Evas_Event_Mouse_In *ev;
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
uint32_t serial;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2015-01-14 13:11:53 -08:00
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
2015-08-04 15:44:23 -07:00
|
|
|
e_comp->wl_comp_data->ptr.ec = ec;
|
2015-03-13 12:41:21 -07:00
|
|
|
if (!eina_list_count(e_comp->wl_comp_data->ptr.resources)) return;
|
2015-03-10 13:24:45 -07:00
|
|
|
|
2014-10-16 09:56:40 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2015-03-13 12:41:21 -07:00
|
|
|
serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->ptr.resources, l, res)
|
2014-10-16 09:56:40 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
2015-02-24 14:34:20 -08:00
|
|
|
wl_pointer_send_enter(res, serial, ec->comp_data->surface,
|
e_comp_wl: fix not sending a mouse enter event to client.
Summary:
First of all, currently cdata->ptr.x,y contains e_client related pos.
But, cdata is owned by e_comp, not per e_client. So cdata->ptr.x,y should contain
absolute pos.
And, when a pointer resource is created, enter event should be sent to client.
Change-Id: I21cb031e293fe281e35ba89f3a96116a28a48856
Signed-off-by: Boram Park <boram1288.park@samsung.com>
Test Plan:
1. run e as wayland server
2. move cursor to around 50,50
3. run elementary_test
4. click the mouse left button on slide toggle widget.
(Don't move a cursor out of elementary_test. If you do, you can't find bug)
Reviewers: gwanglim, raster, devilhorns, ManMower, zmike
Reviewed By: zmike
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D2330
2015-05-18 08:53:05 -07:00
|
|
|
wl_fixed_from_int(ev->canvas.x - ec->client.x),
|
|
|
|
wl_fixed_from_int(ev->canvas.y - ec->client.y));
|
2014-10-16 09:56:40 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 10:06:24 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
uint32_t serial;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
if (ec->cur_mouse_action) return;
|
2015-02-06 15:28:11 -08:00
|
|
|
/* FIXME? this is a hack to just reset the cursor whenever we mouse out. not sure if accurate */
|
|
|
|
{
|
|
|
|
Evas_Object *o;
|
|
|
|
|
|
|
|
ecore_evas_cursor_get(e_comp->ee, &o, NULL, NULL, NULL);
|
|
|
|
if (e_comp->pointer->o_ptr != o)
|
2015-02-13 12:11:33 -08:00
|
|
|
e_pointer_object_set(e_comp->pointer, NULL, 0, 0);
|
2015-02-06 15:28:11 -08:00
|
|
|
}
|
2015-08-04 15:44:23 -07:00
|
|
|
if (e_comp->wl_comp_data->ptr.ec == ec)
|
|
|
|
e_comp->wl_comp_data->ptr.ec = NULL;
|
2014-10-16 10:06:24 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2015-01-14 13:11:53 -08:00
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
2015-03-13 12:41:21 -07:00
|
|
|
if (!eina_list_count(e_comp->wl_comp_data->ptr.resources)) return;
|
2015-03-10 13:24:45 -07:00
|
|
|
|
2014-10-16 10:06:24 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2015-03-13 12:41:21 -07:00
|
|
|
serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
|
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->ptr.resources, l, res)
|
2014-10-16 10:06:24 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
wl_pointer_send_leave(res, serial, ec->comp_data->surface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 10:08:22 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
Evas_Event_Mouse_Move *ev;
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
if (ec->cur_mouse_action) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
2015-06-30 15:31:43 -07:00
|
|
|
if (ec->ignored) return;
|
2015-01-14 13:11:53 -08:00
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
2014-10-16 10:08:22 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2015-03-13 12:41:21 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->ptr.resources, l, res)
|
2014-10-16 10:08:22 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
2015-02-24 14:34:20 -08:00
|
|
|
wl_pointer_send_motion(res, ev->timestamp,
|
e_comp_wl: fix not sending a mouse enter event to client.
Summary:
First of all, currently cdata->ptr.x,y contains e_client related pos.
But, cdata is owned by e_comp, not per e_client. So cdata->ptr.x,y should contain
absolute pos.
And, when a pointer resource is created, enter event should be sent to client.
Change-Id: I21cb031e293fe281e35ba89f3a96116a28a48856
Signed-off-by: Boram Park <boram1288.park@samsung.com>
Test Plan:
1. run e as wayland server
2. move cursor to around 50,50
3. run elementary_test
4. click the mouse left button on slide toggle widget.
(Don't move a cursor out of elementary_test. If you do, you can't find bug)
Reviewers: gwanglim, raster, devilhorns, ManMower, zmike
Reviewed By: zmike
Subscribers: cedric
Differential Revision: https://phab.enlightenment.org/D2330
2015-05-18 08:53:05 -07:00
|
|
|
wl_fixed_from_int(ev->cur.canvas.x - ec->client.x),
|
|
|
|
wl_fixed_from_int(ev->cur.canvas.y - ec->client.y));
|
2014-10-16 10:08:22 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-25 19:00:11 -08:00
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_evas_handle_mouse_button(E_Client *ec, uint32_t timestamp, uint32_t button_id, uint32_t state)
|
2014-10-16 14:10:01 -07:00
|
|
|
{
|
|
|
|
Eina_List *l;
|
2015-02-25 19:00:11 -08:00
|
|
|
struct wl_client *wc;
|
2014-10-16 14:10:01 -07:00
|
|
|
uint32_t serial, btn;
|
2015-02-25 19:00:11 -08:00
|
|
|
struct wl_resource *res;
|
2014-10-16 14:10:01 -07:00
|
|
|
|
2015-02-26 18:55:34 -08:00
|
|
|
if (ec->cur_mouse_action || ec->border_menu) return EINA_FALSE;
|
2015-02-26 18:54:17 -08:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return EINA_FALSE;
|
2015-06-30 15:31:43 -07:00
|
|
|
if (ec->ignored) return EINA_FALSE;
|
2015-02-26 18:54:17 -08:00
|
|
|
|
2015-02-25 19:00:11 -08:00
|
|
|
switch (button_id)
|
2014-10-16 14:10:01 -07:00
|
|
|
{
|
|
|
|
case 1:
|
|
|
|
btn = BTN_LEFT;
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
btn = BTN_MIDDLE;
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
btn = BTN_RIGHT;
|
|
|
|
break;
|
|
|
|
default:
|
2015-02-25 19:00:11 -08:00
|
|
|
btn = button_id;
|
2014-10-16 14:10:01 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->ptr.button = btn;
|
2014-10-16 14:10:01 -07:00
|
|
|
|
2015-02-25 19:00:11 -08:00
|
|
|
if (!ec->comp_data->surface) return EINA_FALSE;
|
2015-01-14 13:11:53 -08:00
|
|
|
|
2015-03-13 12:41:21 -07:00
|
|
|
if (!eina_list_count(e_comp->wl_comp_data->ptr.resources))
|
2015-03-10 13:24:45 -07:00
|
|
|
return EINA_TRUE;
|
|
|
|
|
2014-10-16 14:10:01 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2015-03-13 12:41:21 -07:00
|
|
|
serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
|
2015-02-25 19:00:11 -08:00
|
|
|
|
2015-03-13 12:41:21 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->ptr.resources, l, res)
|
2014-10-16 14:10:01 -07:00
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
2015-02-25 19:00:11 -08:00
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
wl_pointer_send_button(res, serial, timestamp, btn, state);
|
2014-10-16 14:10:01 -07:00
|
|
|
}
|
2015-02-25 19:00:11 -08:00
|
|
|
return EINA_TRUE;
|
2014-10-16 14:10:01 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2015-02-25 19:00:11 -08:00
|
|
|
_e_comp_wl_evas_cb_mouse_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
2014-10-16 14:11:43 -07:00
|
|
|
{
|
2015-02-26 18:54:17 -08:00
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Mouse_Down *ev = event;
|
2014-10-16 14:11:43 -07:00
|
|
|
|
2015-02-25 19:00:11 -08:00
|
|
|
_e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
|
|
|
|
WL_POINTER_BUTTON_STATE_PRESSED);
|
|
|
|
}
|
2014-10-16 14:11:43 -07:00
|
|
|
|
2015-02-25 19:00:11 -08:00
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_mouse_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
2015-02-26 18:54:17 -08:00
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Mouse_Up *ev = event;
|
2015-01-14 13:11:53 -08:00
|
|
|
|
2015-02-25 19:00:11 -08:00
|
|
|
_e_comp_wl_evas_handle_mouse_button(ec, ev->timestamp, ev->button,
|
|
|
|
WL_POINTER_BUTTON_STATE_RELEASED);
|
2014-10-16 14:11:43 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 14:13:15 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_wheel(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
Evas_Event_Mouse_Wheel *ev;
|
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
|
|
|
uint32_t axis, dir;
|
|
|
|
|
|
|
|
ev = event;
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
if (ec->cur_mouse_action) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
2015-06-30 15:31:43 -07:00
|
|
|
if (ec->ignored) return;
|
2014-10-16 14:13:15 -07:00
|
|
|
|
|
|
|
if (ev->direction == 0)
|
|
|
|
axis = WL_POINTER_AXIS_VERTICAL_SCROLL;
|
|
|
|
else
|
|
|
|
axis = WL_POINTER_AXIS_HORIZONTAL_SCROLL;
|
|
|
|
|
|
|
|
if (ev->z < 0)
|
|
|
|
dir = -wl_fixed_from_int(abs(ev->z));
|
|
|
|
else
|
|
|
|
dir = wl_fixed_from_int(ev->z);
|
|
|
|
|
2015-01-14 13:11:53 -08:00
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
2014-10-16 14:13:15 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2015-03-13 12:41:21 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->ptr.resources, l, res)
|
2014-10-16 14:13:15 -07:00
|
|
|
{
|
|
|
|
if (!e_comp_wl_input_pointer_check(res)) continue;
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
wl_pointer_send_axis(res, ev->timestamp, axis, dir);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-13 09:05:57 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_multi_down(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_client *wc;
|
|
|
|
uint32_t serial;
|
|
|
|
struct wl_resource *res;
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Multi_Down *ev = event;
|
|
|
|
wl_fixed_t x, y;
|
|
|
|
|
2015-05-13 09:26:07 -07:00
|
|
|
if (!ec->comp_data->surface) return;
|
2015-05-13 09:05:57 -07:00
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2015-05-13 09:26:07 -07:00
|
|
|
serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
|
2015-05-13 09:05:57 -07:00
|
|
|
|
|
|
|
x = wl_fixed_from_int(ev->canvas.x - ec->client.x);
|
|
|
|
y = wl_fixed_from_int(ev->canvas.y - ec->client.y);
|
|
|
|
|
2015-05-13 09:26:07 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->touch.resources, l, res)
|
2015-05-13 09:05:57 -07:00
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
if (!e_comp_wl_input_touch_check(res)) continue;
|
|
|
|
wl_touch_send_down(res, serial, ev->timestamp, ec->comp_data->surface, ev->device, x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_multi_up(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_client *wc;
|
|
|
|
uint32_t serial;
|
|
|
|
struct wl_resource *res;
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Multi_Up *ev = event;
|
|
|
|
|
2015-05-13 09:26:07 -07:00
|
|
|
if (!ec->comp_data->surface) return;
|
2015-05-13 09:05:57 -07:00
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
2015-05-13 09:26:07 -07:00
|
|
|
serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
|
2015-05-13 09:05:57 -07:00
|
|
|
|
2015-05-13 09:26:07 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->touch.resources, l, res)
|
2015-05-13 09:05:57 -07:00
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
if (!e_comp_wl_input_touch_check(res)) continue;
|
|
|
|
wl_touch_send_up(res, serial, ev->timestamp, ev->device);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_multi_move(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
struct wl_client *wc;
|
|
|
|
struct wl_resource *res;
|
|
|
|
E_Client *ec = data;
|
|
|
|
Evas_Event_Multi_Move *ev = event;
|
|
|
|
wl_fixed_t x, y;
|
|
|
|
|
2015-05-13 09:26:07 -07:00
|
|
|
if (!ec->comp_data->surface) return;
|
2015-05-13 09:05:57 -07:00
|
|
|
|
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
|
|
|
|
x = wl_fixed_from_int(ev->cur.canvas.x - ec->client.x);
|
|
|
|
y = wl_fixed_from_int(ev->cur.canvas.y - ec->client.y);
|
|
|
|
|
2015-05-13 09:26:07 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->touch.resources, l, res)
|
2015-05-13 09:05:57 -07:00
|
|
|
{
|
|
|
|
if (wl_resource_get_client(res) != wc) continue;
|
|
|
|
if (!e_comp_wl_input_touch_check(res)) continue;
|
|
|
|
wl_touch_send_motion(res, ev->timestamp, ev->device, x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-31 11:33:45 -07:00
|
|
|
_e_comp_wl_client_priority_adjust(int pid, int set, int adj, Eina_Bool use_adj, Eina_Bool adj_child, Eina_Bool do_child)
|
|
|
|
{
|
2015-02-24 11:47:56 -08:00
|
|
|
Eina_List *files;
|
|
|
|
char *file, buff[PATH_MAX];
|
|
|
|
FILE *f;
|
|
|
|
int pid2, ppid;
|
|
|
|
int num_read;
|
2014-10-31 11:33:45 -07:00
|
|
|
int n;
|
|
|
|
|
2015-02-24 11:47:56 -08:00
|
|
|
if (use_adj)
|
|
|
|
n = (getpriority(PRIO_PROCESS, pid) + adj);
|
|
|
|
else
|
|
|
|
n = set;
|
2014-10-31 11:33:45 -07:00
|
|
|
setpriority(PRIO_PROCESS, pid, n);
|
|
|
|
|
2015-02-24 11:47:56 -08:00
|
|
|
if (adj_child)
|
|
|
|
use_adj = EINA_TRUE;
|
|
|
|
|
|
|
|
if (!do_child)
|
|
|
|
return;
|
|
|
|
|
|
|
|
files = ecore_file_ls("/proc");
|
|
|
|
EINA_LIST_FREE(files, file)
|
|
|
|
{
|
|
|
|
if (!isdigit(file[0]))
|
|
|
|
continue;
|
|
|
|
|
|
|
|
snprintf(buff, sizeof(buff), "/proc/%s/stat", file);
|
|
|
|
if ((f = fopen(buff, "r")))
|
|
|
|
{
|
|
|
|
pid2 = -1;
|
|
|
|
ppid = -1;
|
|
|
|
num_read = fscanf(f, "%i %*s %*s %i %*s", &pid2, &ppid);
|
|
|
|
fclose(f);
|
|
|
|
if (num_read == 2 && ppid == pid)
|
|
|
|
_e_comp_wl_client_priority_adjust(pid2, set,
|
|
|
|
adj, use_adj,
|
|
|
|
adj_child, do_child);
|
|
|
|
}
|
|
|
|
|
|
|
|
free(file);
|
|
|
|
}
|
2014-10-31 11:33:45 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-31 11:33:45 -07:00
|
|
|
_e_comp_wl_client_priority_raise(E_Client *ec)
|
|
|
|
{
|
|
|
|
if (ec->netwm.pid <= 0) return;
|
|
|
|
if (ec->netwm.pid == getpid()) return;
|
2015-02-24 14:34:20 -08:00
|
|
|
_e_comp_wl_client_priority_adjust(ec->netwm.pid,
|
|
|
|
e_config->priority - 1, -1,
|
2014-10-31 11:33:45 -07:00
|
|
|
EINA_FALSE, EINA_TRUE, EINA_FALSE);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-31 11:33:45 -07:00
|
|
|
_e_comp_wl_client_priority_normal(E_Client *ec)
|
|
|
|
{
|
|
|
|
if (ec->netwm.pid <= 0) return;
|
|
|
|
if (ec->netwm.pid == getpid()) return;
|
2015-02-24 14:34:20 -08:00
|
|
|
_e_comp_wl_client_priority_adjust(ec->netwm.pid, e_config->priority, 1,
|
2014-10-31 11:33:45 -07:00
|
|
|
EINA_FALSE, EINA_TRUE, EINA_FALSE);
|
|
|
|
}
|
|
|
|
|
2015-07-22 14:55:30 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_evas_cb_focus_in_timer(E_Client *ec)
|
|
|
|
{
|
|
|
|
uint32_t serial, *k;
|
|
|
|
struct wl_resource *res;
|
|
|
|
Eina_List *l;
|
2015-07-28 14:34:58 -07:00
|
|
|
double t;
|
2015-07-22 14:55:30 -07:00
|
|
|
|
|
|
|
ec->comp_data->on_focus_timer = NULL;
|
|
|
|
|
2015-07-28 14:36:13 -07:00
|
|
|
if (!e_comp->wl_comp_data->kbd.focused) return EINA_FALSE;
|
2015-07-22 14:55:30 -07:00
|
|
|
serial = wl_display_next_serial(e_comp->wl_comp_data->wl.disp);
|
2015-07-28 14:34:58 -07:00
|
|
|
t = ecore_time_unix_get();
|
2015-07-22 14:55:30 -07:00
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->kbd.focused, l, res)
|
|
|
|
wl_array_for_each(k, &e_comp->wl_comp_data->kbd.keys)
|
2015-07-28 14:34:58 -07:00
|
|
|
wl_keyboard_send_key(res, serial, t,
|
2015-07-22 14:55:30 -07:00
|
|
|
*k, WL_KEYBOARD_KEY_STATE_PRESSED);
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-22 09:06:36 -07:00
|
|
|
_e_comp_wl_evas_cb_focus_in(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec, *focused;
|
2015-07-22 13:59:23 -07:00
|
|
|
struct wl_resource *res;
|
|
|
|
struct wl_client *wc;
|
|
|
|
Eina_List *l;
|
2014-10-22 09:06:36 -07:00
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
if (ec->iconic) return;
|
|
|
|
|
|
|
|
/* block spurious focus events */
|
|
|
|
focused = e_client_focused_get();
|
|
|
|
if ((focused) && (ec != focused)) return;
|
|
|
|
|
2014-10-31 11:33:45 -07:00
|
|
|
/* raise client priority */
|
|
|
|
_e_comp_wl_client_priority_raise(ec);
|
2015-02-11 08:50:06 -08:00
|
|
|
|
2015-07-22 13:59:23 -07:00
|
|
|
wc = wl_resource_get_client(ec->comp_data->surface);
|
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->kbd.resources, l, res)
|
|
|
|
if (wl_resource_get_client(res) == wc)
|
2015-07-22 14:38:40 -07:00
|
|
|
e_comp->wl_comp_data->kbd.focused = eina_list_append(e_comp->wl_comp_data->kbd.focused, res);
|
|
|
|
if (!e_comp->wl_comp_data->kbd.focused) return;
|
|
|
|
e_comp_wl_input_keyboard_enter_send(ec);
|
2015-08-04 15:50:16 -07:00
|
|
|
e_comp_wl_data_device_keyboard_focus_set();
|
2015-07-22 14:55:30 -07:00
|
|
|
ec->comp_data->on_focus_timer = ecore_timer_add(0.8, (Ecore_Task_Cb)_e_comp_wl_evas_cb_focus_in_timer, ec);
|
2014-10-22 09:06:36 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-22 09:06:36 -07:00
|
|
|
_e_comp_wl_evas_cb_focus_out(void *data, Evas *evas EINA_UNUSED, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
2015-06-25 16:16:27 -07:00
|
|
|
E_Comp_Wl_Data *cdata;
|
2014-10-22 09:06:36 -07:00
|
|
|
struct wl_resource *res;
|
|
|
|
uint32_t serial, *k;
|
2015-07-22 14:38:40 -07:00
|
|
|
Eina_List *l, *ll;
|
2015-07-28 14:34:58 -07:00
|
|
|
double t;
|
2014-10-22 09:06:36 -07:00
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
|
2015-03-13 12:41:21 -07:00
|
|
|
cdata = e_comp->wl_comp_data;
|
2014-10-22 09:06:36 -07:00
|
|
|
|
2015-07-22 13:28:48 -07:00
|
|
|
if (!ec->comp_data) return;
|
2015-03-06 10:08:24 -08:00
|
|
|
|
2015-07-22 14:55:30 -07:00
|
|
|
E_FREE_FUNC(ec->comp_data->on_focus_timer, ecore_timer_del);
|
|
|
|
|
2015-03-06 10:08:24 -08:00
|
|
|
/* lower client priority */
|
2015-07-22 13:28:48 -07:00
|
|
|
if (!e_object_is_del(data))
|
|
|
|
_e_comp_wl_client_priority_normal(ec);
|
2015-03-06 10:08:24 -08:00
|
|
|
|
2015-01-14 13:11:53 -08:00
|
|
|
if (!ec->comp_data->surface) return;
|
|
|
|
|
2015-03-10 13:24:45 -07:00
|
|
|
if (!eina_list_count(cdata->kbd.resources)) return;
|
|
|
|
|
2014-10-22 09:06:36 -07:00
|
|
|
/* send keyboard_leave to all keyboard resources */
|
|
|
|
serial = wl_display_next_serial(cdata->wl.disp);
|
2015-07-28 14:34:58 -07:00
|
|
|
t = ecore_time_unix_get();
|
2015-07-22 14:38:40 -07:00
|
|
|
EINA_LIST_FOREACH_SAFE(cdata->kbd.focused, l, ll, res)
|
2014-10-22 09:06:36 -07:00
|
|
|
{
|
2015-07-22 13:59:23 -07:00
|
|
|
wl_array_for_each(k, &cdata->kbd.keys)
|
2015-07-28 14:34:58 -07:00
|
|
|
wl_keyboard_send_key(res, serial, t,
|
2015-07-22 13:59:23 -07:00
|
|
|
*k, WL_KEYBOARD_KEY_STATE_RELEASED);
|
2014-10-22 09:06:36 -07:00
|
|
|
wl_keyboard_send_leave(res, serial, ec->comp_data->surface);
|
2015-07-22 14:38:40 -07:00
|
|
|
e_comp->wl_comp_data->kbd.focused = eina_list_remove_list(e_comp->wl_comp_data->kbd.focused, l);
|
2014-10-22 09:06:36 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-31 09:33:09 -07:00
|
|
|
_e_comp_wl_evas_cb_resize(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
|
2014-11-10 08:58:20 -08:00
|
|
|
if ((ec->shading) || (ec->shaded)) return;
|
2015-02-28 12:43:12 -08:00
|
|
|
if (!ec->comp_data->shell.configure_send) return;
|
2015-07-15 15:08:32 -07:00
|
|
|
if (e_client_util_resizing_get(ec) && e_comp->wl_comp_data->resize.edges)
|
2015-02-28 13:48:07 -08:00
|
|
|
{
|
2015-03-03 13:48:25 -08:00
|
|
|
int x, y, ax, ay;
|
2015-02-28 13:48:07 -08:00
|
|
|
|
|
|
|
x = ec->mouse.last_down[ec->moveinfo.down.button - 1].w;
|
|
|
|
y = ec->mouse.last_down[ec->moveinfo.down.button - 1].h;
|
2015-03-03 13:48:25 -08:00
|
|
|
if (ec->comp_data->shell.window.w && ec->comp_data->shell.window.h)
|
|
|
|
{
|
|
|
|
ax = ec->client.w - ec->comp_data->shell.window.w;
|
|
|
|
ay = ec->client.h - ec->comp_data->shell.window.h;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ax = ay = 0;
|
2015-02-28 13:48:07 -08:00
|
|
|
|
|
|
|
switch (ec->resize_mode)
|
|
|
|
{
|
|
|
|
case E_POINTER_RESIZE_TL:
|
|
|
|
case E_POINTER_RESIZE_L:
|
|
|
|
case E_POINTER_RESIZE_BL:
|
2015-03-03 13:48:25 -08:00
|
|
|
x += ec->mouse.last_down[ec->moveinfo.down.button - 1].mx -
|
|
|
|
ec->mouse.current.mx - ec->comp_data->shell.window.x;
|
2015-02-28 13:48:07 -08:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_TR:
|
|
|
|
case E_POINTER_RESIZE_R:
|
|
|
|
case E_POINTER_RESIZE_BR:
|
2015-03-03 13:48:25 -08:00
|
|
|
x += ec->mouse.current.mx - ec->mouse.last_down[ec->moveinfo.down.button - 1].mx -
|
|
|
|
ec->comp_data->shell.window.x;
|
2015-02-28 13:48:07 -08:00
|
|
|
break;
|
2015-03-03 13:48:25 -08:00
|
|
|
default:
|
|
|
|
x -= ax;
|
2015-02-28 13:48:07 -08:00
|
|
|
}
|
|
|
|
switch (ec->resize_mode)
|
|
|
|
{
|
|
|
|
case E_POINTER_RESIZE_TL:
|
|
|
|
case E_POINTER_RESIZE_T:
|
|
|
|
case E_POINTER_RESIZE_TR:
|
2015-03-03 13:48:25 -08:00
|
|
|
y += ec->mouse.last_down[ec->moveinfo.down.button - 1].my -
|
|
|
|
ec->mouse.current.my - ec->comp_data->shell.window.y;
|
2015-02-28 13:48:07 -08:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_BL:
|
|
|
|
case E_POINTER_RESIZE_B:
|
|
|
|
case E_POINTER_RESIZE_BR:
|
2015-03-03 13:48:25 -08:00
|
|
|
y += ec->mouse.current.my - ec->mouse.last_down[ec->moveinfo.down.button - 1].my -
|
|
|
|
ec->comp_data->shell.window.y;
|
2015-02-28 13:48:07 -08:00
|
|
|
break;
|
2015-03-03 13:48:25 -08:00
|
|
|
default:
|
|
|
|
y -= ay;
|
2015-02-28 13:48:07 -08:00
|
|
|
}
|
2015-03-18 12:52:56 -07:00
|
|
|
x = E_CLAMP(x, 1, x);
|
|
|
|
y = E_CLAMP(y, 1, y);
|
2015-02-28 13:48:07 -08:00
|
|
|
ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
|
2015-06-25 06:48:44 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges,
|
|
|
|
x, y);
|
2015-02-28 13:48:07 -08:00
|
|
|
}
|
2015-07-24 13:33:06 -07:00
|
|
|
else if ((!ec->fullscreen) && (!ec->maximized) && (!ec->comp_data->maximize_pre))
|
2015-02-27 12:55:41 -08:00
|
|
|
ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
|
2015-06-25 06:48:44 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges,
|
|
|
|
ec->client.w, ec->client.h);
|
2014-10-31 09:33:09 -07:00
|
|
|
}
|
|
|
|
|
2015-02-26 19:32:14 -08:00
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_state_update(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2015-02-27 07:59:59 -08:00
|
|
|
/* check for wayland pixmap */
|
|
|
|
|
2015-02-26 19:32:14 -08:00
|
|
|
if (ec->comp_data->shell.configure_send)
|
2015-03-12 12:19:52 -07:00
|
|
|
ec->comp_data->shell.configure_send(ec->comp_data->shell.surface, 0, ec->client.w, ec->client.h);
|
2015-07-24 13:33:06 -07:00
|
|
|
ec->comp_data->maximize_pre = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_evas_cb_maximize_pre(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec = data;
|
|
|
|
|
|
|
|
ec->comp_data->maximize_pre = 1;
|
2015-02-26 19:32:14 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-17 01:39:58 -07:00
|
|
|
_e_comp_wl_evas_cb_delete_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
if (ec->netwm.ping) e_client_ping(ec);
|
|
|
|
|
|
|
|
e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
|
|
|
|
|
2015-02-01 16:01:57 -08:00
|
|
|
e_object_del(E_OBJECT(ec));
|
2014-10-17 01:39:58 -07:00
|
|
|
|
2015-03-18 14:30:49 -07:00
|
|
|
_e_comp_wl_focus_check();
|
2014-10-17 01:39:58 -07:00
|
|
|
|
|
|
|
/* TODO: Delete request send ??
|
|
|
|
* NB: No such animal wrt wayland */
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-17 01:41:32 -07:00
|
|
|
_e_comp_wl_evas_cb_kill_request(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
/* if (ec->netwm.ping) e_client_ping(ec); */
|
|
|
|
|
|
|
|
e_comp_ignore_win_del(E_PIXMAP_TYPE_WL, e_pixmap_window_get(ec->pixmap));
|
|
|
|
if (ec->comp_data)
|
|
|
|
{
|
|
|
|
if (ec->comp_data->reparented)
|
|
|
|
e_client_comp_hidden_set(ec, EINA_TRUE);
|
|
|
|
}
|
|
|
|
|
|
|
|
evas_object_pass_events_set(ec->frame, EINA_TRUE);
|
|
|
|
if (ec->visible) evas_object_hide(ec->frame);
|
|
|
|
if (!ec->internal) e_object_del(E_OBJECT(ec));
|
|
|
|
|
2015-03-18 14:30:49 -07:00
|
|
|
_e_comp_wl_focus_check();
|
2014-10-17 01:41:32 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-17 01:43:11 -07:00
|
|
|
_e_comp_wl_evas_cb_ping(void *data, Evas_Object *obj EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
2015-02-24 11:47:56 -08:00
|
|
|
if (!(ec->comp_data->shell.ping)) return;
|
|
|
|
if (!(ec->comp_data->shell.surface)) return;
|
2014-10-17 01:43:11 -07:00
|
|
|
|
2015-02-24 11:47:56 -08:00
|
|
|
ec->comp_data->shell.ping(ec->comp_data->shell.surface);
|
2014-10-17 01:43:11 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-17 01:44:40 -07:00
|
|
|
_e_comp_wl_evas_cb_color_set(void *data, Evas_Object *obj, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
int a = 0;
|
|
|
|
|
|
|
|
if (!(ec = data)) return;
|
|
|
|
evas_object_color_get(obj, NULL, NULL, NULL, &a);
|
|
|
|
if (ec->netwm.opacity == a) return;
|
|
|
|
ec->netwm.opacity = a;
|
|
|
|
ec->netwm.opacity_changed = EINA_TRUE;
|
2014-10-17 01:47:57 -07:00
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_buffer_reference_cb_destroy(struct wl_listener *listener, void *data)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Buffer_Ref *ref;
|
|
|
|
|
|
|
|
ref = container_of(listener, E_Comp_Wl_Buffer_Ref, destroy_listener);
|
|
|
|
if ((E_Comp_Wl_Buffer *)data != ref->buffer) return;
|
|
|
|
ref->buffer = NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_buffer_cb_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Buffer *buffer;
|
|
|
|
|
|
|
|
buffer = container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
|
|
|
|
wl_signal_emit(&buffer->destroy_signal, buffer);
|
|
|
|
free(buffer);
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2014-10-16 09:18:50 -07:00
|
|
|
_e_comp_wl_client_evas_init(E_Client *ec)
|
|
|
|
{
|
2015-02-11 14:22:55 -08:00
|
|
|
if (ec->comp_data->evas_init) return;
|
2015-02-24 14:34:20 -08:00
|
|
|
evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_SHOW,
|
2014-10-16 09:25:59 -07:00
|
|
|
_e_comp_wl_evas_cb_show, ec);
|
2015-02-24 14:34:20 -08:00
|
|
|
evas_object_event_callback_add(ec->frame, EVAS_CALLBACK_HIDE,
|
2014-10-16 09:28:37 -07:00
|
|
|
_e_comp_wl_evas_cb_hide, ec);
|
2014-10-16 09:25:59 -07:00
|
|
|
|
2014-10-16 09:56:40 -07:00
|
|
|
/* setup input callbacks */
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_IN, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-16 09:56:40 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_in, ec);
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_OUT, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-16 10:06:24 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_out, ec);
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_MOVE, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-16 10:08:22 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_move, ec);
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_DOWN, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-16 14:10:01 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_down, ec);
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_UP, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-16 14:11:43 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_up, ec);
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MOUSE_WHEEL, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-16 14:13:15 -07:00
|
|
|
_e_comp_wl_evas_cb_mouse_wheel, ec);
|
2014-10-22 09:06:36 -07:00
|
|
|
|
2015-05-13 09:05:57 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MULTI_DOWN, EVAS_CALLBACK_PRIORITY_AFTER,
|
|
|
|
_e_comp_wl_evas_cb_multi_down, ec);
|
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MULTI_UP, EVAS_CALLBACK_PRIORITY_AFTER,
|
|
|
|
_e_comp_wl_evas_cb_multi_up, ec);
|
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_MULTI_MOVE, EVAS_CALLBACK_PRIORITY_AFTER,
|
|
|
|
_e_comp_wl_evas_cb_multi_move, ec);
|
|
|
|
|
|
|
|
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_FOCUS_IN, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-22 09:06:36 -07:00
|
|
|
_e_comp_wl_evas_cb_focus_in, ec);
|
2015-04-21 12:17:56 -07:00
|
|
|
evas_object_event_callback_priority_add(ec->frame, EVAS_CALLBACK_FOCUS_OUT, EVAS_CALLBACK_PRIORITY_AFTER,
|
2014-10-22 09:06:36 -07:00
|
|
|
_e_comp_wl_evas_cb_focus_out, ec);
|
|
|
|
|
2014-10-31 09:33:09 -07:00
|
|
|
if (!ec->override)
|
|
|
|
{
|
2015-02-24 14:34:20 -08:00
|
|
|
evas_object_smart_callback_add(ec->frame, "client_resize",
|
2014-10-31 09:33:09 -07:00
|
|
|
_e_comp_wl_evas_cb_resize, ec);
|
2015-02-26 19:32:14 -08:00
|
|
|
evas_object_smart_callback_add(ec->frame, "maximize_done",
|
|
|
|
_e_comp_wl_evas_cb_state_update, ec);
|
|
|
|
evas_object_smart_callback_add(ec->frame, "unmaximize_done",
|
|
|
|
_e_comp_wl_evas_cb_state_update, ec);
|
2015-07-24 13:33:06 -07:00
|
|
|
evas_object_smart_callback_add(ec->frame, "maximize_pre",
|
|
|
|
_e_comp_wl_evas_cb_maximize_pre, ec);
|
|
|
|
evas_object_smart_callback_add(ec->frame, "unmaximize_pre",
|
|
|
|
_e_comp_wl_evas_cb_maximize_pre, ec);
|
2015-02-26 19:32:14 -08:00
|
|
|
evas_object_smart_callback_add(ec->frame, "fullscreen",
|
|
|
|
_e_comp_wl_evas_cb_state_update, ec);
|
|
|
|
evas_object_smart_callback_add(ec->frame, "unfullscreen",
|
|
|
|
_e_comp_wl_evas_cb_state_update, ec);
|
2014-10-31 09:33:09 -07:00
|
|
|
}
|
|
|
|
|
2014-10-17 01:39:58 -07:00
|
|
|
/* setup delete/kill callbacks */
|
2015-02-24 14:34:20 -08:00
|
|
|
evas_object_smart_callback_add(ec->frame, "delete_request",
|
2014-10-17 01:39:58 -07:00
|
|
|
_e_comp_wl_evas_cb_delete_request, ec);
|
2015-02-24 14:34:20 -08:00
|
|
|
evas_object_smart_callback_add(ec->frame, "kill_request",
|
2014-10-17 01:41:32 -07:00
|
|
|
_e_comp_wl_evas_cb_kill_request, ec);
|
2014-10-17 01:39:58 -07:00
|
|
|
|
2014-10-17 01:43:11 -07:00
|
|
|
/* setup ping callback */
|
2015-02-24 14:34:20 -08:00
|
|
|
evas_object_smart_callback_add(ec->frame, "ping",
|
2014-10-17 01:43:11 -07:00
|
|
|
_e_comp_wl_evas_cb_ping, ec);
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
evas_object_smart_callback_add(ec->frame, "color_set",
|
2014-10-17 01:44:40 -07:00
|
|
|
_e_comp_wl_evas_cb_color_set, ec);
|
|
|
|
|
2014-10-16 09:18:50 -07:00
|
|
|
ec->comp_data->evas_init = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static Eina_Bool
|
2015-02-24 10:25:22 -08:00
|
|
|
_e_comp_wl_cb_randr_change(void *data EINA_UNUSED, int type EINA_UNUSED, void *event EINA_UNUSED)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
E_Randr2_Screen *screen;
|
|
|
|
unsigned int transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
|
|
|
2015-04-22 07:29:42 -07:00
|
|
|
if (!e_randr2) return ECORE_CALLBACK_RENEW;
|
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
EINA_LIST_FOREACH(e_randr2->screens, l, screen)
|
|
|
|
{
|
2015-05-13 11:44:51 -07:00
|
|
|
if (!screen->config.enabled)
|
|
|
|
{
|
|
|
|
e_comp_wl_output_remove(screen->id);
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
switch (screen->config.rotation)
|
|
|
|
{
|
|
|
|
case 90:
|
|
|
|
transform = WL_OUTPUT_TRANSFORM_90;
|
|
|
|
break;
|
|
|
|
case 180:
|
|
|
|
transform = WL_OUTPUT_TRANSFORM_180;
|
|
|
|
break;
|
|
|
|
case 270:
|
|
|
|
transform = WL_OUTPUT_TRANSFORM_270;
|
|
|
|
break;
|
|
|
|
case 0:
|
|
|
|
default:
|
|
|
|
transform = WL_OUTPUT_TRANSFORM_NORMAL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-05-13 09:05:17 -07:00
|
|
|
if (!e_comp_wl_output_init(screen->id, screen->info.name,
|
|
|
|
screen->info.screen,
|
2015-03-13 17:06:01 -07:00
|
|
|
screen->config.geom.x, screen->config.geom.y,
|
|
|
|
screen->config.geom.w, screen->config.geom.h,
|
|
|
|
screen->info.size.w, screen->info.size.h,
|
|
|
|
screen->config.mode.refresh, 0, transform))
|
2015-04-06 11:29:47 -07:00
|
|
|
ERR("Could not initialize screen %s", screen->info.name);
|
2015-02-24 10:25:22 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static Eina_Bool
|
2014-10-16 09:18:50 -07:00
|
|
|
_e_comp_wl_cb_comp_object_add(void *data EINA_UNUSED, int type EINA_UNUSED, E_Event_Comp_Object *ev)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
/* try to get the client from the object */
|
2015-02-24 14:34:20 -08:00
|
|
|
if (!(ec = e_comp_object_client_get(ev->comp_object)))
|
2014-10-16 09:18:50 -07:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
|
|
|
|
/* check for client being deleted */
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return ECORE_CALLBACK_RENEW;
|
|
|
|
|
|
|
|
/* check for wayland pixmap */
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return ECORE_CALLBACK_RENEW;
|
2014-10-16 09:18:50 -07:00
|
|
|
|
|
|
|
/* if we have not setup evas callbacks for this client, do it */
|
|
|
|
if (!ec->comp_data->evas_init) _e_comp_wl_client_evas_init(ec);
|
|
|
|
|
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static Eina_Bool
|
2015-07-21 11:27:29 -07:00
|
|
|
_e_comp_wl_cb_mouse_move(void *d EINA_UNUSED, int t EINA_UNUSED, Ecore_Event_Mouse_Move *ev)
|
2015-01-26 11:50:58 -08:00
|
|
|
{
|
|
|
|
_last_event_time = ecore_loop_time_get();
|
2015-02-03 12:34:09 -08:00
|
|
|
|
2015-07-21 11:27:29 -07:00
|
|
|
e_comp->wl_comp_data->ptr.x = wl_fixed_from_int(ev->x);
|
|
|
|
e_comp->wl_comp_data->ptr.y = wl_fixed_from_int(ev->y);
|
2015-07-30 13:35:51 -07:00
|
|
|
e_screensaver_notidle();
|
2015-01-26 11:50:58 -08:00
|
|
|
return ECORE_CALLBACK_RENEW;
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_size_update(E_Client *ec, E_Comp_Wl_Surface_State *state)
|
2014-10-14 14:44:56 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
int w = 0, h = 0;
|
2015-02-25 11:17:14 -08:00
|
|
|
/* double scale = 0.0; */
|
2014-10-14 23:47:56 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!ec->comp_data->buffer_ref.buffer)
|
|
|
|
{
|
|
|
|
state->bw = 0;
|
|
|
|
state->bh = 0;
|
|
|
|
return;
|
|
|
|
}
|
2014-10-15 03:53:45 -07:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
/* scale = e_comp->wl_comp_data->output.scale; */
|
|
|
|
/* switch (e_comp->wl_comp_data->output.transform) */
|
|
|
|
/* { */
|
|
|
|
/* case WL_OUTPUT_TRANSFORM_90: */
|
|
|
|
/* case WL_OUTPUT_TRANSFORM_270: */
|
|
|
|
/* case WL_OUTPUT_TRANSFORM_FLIPPED_90: */
|
|
|
|
/* case WL_OUTPUT_TRANSFORM_FLIPPED_270: */
|
|
|
|
/* w = ec->comp_data->buffer_ref.buffer->h / scale; */
|
|
|
|
/* h = ec->comp_data->buffer_ref.buffer->w / scale; */
|
|
|
|
/* break; */
|
|
|
|
/* default: */
|
|
|
|
/* w = ec->comp_data->buffer_ref.buffer->w / scale; */
|
|
|
|
/* h = ec->comp_data->buffer_ref.buffer->h / scale; */
|
|
|
|
/* break; */
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
w = ec->comp_data->buffer_ref.buffer->w;
|
|
|
|
h = ec->comp_data->buffer_ref.buffer->h;
|
2014-10-14 23:47:56 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
state->bw = w;
|
|
|
|
state->bh = h;
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_cb_buffer_destroy(struct wl_listener *listener, void *data EINA_UNUSED)
|
2014-10-14 14:44:56 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
E_Comp_Wl_Surface_State *state;
|
2014-10-15 03:54:45 -07:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
state =
|
2015-02-25 10:14:30 -08:00
|
|
|
container_of(listener, E_Comp_Wl_Surface_State, buffer_destroy_listener);
|
|
|
|
state->buffer = NULL;
|
|
|
|
}
|
2014-10-15 03:54:45 -07:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_init(E_Comp_Wl_Surface_State *state, int w, int h)
|
|
|
|
{
|
|
|
|
state->new_attach = EINA_FALSE;
|
|
|
|
state->buffer = NULL;
|
2015-02-26 13:42:27 -08:00
|
|
|
state->buffer_destroy_listener.notify =
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_cb_buffer_destroy;
|
|
|
|
state->sx = state->sy = 0;
|
|
|
|
|
|
|
|
state->input = eina_tiler_new(w, h);
|
|
|
|
eina_tiler_tile_size_set(state->input, 1, 1);
|
|
|
|
|
|
|
|
state->opaque = eina_tiler_new(w, h);
|
|
|
|
eina_tiler_tile_size_set(state->opaque, 1, 1);
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_finish(E_Comp_Wl_Surface_State *state)
|
|
|
|
{
|
|
|
|
struct wl_resource *cb;
|
|
|
|
Eina_Rectangle *dmg;
|
|
|
|
|
|
|
|
EINA_LIST_FREE(state->frames, cb)
|
|
|
|
wl_resource_destroy(cb);
|
|
|
|
|
|
|
|
EINA_LIST_FREE(state->damages, dmg)
|
|
|
|
eina_rectangle_free(dmg);
|
|
|
|
|
|
|
|
if (state->opaque) eina_tiler_free(state->opaque);
|
|
|
|
state->opaque = NULL;
|
|
|
|
|
|
|
|
if (state->input) eina_tiler_free(state->input);
|
|
|
|
state->input = NULL;
|
|
|
|
|
|
|
|
if (state->buffer) wl_list_remove(&state->buffer_destroy_listener.link);
|
|
|
|
state->buffer = NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_buffer_set(E_Comp_Wl_Surface_State *state, E_Comp_Wl_Buffer *buffer)
|
|
|
|
{
|
|
|
|
if (state->buffer == buffer) return;
|
2015-02-26 13:42:27 -08:00
|
|
|
if (state->buffer)
|
2015-02-25 10:14:30 -08:00
|
|
|
wl_list_remove(&state->buffer_destroy_listener.link);
|
|
|
|
state->buffer = buffer;
|
2015-02-26 13:42:27 -08:00
|
|
|
if (state->buffer)
|
|
|
|
wl_signal_add(&state->buffer->destroy_signal,
|
2015-02-25 10:14:30 -08:00
|
|
|
&state->buffer_destroy_listener);
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state)
|
|
|
|
{
|
|
|
|
Eina_Bool first = EINA_FALSE;
|
|
|
|
Eina_Rectangle *dmg;
|
2015-06-30 15:34:16 -07:00
|
|
|
Eina_Bool ignored, placed = EINA_TRUE;
|
2015-02-28 12:46:16 -08:00
|
|
|
int x = 0, y = 0;
|
2015-02-25 10:14:30 -08:00
|
|
|
|
|
|
|
first = !e_pixmap_usable_get(ec->pixmap);
|
2015-06-30 15:34:16 -07:00
|
|
|
ignored = ec->ignored;
|
2015-02-25 10:14:30 -08:00
|
|
|
|
|
|
|
if (state->new_attach)
|
|
|
|
e_comp_wl_surface_attach(ec, state->buffer);
|
|
|
|
|
|
|
|
_e_comp_wl_surface_state_buffer_set(state, NULL);
|
|
|
|
|
2015-02-28 12:46:16 -08:00
|
|
|
if (state->new_attach)
|
|
|
|
{
|
|
|
|
_e_comp_wl_surface_state_size_update(ec, &ec->comp_data->pending);
|
|
|
|
|
|
|
|
if (ec->changes.pos)
|
2015-04-21 13:19:30 -07:00
|
|
|
e_comp_object_frame_xy_unadjust(ec->frame, ec->x, ec->y, &x, &y);
|
2015-02-28 12:46:16 -08:00
|
|
|
else
|
|
|
|
x = ec->client.x, y = ec->client.y;
|
|
|
|
|
|
|
|
if (ec->new_client) placed = ec->placed;
|
|
|
|
|
2015-07-08 11:46:12 -07:00
|
|
|
ec->client.w = state->bw;
|
|
|
|
ec->client.h = state->bh;
|
|
|
|
e_comp_object_frame_wh_adjust(ec->frame, ec->client.w, ec->client.h, &ec->w, &ec->h);
|
2015-02-28 12:46:16 -08:00
|
|
|
}
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!e_pixmap_usable_get(ec->pixmap))
|
2014-10-15 03:54:45 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if (ec->comp_data->mapped)
|
|
|
|
{
|
|
|
|
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
|
|
|
|
ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
|
|
|
|
else
|
|
|
|
{
|
2015-06-25 16:22:49 -07:00
|
|
|
ec->visible = EINA_FALSE;
|
2015-02-25 10:14:30 -08:00
|
|
|
evas_object_hide(ec->frame);
|
2015-07-22 14:09:14 -07:00
|
|
|
ec->comp_data->mapped = 0;
|
2015-02-25 10:14:30 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!ec->comp_data->mapped)
|
|
|
|
{
|
|
|
|
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map))
|
|
|
|
ec->comp_data->shell.map(ec->comp_data->shell.surface);
|
|
|
|
else
|
|
|
|
{
|
2015-06-25 16:22:49 -07:00
|
|
|
ec->visible = EINA_TRUE;
|
2015-06-30 15:34:16 -07:00
|
|
|
ec->ignored = 0;
|
2015-02-25 10:14:30 -08:00
|
|
|
evas_object_show(ec->frame);
|
2015-07-22 14:09:14 -07:00
|
|
|
ec->comp_data->mapped = 1;
|
2015-02-25 10:14:30 -08:00
|
|
|
}
|
|
|
|
}
|
2014-10-15 03:54:45 -07:00
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
if (state->new_attach)
|
2014-10-15 03:54:45 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.configure))
|
2015-02-26 13:42:27 -08:00
|
|
|
ec->comp_data->shell.configure(ec->comp_data->shell.surface,
|
2015-02-25 10:14:30 -08:00
|
|
|
x, y, state->bw, state->bh);
|
|
|
|
else
|
2015-07-15 10:55:35 -07:00
|
|
|
{
|
|
|
|
if (ec->netwm.sync.wait)
|
|
|
|
{
|
|
|
|
E_Client_Pending_Resize *pnd = NULL;
|
|
|
|
|
|
|
|
ec->netwm.sync.wait--;
|
|
|
|
|
|
|
|
/* skip pending for which we didn't get a reply */
|
|
|
|
while (ec->pending_resize)
|
|
|
|
{
|
|
|
|
pnd = eina_list_data_get(ec->pending_resize);
|
|
|
|
ec->pending_resize = eina_list_remove(ec->pending_resize, pnd);
|
|
|
|
|
|
|
|
if ((state->bw == pnd->w) && (state->bh == pnd->h))
|
|
|
|
break;
|
|
|
|
|
|
|
|
E_FREE(pnd);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pnd)
|
|
|
|
{
|
|
|
|
e_comp_object_frame_wh_adjust(ec->frame, pnd->w, pnd->h, &ec->w, &ec->h);
|
|
|
|
E_FREE(pnd);
|
|
|
|
}
|
|
|
|
ecore_evas_pointer_xy_get(e_comp->ee, &ec->mouse.current.mx, &ec->mouse.current.my);
|
|
|
|
ec->netwm.sync.send_time = ecore_loop_time_get();
|
|
|
|
}
|
|
|
|
e_client_util_move_resize_without_frame(ec, x, y, state->bw, state->bh);
|
|
|
|
}
|
2015-02-25 10:14:30 -08:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
if (ec->new_client)
|
2015-02-25 10:14:30 -08:00
|
|
|
ec->placed = placed;
|
2015-07-29 12:38:17 -07:00
|
|
|
else if ((first) && (ec->placed) && (!ec->internal) && (!ec->override))
|
2015-02-25 10:14:30 -08:00
|
|
|
{
|
|
|
|
ec->x = ec->y = 0;
|
|
|
|
ec->placed = EINA_FALSE;
|
|
|
|
ec->new_client = EINA_TRUE;
|
|
|
|
}
|
2014-10-15 03:54:45 -07:00
|
|
|
}
|
2015-02-25 10:14:30 -08:00
|
|
|
state->sx = 0;
|
|
|
|
state->sy = 0;
|
|
|
|
state->new_attach = EINA_FALSE;
|
|
|
|
|
2015-06-30 15:34:16 -07:00
|
|
|
ec->ignored = ignored;
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!ec->comp_data->mapped) goto unmapped;
|
|
|
|
|
2015-07-24 13:35:21 -07:00
|
|
|
if (ec->comp_data->shell.surface && ec->comp_data->shell.configure_send && (!ec->maximized) && (!ec->fullscreen))
|
|
|
|
{
|
|
|
|
ec->comp_data->shell.window_offsets.l = ec->comp_data->shell.window.x;
|
|
|
|
ec->comp_data->shell.window_offsets.r = ec->client.w - ec->comp_data->shell.window.w - ec->comp_data->shell.window.x;
|
|
|
|
ec->comp_data->shell.window_offsets.t = ec->comp_data->shell.window.y;
|
|
|
|
ec->comp_data->shell.window_offsets.b = ec->client.h - ec->comp_data->shell.window.h - ec->comp_data->shell.window.y;
|
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
/* put state damages into surface */
|
2015-03-13 12:41:21 -07:00
|
|
|
if ((!e_comp->nocomp) && (ec->frame))
|
2014-10-15 03:54:45 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
EINA_LIST_FREE(state->damages, dmg)
|
|
|
|
{
|
|
|
|
e_comp_object_damage(ec->frame, dmg->x, dmg->y, dmg->w, dmg->h);
|
|
|
|
eina_rectangle_free(dmg);
|
|
|
|
}
|
2014-10-15 03:54:45 -07:00
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
/* put state opaque into surface */
|
2015-07-17 12:58:14 -07:00
|
|
|
e_pixmap_image_opaque_set(ec->pixmap, 0, 0, 0, 0);
|
2015-02-25 10:14:30 -08:00
|
|
|
if (state->opaque)
|
|
|
|
{
|
|
|
|
Eina_Rectangle *rect;
|
|
|
|
Eina_Iterator *itr;
|
2014-11-10 08:58:20 -08:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
itr = eina_tiler_iterator_new(state->opaque);
|
|
|
|
EINA_ITERATOR_FOREACH(itr, rect)
|
|
|
|
{
|
2015-07-20 11:38:31 -07:00
|
|
|
Eina_Rectangle r;
|
|
|
|
|
|
|
|
EINA_RECTANGLE_SET(&r, rect->x, rect->y, rect->w, rect->h);
|
|
|
|
E_RECTS_CLIP_TO_RECT(r.x, r.y, r.w, r.h, 0, 0, state->bw, state->bh);
|
|
|
|
e_pixmap_image_opaque_set(ec->pixmap, r.x, r.y, r.w, r.h);
|
2015-02-25 10:14:30 -08:00
|
|
|
break;
|
|
|
|
}
|
2014-10-15 03:54:45 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
eina_iterator_free(itr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* put state input into surface */
|
|
|
|
if (state->input)
|
2014-10-15 03:54:45 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
Eina_Tiler *src, *tmp;
|
2015-02-24 14:34:20 -08:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
tmp = eina_tiler_new(state->bw, state->bh);
|
|
|
|
eina_tiler_tile_size_set(tmp, 1, 1);
|
2015-02-26 13:42:27 -08:00
|
|
|
eina_tiler_rect_add(tmp,
|
2015-02-25 10:14:30 -08:00
|
|
|
&(Eina_Rectangle){0, 0, state->bw, state->bh});
|
|
|
|
if ((src = eina_tiler_intersection(state->input, tmp)))
|
2014-10-15 03:54:45 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
Eina_Rectangle *rect;
|
|
|
|
Eina_Iterator *itr;
|
|
|
|
|
|
|
|
itr = eina_tiler_iterator_new(src);
|
|
|
|
EINA_ITERATOR_FOREACH(itr, rect)
|
2015-02-26 13:42:27 -08:00
|
|
|
e_comp_object_input_area_set(ec->frame, rect->x, rect->y,
|
2015-02-25 10:14:30 -08:00
|
|
|
rect->w, rect->h);
|
|
|
|
|
|
|
|
eina_iterator_free(itr);
|
|
|
|
eina_tiler_free(src);
|
2014-10-15 03:54:45 -07:00
|
|
|
}
|
2015-02-25 10:14:30 -08:00
|
|
|
else
|
|
|
|
e_comp_object_input_area_set(ec->frame, 0, 0, ec->w, ec->h);
|
|
|
|
|
|
|
|
eina_tiler_free(tmp);
|
2014-10-15 03:54:45 -07:00
|
|
|
}
|
2015-02-25 10:14:30 -08:00
|
|
|
|
|
|
|
/* insert state frame callbacks into comp_data->frames
|
|
|
|
* NB: This clears state->frames list */
|
2015-03-10 13:11:57 -07:00
|
|
|
ec->comp_data->frames = eina_list_merge(ec->comp_data->frames, state->frames);
|
|
|
|
state->frames = NULL;
|
2015-02-25 10:14:30 -08:00
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
unmapped:
|
|
|
|
/* clear pending damages */
|
|
|
|
EINA_LIST_FREE(state->damages, dmg)
|
|
|
|
eina_rectangle_free(dmg);
|
|
|
|
|
|
|
|
/* clear input tiler */
|
|
|
|
if (state->input)
|
|
|
|
eina_tiler_clear(state->input);
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
DBG("Surface Cb Destroy: %d", wl_resource_get_id(resource));
|
2015-03-05 08:41:43 -08:00
|
|
|
wl_resource_destroy(resource);
|
2015-02-25 10:14:30 -08:00
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_cb_attach(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *buffer_resource, int32_t sx, int32_t sy)
|
2014-10-14 14:44:56 -07:00
|
|
|
{
|
2014-10-16 08:22:58 -07:00
|
|
|
E_Client *ec;
|
2015-02-25 10:14:30 -08:00
|
|
|
E_Comp_Wl_Buffer *buffer = NULL;
|
2014-10-16 08:22:58 -07:00
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2015-02-25 10:14:30 -08:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
2014-10-16 08:22:58 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
if (buffer_resource)
|
2014-10-16 08:22:58 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!(buffer = e_comp_wl_buffer_get(buffer_resource)))
|
|
|
|
{
|
|
|
|
ERR("Could not get buffer from resource");
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
2014-10-16 08:22:58 -07:00
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_buffer_set(&ec->comp_data->pending, buffer);
|
2014-10-16 08:22:58 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
ec->comp_data->pending.sx = sx;
|
|
|
|
ec->comp_data->pending.sy = sy;
|
|
|
|
ec->comp_data->pending.new_attach = EINA_TRUE;
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_cb_damage(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
Eina_Rectangle *dmg = NULL;
|
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2015-02-25 10:14:30 -08:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
2014-11-10 08:58:20 -08:00
|
|
|
|
2014-10-20 14:04:48 -07:00
|
|
|
if (!(dmg = eina_rectangle_new(x, y, w, h))) return;
|
2014-10-16 08:22:58 -07:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
ec->comp_data->pending.damages =
|
2014-10-16 08:22:58 -07:00
|
|
|
eina_list_append(ec->comp_data->pending.damages, dmg);
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-22 09:16:31 -07:00
|
|
|
_e_comp_wl_frame_cb_destroy(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
ec->comp_data->frames =
|
2015-02-25 10:14:30 -08:00
|
|
|
eina_list_remove(ec->comp_data->frames, resource);
|
2014-10-22 09:16:31 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 14:44:56 -07:00
|
|
|
_e_comp_wl_surface_cb_frame(struct wl_client *client, struct wl_resource *resource, uint32_t callback)
|
|
|
|
{
|
2014-10-22 09:16:31 -07:00
|
|
|
E_Client *ec;
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-10-22 09:16:31 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
|
|
|
/* create frame callback */
|
2015-02-24 14:34:20 -08:00
|
|
|
if (!(res =
|
2014-10-22 09:16:31 -07:00
|
|
|
wl_resource_create(client, &wl_callback_interface, 1, callback)))
|
|
|
|
{
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_resource_set_implementation(res, NULL, ec, _e_comp_wl_frame_cb_destroy);
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
ec->comp_data->pending.frames =
|
2015-02-25 10:14:30 -08:00
|
|
|
eina_list_prepend(ec->comp_data->pending.frames, res);
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 14:44:56 -07:00
|
|
|
_e_comp_wl_surface_cb_opaque_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource)
|
|
|
|
{
|
2014-10-16 08:23:41 -07:00
|
|
|
E_Client *ec;
|
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-10-16 08:23:41 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2015-07-20 11:10:55 -07:00
|
|
|
if (ec->comp_data->pending.opaque)
|
|
|
|
eina_tiler_clear(ec->comp_data->pending.opaque);
|
2014-10-16 08:23:41 -07:00
|
|
|
if (region_resource)
|
|
|
|
{
|
|
|
|
Eina_Tiler *tmp;
|
|
|
|
|
|
|
|
if (!(tmp = wl_resource_get_user_data(region_resource)))
|
|
|
|
return;
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
eina_tiler_union(ec->comp_data->pending.opaque, tmp);
|
|
|
|
}
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 14:44:56 -07:00
|
|
|
_e_comp_wl_surface_cb_input_region_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *region_resource)
|
|
|
|
{
|
2014-10-16 08:24:03 -07:00
|
|
|
E_Client *ec;
|
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-10-16 08:24:03 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2015-07-20 11:10:55 -07:00
|
|
|
if (ec->comp_data->pending.input)
|
|
|
|
eina_tiler_clear(ec->comp_data->pending.input);
|
2014-10-16 08:24:03 -07:00
|
|
|
if (region_resource)
|
|
|
|
{
|
|
|
|
Eina_Tiler *tmp;
|
|
|
|
|
|
|
|
if (!(tmp = wl_resource_get_user_data(region_resource)))
|
|
|
|
return;
|
|
|
|
|
|
|
|
eina_tiler_union(ec->comp_data->pending.input, tmp);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-02-24 14:34:20 -08:00
|
|
|
eina_tiler_rect_add(ec->comp_data->pending.input,
|
2014-10-16 08:24:03 -07:00
|
|
|
&(Eina_Rectangle){0, 0, ec->client.w, ec->client.h});
|
|
|
|
}
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 14:44:56 -07:00
|
|
|
_e_comp_wl_surface_cb_commit(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Client *ec, *subc;
|
|
|
|
Eina_List *l;
|
2014-10-15 07:44:10 -07:00
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-10-15 07:44:10 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (e_comp_wl_subsurface_commit(ec)) return;
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
e_comp_wl_surface_commit(ec);
|
2014-11-10 08:58:20 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
|
|
|
{
|
|
|
|
if (ec != subc)
|
|
|
|
_e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
|
|
|
|
}
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 14:44:56 -07:00
|
|
|
_e_comp_wl_surface_cb_buffer_transform_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t transform EINA_UNUSED)
|
|
|
|
{
|
2014-10-15 07:44:10 -07:00
|
|
|
DBG("Surface Buffer Transform: %d", wl_resource_get_id(resource));
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 14:44:56 -07:00
|
|
|
_e_comp_wl_surface_cb_buffer_scale_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource EINA_UNUSED, int32_t scale EINA_UNUSED)
|
|
|
|
{
|
2014-10-15 07:44:10 -07:00
|
|
|
DBG("Surface Buffer Scale: %d", wl_resource_get_id(resource));
|
2014-10-14 14:44:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static const struct wl_surface_interface _e_surface_interface =
|
2014-10-14 14:44:56 -07:00
|
|
|
{
|
|
|
|
_e_comp_wl_surface_cb_destroy,
|
|
|
|
_e_comp_wl_surface_cb_attach,
|
|
|
|
_e_comp_wl_surface_cb_damage,
|
|
|
|
_e_comp_wl_surface_cb_frame,
|
|
|
|
_e_comp_wl_surface_cb_opaque_region_set,
|
|
|
|
_e_comp_wl_surface_cb_input_region_set,
|
|
|
|
_e_comp_wl_surface_cb_commit,
|
|
|
|
_e_comp_wl_surface_cb_buffer_transform_set,
|
|
|
|
_e_comp_wl_surface_cb_buffer_scale_set
|
|
|
|
};
|
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_surface_render_stop(E_Client *ec)
|
|
|
|
{
|
|
|
|
/* FIXME: this may be fine after e_pixmap can create textures for wl clients? */
|
|
|
|
//if ((!ec->internal) && (!e_comp_gl_get()))
|
|
|
|
ec->dead = ec->hidden = 1;
|
|
|
|
evas_object_hide(ec->frame);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-11-03 12:10:38 -08:00
|
|
|
_e_comp_wl_surface_destroy(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-11-03 12:10:38 -08:00
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
_e_comp_wl_surface_render_stop(ec);
|
2014-11-03 12:10:38 -08:00
|
|
|
e_object_del(E_OBJECT(ec));
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 12:17:56 -07:00
|
|
|
_e_comp_wl_compositor_cb_surface_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
|
|
|
{
|
2014-10-14 14:44:56 -07:00
|
|
|
struct wl_resource *res;
|
2015-06-25 16:55:37 -07:00
|
|
|
E_Client *wc, *ec = NULL;
|
|
|
|
Eina_List *l;
|
2015-01-28 14:31:40 -08:00
|
|
|
pid_t pid;
|
2014-10-14 12:17:56 -07:00
|
|
|
|
2014-10-14 14:44:56 -07:00
|
|
|
DBG("Compositor Cb Surface Create: %d", id);
|
|
|
|
|
|
|
|
/* try to create an internal surface */
|
2015-02-24 14:34:20 -08:00
|
|
|
if (!(res = wl_resource_create(client, &wl_surface_interface,
|
2014-10-14 14:44:56 -07:00
|
|
|
wl_resource_get_version(resource), id)))
|
|
|
|
{
|
|
|
|
ERR("Could not create compositor surface");
|
2014-10-15 03:53:45 -07:00
|
|
|
wl_client_post_no_memory(client);
|
2014-10-14 14:44:56 -07:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-10-14 23:47:56 -07:00
|
|
|
DBG("\tCreated Resource: %d", wl_resource_get_id(res));
|
|
|
|
|
2014-10-14 14:44:56 -07:00
|
|
|
/* set implementation on resource */
|
2015-02-24 14:34:20 -08:00
|
|
|
wl_resource_set_implementation(res, &_e_surface_interface, NULL,
|
2014-11-03 12:10:38 -08:00
|
|
|
_e_comp_wl_surface_destroy);
|
2014-10-14 14:44:56 -07:00
|
|
|
|
2015-01-28 14:31:40 -08:00
|
|
|
wl_client_get_credentials(client, &pid, NULL, NULL);
|
2015-04-21 12:19:20 -07:00
|
|
|
if (pid == getpid()) //internal!
|
|
|
|
ec = e_pixmap_find_client(E_PIXMAP_TYPE_WL, (uintptr_t)id);
|
|
|
|
if (!ec)
|
2015-01-28 14:29:17 -08:00
|
|
|
{
|
2015-04-21 12:19:20 -07:00
|
|
|
E_Pixmap *ep;
|
2015-01-28 14:29:17 -08:00
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
/* try to create new pixmap */
|
2015-04-21 12:41:10 -07:00
|
|
|
if (!(ep = e_pixmap_new(E_PIXMAP_TYPE_WL, res)))
|
2015-04-21 12:19:20 -07:00
|
|
|
{
|
|
|
|
ERR("Could not create new pixmap");
|
|
|
|
wl_resource_destroy(res);
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
DBG("\tUsing Pixmap: %p", ep);
|
|
|
|
|
2015-07-02 11:26:02 -07:00
|
|
|
ec = e_client_new(ep, 0, 0);
|
|
|
|
}
|
|
|
|
if (ec)
|
|
|
|
{
|
|
|
|
if (ec->new_client)
|
|
|
|
e_comp->new_clients--;
|
|
|
|
ec->new_client = 0;
|
|
|
|
if ((!ec->client.w) && (ec->client.h))
|
|
|
|
ec->client.w = ec->client.h = 1;
|
|
|
|
ec->comp_data->surface = res;
|
2015-04-21 06:36:00 -07:00
|
|
|
}
|
2015-03-30 09:13:04 -07:00
|
|
|
|
2015-01-28 14:29:17 -08:00
|
|
|
/* set reference to pixmap so we can fetch it later */
|
2015-04-21 12:19:20 -07:00
|
|
|
wl_resource_set_user_data(res, ec);
|
2015-06-25 16:55:37 -07:00
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
|
|
|
EINA_LIST_FOREACH(e_comp->wl_comp_data->xwl_pending, l, wc)
|
|
|
|
{
|
|
|
|
if (!e_pixmap_is_x(wc->pixmap)) continue;
|
2015-06-30 15:33:38 -07:00
|
|
|
if (wl_resource_get_id(res) != ((E_Comp_X_Client_Data*)wc->comp_data)->surface_id) continue;
|
2015-06-25 16:55:37 -07:00
|
|
|
e_comp_x_xwayland_client_setup(wc, ec);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
#endif
|
2014-10-14 14:44:56 -07:00
|
|
|
/* emit surface create signal */
|
2015-03-18 14:30:49 -07:00
|
|
|
wl_signal_emit(&e_comp->wl_comp_data->signals.surface.create, res);
|
2014-10-14 12:17:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 08:21:33 -07:00
|
|
|
_e_comp_wl_region_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
DBG("Region Destroy: %d", wl_resource_get_id(resource));
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 08:21:33 -07:00
|
|
|
_e_comp_wl_region_cb_add(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
|
|
|
|
{
|
|
|
|
Eina_Tiler *tiler;
|
|
|
|
|
|
|
|
DBG("Region Add: %d", wl_resource_get_id(resource));
|
|
|
|
DBG("\tGeom: %d %d %d %d", x, y, w, h);
|
|
|
|
|
|
|
|
/* get the tiler from the resource */
|
|
|
|
if ((tiler = wl_resource_get_user_data(resource)))
|
2015-07-20 11:10:55 -07:00
|
|
|
eina_tiler_rect_add(tiler, &(Eina_Rectangle){x, y, w, h});
|
2014-10-16 08:21:33 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 08:21:33 -07:00
|
|
|
_e_comp_wl_region_cb_subtract(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y, int32_t w, int32_t h)
|
|
|
|
{
|
|
|
|
Eina_Tiler *tiler;
|
|
|
|
|
|
|
|
DBG("Region Subtract: %d", wl_resource_get_id(resource));
|
|
|
|
DBG("\tGeom: %d %d %d %d", x, y, w, h);
|
|
|
|
|
|
|
|
/* get the tiler from the resource */
|
|
|
|
if ((tiler = wl_resource_get_user_data(resource)))
|
2015-07-20 11:10:55 -07:00
|
|
|
eina_tiler_rect_del(tiler, &(Eina_Rectangle){x, y, w, h});
|
2014-10-16 08:21:33 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static const struct wl_region_interface _e_region_interface =
|
2014-10-16 08:21:33 -07:00
|
|
|
{
|
2015-02-24 14:34:20 -08:00
|
|
|
_e_comp_wl_region_cb_destroy,
|
|
|
|
_e_comp_wl_region_cb_add,
|
2014-10-16 08:21:33 -07:00
|
|
|
_e_comp_wl_region_cb_subtract
|
|
|
|
};
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-16 08:21:33 -07:00
|
|
|
_e_comp_wl_compositor_cb_region_destroy(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
Eina_Tiler *tiler;
|
|
|
|
|
|
|
|
DBG("Compositor Region Destroy: %d", wl_resource_get_id(resource));
|
|
|
|
|
2014-10-16 08:32:13 -07:00
|
|
|
/* try to get the tiler from the region resource */
|
2014-10-16 08:21:33 -07:00
|
|
|
if ((tiler = wl_resource_get_user_data(resource)))
|
|
|
|
eina_tiler_free(tiler);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-14 12:17:56 -07:00
|
|
|
_e_comp_wl_compositor_cb_region_create(struct wl_client *client, struct wl_resource *resource, uint32_t id)
|
|
|
|
{
|
2014-10-16 08:21:33 -07:00
|
|
|
Eina_Tiler *tiler;
|
|
|
|
struct wl_resource *res;
|
2014-10-14 12:17:56 -07:00
|
|
|
|
2014-10-16 08:21:33 -07:00
|
|
|
DBG("Region Create: %d", wl_resource_get_id(resource));
|
|
|
|
|
|
|
|
/* try to create new tiler */
|
2015-03-19 13:03:51 -07:00
|
|
|
if (!(tiler = eina_tiler_new(e_comp->w, e_comp->h)))
|
2014-10-16 08:21:33 -07:00
|
|
|
{
|
|
|
|
ERR("Could not create Eina_Tiler");
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set tiler size */
|
|
|
|
eina_tiler_tile_size_set(tiler, 1, 1);
|
|
|
|
|
|
|
|
if (!(res = wl_resource_create(client, &wl_region_interface, 1, id)))
|
|
|
|
{
|
|
|
|
ERR("\tFailed to create region resource");
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
wl_resource_set_implementation(res, &_e_region_interface, tiler,
|
2014-10-16 08:21:33 -07:00
|
|
|
_e_comp_wl_compositor_cb_region_destroy);
|
2014-10-14 12:17:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static const struct wl_compositor_interface _e_comp_interface =
|
2014-10-14 12:17:56 -07:00
|
|
|
{
|
|
|
|
_e_comp_wl_compositor_cb_surface_create,
|
|
|
|
_e_comp_wl_compositor_cb_region_create
|
|
|
|
};
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2015-03-18 14:30:49 -07:00
|
|
|
_e_comp_wl_compositor_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
|
2014-10-14 11:20:33 -07:00
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
if (!(res =
|
|
|
|
wl_resource_create(client, &wl_compositor_interface,
|
2014-10-14 11:20:33 -07:00
|
|
|
MIN(version, COMPOSITOR_VERSION), id)))
|
|
|
|
{
|
|
|
|
ERR("Could not create compositor resource: %m");
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
2014-10-14 12:17:56 -07:00
|
|
|
|
2015-03-18 14:30:49 -07:00
|
|
|
wl_resource_set_implementation(res, &_e_comp_interface, e_comp, NULL);
|
2014-10-14 11:20:33 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2015-05-18 06:08:52 -07:00
|
|
|
_e_comp_wl_compositor_cb_del(void *data EINA_UNUSED)
|
2014-10-14 11:03:15 -07:00
|
|
|
{
|
2015-06-25 16:16:27 -07:00
|
|
|
E_Comp_Wl_Data *cdata;
|
2015-02-24 10:25:22 -08:00
|
|
|
E_Comp_Wl_Output *output;
|
2014-10-14 11:03:15 -07:00
|
|
|
|
2015-05-18 06:08:52 -07:00
|
|
|
cdata = e_comp->wl_comp_data;
|
2014-10-14 11:03:15 -07:00
|
|
|
|
2015-07-08 12:04:49 -07:00
|
|
|
if (cdata->screenshooter.global)
|
|
|
|
wl_global_destroy(cdata->screenshooter.global);
|
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
EINA_LIST_FREE(cdata->outputs, output)
|
|
|
|
{
|
|
|
|
if (output->id) eina_stringshare_del(output->id);
|
|
|
|
if (output->make) eina_stringshare_del(output->make);
|
|
|
|
if (output->model) eina_stringshare_del(output->model);
|
|
|
|
free(output);
|
|
|
|
}
|
|
|
|
|
2014-10-14 14:46:07 -07:00
|
|
|
/* delete fd handler */
|
|
|
|
if (cdata->fd_hdlr) ecore_main_fd_handler_del(cdata->fd_hdlr);
|
|
|
|
|
2014-10-14 11:03:15 -07:00
|
|
|
/* free allocated data structure */
|
|
|
|
free(cdata);
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2014-11-03 08:27:17 -08:00
|
|
|
_e_comp_wl_subsurface_destroy(struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
|
|
|
|
|
|
|
/* try to get the client from resource data */
|
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
|
|
|
|
2014-11-03 12:10:38 -08:00
|
|
|
if (!ec->comp_data) return;
|
|
|
|
|
2014-11-03 08:27:17 -08:00
|
|
|
if (!(sdata = ec->comp_data->sub.data)) return;
|
|
|
|
|
|
|
|
if (sdata->parent)
|
|
|
|
{
|
|
|
|
/* remove this client from parents sub list */
|
2015-02-24 14:34:20 -08:00
|
|
|
sdata->parent->comp_data->sub.list =
|
2014-11-03 08:27:17 -08:00
|
|
|
eina_list_remove(sdata->parent->comp_data->sub.list, ec);
|
|
|
|
}
|
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
_e_comp_wl_surface_state_finish(&sdata->cached);
|
|
|
|
e_comp_wl_buffer_reference(&sdata->cached_buffer_ref, NULL);
|
2014-11-03 08:27:17 -08:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
/* the client is getting deleted, which means the pixmap will be getting
|
2014-11-03 08:27:17 -08:00
|
|
|
* freed. We need to unset the surface user data */
|
|
|
|
/* wl_resource_set_user_data(ec->comp_data->surface, NULL); */
|
|
|
|
|
|
|
|
E_FREE(sdata);
|
|
|
|
|
|
|
|
ec->comp_data->sub.data = NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static Eina_Bool
|
2014-11-03 09:50:07 -08:00
|
|
|
_e_comp_wl_subsurface_synchronized_get(E_Comp_Wl_Subsurf_Data *sdata)
|
2014-11-03 09:26:40 -08:00
|
|
|
{
|
|
|
|
while (sdata)
|
|
|
|
{
|
|
|
|
if (sdata->synchronized) return EINA_TRUE;
|
|
|
|
if (!sdata->parent) return EINA_FALSE;
|
|
|
|
sdata = sdata->parent->comp_data->sub.data;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2014-11-03 09:26:40 -08:00
|
|
|
_e_comp_wl_subsurface_commit_to_cache(E_Client *ec)
|
|
|
|
{
|
2014-11-03 11:30:22 -08:00
|
|
|
E_Comp_Client_Data *cdata;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
2015-02-25 11:17:14 -08:00
|
|
|
struct wl_resource *cb;
|
2014-11-03 11:30:22 -08:00
|
|
|
Eina_List *l;
|
2015-02-25 11:17:14 -08:00
|
|
|
Eina_Iterator *itr;
|
|
|
|
Eina_Rectangle *rect;
|
2014-11-03 11:30:22 -08:00
|
|
|
|
|
|
|
if (!(cdata = ec->comp_data)) return;
|
|
|
|
if (!(sdata = cdata->sub.data)) return;
|
|
|
|
|
|
|
|
DBG("Subsurface Commit to Cache");
|
|
|
|
|
|
|
|
/* move pending damage to cached */
|
2015-02-25 11:17:14 -08:00
|
|
|
EINA_LIST_FOREACH(cdata->pending.damages, l, rect)
|
|
|
|
eina_list_move(&sdata->cached.damages, &cdata->pending.damages, rect);
|
2014-11-03 09:26:40 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (cdata->pending.new_attach)
|
|
|
|
{
|
|
|
|
sdata->cached.new_attach = EINA_TRUE;
|
2015-02-26 13:42:27 -08:00
|
|
|
_e_comp_wl_surface_state_buffer_set(&sdata->cached,
|
2015-02-25 11:17:14 -08:00
|
|
|
cdata->pending.buffer);
|
2015-02-26 13:42:27 -08:00
|
|
|
e_comp_wl_buffer_reference(&sdata->cached_buffer_ref,
|
2015-02-25 11:17:14 -08:00
|
|
|
cdata->pending.buffer);
|
|
|
|
}
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
sdata->cached.sx = cdata->pending.sx;
|
|
|
|
sdata->cached.sy = cdata->pending.sy;
|
|
|
|
/* sdata->cached.buffer = cdata->pending.buffer; */
|
2014-11-03 11:30:22 -08:00
|
|
|
sdata->cached.new_attach = cdata->pending.new_attach;
|
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
/* _e_comp_wl_surface_state_buffer_set(&cdata->pending, NULL); */
|
|
|
|
/* cdata->pending.sx = 0; */
|
|
|
|
/* cdata->pending.sy = 0; */
|
|
|
|
/* cdata->pending.new_attach = EINA_FALSE; */
|
|
|
|
|
|
|
|
/* copy cdata->pending.opaque into sdata->cached.opaque */
|
|
|
|
itr = eina_tiler_iterator_new(cdata->pending.opaque);
|
|
|
|
EINA_ITERATOR_FOREACH(itr, rect)
|
|
|
|
eina_tiler_rect_add(sdata->cached.opaque, rect);
|
|
|
|
eina_iterator_free(itr);
|
|
|
|
|
|
|
|
/* repeat for input */
|
|
|
|
itr = eina_tiler_iterator_new(cdata->pending.input);
|
|
|
|
EINA_ITERATOR_FOREACH(itr, rect)
|
|
|
|
eina_tiler_rect_add(sdata->cached.input, rect);
|
|
|
|
eina_iterator_free(itr);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(cdata->pending.frames, l, cb)
|
|
|
|
eina_list_move(&sdata->cached.frames, &cdata->pending.frames, cb);
|
2014-11-03 11:30:22 -08:00
|
|
|
|
|
|
|
sdata->cached.has_data = EINA_TRUE;
|
2014-11-03 09:26:40 -08:00
|
|
|
}
|
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2014-11-03 09:26:40 -08:00
|
|
|
_e_comp_wl_subsurface_commit_from_cache(E_Client *ec)
|
|
|
|
{
|
2014-11-03 11:30:22 -08:00
|
|
|
E_Comp_Client_Data *cdata;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
|
|
|
|
|
|
|
if (!(cdata = ec->comp_data)) return;
|
|
|
|
if (!(sdata = cdata->sub.data)) return;
|
|
|
|
|
|
|
|
DBG("Subsurface Commit from Cache");
|
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
_e_comp_wl_surface_state_commit(ec, &sdata->cached);
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
e_comp_wl_buffer_reference(&sdata->cached_buffer_ref, NULL);
|
2015-02-05 13:31:18 -08:00
|
|
|
|
2015-07-10 10:22:15 -07:00
|
|
|
e_pixmap_refresh(ec->pixmap);
|
2015-02-25 11:17:14 -08:00
|
|
|
}
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
static void
|
2015-02-25 11:17:14 -08:00
|
|
|
_e_comp_wl_subsurface_parent_commit(E_Client *ec, Eina_Bool parent_synchronized)
|
|
|
|
{
|
|
|
|
E_Client *parent;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
2015-02-11 14:02:01 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (!(sdata = ec->comp_data->sub.data)) return;
|
|
|
|
if (!(parent = sdata->parent)) return;
|
2015-02-11 14:02:01 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (sdata->position.set)
|
2014-11-03 11:30:22 -08:00
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
evas_object_move(ec->frame, parent->x + sdata->position.x,
|
|
|
|
parent->y + sdata->position.y);
|
|
|
|
sdata->position.set = EINA_FALSE;
|
2014-11-03 11:30:22 -08:00
|
|
|
}
|
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if ((parent_synchronized) || (sdata->synchronized))
|
2014-11-03 11:30:22 -08:00
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Client *subc;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (sdata->cached.has_data)
|
|
|
|
_e_comp_wl_subsurface_commit_from_cache(ec);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
2014-11-03 11:30:22 -08:00
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
if (ec != subc)
|
|
|
|
_e_comp_wl_subsurface_parent_commit(subc, EINA_TRUE);
|
2014-11-03 11:30:22 -08:00
|
|
|
}
|
|
|
|
}
|
2015-02-25 11:17:14 -08:00
|
|
|
}
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
static void
|
|
|
|
_e_comp_wl_subsurface_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
|
|
|
wl_resource_destroy(resource);
|
|
|
|
}
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
static void
|
|
|
|
_e_comp_wl_subsurface_cb_position_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, int32_t x, int32_t y)
|
|
|
|
{
|
|
|
|
E_Client *ec;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
DBG("Subsurface Cb Position Set: %d", wl_resource_get_id(resource));
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
/* try to get the client from resource data */
|
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (!(sdata = ec->comp_data->sub.data)) return;
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
sdata->position.x = x;
|
|
|
|
sdata->position.y = y;
|
|
|
|
sdata->position.set = EINA_TRUE;
|
2015-02-25 10:14:30 -08:00
|
|
|
}
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
static void
|
|
|
|
_e_comp_wl_subsurface_cb_place_above(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *sibling_resource)
|
2015-02-25 10:14:30 -08:00
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Client *ec, *ecs;
|
|
|
|
E_Client *parent;
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
DBG("Subsurface Cb Place Above: %d", wl_resource_get_id(resource));
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
/* try to get the client from resource data */
|
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (!ec->comp_data->sub.data) return;
|
2014-11-03 11:30:22 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
/* try to get the client from the sibling resource */
|
|
|
|
if (!(ecs = wl_resource_get_user_data(sibling_resource))) return;
|
2014-11-03 09:26:40 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (!ecs->comp_data->sub.data) return;
|
2014-11-03 11:46:20 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (!(parent = ec->comp_data->sub.data->parent)) return;
|
2014-11-03 09:26:40 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
parent->comp_data->sub.list =
|
|
|
|
eina_list_remove(parent->comp_data->sub.list, ec);
|
2014-11-03 11:46:20 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
parent->comp_data->sub.list =
|
|
|
|
eina_list_append_relative(parent->comp_data->sub.list, ec, ecs);
|
2014-11-03 11:46:20 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
parent->comp_data->sub.restack_target = parent;
|
2014-11-03 09:26:40 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2015-02-25 11:17:14 -08:00
|
|
|
_e_comp_wl_subsurface_cb_place_below(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *sibling_resource)
|
2014-11-03 08:14:50 -08:00
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Client *ec, *ecs;
|
|
|
|
E_Client *parent;
|
2014-11-03 08:14:50 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
DBG("Subsurface Cb Place Below: %d", wl_resource_get_id(resource));
|
2014-11-03 08:14:50 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
/* try to get the client from resource data */
|
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
2014-11-03 08:14:50 -08:00
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
if (!ec->comp_data->sub.data) return;
|
|
|
|
|
|
|
|
/* try to get the client from the sibling resource */
|
|
|
|
if (!(ecs = wl_resource_get_user_data(sibling_resource))) return;
|
|
|
|
|
|
|
|
if (!ecs->comp_data->sub.data) return;
|
|
|
|
|
|
|
|
if (!(parent = ec->comp_data->sub.data->parent)) return;
|
|
|
|
|
|
|
|
parent->comp_data->sub.list =
|
|
|
|
eina_list_remove(parent->comp_data->sub.list, ec);
|
|
|
|
|
|
|
|
parent->comp_data->sub.list =
|
|
|
|
eina_list_prepend_relative(parent->comp_data->sub.list, ec, ecs);
|
|
|
|
|
|
|
|
parent->comp_data->sub.restack_target = parent;
|
2014-11-03 08:14:50 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-11-03 08:14:50 -08:00
|
|
|
_e_comp_wl_subsurface_cb_sync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Client *ec;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
|
|
|
|
|
|
|
DBG("Subsurface Cb Sync Set: %d", wl_resource_get_id(resource));
|
|
|
|
|
|
|
|
/* try to get the client from resource data */
|
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
|
|
|
|
|
|
|
if (!(sdata = ec->comp_data->sub.data)) return;
|
|
|
|
|
|
|
|
sdata->synchronized = EINA_TRUE;
|
2014-11-03 08:14:50 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-11-03 08:14:50 -08:00
|
|
|
_e_comp_wl_subsurface_cb_desync_set(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Client *ec;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
|
|
|
|
|
|
|
DBG("Subsurface Cb Desync Set: %d", wl_resource_get_id(resource));
|
|
|
|
|
|
|
|
/* try to get the client from resource data */
|
|
|
|
if (!(ec = wl_resource_get_user_data(resource))) return;
|
|
|
|
|
|
|
|
if (!(sdata = ec->comp_data->sub.data)) return;
|
|
|
|
|
|
|
|
sdata->synchronized = EINA_FALSE;
|
2014-11-03 08:14:50 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static const struct wl_subsurface_interface _e_subsurface_interface =
|
2014-11-03 08:14:50 -08:00
|
|
|
{
|
|
|
|
_e_comp_wl_subsurface_cb_destroy,
|
|
|
|
_e_comp_wl_subsurface_cb_position_set,
|
|
|
|
_e_comp_wl_subsurface_cb_place_above,
|
|
|
|
_e_comp_wl_subsurface_cb_place_below,
|
2015-02-24 14:34:20 -08:00
|
|
|
_e_comp_wl_subsurface_cb_sync_set,
|
2014-11-03 08:14:50 -08:00
|
|
|
_e_comp_wl_subsurface_cb_desync_set
|
|
|
|
};
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static Eina_Bool
|
2014-11-03 08:14:50 -08:00
|
|
|
_e_comp_wl_subsurface_create(E_Client *ec, E_Client *epc, uint32_t id, struct wl_resource *surface_resource)
|
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
struct wl_client *client;
|
|
|
|
struct wl_resource *res;
|
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
|
|
|
|
|
|
|
/* try to get the wayland client from the surface resource */
|
|
|
|
if (!(client = wl_resource_get_client(surface_resource)))
|
|
|
|
{
|
|
|
|
ERR("Could not get client from resource %d",
|
|
|
|
wl_resource_get_id(surface_resource));
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to allocate subsurface data */
|
|
|
|
if (!(sdata = E_NEW(E_Comp_Wl_Subsurf_Data, 1)))
|
|
|
|
{
|
|
|
|
ERR("Could not allocate space for subsurface data");
|
|
|
|
goto dat_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to create the subsurface resource */
|
|
|
|
if (!(res = wl_resource_create(client, &wl_subsurface_interface, 1, id)))
|
|
|
|
{
|
|
|
|
ERR("Failed to create subsurface resource");
|
|
|
|
wl_resource_post_no_memory(surface_resource);
|
|
|
|
goto res_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set resource implementation */
|
|
|
|
wl_resource_set_implementation(res, &_e_subsurface_interface, ec,
|
|
|
|
_e_comp_wl_subsurface_destroy);
|
|
|
|
|
|
|
|
_e_comp_wl_surface_state_init(&sdata->cached, ec->w, ec->h);
|
|
|
|
|
|
|
|
/* set subsurface data properties */
|
|
|
|
sdata->cached_buffer_ref.buffer = NULL;
|
|
|
|
sdata->resource = res;
|
|
|
|
sdata->synchronized = EINA_TRUE;
|
|
|
|
sdata->parent = epc;
|
|
|
|
|
|
|
|
/* set subsurface client properties */
|
|
|
|
ec->borderless = EINA_TRUE;
|
|
|
|
ec->argb = EINA_TRUE;
|
|
|
|
ec->lock_border = EINA_TRUE;
|
|
|
|
ec->lock_focus_in = ec->lock_focus_out = EINA_TRUE;
|
|
|
|
ec->netwm.state.skip_taskbar = EINA_TRUE;
|
|
|
|
ec->netwm.state.skip_pager = EINA_TRUE;
|
|
|
|
ec->no_shape_cut = EINA_TRUE;
|
|
|
|
ec->border_size = 0;
|
|
|
|
|
|
|
|
if (epc)
|
|
|
|
{
|
|
|
|
if (epc->comp_data)
|
|
|
|
{
|
|
|
|
/* append this client to the parents subsurface list */
|
|
|
|
epc->comp_data->sub.list =
|
|
|
|
eina_list_append(epc->comp_data->sub.list, ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* TODO: add callbacks ?? */
|
|
|
|
}
|
|
|
|
|
|
|
|
ec->comp_data->surface = surface_resource;
|
|
|
|
ec->comp_data->sub.data = sdata;
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
|
|
|
|
|
|
|
res_err:
|
|
|
|
free(sdata);
|
|
|
|
dat_err:
|
|
|
|
return EINA_FALSE;
|
2014-11-03 08:14:50 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-11-03 08:14:50 -08:00
|
|
|
_e_comp_wl_subcompositor_cb_destroy(struct wl_client *client EINA_UNUSED, struct wl_resource *resource)
|
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
wl_resource_destroy(resource);
|
2014-11-03 08:14:50 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-11-03 08:14:50 -08:00
|
|
|
_e_comp_wl_subcompositor_cb_subsurface_get(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, uint32_t id, struct wl_resource *surface_resource, struct wl_resource *parent_resource)
|
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Client *ec, *epc = NULL;
|
|
|
|
static const char where[] = "get_subsurface: wl_subsurface@";
|
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (!(ec = wl_resource_get_user_data(surface_resource))) return;
|
|
|
|
if (!(epc = wl_resource_get_user_data(parent_resource))) return;
|
2015-02-25 11:17:14 -08:00
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (ec == epc)
|
2015-02-25 11:17:14 -08:00
|
|
|
{
|
|
|
|
wl_resource_post_error(resource, WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
|
|
"%s%d: wl_surface@%d cannot be its own parent",
|
|
|
|
where, id, wl_resource_get_id(surface_resource));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
2015-04-21 12:19:20 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(epc))) return;
|
2015-02-25 11:17:14 -08:00
|
|
|
|
|
|
|
/* check if this surface is already a sub-surface */
|
|
|
|
if ((ec->comp_data) && (ec->comp_data->sub.data))
|
|
|
|
{
|
|
|
|
wl_resource_post_error(resource,
|
|
|
|
WL_SUBCOMPOSITOR_ERROR_BAD_SURFACE,
|
|
|
|
"%s%d: wl_surface@%d is already a sub-surface",
|
|
|
|
where, id, wl_resource_get_id(surface_resource));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to create a new subsurface */
|
|
|
|
if (!_e_comp_wl_subsurface_create(ec, epc, id, surface_resource))
|
|
|
|
ERR("Failed to create subsurface for surface %d",
|
|
|
|
wl_resource_get_id(surface_resource));
|
2014-11-03 08:14:50 -08:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static const struct wl_subcompositor_interface _e_subcomp_interface =
|
2014-11-03 08:14:50 -08:00
|
|
|
{
|
|
|
|
_e_comp_wl_subcompositor_cb_destroy,
|
|
|
|
_e_comp_wl_subcompositor_cb_subsurface_get
|
|
|
|
};
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2015-03-18 14:30:49 -07:00
|
|
|
_e_comp_wl_subcompositor_cb_bind(struct wl_client *client, void *data EINA_UNUSED, uint32_t version, uint32_t id)
|
2014-11-03 08:14:50 -08:00
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
if (!(res =
|
|
|
|
wl_resource_create(client, &wl_subcompositor_interface,
|
2014-11-03 08:14:50 -08:00
|
|
|
MIN(version, 1), id)))
|
|
|
|
{
|
|
|
|
ERR("Could not create subcompositor resource: %m");
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-18 14:30:49 -07:00
|
|
|
wl_resource_set_implementation(res, &_e_subcomp_interface, e_comp, NULL);
|
2014-11-03 08:14:50 -08:00
|
|
|
|
|
|
|
/* TODO: add handlers for client iconify/uniconify */
|
|
|
|
}
|
|
|
|
|
2015-07-08 12:04:49 -07:00
|
|
|
static void
|
|
|
|
_e_comp_wl_screenshooter_cb_shoot(struct wl_client *client EINA_UNUSED, struct wl_resource *resource, struct wl_resource *output_resource, struct wl_resource *buffer_resource)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Output *output;
|
|
|
|
E_Comp_Wl_Buffer *buffer;
|
|
|
|
struct wl_shm_buffer *shm_buffer;
|
|
|
|
int stride;
|
|
|
|
void *pixels, *d;
|
|
|
|
|
|
|
|
output = wl_resource_get_user_data(output_resource);
|
|
|
|
buffer = e_comp_wl_buffer_get(buffer_resource);
|
|
|
|
|
|
|
|
if (!buffer)
|
|
|
|
{
|
|
|
|
wl_resource_post_no_memory(resource);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((buffer->w < output->w) || (buffer->h < output->h))
|
|
|
|
{
|
|
|
|
ERR("Buffer size less than output");
|
|
|
|
/* send done with bad buffer error */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
stride = buffer->w * sizeof(int);
|
|
|
|
|
|
|
|
pixels = malloc(stride * buffer->h);
|
|
|
|
if (!pixels)
|
|
|
|
{
|
|
|
|
/* send done with bad buffer error */
|
|
|
|
ERR("Could not allocate space for destination");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e_comp->wl_comp_data->screenshooter.read_pixels)
|
|
|
|
e_comp->wl_comp_data->screenshooter.read_pixels(output, pixels);
|
|
|
|
|
|
|
|
shm_buffer = wl_shm_buffer_get(buffer->resource);
|
|
|
|
if (!shm_buffer)
|
|
|
|
{
|
|
|
|
ERR("Could not get shm_buffer from resource");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
stride = wl_shm_buffer_get_stride(shm_buffer);
|
|
|
|
d = wl_shm_buffer_get_data(shm_buffer);
|
|
|
|
if (!d)
|
|
|
|
{
|
|
|
|
ERR("Could not get buffer data");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_shm_buffer_begin_access(shm_buffer);
|
|
|
|
memcpy(d, pixels, buffer->h * stride);
|
|
|
|
wl_shm_buffer_end_access(shm_buffer);
|
|
|
|
|
|
|
|
screenshooter_send_done(resource);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct screenshooter_interface _e_screenshooter_interface =
|
|
|
|
{
|
|
|
|
_e_comp_wl_screenshooter_cb_shoot
|
|
|
|
};
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_screenshooter_cb_bind(struct wl_client *client, void *data, uint32_t version EINA_UNUSED, uint32_t id)
|
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
|
|
|
|
res = wl_resource_create(client, &screenshooter_interface, 1, id);
|
|
|
|
if (!res)
|
|
|
|
{
|
|
|
|
ERR("Could not create screenshooter resource: %m");
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
wl_resource_set_implementation(res, &_e_screenshooter_interface, data, NULL);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-15 05:01:14 -07:00
|
|
|
_e_comp_wl_client_cb_new(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
|
|
|
uint64_t win;
|
|
|
|
|
|
|
|
/* make sure this is a wayland client */
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
|
2014-10-15 05:01:14 -07:00
|
|
|
|
|
|
|
/* get window id from pixmap */
|
|
|
|
win = e_pixmap_window_get(ec->pixmap);
|
|
|
|
|
|
|
|
/* ignore fake root windows */
|
|
|
|
if ((ec->override) && ((ec->x == -77) && (ec->y == -77)))
|
|
|
|
{
|
|
|
|
e_comp_ignore_win_add(E_PIXMAP_TYPE_WL, win);
|
|
|
|
e_object_del(E_OBJECT(ec));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!(ec->comp_data = E_NEW(E_Comp_Client_Data, 1)))
|
|
|
|
{
|
|
|
|
ERR("Could not allocate new client data structure");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
wl_signal_init(&ec->comp_data->destroy_signal);
|
|
|
|
|
|
|
|
_e_comp_wl_surface_state_init(&ec->comp_data->pending, ec->w, ec->h);
|
2014-10-16 08:21:33 -07:00
|
|
|
|
2014-10-15 05:01:14 -07:00
|
|
|
/* set initial client properties */
|
2015-01-12 10:03:52 -08:00
|
|
|
ec->argb = EINA_TRUE;
|
|
|
|
ec->no_shape_cut = EINA_TRUE;
|
2015-07-17 11:54:56 -07:00
|
|
|
ec->ignored = 1;
|
2014-10-15 05:01:14 -07:00
|
|
|
ec->border_size = 0;
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
/* NB: could not find a better place to do this, BUT for internal windows,
|
|
|
|
* we need to set delete_request else the close buttons on the frames do
|
2014-10-15 05:01:14 -07:00
|
|
|
* basically nothing */
|
2015-02-24 14:34:20 -08:00
|
|
|
if ((ec->internal) || (ec->internal_elm_win))
|
2015-01-09 09:45:03 -08:00
|
|
|
ec->icccm.delete_request = EINA_TRUE;
|
2014-10-15 05:01:14 -07:00
|
|
|
|
|
|
|
/* set initial client data properties */
|
|
|
|
ec->comp_data->mapped = EINA_FALSE;
|
2015-02-13 12:17:48 -08:00
|
|
|
ec->comp_data->first_damage = ec->internal;
|
2014-10-15 05:01:14 -07:00
|
|
|
|
2015-02-13 12:17:48 -08:00
|
|
|
ec->comp_data->need_reparent = !ec->internal;
|
2014-10-15 05:01:14 -07:00
|
|
|
|
|
|
|
/* add this client to the hash */
|
2014-10-31 09:33:09 -07:00
|
|
|
/* eina_hash_add(clients_win_hash, &win, ec); */
|
2014-10-15 05:01:14 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-15 05:07:56 -07:00
|
|
|
_e_comp_wl_client_cb_del(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
/* Eina_Rectangle *dmg; */
|
|
|
|
struct wl_resource *cb;
|
2015-05-12 11:43:00 -07:00
|
|
|
E_Client *subc;
|
2014-10-15 05:07:56 -07:00
|
|
|
|
|
|
|
/* make sure this is a wayland client */
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
|
2014-10-15 05:07:56 -07:00
|
|
|
|
2014-10-17 02:16:30 -07:00
|
|
|
if ((!ec->already_unparented) && (ec->comp_data->reparented))
|
|
|
|
_e_comp_wl_focus_down_set(ec);
|
2014-10-15 05:07:56 -07:00
|
|
|
|
|
|
|
ec->already_unparented = EINA_TRUE;
|
|
|
|
if (ec->comp_data->reparented)
|
|
|
|
{
|
|
|
|
/* reset pixmap parent window */
|
|
|
|
e_pixmap_parent_window_set(ec->pixmap, 0);
|
|
|
|
}
|
|
|
|
|
2015-05-12 11:43:00 -07:00
|
|
|
/* remove sub list */
|
|
|
|
EINA_LIST_FREE(ec->comp_data->sub.list, subc)
|
|
|
|
subc->comp_data->sub.data->parent = NULL;
|
|
|
|
|
2014-10-15 05:07:56 -07:00
|
|
|
if ((ec->parent) && (ec->parent->modal == ec))
|
|
|
|
{
|
|
|
|
ec->parent->lock_close = EINA_FALSE;
|
|
|
|
ec->parent->modal = NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
wl_signal_emit(&ec->comp_data->destroy_signal, &ec->comp_data->surface);
|
2014-10-31 09:33:09 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_finish(&ec->comp_data->pending);
|
|
|
|
|
|
|
|
e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, NULL);
|
|
|
|
|
|
|
|
EINA_LIST_FREE(ec->comp_data->frames, cb)
|
|
|
|
wl_resource_destroy(cb);
|
|
|
|
|
|
|
|
if (ec->comp_data->surface)
|
|
|
|
wl_resource_set_user_data(ec->comp_data->surface, NULL);
|
2014-10-16 08:39:03 -07:00
|
|
|
|
2015-04-21 12:19:20 -07:00
|
|
|
if (ec->internal_elm_win)
|
|
|
|
_e_comp_wl_surface_render_stop(ec);
|
2015-03-18 14:30:49 -07:00
|
|
|
_e_comp_wl_focus_check();
|
2014-10-17 02:16:30 -07:00
|
|
|
}
|
|
|
|
|
2015-06-17 08:28:55 -07:00
|
|
|
#if 0
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-11-05 06:58:49 -08:00
|
|
|
_e_comp_wl_client_cb_pre_frame(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
|
|
|
uint64_t parent;
|
|
|
|
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
|
2014-11-05 06:58:49 -08:00
|
|
|
if (!ec->comp_data->need_reparent) return;
|
|
|
|
|
|
|
|
DBG("Client Pre Frame: %d", wl_resource_get_id(ec->comp_data->surface));
|
|
|
|
|
|
|
|
parent = e_client_util_pwin_get(ec);
|
|
|
|
|
|
|
|
/* set pixmap parent window */
|
|
|
|
e_pixmap_parent_window_set(ec->pixmap, parent);
|
|
|
|
|
|
|
|
ec->border_size = 0;
|
|
|
|
ec->border.changed = EINA_TRUE;
|
|
|
|
ec->changes.shape = EINA_TRUE;
|
|
|
|
ec->changes.shape_input = EINA_TRUE;
|
|
|
|
EC_CHANGED(ec);
|
|
|
|
|
|
|
|
if (ec->visible)
|
|
|
|
{
|
2014-11-02 18:35:13 -08:00
|
|
|
if ((ec->comp_data->set_win_type) && (ec->internal_elm_win))
|
2014-11-05 06:58:49 -08:00
|
|
|
{
|
|
|
|
int type = ECORE_WL_WINDOW_TYPE_TOPLEVEL;
|
|
|
|
|
|
|
|
switch (ec->netwm.type)
|
|
|
|
{
|
|
|
|
case E_WINDOW_TYPE_DIALOG:
|
2015-02-24 14:34:20 -08:00
|
|
|
/* NB: If there is No transient set, then dialogs get
|
2014-11-05 06:58:49 -08:00
|
|
|
* treated as Normal Toplevel windows */
|
|
|
|
if (ec->icccm.transient_for)
|
|
|
|
type = ECORE_WL_WINDOW_TYPE_TRANSIENT;
|
|
|
|
break;
|
|
|
|
case E_WINDOW_TYPE_DESKTOP:
|
|
|
|
type = ECORE_WL_WINDOW_TYPE_FULLSCREEN;
|
|
|
|
break;
|
|
|
|
case E_WINDOW_TYPE_DND:
|
|
|
|
type = ECORE_WL_WINDOW_TYPE_DND;
|
|
|
|
break;
|
|
|
|
case E_WINDOW_TYPE_MENU:
|
|
|
|
case E_WINDOW_TYPE_DROPDOWN_MENU:
|
|
|
|
case E_WINDOW_TYPE_POPUP_MENU:
|
|
|
|
type = ECORE_WL_WINDOW_TYPE_MENU;
|
|
|
|
break;
|
|
|
|
case E_WINDOW_TYPE_NORMAL:
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2014-11-02 18:35:13 -08:00
|
|
|
ecore_evas_wayland_type_set(e_win_ee_get(ec->internal_elm_win), type);
|
2014-11-05 06:58:49 -08:00
|
|
|
ec->comp_data->set_win_type = EINA_FALSE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
e_bindings_mouse_grab(E_BINDING_CONTEXT_WINDOW, parent);
|
|
|
|
e_bindings_wheel_grab(E_BINDING_CONTEXT_WINDOW, parent);
|
|
|
|
|
|
|
|
_e_comp_wl_client_evas_init(ec);
|
|
|
|
|
|
|
|
/* if ((ec->netwm.ping) && (!ec->ping_poller)) */
|
|
|
|
/* e_client_ping(ec); */
|
|
|
|
|
|
|
|
if (ec->visible) evas_object_show(ec->frame);
|
|
|
|
|
|
|
|
ec->comp_data->need_reparent = EINA_FALSE;
|
|
|
|
ec->redirected = EINA_TRUE;
|
|
|
|
|
|
|
|
if (ec->comp_data->change_icon)
|
|
|
|
{
|
|
|
|
ec->comp_data->change_icon = EINA_FALSE;
|
|
|
|
ec->changes.icon = EINA_TRUE;
|
|
|
|
EC_CHANGED(ec);
|
|
|
|
}
|
|
|
|
|
|
|
|
ec->comp_data->reparented = EINA_TRUE;
|
|
|
|
}
|
2015-06-17 08:28:55 -07:00
|
|
|
#endif
|
2014-11-05 06:58:49 -08:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-17 02:16:30 -07:00
|
|
|
_e_comp_wl_client_cb_focus_set(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
|
2014-10-17 02:17:41 -07:00
|
|
|
|
2014-10-17 02:16:30 -07:00
|
|
|
/* send configure */
|
|
|
|
if (ec->comp_data->shell.configure_send)
|
|
|
|
{
|
|
|
|
if (ec->comp_data->shell.surface)
|
2015-02-24 14:34:20 -08:00
|
|
|
ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
|
2015-07-24 13:34:18 -07:00
|
|
|
0, ec->client.w, ec->client.h);
|
2014-10-17 02:16:30 -07:00
|
|
|
}
|
|
|
|
|
2015-06-25 16:23:35 -07:00
|
|
|
//if ((ec->icccm.take_focus) && (ec->icccm.accepts_focus))
|
|
|
|
//e_grabinput_focus(e_client_util_win_get(ec),
|
|
|
|
//E_FOCUS_METHOD_LOCALLY_ACTIVE);
|
|
|
|
//else if (!ec->icccm.accepts_focus)
|
|
|
|
//e_grabinput_focus(e_client_util_win_get(ec),
|
|
|
|
//E_FOCUS_METHOD_GLOBALLY_ACTIVE);
|
|
|
|
//else if (!ec->icccm.take_focus)
|
|
|
|
//e_grabinput_focus(e_client_util_win_get(ec), E_FOCUS_METHOD_PASSIVE);
|
2014-10-17 02:16:30 -07:00
|
|
|
|
2015-08-04 15:50:16 -07:00
|
|
|
e_comp->wl_comp_data->kbd.focus = ec->comp_data->surface;
|
2014-10-17 02:16:30 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-17 02:16:30 -07:00
|
|
|
_e_comp_wl_client_cb_focus_unset(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
|
2014-10-17 02:17:41 -07:00
|
|
|
|
2014-10-17 02:16:30 -07:00
|
|
|
/* send configure */
|
|
|
|
if (ec->comp_data->shell.configure_send)
|
|
|
|
{
|
|
|
|
if (ec->comp_data->shell.surface)
|
2015-02-24 14:34:20 -08:00
|
|
|
ec->comp_data->shell.configure_send(ec->comp_data->shell.surface,
|
2015-07-24 13:34:18 -07:00
|
|
|
0, ec->client.w, ec->client.h);
|
2014-10-17 02:16:30 -07:00
|
|
|
}
|
|
|
|
|
2015-03-18 14:30:49 -07:00
|
|
|
_e_comp_wl_focus_check();
|
2014-10-17 02:16:30 -07:00
|
|
|
|
2015-03-13 12:41:21 -07:00
|
|
|
if (e_comp->wl_comp_data->kbd.focus == ec->comp_data->surface)
|
|
|
|
e_comp->wl_comp_data->kbd.focus = NULL;
|
2014-10-15 05:07:56 -07:00
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-22 08:50:41 -07:00
|
|
|
_e_comp_wl_client_cb_resize_begin(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
|
2014-10-22 08:50:41 -07:00
|
|
|
|
2015-07-15 15:08:32 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 0;
|
|
|
|
if (ec->keyboard_resizing) return;
|
2014-10-22 08:50:41 -07:00
|
|
|
switch (ec->resize_mode)
|
|
|
|
{
|
|
|
|
case E_POINTER_RESIZE_T: // 1
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 1;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_B: // 2
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 2;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_L: // 4
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 4;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_R: // 8
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 8;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_TL: // 5
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 5;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_TR: // 9
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 9;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_BL: // 6
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 6;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
case E_POINTER_RESIZE_BR: // 10
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 10;
|
2014-10-22 08:50:41 -07:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static void
|
2014-10-22 08:50:41 -07:00
|
|
|
_e_comp_wl_client_cb_resize_end(void *data EINA_UNUSED, E_Client *ec)
|
|
|
|
{
|
2014-10-31 09:33:09 -07:00
|
|
|
if (e_object_is_del(E_OBJECT(ec))) return;
|
2015-02-27 06:21:55 -08:00
|
|
|
if (e_pixmap_type_get(ec->pixmap) != E_PIXMAP_TYPE_WL) return;
|
2014-10-22 08:50:41 -07:00
|
|
|
|
2015-03-13 12:41:21 -07:00
|
|
|
e_comp->wl_comp_data->resize.edges = 0;
|
|
|
|
e_comp->wl_comp_data->resize.resource = NULL;
|
2014-10-22 08:50:41 -07:00
|
|
|
|
|
|
|
if (ec->pending_resize)
|
|
|
|
{
|
2014-10-31 09:33:09 -07:00
|
|
|
|
2015-01-09 09:45:03 -08:00
|
|
|
ec->changes.pos = EINA_TRUE;
|
|
|
|
ec->changes.size = EINA_TRUE;
|
2014-11-10 08:58:20 -08:00
|
|
|
EC_CHANGED(ec);
|
2014-10-22 08:50:41 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
E_FREE_LIST(ec->pending_resize, free);
|
|
|
|
}
|
|
|
|
|
2015-02-19 11:49:01 -08:00
|
|
|
static void
|
|
|
|
_e_comp_wl_cb_output_unbind(struct wl_resource *resource)
|
|
|
|
{
|
2015-02-24 10:25:22 -08:00
|
|
|
E_Comp_Wl_Output *output;
|
2015-02-19 11:49:01 -08:00
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
if (!(output = wl_resource_get_user_data(resource))) return;
|
|
|
|
|
2015-02-24 12:10:37 -08:00
|
|
|
output->resources = eina_list_remove(output->resources, resource);
|
2015-02-19 11:49:01 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2015-02-19 14:02:46 -08:00
|
|
|
_e_comp_wl_cb_output_bind(struct wl_client *client, void *data, uint32_t version, uint32_t id)
|
2015-02-19 11:49:01 -08:00
|
|
|
{
|
2015-02-24 10:25:22 -08:00
|
|
|
E_Comp_Wl_Output *output;
|
2015-02-19 11:49:01 -08:00
|
|
|
struct wl_resource *resource;
|
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
if (!(output = data)) return;
|
2015-02-19 14:02:04 -08:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
resource =
|
2015-02-19 14:02:04 -08:00
|
|
|
wl_resource_create(client, &wl_output_interface, MIN(version, 2), id);
|
2015-02-24 10:25:22 -08:00
|
|
|
if (!resource)
|
2015-02-19 11:49:01 -08:00
|
|
|
{
|
|
|
|
wl_client_post_no_memory(client);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-03-21 13:30:11 -07:00
|
|
|
DBG("Bound Output: %s", output->id);
|
2015-03-21 13:59:48 -07:00
|
|
|
DBG("\tGeom: %d %d %d %d", output->x, output->y, output->w, output->h);
|
2015-03-21 13:30:11 -07:00
|
|
|
|
2015-02-24 12:10:37 -08:00
|
|
|
output->resources = eina_list_append(output->resources, resource);
|
2015-02-19 11:49:01 -08:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
wl_resource_set_implementation(resource, NULL, output,
|
2015-02-24 10:25:22 -08:00
|
|
|
_e_comp_wl_cb_output_unbind);
|
|
|
|
wl_resource_set_user_data(resource, output);
|
2015-02-19 11:49:01 -08:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
wl_output_send_geometry(resource, output->x, output->y,
|
|
|
|
output->phys_width, output->phys_height,
|
2015-04-22 14:46:43 -07:00
|
|
|
output->subpixel, output->make ?: "", output->model ?: "",
|
2015-02-24 10:25:22 -08:00
|
|
|
output->transform);
|
2015-02-19 11:49:01 -08:00
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
if (version >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
2015-02-28 08:36:42 -08:00
|
|
|
wl_output_send_scale(resource, output->scale);
|
2015-02-19 11:49:01 -08:00
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
/* 3 == preferred + current */
|
|
|
|
wl_output_send_mode(resource, 3, output->w, output->h, output->refresh);
|
2015-02-19 11:49:01 -08:00
|
|
|
|
|
|
|
if (version >= WL_OUTPUT_DONE_SINCE_VERSION)
|
|
|
|
wl_output_send_done(resource);
|
|
|
|
}
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
static Eina_Bool
|
2014-10-14 11:03:15 -07:00
|
|
|
_e_comp_wl_compositor_create(void)
|
|
|
|
{
|
2015-06-25 16:16:27 -07:00
|
|
|
E_Comp_Wl_Data *cdata;
|
2014-10-14 11:12:32 -07:00
|
|
|
const char *name;
|
2014-10-14 11:40:02 -07:00
|
|
|
int fd = 0;
|
2014-10-14 11:03:15 -07:00
|
|
|
|
|
|
|
/* check for existing compositor. create if needed */
|
2015-04-22 13:58:00 -07:00
|
|
|
if (e_comp->comp_type == E_PIXMAP_TYPE_NONE)
|
|
|
|
E_OBJECT_DEL_SET(e_comp, _e_comp_wl_compositor_cb_del);
|
2014-10-14 11:03:15 -07:00
|
|
|
|
|
|
|
/* create new compositor data */
|
2015-06-25 16:16:27 -07:00
|
|
|
if (!(cdata = E_NEW(E_Comp_Wl_Data, 1)))
|
2015-02-27 06:18:27 -08:00
|
|
|
{
|
|
|
|
ERR("Could not create compositor data: %m");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
2014-10-14 11:03:15 -07:00
|
|
|
|
2015-02-24 10:25:22 -08:00
|
|
|
/* set compositor wayland data */
|
2015-03-18 14:30:49 -07:00
|
|
|
e_comp->wl_comp_data = cdata;
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2014-10-14 11:07:38 -07:00
|
|
|
/* set wayland log handler */
|
|
|
|
wl_log_set_handler_server(_e_comp_wl_log_cb_print);
|
|
|
|
|
2014-10-14 11:09:58 -07:00
|
|
|
/* try to create a wayland display */
|
|
|
|
if (!(cdata->wl.disp = wl_display_create()))
|
|
|
|
{
|
|
|
|
ERR("Could not create a Wayland display: %m");
|
|
|
|
goto disp_err;
|
|
|
|
}
|
|
|
|
|
2014-10-14 11:12:32 -07:00
|
|
|
/* try to setup wayland socket */
|
|
|
|
if (!(name = wl_display_add_socket_auto(cdata->wl.disp)))
|
|
|
|
{
|
|
|
|
ERR("Could not create Wayland display socket: %m");
|
|
|
|
goto sock_err;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set wayland display environment variable */
|
|
|
|
e_env_set("WAYLAND_DISPLAY", name);
|
|
|
|
|
2014-10-14 11:13:22 -07:00
|
|
|
/* initialize compositor signals */
|
|
|
|
wl_signal_init(&cdata->signals.surface.create);
|
|
|
|
wl_signal_init(&cdata->signals.surface.activate);
|
|
|
|
wl_signal_init(&cdata->signals.surface.kill);
|
|
|
|
|
2015-02-25 11:17:14 -08:00
|
|
|
/* cdata->output.transform = WL_OUTPUT_TRANSFORM_NORMAL; */
|
|
|
|
/* cdata->output.scale = e_scale; */
|
2015-02-25 10:14:30 -08:00
|
|
|
|
2014-10-14 11:20:33 -07:00
|
|
|
/* try to add compositor to wayland globals */
|
2015-02-24 14:34:20 -08:00
|
|
|
if (!wl_global_create(cdata->wl.disp, &wl_compositor_interface,
|
2015-03-18 14:30:49 -07:00
|
|
|
COMPOSITOR_VERSION, e_comp,
|
2014-10-14 11:20:33 -07:00
|
|
|
_e_comp_wl_compositor_cb_bind))
|
|
|
|
{
|
|
|
|
ERR("Could not add compositor to wayland globals: %m");
|
|
|
|
goto comp_global_err;
|
|
|
|
}
|
|
|
|
|
2014-11-03 08:14:50 -08:00
|
|
|
/* try to add subcompositor to wayland globals */
|
2015-02-24 14:34:20 -08:00
|
|
|
if (!wl_global_create(cdata->wl.disp, &wl_subcompositor_interface, 1,
|
2015-03-18 14:30:49 -07:00
|
|
|
e_comp, _e_comp_wl_subcompositor_cb_bind))
|
2014-11-03 08:14:50 -08:00
|
|
|
{
|
|
|
|
ERR("Could not add subcompositor to wayland globals: %m");
|
|
|
|
goto comp_global_err;
|
|
|
|
}
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-07-08 12:04:49 -07:00
|
|
|
cdata->screenshooter.global =
|
|
|
|
wl_global_create(cdata->wl.disp, &screenshooter_interface, 1,
|
|
|
|
e_comp, _e_comp_wl_screenshooter_cb_bind);
|
|
|
|
if (!cdata->screenshooter.global)
|
|
|
|
{
|
|
|
|
ERR("Could not create screenshooter global: %m");
|
|
|
|
goto comp_global_err;
|
|
|
|
}
|
|
|
|
|
2015-05-13 11:44:51 -07:00
|
|
|
/* _e_comp_wl_cb_randr_change(NULL, 0, NULL); */
|
2014-11-03 08:14:50 -08:00
|
|
|
|
2014-10-14 11:47:32 -07:00
|
|
|
/* try to init data manager */
|
2015-05-18 06:08:52 -07:00
|
|
|
if (!e_comp_wl_data_manager_init())
|
2014-10-14 11:47:32 -07:00
|
|
|
{
|
|
|
|
ERR("Could not initialize data manager");
|
|
|
|
goto data_err;
|
|
|
|
}
|
|
|
|
|
2014-10-14 11:49:05 -07:00
|
|
|
/* try to init input */
|
2015-05-18 06:08:52 -07:00
|
|
|
if (!e_comp_wl_input_init())
|
2014-10-14 11:49:05 -07:00
|
|
|
{
|
|
|
|
ERR("Could not initialize input");
|
|
|
|
goto input_err;
|
|
|
|
}
|
|
|
|
|
2014-11-05 06:58:49 -08:00
|
|
|
#ifndef HAVE_WAYLAND_ONLY
|
2015-07-28 09:32:50 -07:00
|
|
|
if (e_comp_util_has_x())
|
2014-11-05 06:58:49 -08:00
|
|
|
{
|
|
|
|
E_Config_XKB_Layout *ekbd;
|
|
|
|
Ecore_X_Atom xkb = 0;
|
|
|
|
Ecore_X_Window root = 0;
|
|
|
|
int len = 0;
|
|
|
|
unsigned char *dat;
|
2015-07-02 14:54:40 -07:00
|
|
|
char *rules = NULL, *model = NULL, *layout = NULL;
|
2014-11-05 06:58:49 -08:00
|
|
|
|
|
|
|
if ((ekbd = e_xkb_layout_get()))
|
|
|
|
{
|
|
|
|
model = strdup(ekbd->model);
|
|
|
|
layout = strdup(ekbd->name);
|
|
|
|
}
|
|
|
|
|
|
|
|
root = ecore_x_window_root_first_get();
|
|
|
|
xkb = ecore_x_atom_get("_XKB_RULES_NAMES");
|
2015-02-24 14:34:20 -08:00
|
|
|
ecore_x_window_prop_property_get(root, xkb, ECORE_X_ATOM_STRING,
|
2014-11-05 06:58:49 -08:00
|
|
|
1024, &dat, &len);
|
|
|
|
if ((dat) && (len > 0))
|
|
|
|
{
|
|
|
|
rules = (char *)dat;
|
|
|
|
dat += strlen((const char *)dat) + 1;
|
|
|
|
if (!model) model = strdup((const char *)dat);
|
|
|
|
dat += strlen((const char *)dat) + 1;
|
|
|
|
if (!layout) layout = strdup((const char *)dat);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fallback */
|
|
|
|
if (!rules) rules = strdup("evdev");
|
|
|
|
if (!model) model = strdup("pc105");
|
|
|
|
if (!layout) layout = strdup("us");
|
|
|
|
|
|
|
|
/* update compositor keymap */
|
2015-05-18 08:48:31 -07:00
|
|
|
e_comp_wl_input_keymap_set(rules, model, layout);
|
2014-11-05 06:58:49 -08:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2014-10-14 11:21:48 -07:00
|
|
|
/* initialize shm mechanism */
|
|
|
|
wl_display_init_shm(cdata->wl.disp);
|
|
|
|
|
2014-10-14 11:40:02 -07:00
|
|
|
/* get the wayland display loop */
|
|
|
|
cdata->wl.loop = wl_display_get_event_loop(cdata->wl.disp);
|
|
|
|
|
|
|
|
/* get the file descriptor of the wayland event loop */
|
|
|
|
fd = wl_event_loop_get_fd(cdata->wl.loop);
|
|
|
|
|
|
|
|
/* create a listener for wayland main loop events */
|
2015-02-24 14:34:20 -08:00
|
|
|
cdata->fd_hdlr =
|
|
|
|
ecore_main_fd_handler_add(fd, (ECORE_FD_READ | ECORE_FD_ERROR),
|
2014-10-14 11:40:02 -07:00
|
|
|
_e_comp_wl_cb_read, cdata, NULL, NULL);
|
2015-02-24 14:34:20 -08:00
|
|
|
ecore_main_fd_handler_prepare_callback_set(cdata->fd_hdlr,
|
2014-10-14 11:40:02 -07:00
|
|
|
_e_comp_wl_cb_prepare, cdata);
|
|
|
|
|
2014-10-14 11:44:21 -07:00
|
|
|
/* setup module idler to load shell mmodule */
|
|
|
|
ecore_idler_add(_e_comp_wl_cb_module_idle, cdata);
|
|
|
|
|
2015-03-18 14:30:49 -07:00
|
|
|
if (e_comp->comp_type == E_PIXMAP_TYPE_X)
|
2014-10-14 11:50:27 -07:00
|
|
|
{
|
2015-05-13 09:05:57 -07:00
|
|
|
e_comp_wl_input_pointer_enabled_set(EINA_TRUE);
|
|
|
|
e_comp_wl_input_keyboard_enabled_set(EINA_TRUE);
|
|
|
|
e_comp_wl_input_touch_enabled_set(EINA_TRUE);
|
2014-10-14 11:50:27 -07:00
|
|
|
}
|
|
|
|
|
2014-10-14 11:03:15 -07:00
|
|
|
return EINA_TRUE;
|
2014-10-14 11:09:58 -07:00
|
|
|
|
2014-10-14 11:49:05 -07:00
|
|
|
input_err:
|
2015-05-18 06:08:52 -07:00
|
|
|
e_comp_wl_data_manager_shutdown();
|
2014-10-14 11:47:32 -07:00
|
|
|
data_err:
|
2014-10-14 11:20:33 -07:00
|
|
|
comp_global_err:
|
|
|
|
e_env_unset("WAYLAND_DISPLAY");
|
2014-10-14 11:12:32 -07:00
|
|
|
sock_err:
|
|
|
|
wl_display_destroy(cdata->wl.disp);
|
2014-10-14 11:09:58 -07:00
|
|
|
disp_err:
|
|
|
|
free(cdata);
|
|
|
|
return EINA_FALSE;
|
2014-10-14 11:03:15 -07:00
|
|
|
}
|
|
|
|
|
2015-07-21 11:25:16 -07:00
|
|
|
static Eina_Bool
|
|
|
|
_e_comp_wl_desklock_show(void)
|
|
|
|
{
|
|
|
|
return e_comp_grab_input(1, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
_e_comp_wl_desklock_hide(void)
|
|
|
|
{
|
|
|
|
e_comp_ungrab_input(1, 1);
|
|
|
|
}
|
|
|
|
|
2014-10-14 10:52:26 -07:00
|
|
|
/* public functions */
|
2015-02-27 06:24:59 -08:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Creates and initializes a Wayland compositor with ecore.
|
|
|
|
* Registers callback handlers for keyboard and mouse activity
|
|
|
|
* and other client events.
|
|
|
|
*
|
|
|
|
* @returns true on success, false if initialization failed.
|
|
|
|
*/
|
2015-05-07 12:13:10 -07:00
|
|
|
E_API Eina_Bool
|
2014-10-14 10:52:26 -07:00
|
|
|
e_comp_wl_init(void)
|
|
|
|
{
|
2014-10-14 10:53:25 -07:00
|
|
|
/* set gl available if we have ecore_evas support */
|
2015-02-24 14:34:20 -08:00
|
|
|
if (ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_WAYLAND_EGL) ||
|
2014-10-14 10:53:25 -07:00
|
|
|
ecore_evas_engine_type_supported_get(ECORE_EVAS_ENGINE_OPENGL_DRM))
|
|
|
|
e_comp_gl_set(EINA_TRUE);
|
|
|
|
|
2014-10-14 11:03:15 -07:00
|
|
|
/* try to create a wayland compositor */
|
|
|
|
if (!_e_comp_wl_compositor_create())
|
|
|
|
{
|
|
|
|
e_error_message_show(_("Enlightenment cannot create a Wayland Compositor!\n"));
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2015-05-15 11:44:21 -07:00
|
|
|
ecore_wl_server_mode_set(1);
|
|
|
|
|
2014-10-14 11:52:20 -07:00
|
|
|
/* try to init ecore_wayland */
|
|
|
|
if (!ecore_wl_init(NULL))
|
|
|
|
{
|
|
|
|
e_error_message_show(_("Enlightenment cannot initialize Ecore_Wayland!\n"));
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
2014-10-15 03:57:16 -07:00
|
|
|
/* create hash to store clients */
|
2014-10-31 09:33:09 -07:00
|
|
|
/* clients_win_hash = eina_hash_int64_new(NULL); */
|
2014-10-15 03:57:16 -07:00
|
|
|
|
2014-10-16 09:18:50 -07:00
|
|
|
/* add event handlers to catch E events */
|
2015-04-22 15:20:47 -07:00
|
|
|
if (e_comp->comp_type != E_PIXMAP_TYPE_X)
|
2015-06-25 17:04:01 -07:00
|
|
|
{
|
|
|
|
if (e_randr2_init())
|
|
|
|
e_randr2_screens_setup(-1, -1);
|
|
|
|
elm_config_preferred_engine_set("wayland_shm");
|
|
|
|
}
|
2015-07-30 13:29:25 -07:00
|
|
|
e_util_env_set("ELM_DISPLAY", "wl");
|
2015-04-22 07:29:42 -07:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
E_LIST_HANDLER_APPEND(handlers, E_EVENT_RANDR_CHANGE,
|
2015-04-22 15:20:47 -07:00
|
|
|
_e_comp_wl_cb_randr_change, NULL);
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
E_LIST_HANDLER_APPEND(handlers, E_EVENT_COMP_OBJECT_ADD,
|
2014-10-16 09:18:50 -07:00
|
|
|
_e_comp_wl_cb_comp_object_add, NULL);
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
E_LIST_HANDLER_APPEND(handlers, ECORE_EVENT_MOUSE_MOVE,
|
2015-07-21 11:27:29 -07:00
|
|
|
_e_comp_wl_cb_mouse_move, NULL);
|
2015-01-26 11:50:58 -08:00
|
|
|
|
2014-10-15 05:01:14 -07:00
|
|
|
/* add hooks to catch e_client events */
|
|
|
|
e_client_hook_add(E_CLIENT_HOOK_NEW_CLIENT, _e_comp_wl_client_cb_new, NULL);
|
2014-10-15 05:07:56 -07:00
|
|
|
e_client_hook_add(E_CLIENT_HOOK_DEL, _e_comp_wl_client_cb_del, NULL);
|
2014-10-15 05:01:14 -07:00
|
|
|
|
2014-11-05 06:58:49 -08:00
|
|
|
/* e_client_hook_add(E_CLIENT_HOOK_EVAL_PRE_FRAME_ASSIGN, */
|
|
|
|
/* _e_comp_wl_client_cb_pre_frame, NULL); */
|
2014-11-04 07:22:17 -08:00
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
e_client_hook_add(E_CLIENT_HOOK_FOCUS_SET,
|
2014-10-17 02:16:30 -07:00
|
|
|
_e_comp_wl_client_cb_focus_set, NULL);
|
2015-02-24 14:34:20 -08:00
|
|
|
e_client_hook_add(E_CLIENT_HOOK_FOCUS_UNSET,
|
2014-10-17 02:16:30 -07:00
|
|
|
_e_comp_wl_client_cb_focus_unset, NULL);
|
|
|
|
|
2015-02-24 14:34:20 -08:00
|
|
|
e_client_hook_add(E_CLIENT_HOOK_RESIZE_BEGIN,
|
2014-10-22 08:50:41 -07:00
|
|
|
_e_comp_wl_client_cb_resize_begin, NULL);
|
2015-02-24 14:34:20 -08:00
|
|
|
e_client_hook_add(E_CLIENT_HOOK_RESIZE_END,
|
2014-10-22 08:50:41 -07:00
|
|
|
_e_comp_wl_client_cb_resize_end, NULL);
|
|
|
|
|
2015-07-21 11:25:16 -07:00
|
|
|
e_desklock_show_hook_add(_e_comp_wl_desklock_show);
|
|
|
|
e_desklock_hide_hook_add(_e_comp_wl_desklock_hide);
|
|
|
|
|
2015-01-26 11:50:58 -08:00
|
|
|
_last_event_time = ecore_loop_time_get();
|
|
|
|
|
2014-10-14 11:03:15 -07:00
|
|
|
return EINA_TRUE;
|
2014-10-14 10:52:26 -07:00
|
|
|
}
|
|
|
|
|
2015-02-27 06:24:59 -08:00
|
|
|
/**
|
|
|
|
* Get the signal that is fired for the creation of a Wayland surface.
|
|
|
|
*
|
|
|
|
* @returns the corresponding Wayland signal
|
|
|
|
*/
|
2015-05-07 12:13:10 -07:00
|
|
|
E_API struct wl_signal
|
2015-03-18 14:30:49 -07:00
|
|
|
e_comp_wl_surface_create_signal_get(void)
|
2014-10-14 10:52:26 -07:00
|
|
|
{
|
2015-03-18 14:30:49 -07:00
|
|
|
return e_comp->wl_comp_data->signals.surface.create;
|
2014-10-14 10:52:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/* internal functions */
|
2015-02-24 14:34:20 -08:00
|
|
|
EINTERN void
|
2014-10-14 10:52:26 -07:00
|
|
|
e_comp_wl_shutdown(void)
|
|
|
|
{
|
2014-10-16 09:18:50 -07:00
|
|
|
/* free handlers */
|
|
|
|
E_FREE_LIST(handlers, ecore_event_handler_del);
|
|
|
|
|
2015-07-16 13:51:54 -07:00
|
|
|
while (e_comp->wl_comp_data->wl.globals)
|
|
|
|
{
|
|
|
|
Ecore_Wl_Global *global = EINA_INLIST_CONTAINER_GET(e_comp->wl_comp_data->wl.globals, Ecore_Wl_Global);
|
|
|
|
e_comp->wl_comp_data->wl.globals =
|
|
|
|
eina_inlist_remove(e_comp->wl_comp_data->wl.globals,
|
|
|
|
e_comp->wl_comp_data->wl.globals);
|
|
|
|
free(global->interface);
|
|
|
|
free(global);
|
|
|
|
}
|
|
|
|
if (e_comp->wl_comp_data->wl.shm) wl_shm_destroy(e_comp->wl_comp_data->wl.shm);
|
|
|
|
|
2014-10-14 11:53:06 -07:00
|
|
|
/* shutdown ecore_wayland */
|
|
|
|
ecore_wl_shutdown();
|
2014-10-14 10:52:26 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN struct wl_resource *
|
|
|
|
e_comp_wl_surface_create(struct wl_client *client, int version, uint32_t id)
|
|
|
|
{
|
2014-10-14 14:44:56 -07:00
|
|
|
struct wl_resource *ret = NULL;
|
|
|
|
|
|
|
|
if ((ret = wl_resource_create(client, &wl_surface_interface, version, id)))
|
2014-10-17 02:21:28 -07:00
|
|
|
DBG("Created Surface: %d", wl_resource_get_id(ret));
|
2014-10-14 14:44:56 -07:00
|
|
|
|
|
|
|
return ret;
|
2014-10-14 10:52:26 -07:00
|
|
|
}
|
2014-10-15 07:44:10 -07:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
EINTERN void
|
2015-02-25 10:14:30 -08:00
|
|
|
e_comp_wl_surface_attach(E_Client *ec, E_Comp_Wl_Buffer *buffer)
|
2014-10-15 07:44:10 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
e_comp_wl_buffer_reference(&ec->comp_data->buffer_ref, buffer);
|
2014-10-15 07:44:10 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
/* set usable early because shell module checks this */
|
|
|
|
e_pixmap_usable_set(ec->pixmap, (buffer != NULL));
|
|
|
|
e_pixmap_resource_set(ec->pixmap, buffer);
|
|
|
|
e_pixmap_dirty(ec->pixmap);
|
2014-10-15 07:44:10 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_size_update(ec, &ec->comp_data->pending);
|
|
|
|
}
|
2014-10-15 07:44:10 -07:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
EINTERN Eina_Bool
|
2015-02-25 10:14:30 -08:00
|
|
|
e_comp_wl_surface_commit(E_Client *ec)
|
|
|
|
{
|
2015-06-30 15:34:16 -07:00
|
|
|
Eina_Bool ignored;
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
_e_comp_wl_surface_state_commit(ec, &ec->comp_data->pending);
|
2015-02-05 13:31:18 -08:00
|
|
|
|
2015-06-30 15:34:16 -07:00
|
|
|
ignored = ec->ignored;
|
2015-07-10 10:22:15 -07:00
|
|
|
|
|
|
|
e_pixmap_refresh(ec->pixmap);
|
2014-10-31 09:33:09 -07:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!e_pixmap_usable_get(ec->pixmap))
|
2014-10-15 07:44:10 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if (ec->comp_data->mapped)
|
2014-10-15 07:44:10 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.unmap))
|
|
|
|
ec->comp_data->shell.unmap(ec->comp_data->shell.surface);
|
2015-02-06 15:27:01 -08:00
|
|
|
else
|
|
|
|
{
|
2015-06-25 16:22:49 -07:00
|
|
|
ec->visible = EINA_FALSE;
|
2015-02-25 10:14:30 -08:00
|
|
|
evas_object_hide(ec->frame);
|
2015-07-22 14:09:14 -07:00
|
|
|
ec->comp_data->mapped = 0;
|
2015-02-06 15:27:01 -08:00
|
|
|
}
|
2014-10-15 07:44:10 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!ec->comp_data->mapped)
|
2014-10-15 07:44:10 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if ((ec->comp_data->shell.surface) && (ec->comp_data->shell.map))
|
|
|
|
ec->comp_data->shell.map(ec->comp_data->shell.surface);
|
2015-02-06 15:27:01 -08:00
|
|
|
else
|
|
|
|
{
|
2015-06-25 16:22:49 -07:00
|
|
|
ec->visible = EINA_TRUE;
|
2015-06-30 15:34:16 -07:00
|
|
|
ec->ignored = 0;
|
2015-02-25 10:14:30 -08:00
|
|
|
evas_object_show(ec->frame);
|
2015-07-22 14:09:14 -07:00
|
|
|
ec->comp_data->mapped = 1;
|
2015-02-06 15:27:01 -08:00
|
|
|
}
|
2014-10-15 07:44:10 -07:00
|
|
|
}
|
|
|
|
}
|
2015-06-30 15:34:16 -07:00
|
|
|
ec->ignored = ignored;
|
2015-02-25 10:14:30 -08:00
|
|
|
return EINA_TRUE;
|
|
|
|
}
|
2015-02-11 14:02:01 -08:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
EINTERN Eina_Bool
|
2015-02-25 10:14:30 -08:00
|
|
|
e_comp_wl_subsurface_commit(E_Client *ec)
|
|
|
|
{
|
2015-02-25 11:17:14 -08:00
|
|
|
E_Comp_Wl_Subsurf_Data *sdata;
|
|
|
|
|
|
|
|
/* check for valid subcompositor data */
|
|
|
|
if (!(sdata = ec->comp_data->sub.data)) return EINA_FALSE;
|
|
|
|
|
|
|
|
if (_e_comp_wl_subsurface_synchronized_get(sdata))
|
|
|
|
_e_comp_wl_subsurface_commit_to_cache(ec);
|
|
|
|
else
|
|
|
|
{
|
|
|
|
E_Client *subc;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
if (sdata->cached.has_data)
|
|
|
|
{
|
|
|
|
_e_comp_wl_subsurface_commit_to_cache(ec);
|
|
|
|
_e_comp_wl_subsurface_commit_from_cache(ec);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
e_comp_wl_surface_commit(ec);
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(ec->comp_data->sub.list, l, subc)
|
|
|
|
{
|
|
|
|
if (ec != subc)
|
|
|
|
_e_comp_wl_subsurface_parent_commit(subc, EINA_FALSE);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return EINA_TRUE;
|
2015-02-25 10:14:30 -08:00
|
|
|
}
|
2014-10-16 09:56:40 -07:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
EINTERN void
|
2015-02-25 10:14:30 -08:00
|
|
|
e_comp_wl_buffer_reference(E_Comp_Wl_Buffer_Ref *ref, E_Comp_Wl_Buffer *buffer)
|
|
|
|
{
|
|
|
|
if ((ref->buffer) && (buffer != ref->buffer))
|
2014-10-16 08:24:59 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
ref->buffer->busy--;
|
|
|
|
if (ref->buffer->busy == 0)
|
2014-10-16 08:24:59 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!wl_resource_get_client(ref->buffer->resource)) return;
|
|
|
|
wl_resource_queue_event(ref->buffer->resource, WL_BUFFER_RELEASE);
|
2014-10-16 08:24:59 -07:00
|
|
|
}
|
2015-02-25 10:14:30 -08:00
|
|
|
wl_list_remove(&ref->destroy_listener.link);
|
2014-10-16 08:24:59 -07:00
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
if ((buffer) && (buffer != ref->buffer))
|
2014-10-16 08:26:18 -07:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
buffer->busy++;
|
|
|
|
wl_signal_add(&buffer->destroy_signal, &ref->destroy_listener);
|
2014-10-16 08:26:18 -07:00
|
|
|
}
|
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
ref->buffer = buffer;
|
|
|
|
ref->destroy_listener.notify = _e_comp_wl_buffer_reference_cb_destroy;
|
2014-10-15 07:44:10 -07:00
|
|
|
}
|
2014-11-03 09:26:40 -08:00
|
|
|
|
2015-02-27 06:24:59 -08:00
|
|
|
/**
|
|
|
|
* Get the buffer for a given resource.
|
|
|
|
*
|
|
|
|
* Retrieves the Wayland SHM buffer for the resource and
|
2015-06-16 13:10:21 -07:00
|
|
|
* uses it to create a new E_Comp_Wl_Buffer object. This
|
2015-02-27 06:24:59 -08:00
|
|
|
* buffer will be freed when the resource is destroyed.
|
|
|
|
*
|
|
|
|
* @param resource that owns the desired buffer
|
|
|
|
* @returns a new E_Comp_Wl_Buffer object
|
|
|
|
*/
|
2015-05-07 12:13:10 -07:00
|
|
|
E_API E_Comp_Wl_Buffer *
|
2015-02-25 10:14:30 -08:00
|
|
|
e_comp_wl_buffer_get(struct wl_resource *resource)
|
2014-11-03 09:26:40 -08:00
|
|
|
{
|
2015-02-25 10:14:30 -08:00
|
|
|
E_Comp_Wl_Buffer *buffer;
|
|
|
|
struct wl_listener *listener;
|
|
|
|
struct wl_shm_buffer *shmbuff;
|
2014-11-03 09:26:40 -08:00
|
|
|
|
2015-02-26 13:42:27 -08:00
|
|
|
listener =
|
2015-02-25 10:14:30 -08:00
|
|
|
wl_resource_get_destroy_listener(resource, _e_comp_wl_buffer_cb_destroy);
|
|
|
|
if (listener)
|
|
|
|
return container_of(listener, E_Comp_Wl_Buffer, destroy_listener);
|
2014-11-03 09:26:40 -08:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
if (!(shmbuff = wl_shm_buffer_get(resource))) return NULL;
|
2015-02-27 06:18:27 -08:00
|
|
|
if (!(buffer = E_NEW(E_Comp_Wl_Buffer, 1))) return NULL;
|
2014-11-03 09:26:40 -08:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
buffer->w = wl_shm_buffer_get_width(shmbuff);
|
|
|
|
buffer->h = wl_shm_buffer_get_height(shmbuff);
|
2014-11-03 09:50:07 -08:00
|
|
|
|
2015-02-25 10:14:30 -08:00
|
|
|
buffer->resource = resource;
|
|
|
|
wl_signal_init(&buffer->destroy_signal);
|
|
|
|
buffer->destroy_listener.notify = _e_comp_wl_buffer_cb_destroy;
|
|
|
|
wl_resource_add_destroy_listener(resource, &buffer->destroy_listener);
|
|
|
|
|
|
|
|
return buffer;
|
2014-11-03 09:26:40 -08:00
|
|
|
}
|
2015-01-26 11:50:58 -08:00
|
|
|
|
2015-02-27 06:24:59 -08:00
|
|
|
/**
|
|
|
|
* Computes the time since the last input event.
|
|
|
|
*
|
|
|
|
* @returns time in seconds.
|
|
|
|
*/
|
2015-05-07 12:13:10 -07:00
|
|
|
E_API double
|
2015-01-26 11:50:58 -08:00
|
|
|
e_comp_wl_idle_time_get(void)
|
|
|
|
{
|
|
|
|
return (ecore_loop_time_get() - _last_event_time);
|
|
|
|
}
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
static E_Comp_Wl_Output *
|
|
|
|
_e_comp_wl_output_get(Eina_List *outputs, const char *id)
|
|
|
|
{
|
|
|
|
Eina_List *l;
|
|
|
|
E_Comp_Wl_Output *output;
|
|
|
|
|
|
|
|
EINA_LIST_FOREACH(outputs, l, output)
|
|
|
|
{
|
|
|
|
if (!strcmp(output->id, id))
|
|
|
|
return output;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2015-02-27 06:24:59 -08:00
|
|
|
/**
|
|
|
|
* Initializes information about one display output.
|
|
|
|
*
|
|
|
|
* Adds or updates the given data about a single display output,
|
|
|
|
* with an id matching the provided id.
|
|
|
|
*
|
|
|
|
* @param id identification of output to be added or changed
|
|
|
|
* @param make manufacturer name of the display output
|
|
|
|
* @param model model name of the display output
|
|
|
|
* @param x output's top left corner x coordinate
|
|
|
|
* @param y output's top left corner y coordinate
|
|
|
|
* @param w output's width in pixels
|
|
|
|
* @param h output's height in pixels
|
|
|
|
* @param pw output's physical width in millimeters
|
|
|
|
* @param ph output's physical height in millimeters
|
|
|
|
* @param refresh output's refresh rate in Hz
|
|
|
|
* @param subpixel output's subpixel layout
|
|
|
|
* @param transform output's rotation and/or mirror transformation
|
2015-03-13 17:06:01 -07:00
|
|
|
*
|
|
|
|
* @returns True if a display output object could be added or updated
|
2015-02-27 06:24:59 -08:00
|
|
|
*/
|
2015-05-07 12:13:10 -07:00
|
|
|
E_API Eina_Bool
|
2015-03-13 17:06:01 -07:00
|
|
|
e_comp_wl_output_init(const char *id, const char *make, const char *model,
|
|
|
|
int x, int y, int w, int h, int pw, int ph,
|
|
|
|
unsigned int refresh, unsigned int subpixel,
|
|
|
|
unsigned int transform)
|
2015-02-24 10:25:22 -08:00
|
|
|
{
|
2015-06-25 16:16:27 -07:00
|
|
|
E_Comp_Wl_Data *cdata;
|
2015-02-24 10:25:22 -08:00
|
|
|
E_Comp_Wl_Output *output;
|
2015-02-27 16:23:11 -08:00
|
|
|
Eina_List *l2;
|
2015-02-24 12:10:37 -08:00
|
|
|
struct wl_resource *resource;
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-03-13 17:06:01 -07:00
|
|
|
if (!(cdata = e_comp->wl_comp_data)) return EINA_FALSE;
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
/* retrieve named output; or create it if it doesn't exist */
|
|
|
|
output = _e_comp_wl_output_get(cdata->outputs, id);
|
|
|
|
if (!output)
|
2015-02-24 10:25:22 -08:00
|
|
|
{
|
2015-03-13 17:06:01 -07:00
|
|
|
if (!(output = E_NEW(E_Comp_Wl_Output, 1))) return EINA_FALSE;
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
if (id) output->id = eina_stringshare_add(id);
|
|
|
|
if (make) output->make = eina_stringshare_add(make);
|
|
|
|
if (model) output->model = eina_stringshare_add(model);
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
cdata->outputs = eina_list_append(cdata->outputs, output);
|
2015-02-24 10:25:22 -08:00
|
|
|
|
2015-03-21 13:30:11 -07:00
|
|
|
output->global =
|
|
|
|
wl_global_create(cdata->wl.disp, &wl_output_interface,
|
|
|
|
2, output, _e_comp_wl_cb_output_bind);
|
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
output->resources = NULL;
|
2015-02-28 08:36:42 -08:00
|
|
|
output->scale = e_scale;
|
2015-02-24 10:25:22 -08:00
|
|
|
}
|
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
/* update the output details */
|
2015-02-24 10:25:22 -08:00
|
|
|
output->x = x;
|
|
|
|
output->y = y;
|
|
|
|
output->w = w;
|
|
|
|
output->h = h;
|
|
|
|
output->phys_width = pw;
|
|
|
|
output->phys_height = ph;
|
|
|
|
output->refresh = refresh * 1000;
|
|
|
|
output->subpixel = subpixel;
|
|
|
|
output->transform = transform;
|
|
|
|
|
2015-02-27 16:45:24 -08:00
|
|
|
if (output->scale <= 0)
|
2015-02-28 08:36:42 -08:00
|
|
|
output->scale = e_scale;
|
2015-02-27 16:45:24 -08:00
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
/* if we have bound resources, send updates */
|
|
|
|
EINA_LIST_FOREACH(output->resources, l2, resource)
|
|
|
|
{
|
|
|
|
wl_output_send_geometry(resource,
|
|
|
|
output->x, output->y,
|
|
|
|
output->phys_width,
|
|
|
|
output->phys_height,
|
|
|
|
output->subpixel,
|
2015-04-22 14:46:43 -07:00
|
|
|
output->make ?: "", output->model ?: "",
|
2015-02-27 16:23:11 -08:00
|
|
|
output->transform);
|
|
|
|
|
|
|
|
if (wl_resource_get_version(resource) >= WL_OUTPUT_SCALE_SINCE_VERSION)
|
2015-02-28 08:36:42 -08:00
|
|
|
wl_output_send_scale(resource, output->scale);
|
2015-02-24 12:27:48 -08:00
|
|
|
|
2015-02-27 16:23:11 -08:00
|
|
|
/* 3 == preferred + current */
|
|
|
|
wl_output_send_mode(resource, 3, output->w, output->h, output->refresh);
|
|
|
|
|
|
|
|
if (wl_resource_get_version(resource) >= WL_OUTPUT_DONE_SINCE_VERSION)
|
|
|
|
wl_output_send_done(resource);
|
|
|
|
}
|
2015-05-13 11:44:51 -07:00
|
|
|
|
2015-03-13 17:06:01 -07:00
|
|
|
return EINA_TRUE;
|
2015-02-24 10:25:22 -08:00
|
|
|
}
|
2015-05-13 11:44:51 -07:00
|
|
|
|
|
|
|
E_API void
|
|
|
|
e_comp_wl_output_remove(const char *id)
|
|
|
|
{
|
2015-06-25 16:16:27 -07:00
|
|
|
E_Comp_Wl_Data *cdata;
|
2015-05-13 11:44:51 -07:00
|
|
|
E_Comp_Wl_Output *output;
|
|
|
|
|
|
|
|
if (!(cdata = e_comp->wl_comp_data)) return;
|
|
|
|
|
|
|
|
output = _e_comp_wl_output_get(cdata->outputs, id);
|
|
|
|
if (output)
|
|
|
|
{
|
|
|
|
cdata->outputs = eina_list_remove(cdata->outputs, output);
|
|
|
|
|
|
|
|
/* wl_global_destroy(output->global); */
|
|
|
|
|
|
|
|
/* eina_stringshare_del(output->id); */
|
|
|
|
/* eina_stringshare_del(output->make); */
|
|
|
|
/* eina_stringshare_del(output->model); */
|
|
|
|
|
|
|
|
/* free(output); */
|
|
|
|
}
|
|
|
|
}
|
2015-06-25 16:55:37 -07:00
|
|
|
|
2015-07-21 11:27:29 -07:00
|
|
|
EINTERN Eina_Bool
|
|
|
|
e_comp_wl_key_down(Ecore_Event_Key *ev)
|
|
|
|
{
|
|
|
|
E_Comp_Wl_Data *cdata;
|
|
|
|
E_Client *ec = NULL;
|
|
|
|
uint32_t serial, *end, *k, keycode;
|
|
|
|
|
2015-07-22 09:24:35 -07:00
|
|
|
if ((e_comp->comp_type != E_PIXMAP_TYPE_WL) || (ev->window != e_comp->ee_win)) return EINA_FALSE;
|
2015-07-21 11:27:29 -07:00
|
|
|
_last_event_time = ecore_loop_time_get();
|
|
|
|
|
|
|
|
keycode = (ev->keycode - 8);
|
|
|
|
if (!(cdata = e_comp->wl_comp_data)) return EINA_FALSE;
|
|
|
|
|
|
|
|
#ifndef E_RELEASE_BUILD
|
|
|
|
if ((ev->modifiers & ECORE_EVENT_MODIFIER_CTRL) &&
|
|
|
|
((ev->modifiers & ECORE_EVENT_MODIFIER_ALT) ||
|
|
|
|
(ev->modifiers & ECORE_EVENT_MODIFIER_ALTGR)) &&
|
|
|
|
eina_streq(ev->key, "BackSpace"))
|
|
|
|
exit(0);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k));
|
|
|
|
|
|
|
|
for (k = cdata->kbd.keys.data; k < end; k++)
|
|
|
|
{
|
|
|
|
/* ignore server-generated key repeats */
|
|
|
|
if (*k == keycode) return EINA_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data;
|
|
|
|
if (!(k = wl_array_add(&cdata->kbd.keys, sizeof(*k))))
|
|
|
|
{
|
|
|
|
DBG("wl_array_add: Out of memory\n");
|
|
|
|
return EINA_FALSE;
|
|
|
|
}
|
|
|
|
*k = keycode;
|
|
|
|
|
|
|
|
if ((!e_client_action_get()) && (!e_comp->input_key_grabs) && (!e_menu_grab_window_get()))
|
|
|
|
{
|
|
|
|
ec = e_client_focused_get();
|
2015-07-22 14:38:40 -07:00
|
|
|
if (ec && ec->comp_data->surface && cdata->kbd.focused)
|
2015-07-21 11:27:29 -07:00
|
|
|
{
|
|
|
|
struct wl_resource *res;
|
|
|
|
Eina_List *l;
|
|
|
|
|
|
|
|
serial = wl_display_next_serial(cdata->wl.disp);
|
2015-07-22 14:38:40 -07:00
|
|
|
EINA_LIST_FOREACH(cdata->kbd.focused, l, res)
|
|
|
|
wl_keyboard_send_key(res, serial, ev->timestamp,
|
|
|
|
keycode, WL_KEYBOARD_KEY_STATE_PRESSED);
|
2015-07-21 11:27:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update modifier state */
|
|
|
|
e_comp_wl_input_keyboard_state_update(keycode, EINA_TRUE);
|
|
|
|
return !!ec;
|
|
|
|
}
|
|
|
|
|
|
|
|
EINTERN Eina_Bool
|
|
|
|
e_comp_wl_key_up(Ecore_Event_Key *ev)
|
|
|
|
{
|
|
|
|
E_Client *ec = NULL;
|
|
|
|
E_Comp_Wl_Data *cdata;
|
|
|
|
uint32_t serial, *end, *k, keycode;
|
|
|
|
struct wl_resource *res;
|
|
|
|
Eina_List *l;
|
|
|
|
|
2015-07-22 09:24:35 -07:00
|
|
|
if ((e_comp->comp_type != E_PIXMAP_TYPE_WL) || (ev->window != e_comp->ee_win)) return EINA_FALSE;
|
2015-07-21 11:27:29 -07:00
|
|
|
_last_event_time = ecore_loop_time_get();
|
|
|
|
|
|
|
|
keycode = (ev->keycode - 8);
|
|
|
|
if (!(cdata = e_comp->wl_comp_data)) return EINA_FALSE;
|
|
|
|
|
|
|
|
end = (uint32_t *)cdata->kbd.keys.data + (cdata->kbd.keys.size / sizeof(*k));
|
|
|
|
for (k = cdata->kbd.keys.data; k < end; k++)
|
|
|
|
if (*k == keycode) *k = *--end;
|
|
|
|
|
|
|
|
cdata->kbd.keys.size = (const char *)end - (const char *)cdata->kbd.keys.data;
|
|
|
|
|
|
|
|
if ((!e_client_action_get()) && (!e_comp->input_key_grabs) && (!e_menu_grab_window_get()))
|
|
|
|
{
|
|
|
|
ec = e_client_focused_get();
|
|
|
|
|
2015-07-22 14:38:40 -07:00
|
|
|
if (cdata->kbd.focused)
|
2015-07-21 11:27:29 -07:00
|
|
|
{
|
|
|
|
serial = wl_display_next_serial(cdata->wl.disp);
|
2015-07-22 14:38:40 -07:00
|
|
|
EINA_LIST_FOREACH(cdata->kbd.focused, l, res)
|
|
|
|
wl_keyboard_send_key(res, serial, ev->timestamp,
|
|
|
|
keycode, WL_KEYBOARD_KEY_STATE_RELEASED);
|
2015-07-21 11:27:29 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* update modifier state */
|
|
|
|
e_comp_wl_input_keyboard_state_update(keycode, EINA_FALSE);
|
|
|
|
return !!ec;
|
|
|
|
}
|
|
|
|
|
2015-06-25 16:55:37 -07:00
|
|
|
EINTERN void
|
|
|
|
e_comp_wl_xwayland_client_queue(E_Client *ec)
|
|
|
|
{
|
|
|
|
e_comp->wl_comp_data->xwl_pending = eina_list_append(e_comp->wl_comp_data->xwl_pending, ec);
|
|
|
|
}
|