[PATCH 6/6] DirectFB integration

Denis Oliver Kropp dfbdok at gmail.com
Fri Oct 25 00:11:18 CEST 2013


DirectFB: Add weston-dfb-adapter to integrate native
 DirectFB clients into Wayland protocol

This component might be moved into Weston server process.

Actually, at the moment this adapter should work with non-Weston
compositors as well, as long as they are using the wayland-dfb
library which is part of DirectFB.
---
 clients/Makefile.am            |   12 +
 clients/dfb_test1.cpp          |  290 ++++++++++
 clients/weston-dfb-adapter.cpp | 1220
++++++++++++++++++++++++++++++++++++++++
 3 files changed, 1522 insertions(+)
 create mode 100644 clients/dfb_test1.cpp
 create mode 100644 clients/weston-dfb-adapter.cpp

diff --git a/clients/Makefile.am b/clients/Makefile.am
index 4f9dc48..edf8489 100644
--- a/clients/Makefile.am
+++ b/clients/Makefile.am
@@ -1,5 +1,7 @@
 bin_PROGRAMS = \
  weston-info \
+ weston-dfb-adapter \
+ weston-dfb-test1 \
  $(terminal)

 demo_clients = \
@@ -202,6 +204,16 @@ weston_info_SOURCES = \
  ../shared/os-compatibility.h
 weston_info_LDADD = $(WESTON_INFO_LIBS)

+weston_dfb_test1_SOURCES = \
+ dfb_test1.cpp
+weston_dfb_test1_CXXFLAGS = $(DIRECTFB_COMPOSITOR_CFLAGS)
+weston_dfb_test1_LDADD = $(DIRECTFB_COMPOSITOR_LIBS) $(CLIENT_LIBS)
+
+weston_dfb_adapter_SOURCES = \
+ weston-dfb-adapter.cpp
+weston_dfb_adapter_CXXFLAGS = $(DIRECTFB_COMPOSITOR_CFLAGS)
+weston_dfb_adapter_LDADD = $(DIRECTFB_COMPOSITOR_LIBS) $(CLIENT_LIBS)
+
 weston_desktop_shell_SOURCES = \
  desktop-shell.c \
  desktop-shell-client-protocol.h \
diff --git a/clients/dfb_test1.cpp b/clients/dfb_test1.cpp
new file mode 100644
index 0000000..cbbebb7
--- /dev/null
+++ b/clients/dfb_test1.cpp
@@ -0,0 +1,290 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
+ * Copyright © 2012 Raspberry Pi Foundation
+ * Copyright © 2013 Philip Withnall
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee,
provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * 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 "config.h"
+
+#include <++dfb.h>
+
+#include <++dfb_mangle.h>
+#include <wayland-dfb.h>
+#include <++dfb_unmangle.h>
+
+#include <stdexcept>
+
+#include <wayland-client.h>
+
+#include <wayland-dfb-client-protocol.h>
+
+
+extern "C" {
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+}
+
+
+D_DEBUG_DOMAIN( Weston_DFBTest1, "Weston/DFBTest1", "Weston DFBTest1" );
+
+/**********************************************************************************************************************/
+
+class DFBTest1 {
+public:
+ struct wl_display       *display;
+ struct wl_registry      *registry;
+ struct wl_compositor    *compositor;
+ struct wl_shell         *shell;
+ struct wl_dfb           *wl_dfb;
+ struct wl_dfb_buffer    *buffer;
+ struct wl_surface       *wl_surface;
+ struct wl_shell_surface *shell_surface;
+
+ IDirectFB                dfb;
+ IDirectFBDisplayLayer    layer;
+ IDirectFBWindow          window;
+ IDirectFBSurface         surface;
+ DFBSurfaceID             surface_id;
+ int                      width, height;
+
+ DFBTest1()
+ :
+ configured( false ),
+ fullscreen( false )
+ {
+ }
+
+ ~DFBTest1()
+ {
+ }
+
+ void init();
+ void redraw();
+ void run();
+ void toggle_fullscreen( bool fullscreen );
+
+ bool configured;
+ bool fullscreen;
+};
+
+/**********************************************************************************************************************/
+
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+       uint32_t name, const char *interface, uint32_t version)
+{
+ DFBTest1 *test = (DFBTest1*) data;
+
+ D_DEBUG_AT( Weston_DFBTest1, "WindowAdapter::%s( %p, %s )\n",
__FUNCTION__, test, interface );
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ test->compositor = (wl_compositor*)wl_registry_bind( registry, name,
&wl_compositor_interface, 1 );
+ D_ASSERT( test->compositor != NULL );
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ test->shell = (wl_shell*)wl_registry_bind( registry, name,
&wl_shell_interface, 1 );
+ D_ASSERT( test->shell != NULL );
+ } else if (strcmp(interface, "wl_dfb") == 0) {
+ test->wl_dfb = (wl_dfb*)wl_registry_bind( registry, name,
&wl_dfb_interface, 1 );
+ D_ASSERT( test->wl_dfb != NULL );
+ }
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+      uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+/**********************************************************************************************************************/
+
+static void
+handle_ping(void *data, struct wl_shell_surface *shell_surface,
+    uint32_t serial)
+{
+ D_DEBUG_AT( Weston_DFBTest1, "%s( %p, shell_surface %p, serial %u )\n",
__FUNCTION__, data, shell_surface, serial );
+
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void
+handle_configure(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+ D_DEBUG_AT( Weston_DFBTest1, "%s( %p, shell_surface %p, edges 0x%04x,
width %d, height %d )\n",
+    __FUNCTION__, data, shell_surface, edges, width, height );
+}
+
+static void
+handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
+{
+ D_DEBUG_AT( Weston_DFBTest1, "%s( %p, shell_surface %p )\n",
__FUNCTION__, data, shell_surface );
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+ handle_ping,
+ handle_configure,
+ handle_popup_done
+};
+
+/**********************************************************************************************************************/
+
+static void
+configure_callback(void *data, struct wl_callback *callback, uint32_t
 time)
+{
+ DFBTest1 *test = (DFBTest1*) data;
+
+ D_DEBUG_AT( Weston_DFBTest1, "%s( %p, callback %p )\n", __FUNCTION__,
data, callback );
+
+ wl_callback_destroy( callback );
+
+ test->configured = 1;
+
+// if (test->callback == NULL)
+ test->redraw();
+}
+
+static struct wl_callback_listener configure_callback_listener = {
+ configure_callback,
+};
+
+/**********************************************************************************************************************/
+
+void
+DFBTest1::init()
+{
+ D_DEBUG_AT( Weston_DFBTest1, "DFBTest1::%s( %p )\n", __FUNCTION__, this );
+
+ display = wl_display_connect( NULL );
+ if (!display)
+ throw std::runtime_error( "wl_display_connect_to_fd failed" );
+
+ registry = wl_display_get_registry( display );
+
+ wl_registry_add_listener( registry, &registry_listener, this );
+
+ wl_display_dispatch( display );
+
+
+ wl_surface    = wl_compositor_create_surface( compositor );
+ shell_surface = wl_shell_get_shell_surface( shell, wl_surface );
+
+ wl_shell_surface_add_listener( shell_surface, &shell_surface_listener,
this );
+
+
+ wl_shell_surface_set_title( shell_surface, "DFB Test" );
+
+ toggle_fullscreen( false );
+
+
+
+ dfb     = DirectFB::Create();
+ layer   = dfb.GetDisplayLayer( DLID_PRIMARY );
+
+ DFBWindowDescription desc;
+
+ desc.flags  = (DFBWindowDescriptionFlags)(DWDESC_WIDTH | DWDESC_HEIGHT);
+ desc.width  = 300;
+ desc.height = 300;
+
+ window  = layer.CreateWindow( desc );
+ surface = window.GetSurface();
+
+ surface.AllowAccess( "*" );
+
+ surface_id = surface.GetID();
+
+ surface.GetSize( &width, &height );
+}
+
+void
+DFBTest1::redraw()
+{
+ D_DEBUG_AT( Weston_DFBTest1, "DFBTest1::%s( %p )\n", __FUNCTION__, this );
+
+ buffer = wl_dfb_create_buffer( wl_dfb, surface_id, 0, 0 );
+
+ wl_surface_attach( wl_surface, (struct wl_buffer*) buffer, 0, 0 );
+
+ wl_surface_damage( wl_surface, 0, 0, width, height );
+ wl_surface_commit( wl_surface );
+}
+
+void
+DFBTest1::run()
+{
+ D_DEBUG_AT( Weston_DFBTest1, "DFBTest1::%s( %p )\n", __FUNCTION__, this );
+
+ while (true) {
+ wl_display_dispatch( display );
+ }
+}
+
+void
+DFBTest1::toggle_fullscreen( bool fullscreen )
+{
+ struct wl_callback *callback;
+
+ this->fullscreen = fullscreen;
+ this->configured = false;
+
+ if (fullscreen) {
+ wl_shell_surface_set_fullscreen( shell_surface,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ 0, NULL );
+ } else {
+ wl_shell_surface_set_toplevel( shell_surface );
+
+ handle_configure( this, shell_surface, 0, width, height );
+ }
+
+ callback = wl_display_sync( display );
+
+ wl_callback_add_listener( callback, &configure_callback_listener, this );
+}
+
+/**********************************************************************************************************************/
+
+int
+main( int argc, char *argv[] )
+{
+ DFBTest1 test1;
+
+ DirectFB::Init( &argc, &argv );
+
+ test1.init();
+
+ test1.run();
+
+ return 0;
+}
diff --git a/clients/weston-dfb-adapter.cpp b/clients/weston-dfb-adapter.cpp
new file mode 100644
index 0000000..a21fa38
--- /dev/null
+++ b/clients/weston-dfb-adapter.cpp
@@ -0,0 +1,1220 @@
+/*
+ * Copyright © 2008-2011 Kristian Høgsberg
+ * Copyright © 2011 Intel Corporation
+ * Copyright © 2012 Raspberry Pi Foundation
+ * Copyright © 2013 Philip Withnall
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and
+ * its documentation for any purpose is hereby granted without fee,
provided
+ * that the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the copyright holders not be used in
+ * advertising or publicity pertaining to distribution of the software
+ * without specific, written prior permission.  The copyright holders make
+ * no representations about the suitability of this software for any
+ * purpose.  It is provided "as is" without express or implied warranty.
+ *
+ * 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 "config.h"
+
+#include <++dfb.h>
+
+#include <++dfb_mangle.h>
+#include <wayland-dfb.h>
+#include <++dfb_unmangle.h>
+
+#include <stdexcept>
+
+#include <wayland-client.h>
+
+#include <wayland-dfb-client-protocol.h>
+
+
+#include <directfb_windows.h>
+
+extern "C" {
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include <sys/poll.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <linux/input.h>
+}
+
+
+
+D_DEBUG_DOMAIN( DFBWayland_Adapter, "DFBWayland/Adapter", "DirectFB
Wayland Adapter" );
+
+/**********************************************************************************************************************/
+
+class Adapter;
+
+/**********************************************************************************************************************/
+
+class Client {
+public:
+ Adapter                 &adapter;
+
+ struct wl_display       *display;
+ struct wl_registry      *registry;
+
+ struct wl_compositor    *compositor;
+ struct wl_shell         *shell;
+ struct wl_seat          *seat;
+ struct wl_pointer       *pointer;
+ struct wl_keyboard      *keyboard;
+ struct wl_touch         *touch;
+ struct wl_dfb           *wl_dfb;
+
+ Client( Adapter &adapter )
+ :
+ adapter( adapter ),
+ display( NULL ),
+ registry( NULL ),
+ compositor( NULL ),
+ shell( NULL ),
+ seat( NULL ),
+ pointer( NULL ),
+ keyboard( NULL ),
+ touch( NULL ),
+ wl_dfb( NULL )
+ {
+ }
+
+ ~Client()
+ {
+ }
+
+ void init();
+ void run();
+
+ void check();
+};
+
+/**********************************************************************************************************************/
+
+class DFBWindow {
+public:
+ Adapter                 &adapter;
+
+ IDirectFBWindow          window;
+ IDirectFBSurface         surface;
+
+ DFBWindowID              window_id;
+ DFBSurfaceID             surface_id;
+
+ struct wl_dfb_buffer    *buffer;
+ struct wl_surface       *wl_surface;
+ struct wl_shell_surface *shell_surface;
+
+ int                      width;
+ int                      height;
+
+ u32                      wl_surface_id;
+
+
+public:
+ DFBWindow( Adapter     &adapter,
+   DFBWindowID  window_id );
+ ~DFBWindow();
+
+private:
+public:
+ void integrate();
+
+
+ void HandleSurfaceEvent( const DFBSurfaceEvent &event );
+
+ void toggle_fullscreen( bool fullscreen );
+
+ bool configured;
+ bool fullscreen;
+
+ void push_buffer( u32 flip_count );
+
+
+ void dispatchEnter( int x, int y );
+ void dispatchLeave();
+ void dispatchMotion( int x, int y );
+ void dispatchButton( DFBInputDeviceButtonIdentifier button,
+     bool                           pressed );
+ void dispatchWheel( int v );
+
+ void dispatchKey( int                   key_code,
+  bool                  pressed );
+
+ int                      pointer_x;
+ int                      pointer_y;
+};
+
+/**********************************************************************************************************************/
+
+class Adapter {
+public:
+ IDirectFB                dfb;
+ IDirectFBEventBuffer     events;
+ IDirectFBDisplayLayer    layer;
+ IDirectFBWindows        *dfb_windows;
+
+ Client                   client;
+
+ std::map<DFBWindowID,std::shared_ptr<DFBWindow> >  windows;
+ std::map<DFBSurfaceID,std::shared_ptr<DFBWindow> > surfaces;
+ std::map<u32,std::shared_ptr<DFBWindow> >          wl_surfaces;
+
+ std::shared_ptr<DFBWindow>                         pointer_focus;
+ std::shared_ptr<DFBWindow>                         keyboard_focus;
+
+
+ Adapter();
+ ~Adapter();
+
+ void init();
+ void run();
+ void shutdown();
+
+ void AddWindow( DFBWindowID window_id );
+ void RemoveWindow( DFBWindowID window_id );
+
+ void HandleWindowEvent( const DFBWindowEvent &event );
+ void HandleSurfaceEvent( const DFBSurfaceEvent &event );
+
+
+ /*
+ * Pointer
+ */
+ void handleEnter( struct wl_pointer *pointer,
+  struct wl_surface *surface,
+  wl_fixed_t         sx_w,
+  wl_fixed_t         sy_w );
+
+ void handleLeave( struct wl_pointer *pointer,
+  struct wl_surface *surface );
+
+ void handleMotion( struct wl_pointer *pointer,
+   wl_fixed_t         sx_w,
+   wl_fixed_t         sy_w );
+
+ void handleButton( struct wl_pointer *pointer,
+   uint32_t           button,
+   uint32_t           state_w );
+
+ void handleAxis( struct wl_pointer *pointer,
+ uint32_t           axis,
+ wl_fixed_t         value );
+
+
+ /*
+ * Keyboard
+ */
+ void handleEnter( struct wl_keyboard *keyboard,
+  struct wl_surface  *surface );
+
+ void handleLeave( struct wl_keyboard *keyboard,
+  struct wl_surface  *surface );
+
+ void handleKey  ( struct wl_keyboard *keyboard,
+  uint32_t            key,
+  uint32_t            state_w );
+
+
+ DFBWindowsWatcher watcher;
+
+ void Watcher_WindowAdd( const DFBWindowInfo *info );
+ void Watcher_WindowRemove( DFBWindowID  window_id );
+ void Watcher_WindowConfig( DFBWindowID            window_id,
+   const DFBWindowConfig *config,
+   DFBWindowConfigFlags   flags );
+ void Watcher_WindowState( DFBWindowID           window_id,
+  const DFBWindowState *state );
+ void Watcher_WindowRestack( DFBWindowID   window_id,
+    unsigned int  index );
+ void Watcher_WindowFocus( DFBWindowID  window_id );
+};
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static void
+registry_handle_global(void *data, struct wl_registry *registry,
+       uint32_t name, const char *interface, uint32_t version)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, %s )\n", __FUNCTION__,
client, interface );
+
+ if (strcmp(interface, "wl_compositor") == 0) {
+ client->compositor = (wl_compositor*)wl_registry_bind( registry, name,
&wl_compositor_interface, 1 );
+ D_ASSERT( client->compositor != NULL );
+ } else if (strcmp(interface, "wl_seat") == 0) {
+ client->seat = (wl_seat*)wl_registry_bind( registry, name,
&wl_seat_interface, 1 );
+ D_ASSERT( client->shell != NULL );
+ } else if (strcmp(interface, "wl_shell") == 0) {
+ client->shell = (wl_shell*)wl_registry_bind( registry, name,
&wl_shell_interface, 1 );
+ D_ASSERT( client->shell != NULL );
+ } else if (strcmp(interface, "wl_dfb") == 0) {
+ client->wl_dfb = (wl_dfb*)wl_registry_bind( registry, name,
&wl_dfb_interface, 1 );
+ D_ASSERT( client->wl_dfb != NULL );
+ }
+}
+
+static void
+registry_handle_global_remove(void *data, struct wl_registry *registry,
+      uint32_t name)
+{
+}
+
+static const struct wl_registry_listener registry_listener = {
+ registry_handle_global,
+ registry_handle_global_remove
+};
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static void
+pointer_handle_enter(void *data, struct wl_pointer *pointer,
+     uint32_t serial, struct wl_surface *surface,
+     wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, pointer %p, surface %p
)\n", __FUNCTION__, client, pointer, surface );
+
+ if (!surface) {
+ /* enter event for a window we've just destroyed */
+ return;
+ }
+
+ client->adapter.handleEnter( pointer, surface, sx_w, sy_w );
+}
+
+static void
+pointer_handle_leave(void *data, struct wl_pointer *pointer,
+     uint32_t serial, struct wl_surface *surface)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, pointer %p )\n",
__FUNCTION__, client, pointer );
+
+ client->adapter.handleLeave( pointer, surface );
+}
+
+static void
+pointer_handle_motion(void *data, struct wl_pointer *pointer,
+      uint32_t time, wl_fixed_t sx_w, wl_fixed_t sy_w)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, pointer %p )\n",
__FUNCTION__, client, pointer );
+
+ client->adapter.handleMotion( pointer, sx_w, sy_w );
+}
+
+static void
+pointer_handle_button(void *data, struct wl_pointer *pointer, uint32_t
serial,
+      uint32_t time, uint32_t button, uint32_t state_w)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, pointer %p )\n",
__FUNCTION__, client, pointer );
+
+ client->adapter.handleButton( pointer, button, state_w );
+}
+
+static void
+pointer_handle_axis(void *data, struct wl_pointer *pointer,
+    uint32_t time, uint32_t axis, wl_fixed_t value)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, pointer %p )\n",
__FUNCTION__, client, pointer );
+
+ client->adapter.handleAxis( pointer, axis, value );
+}
+
+static const struct wl_pointer_listener pointer_listener = {
+ pointer_handle_enter,
+ pointer_handle_leave,
+ pointer_handle_motion,
+ pointer_handle_button,
+ pointer_handle_axis,
+};
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static void
+keyboard_handle_keymap(void *data, struct wl_keyboard *keyboard,
+       uint32_t format, int fd, uint32_t size)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, keyboard %p )\n",
__FUNCTION__, client, keyboard );
+
+#if 0
+ char *map_str;
+
+ if (!data) {
+ close(fd);
+ return;
+ }
+
+ if (format != WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1) {
+ close(fd);
+ return;
+ }
+
+ map_str = (char*) mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
+ if (map_str == MAP_FAILED) {
+ close(fd);
+ return;
+ }
+
+ D_INFO("Keymap: '%s'\n", map_str);
+
+ client->xkb.keymap = xkb_map_new_from_string(client->display->xkb_context,
+     map_str,
+     XKB_KEYMAP_FORMAT_TEXT_V1,
+     0);
+ munmap(map_str, size);
+ close(fd);
+
+
+ if (!client->xkb.keymap) {
+ fprintf(stderr, "failed to compile keymap\n");
+ return;
+ }
+
+ client->xkb.state = xkb_state_new(client->xkb.keymap);
+ if (!client->xkb.state) {
+ fprintf(stderr, "failed to create XKB state\n");
+ xkb_map_unref(client->xkb.keymap);
+ client->xkb.keymap = NULL;
+ return;
+ }
+
+ client->xkb.control_mask =
+ 1 << xkb_map_mod_get_index(client->xkb.keymap, "Control");
+ client->xkb.alt_mask =
+ 1 << xkb_map_mod_get_index(client->xkb.keymap, "Mod1");
+ client->xkb.shift_mask =
+ 1 << xkb_map_mod_get_index(client->xkb.keymap, "Shift");
+#endif
+}
+
+static void
+keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
+      uint32_t serial, struct wl_surface *surface,
+      struct wl_array *keys)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, keyboard %p )\n",
__FUNCTION__, client, keyboard );
+
+ client->adapter.handleEnter( keyboard, surface );
+}
+
+static void
+keyboard_handle_leave(void *data, struct wl_keyboard *keyboard,
+      uint32_t serial, struct wl_surface *surface)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, keyboard %p )\n",
__FUNCTION__, client, keyboard );
+
+ client->adapter.handleLeave( keyboard, surface );
+}
+
+static void
+keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
+    uint32_t serial, uint32_t time, uint32_t key,
+    uint32_t state_w)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, keyboard %p )\n",
__FUNCTION__, client, keyboard );
+
+ client->adapter.handleKey( keyboard, key, state_w );
+}
+
+static void
+keyboard_handle_modifiers(void *data, struct wl_keyboard *keyboard,
+  uint32_t serial, uint32_t mods_depressed,
+  uint32_t mods_latched, uint32_t mods_locked,
+  uint32_t group)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, keyboard %p )\n",
__FUNCTION__, client, keyboard );
+
+}
+
+static const struct wl_keyboard_listener keyboard_listener = {
+ keyboard_handle_keymap,
+ keyboard_handle_enter,
+ keyboard_handle_leave,
+ keyboard_handle_key,
+ keyboard_handle_modifiers,
+};
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static void
+seat_handle_capabilities(void *data,
+ struct wl_seat *wl_seat,
+ uint32_t capabilities)
+{
+ Client *client = (Client*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, seat %p, caps 0x%08x
)\n", __FUNCTION__, client, wl_seat, capabilities );
+
+ if ((capabilities & WL_SEAT_CAPABILITY_POINTER) && !client->pointer) {
+ client->pointer = wl_seat_get_pointer( wl_seat );
+ wl_pointer_add_listener( client->pointer, &pointer_listener, client );
+ } else if (!(capabilities & WL_SEAT_CAPABILITY_POINTER) &&
client->pointer) {
+ wl_pointer_destroy( client->pointer );
+ client->pointer = NULL;
+ }
+
+ if ((capabilities & WL_SEAT_CAPABILITY_KEYBOARD) && !client->keyboard) {
+ client->keyboard = wl_seat_get_keyboard( wl_seat );
+ wl_keyboard_add_listener(client->keyboard, &keyboard_listener,
+ client);
+ } else if (!(capabilities & WL_SEAT_CAPABILITY_KEYBOARD) &&
client->keyboard) {
+ wl_keyboard_destroy(client->keyboard);
+ client->keyboard = NULL;
+ }
+
+//     if ((capabilities & WL_SEAT_CAPABILITY_TOUCH) && !client->touch) {
+//          client->touch = wl_seat_get_touch( wl_seat );
+//          wl_touch_add_listener(client->touch, &touch_listener, client);
+//     }
+//     else if (!(capabilities & WL_SEAT_CAPABILITY_TOUCH) &&
client->touch) {
+//          wl_touch_destroy(client->touch);
+//          client->touch = NULL;
+//     }
+}
+
+static const struct wl_seat_listener seat_listener = {
+ seat_handle_capabilities,
+};
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+void
+Client::init()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Client::%s( %p )\n", __FUNCTION__, this
);
+
+ display = wl_display_connect( NULL );
+ if (!display)
+ throw std::runtime_error( "wl_display_connect_to_fd failed" );
+
+ registry = wl_display_get_registry( display );
+
+ wl_registry_add_listener( registry, &registry_listener, this );
+
+ wl_display_dispatch( display );
+
+ wl_seat_add_listener( seat, &seat_listener, this );
+}
+
+void
+Client::run()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Client::%s( %p )\n", __FUNCTION__, this
);
+
+ while (true)
+ wl_display_dispatch( display );
+}
+
+void
+Client::check()
+{
+ //D_DEBUG_AT( DFBWayland_Adapter, "Client::%s( %p )\n", __FUNCTION__,
this );
+
+ wl_display_flush( display );
+
+
+ struct pollfd pfd[1];
+
+ pfd[0].fd = wl_display_get_fd( display );
+ pfd[0].events = POLLIN;
+
+ int ret = poll(pfd, 1, 10);
+ switch (ret) {
+ case -1:
+ D_PERROR( "DFBWayland/Adapter: poll\n" );
+ return;
+
+ case 0:
+ return;
+ }
+
+ wl_display_dispatch( display );
+}
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static void
+handle_ping(void *data, struct wl_shell_surface *shell_surface,
+    uint32_t serial)
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "%s( %p, shell_surface %p, serial %u
)\n", __FUNCTION__, data, shell_surface, serial );
+
+ wl_shell_surface_pong(shell_surface, serial);
+}
+
+static void
+handle_configure(void *data, struct wl_shell_surface *shell_surface,
+ uint32_t edges, int32_t width, int32_t height)
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "%s( %p, shell_surface %p, edges 0x%04x,
width %d, height %d )\n",
+    __FUNCTION__, data, shell_surface, edges, width, height );
+}
+
+static void
+handle_popup_done(void *data, struct wl_shell_surface *shell_surface)
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "%s( %p, shell_surface %p )\n",
__FUNCTION__, data, shell_surface );
+}
+
+static const struct wl_shell_surface_listener shell_surface_listener = {
+ handle_ping,
+ handle_configure,
+ handle_popup_done
+};
+
+/**********************************************************************************************************************/
+
+static void
+configure_callback(void *data, struct wl_callback *callback, uint32_t
 time)
+{
+ DFBWindow *window = (DFBWindow*) data;
+
+ D_DEBUG_AT( DFBWayland_Adapter, "%s( %p, callback %p )\n", __FUNCTION__,
data, callback );
+
+ wl_callback_destroy( callback );
+
+ window->configured = true;
+
+ window->push_buffer( 0 );
+}
+
+static struct wl_callback_listener configure_callback_listener = {
+ configure_callback,
+};
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+DFBWindow::DFBWindow( Adapter &adapter,
+      DFBWindowID    window_id )
+ :
+ adapter( adapter ),
+ window_id( window_id ),
+ buffer( NULL ),
+ wl_surface( NULL ),
+ shell_surface( NULL ),
+ wl_surface_id( 0 ),
+ configured( false ),
+ fullscreen( false ),
+ pointer_x( 0 ),
+ pointer_y( 0 )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, id %u )\n",
__FUNCTION__, this, window_id );
+
+ window     = adapter.layer.GetWindow( window_id );
+ surface    = window.GetSurface();
+ surface_id = surface.GetID();
+
+ surface.GetSize( &width, &height );
+
+ surface.iface->AttachEventBuffer( surface.iface, adapter.events.iface );
+
+ surface.iface->MakeClient( surface.iface );
+}
+
+DFBWindow::~DFBWindow()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p ) <- id %u\n",
__FUNCTION__, this, window_id );
+}
+
+void
+DFBWindow::integrate()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p ) <- id %u\n",
__FUNCTION__, this, window_id );
+
+ wl_surface    = wl_compositor_create_surface( adapter.client.compositor );
+ wl_surface_id = wl_proxy_get_id((wl_proxy*)wl_surface);
+
+ shell_surface = wl_shell_get_shell_surface( adapter.client.shell,
wl_surface );
+
+ wl_shell_surface_add_listener( shell_surface, &shell_surface_listener,
this );
+
+ wl_shell_surface_set_title( shell_surface, "DFB Test" );
+
+ toggle_fullscreen( false );
+}
+
+void
+DFBWindow::HandleSurfaceEvent( const DFBSurfaceEvent &event )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, event %p ) <- type
0x%04x\n", __FUNCTION__, this, &event, event.type );
+
+ switch (event.type) {
+ case DSEVT_UPDATE: {
+ D_DEBUG_AT( DFBWayland_Adapter, "  -> UPDATE %u %d,%d-%dx%d %d\n",
+    event.surface_id, DFB_RECTANGLE_VALS_FROM_REGION( &event.update ),
event.flip_count );
+
+ surface.iface->FrameAck( surface.iface, event.flip_count );
+
+ if (configured)
+ push_buffer( event.flip_count );
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+void
+DFBWindow::toggle_fullscreen( bool fullscreen )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p )\n", __FUNCTION__,
this );
+
+ struct wl_callback *callback;
+
+ this->fullscreen = fullscreen;
+ this->configured = false;
+
+ if (fullscreen) {
+ wl_shell_surface_set_fullscreen( shell_surface,
+ WL_SHELL_SURFACE_FULLSCREEN_METHOD_DEFAULT,
+ 0, NULL );
+ } else {
+ wl_shell_surface_set_toplevel( shell_surface );
+
+ handle_configure( this, shell_surface, 0, width, height );
+ }
+
+ callback = wl_display_sync( adapter.client.display );
+
+ wl_callback_add_listener( callback, &configure_callback_listener, this );
+}
+
+void
+DFBWindow::push_buffer( u32 flip_count )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, flip_count %u )\n",
__FUNCTION__, this, flip_count );
+
+//     if (buffer)
+//          wl_dfb_buffer_destroy( buffer );
+//
+//     buffer = wl_dfb_create_buffer( adapter.client.wl_dfb, surface_id,
0, 0 );
+
+ if (!buffer)
+ buffer = wl_dfb_create_buffer( adapter.client.wl_dfb, surface_id, 0, 0 );
+
+ wl_surface_attach( wl_surface, (struct wl_buffer*) buffer, 0, 0 );
+ wl_surface_damage( wl_surface, 0, 0, width, height );
+ wl_surface_commit( wl_surface );
+}
+
+void
+DFBWindow::dispatchEnter( int x, int y )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, %d,%d )\n",
__FUNCTION__, this, x, y );
+
+ DFBWindowEvent event;
+
+ event.type  = DWET_ENTER;
+ event.flags = DWEF_NONE;
+ event.x     = x;
+ event.y     = y;
+
+ pointer_x = x;
+ pointer_y = y;
+
+ window.iface->SendEvent( window.iface, &event );
+}
+
+void
+DFBWindow::dispatchLeave()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p )\n", __FUNCTION__,
this );
+
+ DFBWindowEvent event;
+
+ event.type  = DWET_LEAVE;
+ event.flags = DWEF_NONE;
+ event.x     = pointer_x;
+ event.y     = pointer_y;
+
+ window.iface->SendEvent( window.iface, &event );
+}
+
+void
+DFBWindow::dispatchMotion( int x, int y )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, %d,%d )\n",
__FUNCTION__, this, x, y );
+
+ DFBWindowEvent event;
+
+ event.type  = DWET_MOTION;
+ event.flags = DWEF_NONE;
+ event.x     = x;
+ event.y     = y;
+
+ pointer_x = x;
+ pointer_y = y;
+
+ window.iface->SendEvent( window.iface, &event );
+}
+
+void
+DFBWindow::dispatchButton( DFBInputDeviceButtonIdentifier button,
+   bool                           pressed )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, button %d, pressed %d
)\n", __FUNCTION__, this, button, pressed );
+
+ DFBWindowEvent event;
+
+ event.type   = pressed ? DWET_BUTTONDOWN : DWET_BUTTONUP;
+ event.flags  = DWEF_NONE;
+ event.button = button;
+ event.x      = pointer_x;
+ event.y      = pointer_y;
+
+ window.iface->SendEvent( window.iface, &event );
+}
+
+void
+DFBWindow::dispatchWheel( int v )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, %d )\n",
__FUNCTION__, this, v );
+
+ DFBWindowEvent event;
+
+ event.type  = DWET_WHEEL;
+ event.flags = DWEF_NONE;
+ event.step  = v;
+ event.x     = pointer_x;
+ event.y     = pointer_y;
+
+ window.iface->SendEvent( window.iface, &event );
+}
+
+void
+DFBWindow::dispatchKey( int  key_code,
+ bool pressed )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "DFBWindow::%s( %p, key_code %d, pressed
%d )\n", __FUNCTION__, this, key_code, pressed );
+
+ DFBWindowEvent event;
+
+ event.type       = pressed ? DWET_KEYDOWN : DWET_KEYUP;
+ event.flags      = DWEF_NONE;
+ event.key_code   = key_code;
+ //event.key_id     = key_code;
+ //event.key_symbol = key_code;
+
+ window.iface->SendEvent( window.iface, &event );
+}
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+static void
+dump_config( const DFBWindowConfig *config )
+{
+ D_INFO( "  -> bounds       %d,%d-%dx%d\n", DFB_RECTANGLE_VALS(
&config->bounds ) );
+ D_INFO( "  -> opacity      %d\n", config->opacity );
+ D_INFO( "  -> cursor flags 0x%08x\n", config->cursor_flags );
+}
+
+/**********************************************************************************************************************/
+
+void
+Adapter::Watcher_WindowAdd( const DFBWindowInfo *info )
+{
+ D_INFO( "%s( ID %u )\n", __FUNCTION__, info->window_id );
+ D_INFO( "  -> caps         0x%08x\n", info->caps );
+ D_INFO( "  -> resource id  0x%016llx\n", (unsigned long long)
info->resource_id );
+ D_INFO( "  -> process id   %d\n", info->process_id );
+ D_INFO( "  -> instance id  %d\n", info->instance_id );
+ D_INFO( "  -> state        0x%08x\n", info->state.flags );
+
+ dump_config( &info->config );
+
+ if (info->resource_id == 0) {
+ AddWindow( info->window_id );
+ }
+}
+
+void
+Adapter::Watcher_WindowRemove( DFBWindowID  window_id )
+{
+ D_INFO( "%s( ID %u )\n", __FUNCTION__, window_id );
+
+ RemoveWindow( window_id );
+}
+
+void
+Adapter::Watcher_WindowConfig( DFBWindowID            window_id,
+       const DFBWindowConfig *config,
+       DFBWindowConfigFlags   flags )
+{
+ D_INFO( "%s( ID %u )\n", __FUNCTION__, window_id );
+ D_INFO( "  -> flags        0x%08x\n", flags );
+ D_INFO( "  -> cursor flags 0x%08x\n", config->cursor_flags );
+
+ dump_config( config );
+}
+
+void
+Adapter::Watcher_WindowState( DFBWindowID           window_id,
+      const DFBWindowState *state )
+{
+ D_INFO( "%s( ID %u )\n", __FUNCTION__, window_id );
+ D_INFO( "  -> flags        0x%08x\n", state->flags );
+}
+
+void
+Adapter::Watcher_WindowRestack( DFBWindowID   window_id,
+ unsigned int  index )
+{
+ D_INFO( "%s( ID %u )\n", __FUNCTION__, window_id );
+ D_INFO( "  -> index        %u\n", index );
+}
+
+void
+Adapter::Watcher_WindowFocus( DFBWindowID  window_id )
+{
+ D_INFO( "%s( ID %u )\n", __FUNCTION__, window_id );
+}
+
+/**********************************************************************************************************************/
+
+Adapter::Adapter()
+ :
+ dfb_windows( NULL ),
+ client( *this )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s()\n", __FUNCTION__ );
+
+ watcher.WindowAdd     = (__typeof__(watcher.WindowAdd    ))(
&Adapter::Watcher_WindowAdd );
+ watcher.WindowRemove  = (__typeof__(watcher.WindowRemove ))(
&Adapter::Watcher_WindowRemove );
+ watcher.WindowConfig  = (__typeof__(watcher.WindowConfig ))(
&Adapter::Watcher_WindowConfig );
+ watcher.WindowState   = (__typeof__(watcher.WindowState  ))(
&Adapter::Watcher_WindowState );
+ watcher.WindowRestack = (__typeof__(watcher.WindowRestack))(
&Adapter::Watcher_WindowRestack );
+ watcher.WindowFocus   = (__typeof__(watcher.WindowFocus  ))(
&Adapter::Watcher_WindowFocus );
+}
+
+Adapter::~Adapter()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s()\n", __FUNCTION__ );
+}
+
+void
+Adapter::init()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s()\n", __FUNCTION__ );
+
+ client.init();
+
+ dfb    = DirectFB::Create();
+ events = dfb.CreateEventBuffer();
+ layer  = dfb.GetDisplayLayer( DLID_PRIMARY );
+
+ dfb_windows = (IDirectFBWindows*) dfb.GetInterface( "IDirectFBWindows",
NULL, NULL );
+
+ dfb_windows->RegisterWatcher( dfb_windows, &watcher, this );
+}
+
+void
+Adapter::run()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s()\n", __FUNCTION__ );
+
+ while (true) {
+ client.check();
+
+ for (auto it=windows.begin(); it!=windows.end(); it++) {
+ std::shared_ptr<DFBWindow> window = (*it).second;
+
+ if (window && !window->wl_surface) {
+ window->integrate();
+
+ wl_surfaces[ window->wl_surface_id ] = window;
+ }
+ }
+
+
+ DFBEvent event;
+
+ while (events.GetEvent( &event )) {
+ switch (event.clazz) {
+ case DFEC_SURFACE:
+ HandleSurfaceEvent( event.surface );
+ break;
+ }
+ }
+ }
+}
+
+void
+Adapter::shutdown()
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s()\n", __FUNCTION__ );
+
+ dfb_windows->UnregisterWatcher( dfb_windows, this );
+
+ dfb_windows->Release( dfb_windows );
+
+ windows.clear();
+}
+
+void
+Adapter::AddWindow( DFBWindowID window_id )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %u )\n", __FUNCTION__,
window_id );
+
+ auto window = windows[window_id];
+
+ if (window) {
+ D_WARN( "window %u already added", window_id );
+ return;
+ }
+
+ window.reset( new DFBWindow( *this, window_id ) );
+
+ windows[window_id] = window;
+ surfaces[window->surface_id] = window;
+}
+
+void
+Adapter::RemoveWindow( DFBWindowID window_id )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %u )\n", __FUNCTION__,
window_id );
+
+ std::shared_ptr<DFBWindow> window = windows[window_id];
+
+ if (!window) {
+ D_WARN( "window %u not added", window_id );
+ return;
+ }
+
+ surfaces.erase( window->surface_id );
+
+ windows.erase( window_id );
+
+ if (window->wl_surface_id)
+ wl_surfaces.erase( window->wl_surface_id );
+
+ if (pointer_focus == window)
+ pointer_focus.reset();
+
+ if (keyboard_focus == window)
+ keyboard_focus.reset();
+}
+
+void
+Adapter::HandleWindowEvent( const DFBWindowEvent &event )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, event %p ) <- type
0x%04x\n", __FUNCTION__, this, &event, event.type );
+
+ switch (event.type) {
+ case DWET_POSITION_SIZE:
+ D_DEBUG_AT( DFBWayland_Adapter, "  -> POSITION_SIZE %d,%d-%dx%d\n",
+    event.x, event.y, event.w, event.h );
+ break;
+
+ default:
+ break;
+ }
+}
+
+void
+Adapter::HandleSurfaceEvent( const DFBSurfaceEvent &event )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, event %p ) <- type
0x%04x\n", __FUNCTION__, this, &event, event.type );
+
+ switch (event.type) {
+ case DSEVT_UPDATE: {
+ D_DEBUG_AT( DFBWayland_Adapter, "  -> UPDATE %u %d,%d-%dx%d %d\n",
+    event.surface_id, DFB_RECTANGLE_VALS_FROM_REGION( &event.update ),
event.flip_count );
+
+ auto window = surfaces[event.surface_id];
+
+ if (window)
+ window->HandleSurfaceEvent( event );
+ else
+ D_LOG( DFBWayland_Adapter, VERBOSE, "  -> SURFACE WITH ID %u NOT
FOUND\n", event.surface_id );
+
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+/**********************************************************************************************************************/
+
+void
+Adapter::handleEnter( struct wl_pointer *pointer,
+      struct wl_surface *surface,
+      wl_fixed_t         sx_w,
+      wl_fixed_t         sy_w )
+{
+ int sx = wl_fixed_to_int( sx_w );
+ int sy = wl_fixed_to_int( sy_w );
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, surface %p, sx %d, sy
%d )\n", __FUNCTION__, this, surface, sx, sy );
+
+ pointer_focus = wl_surfaces[ wl_proxy_get_id((wl_proxy*)surface) ];
+
+ if (pointer_focus) {
+ pointer_focus->dispatchEnter( sx, sy );
+ }
+}
+
+void
+Adapter::handleLeave( struct wl_pointer *pointer,
+      struct wl_surface *surface )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, surface %p )\n",
__FUNCTION__, this, surface );
+
+ auto window = wl_surfaces[ wl_proxy_get_id((wl_proxy*)surface) ];
+
+ D_ASSUME( pointer_focus == window );
+
+ if (pointer_focus == window) {
+ pointer_focus->dispatchLeave();
+ pointer_focus.reset();
+ }
+}
+
+void
+Adapter::handleMotion( struct wl_pointer *pointer,
+       wl_fixed_t         sx_w,
+       wl_fixed_t         sy_w )
+{
+ int sx = wl_fixed_to_int( sx_w );
+ int sy = wl_fixed_to_int( sy_w );
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, sx %d, sy %d )\n",
__FUNCTION__, this, sx, sy );
+
+ if (pointer_focus) {
+ pointer_focus->dispatchMotion( sx, sy );
+ }
+}
+
+void
+Adapter::handleButton( struct wl_pointer *pointer,
+       uint32_t           button,
+       uint32_t           state_w )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, button %d, state %d
)\n", __FUNCTION__, this, button, state_w );
+
+ if (pointer_focus) {
+ pointer_focus->dispatchButton( (DFBInputDeviceButtonIdentifier)(
DIBI_FIRST + button - BTN_LEFT ),
+       state_w == WL_POINTER_BUTTON_STATE_PRESSED );
+ }
+}
+
+void
+Adapter::handleAxis( struct wl_pointer *pointer,
+     uint32_t           axis,
+     wl_fixed_t         value )
+{
+ int v = wl_fixed_to_int( value );
+
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, axis %d, value %d )\n",
__FUNCTION__, this, axis, v );
+
+ if (pointer_focus) {
+ pointer_focus->dispatchWheel( v );
+ }
+}
+
+/**********************************************************************************************************************/
+
+void
+Adapter::handleEnter( struct wl_keyboard *keyboard,
+      struct wl_surface *surface )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, surface %p )\n",
__FUNCTION__, this, surface );
+
+ keyboard_focus = wl_surfaces[ wl_proxy_get_id((wl_proxy*)surface) ];
+}
+
+void
+Adapter::handleLeave( struct wl_keyboard *keyboard,
+      struct wl_surface *surface )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, surface %p )\n",
__FUNCTION__, this, surface );
+
+ auto window = wl_surfaces[ wl_proxy_get_id((wl_proxy*)surface) ];
+
+ D_ASSUME( keyboard_focus == window );
+
+ if (keyboard_focus == window) {
+ keyboard_focus.reset();
+ }
+}
+
+void
+Adapter::handleKey( struct wl_keyboard *keyboard,
+    uint32_t            key,
+    uint32_t            state_w )
+{
+ D_DEBUG_AT( DFBWayland_Adapter, "Adapter::%s( %p, key %d, state %d )\n",
__FUNCTION__, this, key, state_w );
+
+ if (keyboard_focus) {
+ keyboard_focus->dispatchKey( key,
+     state_w == WL_KEYBOARD_KEY_STATE_PRESSED );
+ }
+}
+
+/**********************************************************************************************************************/
+/**********************************************************************************************************************/
+
+/**********************************************************************************************************************/
+
+int
+main( int argc, char *argv[] )
+{
+ Adapter adapter;
+
+ DirectFB::Init( &argc, &argv );
+
+ adapter.init();
+
+ adapter.run();
+
+ return 0;
+}
+
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/wayland-devel/attachments/20131025/ae154e50/attachment-0001.html>


More information about the wayland-devel mailing list