${LIBS}
${X11_X11_LIB}
${WAYLAND_EGL_LIBRARIES}
+ ${XKB_LIBRARIES}
)
set(SOURCES
src/WindowSystems/WaylandBaseWindowSystem.cpp
src/WindowSystems/WaylandX11WindowSystem.cpp
src/WindowSystems/WaylandServerinfoProtocol.cpp
+ src/WindowSystems/WaylandInputDevice.cpp
+ src/WindowSystems/WaylandInputEvent.cpp
+ src/WindowSystems/WaylandX11InputEvent.cpp
src/TextureBinders/WaylandGLESTexture.cpp
)
--- /dev/null
+/***************************************************************************
+ *
+ * Copyright 2010, 2011 BMW Car IT GmbH
+ * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ****************************************************************************/
+#ifndef _WAYLANDINPUTDEVICE_H_
+#define _WAYLANDINPUTDEVICE_H_
+#include <wayland-server.h>
+#include "Log.h"
+#include "config.h"
+#include "InputManager.h"
+
+//////////////////////////////////////////////////////////////////////////////
+class WaylandInputDevice
+{
+// Properties
+private:
+ struct wl_display* m_wlDisplay;
+ struct wl_seat m_wlSeat;
+ bool m_hasPointer;
+ bool m_hasKeyboard;
+ bool m_hasTouch;
+ int m_nTp;
+
+ struct {
+ struct wl_pointer wlPointer;
+ struct wl_keyboard wlKeyboard;
+ struct wl_touch wlTouch;
+ } m_deviceInterfaces;
+
+// Methods
+public:
+ WaylandInputDevice(wl_display *display);
+ virtual ~WaylandInputDevice();
+
+ void initPointerDevice();
+ void initKeyboardDevice();
+ void initTouchDevice();
+
+ struct wl_seat* seat();
+ bool hasPointer() const;
+ bool hasKeyboard() const;
+ bool hasTouch() const;
+
+ struct wl_pointer *pointerDevice();
+ struct wl_keyboard *keyboardDevice();
+ struct wl_touch *touchDevice();
+ const struct wl_pointer *pointerDevice() const;
+ const struct wl_keyboard *keyboardDevice() const;
+ const struct wl_touch *touchDevice() const;
+
+ void sendMousePressEvent(const Point& globalPos, const Point& localPos,
+ uint32_t button, uint32_t time);
+ void sendMouseReleaseEvent(const Point& globalPos, const Point& localPos,
+ uint32_t button, uint32_t time);
+ void sendMouseMotionEvent(struct wl_surface *surface,
+ const Point& globalPos, const Point& localPos, uint32_t time);
+
+ void sendKeyPressEvent(struct wl_surface *surface, uint32_t time, uint32_t code);
+ void sendKeyReleaseEvent(struct wl_surface *surface, uint32_t time, uint32_t code);
+ void setKeyboardFocus(struct wl_surface *surface);
+
+ void sendTouchPointEvent();
+ void sendTouchFrameEvent();
+ void sendTouchCancelEvent();
+
+private:
+ void releaseDevices();
+ void cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev);
+
+ void setMouseFocus(struct wl_surface *surface,
+ const Point& globalPos,
+ const Point& localPos);
+ void sendMouseMotionEvent(const Point& globalPos,
+ const Point& localPos,
+ uint32_t time);
+
+ const static struct wl_seat_interface m_seatInterface;
+
+ static void bindInputDevice(struct wl_client *client,
+ void *data,
+ uint32_t version,
+ uint32_t id);
+ static void destroyResource(struct wl_resource *resource);
+ static void destroyDeviceResource(struct wl_resource *resource);
+
+ static void getPointer(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id);
+ static void getKeyboard(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id);
+ static void getTouch(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id);
+};
+
+inline struct wl_seat* WaylandInputDevice::seat() { return &m_wlSeat; }
+inline bool WaylandInputDevice::hasPointer() const { return m_hasPointer; }
+inline bool WaylandInputDevice::hasKeyboard() const { return m_hasKeyboard; }
+inline bool WaylandInputDevice::hasTouch() const { return m_hasTouch; }
+
+inline struct wl_pointer* WaylandInputDevice::pointerDevice()
+ { return &m_deviceInterfaces.wlPointer; }
+inline struct wl_keyboard* WaylandInputDevice::keyboardDevice()
+ { return &m_deviceInterfaces.wlKeyboard; }
+inline struct wl_touch* WaylandInputDevice::touchDevice()
+ { return &m_deviceInterfaces.wlTouch; }
+
+inline const struct wl_pointer* WaylandInputDevice::pointerDevice() const
+ { return &m_deviceInterfaces.wlPointer; }
+inline const struct wl_keyboard* WaylandInputDevice::keyboardDevice() const
+ { return &m_deviceInterfaces.wlKeyboard; }
+inline const struct wl_touch* WaylandInputDevice::touchDevice() const
+ { return &m_deviceInterfaces.wlTouch; }
+
+#endif /* _WAYLANDINPUTDEVICE_H_ */
--- /dev/null
+/***************************************************************************
+ *
+ * Copyright 2010, 2011 BMW Car IT GmbH
+ * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ****************************************************************************/
+
+#ifndef _WAYLANDINPUTEVENT_H_
+#define _WAYLANDINPUTEVENT_H_
+#include <wayland-server.h>
+#include "Log.h"
+#include "config.h"
+#include "WindowSystems/WaylandInputDevice.h"
+
+//////////////////////////////////////////////////////////////////////////////
+extern "C"
+{
+};
+
+class WaylandBaseWindowSystem;
+
+//////////////////////////////////////////////////////////////////////////////
+class WaylandInputEvent
+{
+// Properties
+protected:
+ WaylandBaseWindowSystem *m_windowSystem;
+ WaylandInputDevice *m_inputDevice;
+ struct wl_event_source *m_wlEventSource;
+ int m_fd;
+
+ struct xkbInfo {
+ struct xkb_keymap *keymap;
+ int keymapFd;
+ size_t keymapSize;
+ char *keymapArea;
+ } m_xkbInfo;
+
+// Methods
+public:
+ WaylandInputEvent(WaylandBaseWindowSystem *windowSystem);
+ virtual ~WaylandInputEvent();
+
+ virtual void setupInputEvent();
+
+ WaylandInputDevice& inputDevice() const;
+ WaylandBaseWindowSystem& windowSystem() const;
+
+protected:
+ int createAnonymousFile(off_t size);
+
+private:
+ void initInputEvent();
+};
+
+inline WaylandInputDevice& WaylandInputEvent::inputDevice() const { return *m_inputDevice; }
+inline WaylandBaseWindowSystem& WaylandInputEvent::windowSystem() const { return *m_windowSystem; }
+
+#endif /* _WAYLANDINPUTEVENT_H_ */
--- /dev/null
+/***************************************************************************
+ *
+ * Copyright 2010, 2011 BMW Car IT GmbH
+ * Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ *
+ * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+ * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+ * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+ * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ ****************************************************************************/
+
+#ifndef _WAYLANDX11INPUTEVENT_H_
+#define _WAYLANDX11INPUTEVENT_H_
+
+#include "config.h"
+
+#define HAVE_XCB_POLL_FOR_QUEUED_EVENT 1
+
+#include <wayland-server.h>
+#include <xcb/xcb.h>
+#ifdef HAVE_XCB_XKB // XCB-XKB Extension: not required
+ #define explicit tmpexplicit
+ #include <xcb/xkb.h>
+ #undef explicit
+#endif
+#include <xkbcommon/xkbcommon.h>
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+#include <X11/Xlib-xcb.h>
+
+#include "Log.h"
+#include "WindowSystems/WaylandBaseWindowSystem.h"
+
+//////////////////////////////////////////////////////////////////////////////
+extern "C"
+{
+ struct atom_ {
+ xcb_atom_t xkbNames;
+ xcb_atom_t string;
+ };
+
+ struct weston_xkb_info_ {
+ struct xkb_keymap *keymap;
+ int keymap_fd;
+ size_t keymap_size;
+ char *keymap_area;
+ xkb_mod_index_t shift_mod;
+ xkb_mod_index_t caps_mod;
+ xkb_mod_index_t ctrl_mod;
+ xkb_mod_index_t alt_mod;
+ xkb_mod_index_t mod2_mod;
+ xkb_mod_index_t mod3_mod;
+ xkb_mod_index_t super_mod;
+ xkb_mod_index_t mod5_mod;
+ xkb_led_index_t num_led;
+ xkb_led_index_t caps_led;
+ xkb_led_index_t scroll_led;
+ };
+};
+
+//////////////////////////////////////////////////////////////////////////////
+class WaylandX11InputEvent : public WaylandInputEvent
+{
+// Properties
+private:
+ Display *m_x11Display;
+ xcb_connection_t *m_xcbConn;
+ xcb_screen_t *m_xcbScreen;
+
+ bool m_hasXkb;
+ uint8_t m_xkbEventBase;
+ struct xkb_context *m_xkbContext;
+ struct xkb_rule_names m_xkbNames;
+ struct xkb_state *m_xkbState;
+ struct atom_ m_atom;
+ struct weston_xkb_info_ m_xkbInfo;
+
+// Methods
+public:
+ WaylandX11InputEvent(WaylandBaseWindowSystem *windowSystem);
+ virtual ~WaylandX11InputEvent();
+
+ virtual void setupInputEvent();
+
+protected:
+private:
+ static int handleInputEvent(int fd, uint32_t mask, void *data);
+ static void updateXkbStateFromCore();
+
+ bool initXkb();
+ void setupXkb();
+ bool hasXkb();
+ struct xkb_keymap *getKeymap();
+ void createNewKeymap();
+ void buildGlobalKeymap();
+
+ xcb_connection_t *connection();
+ uint8_t xkbEventBase();
+};
+
+inline bool WaylandX11InputEvent::hasXkb() { return m_hasXkb; }
+inline xcb_connection_t* WaylandX11InputEvent::connection() { return m_xcbConn; }
+inline uint8_t WaylandX11InputEvent::xkbEventBase() { return m_xkbEventBase; }
+
+#endif /* _WAYLANDX11INPUTEVENT_H_ */
--- /dev/null
+/***************************************************************************
+*
+* Copyright 2010, 2011 BMW Car IT GmbH
+* Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*
+* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*
+****************************************************************************/
+#include <time.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "WindowSystems/WaylandInputDevice.h"
+
+/////////////////////////////////////////////////////////////////////////////
+
+WaylandInputDevice::WaylandInputDevice(struct wl_display *display)
+: m_wlDisplay(display)
+, m_hasPointer(false)
+, m_hasKeyboard(false)
+, m_hasTouch(false)
+, m_nTp(0)
+{
+ wl_seat_init(&m_wlSeat);
+ wl_display_add_global(m_wlDisplay,
+ &wl_seat_interface,
+ this,
+ WaylandInputDevice::bindInputDevice);
+}
+
+WaylandInputDevice::~WaylandInputDevice()
+{
+ releaseDevices();
+}
+
+void
+WaylandInputDevice::initPointerDevice()
+{
+ if (m_hasPointer)
+ return;
+
+ wl_pointer_init(&m_deviceInterfaces.wlPointer);
+ wl_seat_set_pointer(&m_wlSeat, &m_deviceInterfaces.wlPointer);
+
+ m_hasPointer = true;
+ LOG_INFO("WaylandInputDevice", "Available pointer");
+}
+
+void
+WaylandInputDevice::initKeyboardDevice()
+{
+ if (m_hasKeyboard)
+ return;
+
+ wl_keyboard_init(&m_deviceInterfaces.wlKeyboard);
+ wl_seat_set_keyboard(&m_wlSeat, &m_deviceInterfaces.wlKeyboard);
+
+ m_hasKeyboard = true;
+ LOG_INFO("WaylandInputDevice", "Available keyboard");
+}
+
+void
+WaylandInputDevice::initTouchDevice()
+{
+ if (m_hasTouch)
+ return;
+
+ wl_touch_init(&m_deviceInterfaces.wlTouch);
+ wl_seat_set_touch(&m_wlSeat, &m_deviceInterfaces.wlTouch);
+
+ m_hasTouch = true;
+ LOG_INFO("WaylandInputDevice", "Available touch");
+}
+
+void
+WaylandInputDevice::releaseDevices()
+{
+ if (m_hasPointer)
+ wl_pointer_release(&m_deviceInterfaces.wlPointer);
+
+ if (m_hasKeyboard)
+ wl_keyboard_release(&m_deviceInterfaces.wlKeyboard);
+
+ if (m_hasTouch)
+ wl_touch_release(&m_deviceInterfaces.wlTouch);
+}
+
+void
+WaylandInputDevice::cleanupDataDeviceForClient(struct wl_client *client, bool destroyDev)
+{
+}
+
+void
+WaylandInputDevice::bindInputDevice(struct wl_client *client,
+ void *data,
+ uint32_t /*version*/,
+ uint32_t id)
+{
+ struct wl_resource *resource =
+ wl_client_add_object(client,
+ &wl_seat_interface,
+ &WaylandInputDevice::m_seatInterface,
+ id,
+ data);
+
+ WaylandInputDevice *inputDevice = static_cast<WaylandInputDevice*>(data);
+ struct wl_seat *seat = inputDevice->seat();
+
+ resource->destroy = WaylandInputDevice::destroyResource;
+ wl_list_insert(&seat->base_resource_list, &resource->link);
+
+ uint32_t caps = 0;
+
+ if (inputDevice->hasPointer())
+ caps |= WL_SEAT_CAPABILITY_POINTER;
+ if (inputDevice->hasKeyboard())
+ caps |= WL_SEAT_CAPABILITY_KEYBOARD;
+ if (inputDevice->hasTouch())
+ caps |= WL_SEAT_CAPABILITY_TOUCH;
+
+ wl_seat_send_capabilities(resource, caps);
+}
+
+void
+WaylandInputDevice::destroyResource(struct wl_resource *resource)
+{
+ WaylandInputDevice *inputDevice = static_cast<WaylandInputDevice*>(resource->data);
+ if (inputDevice->keyboardDevice()->focus_resource == resource){
+ inputDevice->keyboardDevice()->focus_resource = 0;
+ }
+ if (inputDevice->pointerDevice()->focus_resource == resource){
+ inputDevice->pointerDevice()->focus_resource = 0;
+ }
+
+ inputDevice->cleanupDataDeviceForClient(resource->client, true);
+
+ wl_list_remove(&resource->link);
+
+ free(resource);
+}
+
+void
+WaylandInputDevice::destroyDeviceResource(struct wl_resource *resource)
+{
+ wl_list_remove(&resource->link);
+ free(resource);
+}
+
+const struct wl_seat_interface WaylandInputDevice::m_seatInterface = {
+ getPointer,
+ getKeyboard,
+ getTouch
+};
+
+void
+WaylandInputDevice::getPointer(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id)
+{
+ WaylandInputDevice *inputDevice = static_cast<WaylandInputDevice*>(resource->data);
+ wl_pointer *pointer = inputDevice->pointerDevice();
+ wl_resource *clientResource = wl_client_add_object(client,
+ &wl_pointer_interface,
+ 0,
+ id,
+ pointer);
+ wl_list_insert(&pointer->resource_list, &clientResource->link);
+ clientResource->destroy = WaylandInputDevice::destroyDeviceResource;
+}
+
+void
+WaylandInputDevice::getKeyboard(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id)
+{
+ WaylandInputDevice *inputDevice = static_cast<WaylandInputDevice*>(resource->data);
+ wl_keyboard *keyboard = inputDevice->keyboardDevice();
+ wl_resource *clientResource = wl_client_add_object(client,
+ &wl_keyboard_interface,
+ 0,
+ id,
+ keyboard);
+ wl_list_insert(&keyboard->resource_list, &clientResource->link);
+ clientResource->destroy = WaylandInputDevice::destroyDeviceResource;
+}
+
+void
+WaylandInputDevice::getTouch(struct wl_client *client,
+ struct wl_resource *resource,
+ uint32_t id)
+{
+ WaylandInputDevice *inputDevice = static_cast<WaylandInputDevice*>(resource->data);
+ wl_touch *touch = inputDevice->touchDevice();
+ wl_resource *clientResource = wl_client_add_object(client,
+ &wl_touch_interface,
+ 0,
+ id,
+ touch);
+ wl_list_insert(&touch->resource_list, &clientResource->link);
+ clientResource->destroy = WaylandInputDevice::destroyDeviceResource;
+}
+
+void
+WaylandInputDevice::sendMousePressEvent(const Point& globalPos,
+ const Point& localPos,
+ uint32_t button,
+ uint32_t time)
+{
+ sendMouseMotionEvent(globalPos, localPos, time);
+ wl_pointer *pointer = pointerDevice();
+ pointer->button_count++;
+ const struct wl_pointer_grab_interface *interface = pointer->grab->interface;
+ interface->button(pointer->grab,
+ time,
+ button,
+ WL_POINTER_BUTTON_STATE_PRESSED);
+}
+
+void
+WaylandInputDevice::sendMouseReleaseEvent(const Point& globalPos,
+ const Point& localPos,
+ uint32_t button,
+ uint32_t time)
+{
+ sendMouseMotionEvent(globalPos, localPos, time);
+ wl_pointer *pointer = pointerDevice();
+ pointer->button_count--;
+ const struct wl_pointer_grab_interface *interface = pointer->grab->interface;
+ interface->button(pointer->grab,
+ time,
+ button,
+ WL_POINTER_BUTTON_STATE_RELEASED);
+}
+
+void
+WaylandInputDevice::sendMouseMotionEvent(struct wl_surface* surface,
+ const Point& globalPos,
+ const Point& localPos,
+ uint32_t time)
+{
+ setMouseFocus(surface, globalPos, localPos);
+ sendMouseMotionEvent(globalPos, localPos, time);
+}
+
+void
+WaylandInputDevice::sendMouseMotionEvent(const Point& globalPos,
+ const Point& localPos,
+ uint32_t time)
+{
+ wl_pointer *pointer = pointerDevice();
+ const struct wl_pointer_grab_interface *interface = pointer->grab->interface;
+ pointer->x = wl_fixed_from_double(globalPos.x);
+ pointer->y = wl_fixed_from_double(globalPos.y);
+ interface->motion(pointer->grab,
+ time,
+ wl_fixed_from_double(localPos.x),
+ wl_fixed_from_double(localPos.y));
+}
+
+void
+WaylandInputDevice::sendKeyPressEvent(struct wl_surface* surface,
+ uint32_t time, uint32_t code)
+{
+ wl_keyboard *keyboard = keyboardDevice();
+ if (!keyboard->focus){
+ setKeyboardFocus(surface);
+ }
+ if (keyboard->focus_resource){
+ uint32_t serial = wl_display_next_serial(m_wlDisplay);
+ wl_keyboard_send_key(keyboard->focus_resource,
+ serial, time, code - 8, 1);
+ }
+}
+
+void
+WaylandInputDevice::sendKeyReleaseEvent(struct wl_surface* surface,
+ uint32_t time, uint32_t code)
+{
+ wl_keyboard *keyboard = keyboardDevice();
+ if (keyboard->focus_resource){
+ uint32_t serial = wl_display_next_serial(m_wlDisplay);
+ wl_keyboard_send_key(keyboard->focus_resource,
+ serial, time, code - 8, 0);
+ }
+}
+
+void
+WaylandInputDevice::sendTouchPointEvent()
+{
+}
+
+void
+WaylandInputDevice::sendTouchFrameEvent()
+{
+}
+
+void
+WaylandInputDevice::sendTouchCancelEvent()
+{
+}
+
+void
+WaylandInputDevice::setMouseFocus(struct wl_surface* surface,
+ const Point& globalPos,
+ const Point& localPos)
+{
+ wl_pointer* pointer = pointerDevice();
+ pointer->x = wl_fixed_from_double(globalPos.x);
+ pointer->y = wl_fixed_from_double(globalPos.y);
+ pointer->current = surface;
+ pointer->current_x = wl_fixed_from_double(localPos.x);
+ pointer->current_y = wl_fixed_from_double(localPos.y);
+ pointer->grab->interface->focus(pointer->grab,
+ surface,
+ wl_fixed_from_double(localPos.x),
+ wl_fixed_from_double(localPos.y));
+}
+
+void
+WaylandInputDevice::setKeyboardFocus(struct wl_surface* surface)
+{
+ wl_keyboard_set_focus(keyboardDevice(), surface);
+}
--- /dev/null
+/***************************************************************************
+*
+* Copyright 2010, 2011 BMW Car IT GmbH
+* Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*
+* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*
+****************************************************************************/
+#include <time.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <linux/input.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "WindowSystems/WaylandInputEvent.h"
+#include "WindowSystems/WaylandBaseWindowSystem.h"
+
+#define HAVE_MKOSTEMP 1
+
+/////////////////////////////////////////////////////////////////////////////
+
+static int
+setCloexecOrClose(int fd)
+{
+ long flags;
+ if (fd == -1)
+ return -1;
+
+ flags = fcntl(fd, F_GETFD);
+ if (flags == -1)
+ goto err;
+
+ if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1)
+ goto err;
+
+ return fd;
+err:
+ close(fd);
+ return -1;
+}
+
+static int
+createTmpFileCloexec(char *tmpname)
+{
+ int fd;
+#ifdef HAVE_MKOSTEMP
+ fd = mkostemp(tmpname, O_CLOEXEC);
+ if (fd >= 0){
+ unlink(tmpname);
+ }
+#else
+ fd = mkstemp(tmpname);
+ if (fd >= 0){
+ fd = setCloexecOrClose(fd);
+ unlink(tmpname);
+ }
+#endif
+ return fd;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+WaylandInputEvent::WaylandInputEvent(WaylandBaseWindowSystem *windowSystem)
+: m_windowSystem(windowSystem)
+, m_inputDevice(NULL)
+, m_wlEventSource(NULL)
+, m_fd(0)
+{
+ initInputEvent();
+}
+
+WaylandInputEvent::~WaylandInputEvent()
+{
+ if (!m_wlEventSource)
+ wl_event_source_remove(m_wlEventSource);
+}
+
+void
+WaylandInputEvent::initInputEvent()
+{
+ LOG_DEBUG("WaylandInputEvent", "initInputEvent IN");
+ m_inputDevice = new WaylandInputDevice(m_windowSystem->getNativeDisplayHandle());
+ if (!m_inputDevice){
+ LOG_ERROR("WaylandInputEvent", "Failed to create WaylandInputDevice");
+ return;
+ }
+ LOG_DEBUG("WaylandInputEvent", "initInputEvent OUT");
+}
+
+void
+WaylandInputEvent::setupInputEvent()
+{
+ LOG_ERROR("WaylandInputEvent", "Called setupInputEvent()");
+}
+
+int
+WaylandInputEvent::createAnonymousFile(off_t size)
+{
+ static const char temp[] = "/weston-shared-XXXXXX";
+ const char *path;
+ char *name;
+ int fd;
+
+ path = getenv("XDG_RUNTIME_DIR");
+ if (!path){
+ return -1;
+ }
+
+ name = (char*)malloc(strlen(path) + sizeof(temp));
+ if (!name){
+ return -1;
+ }
+
+ strcpy(name, path);
+ strcat(name, temp);
+ fd = createTmpFileCloexec(name);
+
+ free(name);
+ if (fd < 0){
+ return -1;
+ }
+
+ if (ftruncate(fd, size) < 0){
+ close(fd);
+ return -1;
+ }
+
+ return fd;
+}
--- /dev/null
+/***************************************************************************
+*
+* Copyright 2010, 2011 BMW Car IT GmbH
+* Copyright (C) 2011 DENSO CORPORATION and Robert Bosch Car Multimedia Gmbh
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+*
+* THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
+* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
+* FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
+* SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
+* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
+* CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
+* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+*
+****************************************************************************/
+#include <time.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+#include <sys/mman.h>
+#include <linux/input.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "WindowSystems/WaylandX11InputEvent.h"
+#include "WindowSystems/WaylandX11WindowSystem.h"
+
+extern "C"
+{
+ static int
+ x11GetNextEvent(xcb_connection_t *conn, xcb_generic_event_t **event, uint32_t mask)
+ {
+ if (mask & WL_EVENT_READABLE){
+ *event = xcb_poll_for_event(conn);
+ } else {
+#ifdef HAVE_XCB_POLL_FOR_QUEUED_EVENT
+ *event = xcb_poll_for_queued_event(conn);
+#else
+ *event = xcb_poll_for_event(conn);
+#endif
+ }
+ return *event != NULL;
+ }
+
+ static bool
+ getButtonEvent(xcb_generic_event_t *event, WLEvent *wlEvent, int /*state*/)
+ {
+ xcb_button_press_event_t *buttonEvent = (xcb_button_press_event_t*)event;
+ switch (buttonEvent->detail){
+ default:
+ wlEvent->button = buttonEvent->detail + BTN_LEFT - 1;
+ break;
+ case 2:
+ wlEvent->button = BTN_MIDDLE;
+ break;
+ case 3:
+ wlEvent->button = BTN_RIGHT;
+ break;
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ return false;
+ }
+ return true;
+ }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+WaylandX11InputEvent::WaylandX11InputEvent(WaylandBaseWindowSystem *windowSystem)
+: WaylandInputEvent(windowSystem)
+, m_x11Display(NULL)
+, m_xcbConn(NULL)
+, m_hasXkb(false)
+, m_xkbEventBase(0)
+, m_xkbContext(NULL)
+{
+ memset(&m_xkbNames, 0x00, sizeof(m_xkbNames));
+}
+
+WaylandX11InputEvent::~WaylandX11InputEvent()
+{
+#if 0
+ // WaylandX11WindowSystem should do this
+ if (m_x11Display)
+ XCloseDisplay(m_x11Display);
+#endif
+ if (m_xkbContext)
+ xkb_context_unref(m_xkbContext);
+}
+
+#define F(field) offsetof(struct atom_, field)
+
+void
+WaylandX11InputEvent::setupInputEvent()
+{
+ LOG_DEBUG("WaylandX11InputEvent", "setupInputEvent IN");
+
+ if (!initXkb()){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: Failed to init XKB");
+ return;
+ }
+
+ WaylandX11WindowSystem* x11WindowSystem
+ = dynamic_cast<WaylandX11WindowSystem*>(m_windowSystem);
+ if (!x11WindowSystem){
+ LOG_ERROR("WaylandX11InputEvent", "Invalid window system");
+ return;
+ }
+
+ m_x11Display = x11WindowSystem->x11Display();
+ if (!m_x11Display){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: WindowSystem has not x11 display");
+ return;
+ }
+
+ m_xcbConn = XGetXCBConnection(m_x11Display);
+ XSetEventQueueOwner(m_x11Display, XCBOwnsEventQueue);
+ if (xcb_connection_has_error(m_xcbConn)){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: xcb connection has error.");
+ XCloseDisplay(m_x11Display);
+ return;
+ }
+
+ xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_get_setup(m_xcbConn));
+ m_xcbScreen = iter.data;
+
+ // Get resources
+ {
+ static const struct {
+ const char *name;
+ int offset;
+ } atoms[] = {
+ { "STRING", F(string) },
+ { "_XKB_RULES_NAMES", F(xkbNames) }
+ };
+ xcb_intern_atom_cookie_t cookies[2];
+ xcb_intern_atom_reply_t *reply;
+ unsigned int i = 0;
+ for (i = 0; i < ARRAY_LENGTH(atoms); ++i){
+ cookies[i] = xcb_intern_atom(m_xcbConn, 0,
+ strlen(atoms[i].name),
+ atoms[i].name);
+ }
+ for (i = 0; i < ARRAY_LENGTH(atoms); ++i){
+ reply = xcb_intern_atom_reply(m_xcbConn, cookies[i], NULL);
+ *(xcb_atom_t*)((char *)(&m_atom) + atoms[i].offset) = reply->atom;
+ free(reply);
+ }
+ }
+
+ // Initialize pointer device
+ m_inputDevice->initPointerDevice();
+
+ setupXkb();
+ struct xkb_keymap *keymap = getKeymap();
+ if (!keymap){
+ m_xkbInfo.keymap = xkb_map_ref(keymap);
+ createNewKeymap();
+ }
+ else {
+ buildGlobalKeymap();
+ m_xkbInfo.keymap = xkb_map_ref(m_xkbInfo.keymap);
+ }
+ m_xkbState = xkb_state_new(m_xkbInfo.keymap);
+ if (m_xkbState == NULL){
+ LOG_ERROR("WaylandX11InputEvent", "Failed to initialise XKB state");
+ return;
+ }
+
+ // Initialize keyboard device
+ m_inputDevice->initKeyboardDevice();
+ if (keymap){
+ xkb_map_unref(keymap);
+ }
+
+ // Regist event loop callback
+ m_fd = xcb_get_file_descriptor(m_xcbConn);
+ wl_event_loop *eventLoop = wl_display_get_event_loop(
+ m_windowSystem->getNativeDisplayHandle());
+ m_wlEventSource = wl_event_loop_add_fd(eventLoop,
+ m_fd,
+ WL_EVENT_READABLE,
+ WaylandX11InputEvent::handleInputEvent,
+ this);
+ wl_event_source_check(m_wlEventSource);
+
+ LOG_DEBUG("WaylandX11InputEvent", "setupInputEvent OUT");
+}
+
+bool
+WaylandX11InputEvent::initXkb()
+{
+ m_xkbContext = xkb_context_new(static_cast<xkb_context_flags>(0));
+ if (m_xkbContext == NULL){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: Failed to init XKB context");
+ return false;
+ }
+
+ // TODO: set specified configuration
+ m_xkbNames.rules = strdup("evdev");
+ m_xkbNames.model = strdup("pc105");
+ m_xkbNames.layout = strdup("us");
+
+ return true;
+}
+
+void
+WaylandX11InputEvent::setupXkb()
+{
+#ifndef HAVE_XCB_XKB
+ return;
+#else
+ const xcb_query_extension_reply_t *ext;
+ xcb_generic_error_t *error;
+ xcb_void_cookie_t select;
+ xcb_xkb_per_client_flags_cookie_t pcf;
+ xcb_xkb_per_client_flags_reply_t *pcf_reply;
+
+ ext = xcb_get_extension_data(m_xcbConn, &xcb_xkb_id);
+ if (!ext){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: XKB extension not available on "
+ "host X11 server");
+ return;
+ }
+ m_xkbEventBase = ext->first_event;
+
+ select = xcb_xkb_select_events(m_xcbConn,
+ XCB_XKB_ID_USE_CORE_KBD,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
+ 0,
+ XCB_XKB_EVENT_TYPE_STATE_NOTIFY,
+ 0,
+ 0,
+ NULL);
+ error = xcb_request_check(m_xcbConn, select);
+ if (error){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: Failed to select XKB state events");
+ return;
+ }
+
+ pcf = xcb_xkb_per_client_flags(m_xcbConn,
+ XCB_XKB_ID_USE_CORE_KBD,
+ XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
+ XCB_XKB_PER_CLIENT_FLAG_DETECTABLE_AUTO_REPEAT,
+ 0, 0, 0);
+ pcf_reply = xcb_xkb_per_client_flags_reply(m_xcbConn, pcf, &error);
+ free(pcf_reply);
+ if (error){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: Failed to set XKB per-client flags, "
+ "not using detectable repeat");
+ return;
+ }
+
+ m_hasXkb = true;
+#endif
+}
+
+struct xkb_keymap*
+WaylandX11InputEvent::getKeymap()
+{
+ xcb_get_property_cookie_t cookie;
+ xcb_get_property_reply_t *reply;
+ xcb_generic_error_t *error;
+ struct xkb_rule_names names;
+ struct xkb_keymap *ret;
+ char *value_all, *value_part;
+ int length_all, length_part;
+
+ memset(&names, 0x00, sizeof(names));
+
+ cookie = xcb_get_property(m_xcbConn,
+ 0,
+ m_xcbScreen->root,
+ m_atom.xkbNames,
+ m_atom.string,
+ 0, 1024);
+ reply = xcb_get_property_reply(m_xcbConn, cookie, &error);
+ if (reply == NULL){
+ LOG_ERROR("WaylandX11InputEvent", "ERROR: xcb_get_property_reply");
+ return NULL;
+ }
+
+ value_all = static_cast<char*>(xcb_get_property_value(reply));
+ length_all = xcb_get_property_value_length(reply);
+ value_part = value_all;
+
+#define copy_prop_value(to) \
+ length_part = strlen(value_part); \
+ if (value_part + length_part < (value_all + length_all) && \
+ length_part > 0) \
+ names.to = value_part; \
+ value_part += length_part + 1;
+
+ copy_prop_value(rules);
+ copy_prop_value(model);
+ copy_prop_value(layout);
+ copy_prop_value(variant);
+ copy_prop_value(options);
+#undef copy_prop_value
+
+ ret = xkb_map_new_from_names(m_xkbContext,
+ &names,
+ static_cast<xkb_map_compile_flags>(0));
+
+ free(reply);
+ return ret;
+}
+
+void
+WaylandX11InputEvent::createNewKeymap()
+{
+ m_xkbInfo.shift_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, XKB_MOD_NAME_SHIFT);
+ m_xkbInfo.caps_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, XKB_MOD_NAME_CAPS);
+ m_xkbInfo.ctrl_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, XKB_MOD_NAME_CTRL);
+ m_xkbInfo.alt_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, XKB_MOD_NAME_ALT);
+ m_xkbInfo.mod2_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, "Mod2");
+ m_xkbInfo.mod3_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, "Mod3");
+ m_xkbInfo.super_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, XKB_MOD_NAME_LOGO);
+ m_xkbInfo.mod5_mod = xkb_map_mod_get_index(m_xkbInfo.keymap, "Mod5");
+ m_xkbInfo.num_led = xkb_map_led_get_index(m_xkbInfo.keymap, XKB_LED_NAME_NUM);
+ m_xkbInfo.caps_led = xkb_map_led_get_index(m_xkbInfo.keymap, XKB_LED_NAME_CAPS);
+ m_xkbInfo.scroll_led = xkb_map_led_get_index(m_xkbInfo.keymap, XKB_LED_NAME_SCROLL);
+
+ char *keymapStr = xkb_map_get_as_string(m_xkbInfo.keymap);
+ if (keymapStr == NULL){
+ LOG_ERROR("WaylandX11InputEvent", "Failed to get string version of keymap");
+ return;
+ }
+ m_xkbInfo.keymap_size = strlen(keymapStr) + 1;
+
+ m_xkbInfo.keymap_fd = createAnonymousFile(m_xkbInfo.keymap_size);
+ if (m_xkbInfo.keymap_fd < 0){
+ LOG_WARNING("WaylandX11InputEvent", "Creating a keymap file for " <<
+ (unsigned long)m_xkbInfo.keymap_size <<
+ " bytes failed");
+ goto err_keymapStr;
+ }
+
+ m_xkbInfo.keymap_area = (char*)mmap(NULL,
+ m_xkbInfo.keymap_size,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ m_xkbInfo.keymap_fd,
+ 0);
+ if (m_xkbInfo.keymap_area == MAP_FAILED){
+ LOG_WARNING("WaylandX11InputEvent", "Failed to mmap() " <<
+ (unsigned long) m_xkbInfo.keymap_size <<
+ " bytes");
+ goto err_dev_zero;
+ }
+ strcpy(m_xkbInfo.keymap_area, keymapStr);
+ free(keymapStr);
+
+ return;
+
+err_dev_zero:
+ close(m_xkbInfo.keymap_fd);
+ m_xkbInfo.keymap_fd = -1;
+
+err_keymapStr:
+ free(keymapStr);
+ exit(EXIT_FAILURE);
+}
+
+void
+WaylandX11InputEvent::buildGlobalKeymap()
+{
+ if (m_xkbInfo.keymap != NULL)
+ return;
+
+ m_xkbInfo.keymap = xkb_map_new_from_names(m_xkbContext,
+ &m_xkbNames,
+ static_cast<xkb_map_compile_flags>(0));
+ if (m_xkbInfo.keymap == NULL){
+ LOG_ERROR("WaylandX11InputEvent", "Failed to compile global XKB keymap");
+ LOG_ERROR("WaylandX11InputEvent", " tried rules: " << m_xkbNames.rules <<
+ ", model: " << m_xkbNames.model <<
+ ", layout: " << m_xkbNames.layout);
+ return;
+ }
+
+ createNewKeymap();
+}
+
+int
+WaylandX11InputEvent::handleInputEvent(int /*fd*/, uint32_t mask, void *data)
+{
+ LOG_DEBUG("WaylandX11InputEvent", "handleInputEvent IN");
+
+ WaylandX11InputEvent *ins = static_cast<WaylandX11InputEvent*>(data);
+ WLEvent wlEvent;
+ xcb_generic_event_t *event;
+ xcb_motion_notify_event_t *motionNotify;
+ xcb_button_press_event_t *buttonEvent;
+ xcb_key_press_event_t *keyPress, *keyRelease;
+ InputDevice deviceType = INPUT_DEVICE_POINTER;
+ InputEventState state = INPUT_STATE_MOTION;
+
+ int count = 0;
+ xcb_generic_event_t *prev = NULL;
+ while (x11GetNextEvent(ins->connection(), &event, mask)){
+ switch (prev ? prev->response_type & ~0x80 : 0x80){
+ case XCB_KEY_RELEASE:
+ keyRelease = (xcb_key_press_event_t*)prev;
+ keyPress = (xcb_key_press_event_t*)event;
+ if ((event->response_type & ~0x80) == XCB_KEY_PRESS &&
+ keyRelease->time == keyPress->time &&
+ keyRelease->detail == keyPress->detail){
+ // Don't deliver the held key release event or
+ // the new key press even.
+ free(event);
+ free(prev);
+ prev = NULL;
+ continue;
+ } else {
+ free(prev);
+ prev = NULL;
+ break;
+ }
+ case XCB_FOCUS_IN:
+ free(prev);
+ prev = NULL;
+ break;
+ default:
+ // No previous event held
+ break;
+ }
+
+ memset(&wlEvent, 0x00, sizeof(WLEvent));
+
+ switch (event->response_type & ~0x80){
+ case XCB_KEY_PRESS:
+ LOG_DEBUG("WaylandX11InputEvent", "[EVENT] XCB_KEY_PRESS");
+ keyPress = (xcb_key_press_event_t *)event;
+ wlEvent.keyCode = keyPress->detail - 8;
+ wlEvent.keyState = WL_KEYBOARD_KEY_STATE_PRESSED;
+
+ deviceType = INPUT_DEVICE_KEYBOARD;
+ state = INPUT_STATE_PRESSED;
+ break;
+ case XCB_KEY_RELEASE:
+ LOG_DEBUG("WaylandX11InputEvent", "[EVENT] XCB_KEY_RELEASE");
+ keyRelease = (xcb_key_press_event_t *)event;
+ wlEvent.keyCode = keyRelease->detail - 8;
+ wlEvent.keyState = WL_KEYBOARD_KEY_STATE_RELEASED;
+
+ deviceType = INPUT_DEVICE_KEYBOARD;
+ state = INPUT_STATE_RELEASED;
+ break;
+ case XCB_BUTTON_PRESS:
+ LOG_DEBUG("WaylandX11InputEvent", "[EVENT] XCB_BUTTON_PRESS");
+ if (!getButtonEvent(event, &wlEvent, 1)){
+ continue; // not supported button event
+ }
+ buttonEvent = (xcb_button_press_event_t *)event;
+ wlEvent.x = buttonEvent->event_x;
+ wlEvent.y = buttonEvent->event_y;
+ wlEvent.buttonState = WL_POINTER_BUTTON_STATE_PRESSED;
+
+ deviceType = INPUT_DEVICE_POINTER;
+ state = INPUT_STATE_PRESSED;
+ break;
+ case XCB_BUTTON_RELEASE:
+ LOG_DEBUG("WaylandX11InputEvent", "[EVENT] XCB_BUTTON_RELEASE");
+ if (!getButtonEvent(event, &wlEvent, 0)){
+ continue; // not suported button event
+ }
+ buttonEvent = (xcb_button_press_event_t *)event;
+ wlEvent.x = buttonEvent->event_x;
+ wlEvent.y = buttonEvent->event_y;
+ wlEvent.buttonState = WL_POINTER_BUTTON_STATE_RELEASED;
+
+ deviceType = INPUT_DEVICE_POINTER;
+ state = INPUT_STATE_RELEASED;
+ break;
+ case XCB_MOTION_NOTIFY:
+ LOG_DEBUG("WaylandX11InputEvent", "[EVENT] XCB_MOTION_NOTIFY");
+ motionNotify = (xcb_motion_notify_event_t *)event;
+ wlEvent.x = motionNotify->event_x;
+ wlEvent.y = motionNotify->event_y;
+
+ deviceType = INPUT_DEVICE_POINTER;
+ state = INPUT_STATE_MOTION;
+ break;
+ case XCB_EXPOSE:
+ case XCB_ENTER_NOTIFY:
+ case XCB_LEAVE_NOTIFY:
+ case XCB_CLIENT_MESSAGE:
+ case XCB_FOCUS_OUT:
+ default:
+ LOG_DEBUG("WaylandX11InputEvent", "[EVENT] Not supported (" <<
+ (event->response_type & ~0x80) << ")");
+ if (prev != event){
+ free(event);
+ }
+ continue;
+ }
+
+ ++count;
+ if (prev != event){
+ free(event);
+ }
+ }
+
+ if (count == 0){
+ goto rtn;
+ }
+
+ switch (prev ? prev->response_type & ~0x80 : 0x80){
+ case XCB_KEY_RELEASE:
+ keyRelease = (xcb_key_press_event_t*)prev;
+ wlEvent.keyCode = keyRelease->detail - 8;
+ wlEvent.keyState = WL_KEYBOARD_KEY_STATE_RELEASED;
+ deviceType = INPUT_DEVICE_KEYBOARD;
+ state = INPUT_STATE_RELEASED;
+ free(prev);
+ prev = NULL;
+ break;
+ default:
+ break;
+ }
+
+ ins->windowSystem().manageWLInputEvent(deviceType, state, &wlEvent);
+
+rtn:
+ LOG_DEBUG("WaylandX11InputEvent", "handleInputEvent OUT");
+ return count;
+}
PATHS /usr/lib /usr/local/lib
)
+FIND_PATH(XKB_INCLUDE_DIR /xkbcommon.h
+/usr/include/xkbcommon /usr/local/include/xkbcommon
+)
+
+FIND_LIBRARY(XKB_LIBRARIES
+NAMES xkbcommon
+PATHS /usr/lib /usr/local/lib
+)
+
SET( WAYLAND_FOUND "NO" )
IF(WAYLAND_CLIENT_LIBRARIES AND WAYLAND_SERVER_LIBRARIES)
SET( WAYLAND_FOUND "YES" )
message(STATUS "Found Wayland-Egl libs: ${WAYLAND_EGL_LIBRARIES}")
message(STATUS "Found ffi need by Wayland libs: ${FFI_LIBRARIES}")
message(STATUS "Found ffi need by Wayland includes: ${FFI_INCLUDE_DIR}")
+ message(STATUS "Found xkbcommon need by Wayland libs: ${XKB_LIBRARIES}")
+ message(STATUS "Found xkbcommon need by Wayland includes: ${XKB_INCLUDE_DIR}")
ENDIF(WAYLAND_CLIENT_LIBRARIES AND WAYLAND_SERVER_LIBRARIES)
MARK_AS_ADVANCED(
WAYLAND_EGL_LIBRARIES
FFI_INCLUDE_DIR
FFI_LIBRARIES
+ XKB_LIBRARIES
+ XKB_INCLUDE_DIR
)