static void drag_grab_motion(struct weston_pointer_grab *grab, uint32_t time, wl_fixed_t x, wl_fixed_t y) { struct weston_pointer_drag *drag = container_of(grab, struct weston_pointer_drag, grab); struct weston_pointer *pointer = drag->grab.pointer; float fx, fy; wl_fixed_t sx, sy; weston_pointer_move(pointer, x, y); if (drag->base.icon) { fx = wl_fixed_to_double(pointer->x) + drag->base.dx; fy = wl_fixed_to_double(pointer->y) + drag->base.dy; weston_view_set_position(drag->base.icon, fx, fy); weston_view_schedule_repaint(drag->base.icon); } if (drag->base.focus_resource) { weston_view_from_global_fixed(drag->base.focus, pointer->x, pointer->y, &sx, &sy); wl_data_device_send_motion(drag->base.focus_resource, time, sx, sy); } }
namespace WPE { Shell::Shell(Environment& environment) : m_environment(environment) { auto* compositor = m_environment.compositor(); weston_compositor_set_default_pointer_grab(compositor, &m_pgInterface); weston_compositor_set_default_keyboard_grab(compositor, &m_kgInterface); weston_compositor_set_default_touch_grab(compositor, &m_tgInterface); } const struct weston_pointer_grab_interface Shell::m_pgInterface = { // focus [](struct weston_pointer_grab*) { }, // motion [](struct weston_pointer_grab* grab, uint32_t time, wl_fixed_t x, wl_fixed_t y) { struct weston_pointer* pointer = grab->pointer; weston_pointer_move(pointer, x, y); int newX = wl_fixed_to_int(pointer->x); int newY = wl_fixed_to_int(pointer->y); Shell::instance().m_environment.updateCursorPosition(newX, newY); WPE::Input::Server::singleton().servePointerEvent({ WPE::Input::PointerEvent::Motion, time, newX, newY, 0, 0 }); }, // button [](struct weston_pointer_grab* grab, uint32_t time, uint32_t button, uint32_t state) { WPE::Input::Server::singleton().servePointerEvent({ WPE::Input::PointerEvent::Button, time, 0, 0, button, state }); }, // axis [](struct weston_pointer_grab* grab, uint32_t time, uint32_t axis, wl_fixed_t value) { // Multiply the delta value by -4 to turn it into a more acceptable direction, // and to increase the pixel step into something more ... efficient. WPE::Input::Server::singleton().serveAxisEvent({ WPE::Input::AxisEvent::Motion, time, axis, -4 * wl_fixed_to_int(value) }); }, // cancel [](struct weston_pointer_grab*) { } }; const struct weston_keyboard_grab_interface Shell::m_kgInterface = { // key [](struct weston_keyboard_grab*, uint32_t time, uint32_t key, uint32_t state) { WPE::Input::Server::singleton().serveKeyboardEvent({ time, key, state }); }, // modifiers [](struct weston_keyboard_grab*, uint32_t serial, uint32_t depressed, uint32_t latched, uint32_t locked, uint32_t group) { }, // cancel [](struct weston_keyboard_grab*) { } }; const struct weston_touch_grab_interface Shell::m_tgInterface = { // down [](struct weston_touch_grab*, uint32_t time, int id, wl_fixed_t x, wl_fixed_t y) { WPE::Input::Server::singleton().serveTouchEvent({ WPE::Input::TouchEvent::Down, time, id, wl_fixed_to_int(x), wl_fixed_to_int(y) }); }, // up [](struct weston_touch_grab*, uint32_t time, int id) { WPE::Input::Server::singleton().serveTouchEvent({ WPE::Input::TouchEvent::Up, time, id, 0, 0 }); }, // motion [](struct weston_touch_grab*, uint32_t time, int id, wl_fixed_t x, wl_fixed_t y) { WPE::Input::Server::singleton().serveTouchEvent({ WPE::Input::TouchEvent::Motion, time, id, wl_fixed_to_int(x), wl_fixed_to_int(y) }); }, // frame [](struct weston_touch_grab*) { }, // cancel [](struct weston_touch_grab*) { } }; Shell* Shell::m_instance = nullptr; gpointer Shell::launchWPE(gpointer data) { Shell::m_instance = static_cast<Shell*>(data); GMainContext* threadContext = g_main_context_new(); GMainLoop* threadLoop = g_main_loop_new(threadContext, FALSE); g_main_context_push_thread_default(threadContext); auto pageGroupIdentifier = adoptWK(WKStringCreateWithUTF8CString("WPEPageGroup")); auto pageGroup = adoptWK(WKPageGroupCreateWithIdentifier(pageGroupIdentifier.get())); auto context = adoptWK(WKContextCreate()); Shell::instance().m_view = adoptWK(WKViewCreate(context.get(), pageGroup.get())); auto view = Shell::instance().m_view.get(); WKViewResize(view, Shell::instance().m_environment.outputSize()); WKViewMakeWPEInputTarget(view); const char* url = g_getenv("WPE_SHELL_URL"); if (!url) url = "http://www.webkit.org/blog-files/3d-transforms/poster-circle.html"; auto shellURL = adoptWK(WKURLCreateWithUTF8CString(url)); WKPageLoadURL(WKViewGetPage(view), shellURL.get()); g_main_loop_run(threadLoop); return nullptr; } } // namespace WPE