Merge "add linux wayland platform"
diff --git a/src/starboard/contrib/tizen/shared/gyp_configuration.gypi b/src/starboard/contrib/tizen/shared/gyp_configuration.gypi
index 385c3d9..6e002ad 100644
--- a/src/starboard/contrib/tizen/shared/gyp_configuration.gypi
+++ b/src/starboard/contrib/tizen/shared/gyp_configuration.gypi
@@ -32,6 +32,9 @@
'cobalt_enable_jit': 0,
'linker_flags': [
+ # We don't wrap these symbols, but this ensures that they aren't
+ # linked in.
+ '-Wl,--wrap=eglGetDisplay',
],
'linker_flags_gold': [
'-O3',
diff --git a/src/starboard/contrib/tizen/shared/wayland/application_tizen.cc b/src/starboard/contrib/tizen/shared/wayland/application_tizen.cc
new file mode 100644
index 0000000..0dec35c
--- /dev/null
+++ b/src/starboard/contrib/tizen/shared/wayland/application_tizen.cc
@@ -0,0 +1,54 @@
+// Copyright 2018 Samsung Electronics. All Rights Reserved.
+//
+// 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.
+
+#include "starboard/contrib/tizen/shared/wayland/application_tizen.h"
+
+#include <string.h>
+
+#include "starboard/contrib/tizen/shared/wayland/window_internal_tizen.h"
+
+namespace starboard {
+namespace shared {
+namespace wayland {
+
+void ApplicationWaylandTizen::Initialize() {
+ elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
+ ApplicationWayland::Initialize();
+}
+
+bool ApplicationWaylandTizen::OnGlobalObjectAvailable(
+ struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version) {
+ if (!strcmp(interface, "tizen_policy")) {
+ tz_policy_ = static_cast<tizen_policy*>(wl_registry_bind(
+ registry, name, &tizen_policy_interface, SB_TIZEN_POLICY_VERSION));
+ return true;
+ }
+
+ return ApplicationWayland::OnGlobalObjectAvailable(registry, name, interface,
+ version);
+}
+
+SbWindow ApplicationWaylandTizen::CreateWindow(const SbWindowOptions* options) {
+ SbWindow window = new SbWindowPrivateTizen(
+ display_, tz_policy_, compositor_, shell_, options, video_pixel_ratio_);
+ dev_input_.SetSbWindow(window);
+ return window;
+}
+
+} // wayland
+} // shared
+} // starboard
diff --git a/src/starboard/contrib/tizen/shared/wayland/application_tizen.h b/src/starboard/contrib/tizen/shared/wayland/application_tizen.h
new file mode 100644
index 0000000..e766a81
--- /dev/null
+++ b/src/starboard/contrib/tizen/shared/wayland/application_tizen.h
@@ -0,0 +1,50 @@
+// Copyright 2018 Samsung Electronics. All Rights Reserved.
+//
+// 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.
+
+#ifndef STARBOARD_CONTRIB_TIZEN_SHARED_WAYLAND_APPLICATION_TIZEN_H_
+#define STARBOARD_CONTRIB_TIZEN_SHARED_WAYLAND_APPLICATION_TIZEN_H_
+
+#include <tizen-extension-client-protocol.h>
+
+#include "starboard/shared/wayland/application_wayland.h"
+
+namespace starboard {
+namespace shared {
+namespace wayland {
+
+class ApplicationWaylandTizen : public ApplicationWayland {
+ public:
+ ApplicationWaylandTizen() {}
+ ~ApplicationWaylandTizen() {}
+
+ // wl registry add listener
+ bool OnGlobalObjectAvailable(struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version) override;
+
+ SbWindow CreateWindow(const SbWindowOptions* options) override;
+
+ protected:
+ void Initialize() override;
+
+ private:
+ tizen_policy* tz_policy_;
+};
+
+} // wayland
+} // shared
+} // starboard
+
+#endif // STARBOARD_CONTRIB_TIZEN_SHARED_WAYLAND_APPLICATION_TIZEN_H_
diff --git a/src/starboard/contrib/tizen/shared/wayland/window_internal_tizen.cc b/src/starboard/contrib/tizen/shared/wayland/window_internal_tizen.cc
new file mode 100644
index 0000000..723050c
--- /dev/null
+++ b/src/starboard/contrib/tizen/shared/wayland/window_internal_tizen.cc
@@ -0,0 +1,75 @@
+// Copyright 2018 Samsung Electronics. All Rights Reserved.
+//
+// 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.
+
+#include "starboard/contrib/tizen/shared/wayland/window_internal_tizen.h"
+
+#include "starboard/shared/wayland/application_wayland.h"
+
+static void WindowCbVisibilityChange(void* data,
+ struct tizen_visibility* tizen_visibility
+ EINA_UNUSED,
+ uint32_t visibility) {
+#if SB_HAS(LAZY_SUSPEND)
+ if (visibility == TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED)
+ ApplicationWayland::Get()->Pause(NULL, NULL);
+ else
+ ApplicationWayland::Get()->Unpause(NULL, NULL);
+#else
+ if (visibility == TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED)
+ starboard::shared::starboard::Application::Get()->Suspend(NULL, NULL);
+ else
+ starboard::shared::starboard::Application::Get()->Unpause(NULL, NULL);
+#endif
+}
+
+static const struct tizen_visibility_listener tizen_visibility_listener = {
+ WindowCbVisibilityChange
+};
+
+SbWindowPrivateTizen::SbWindowPrivateTizen(wl_display* display,
+ tizen_policy* policy,
+ wl_compositor* compositor,
+ wl_shell* shell,
+ const SbWindowOptions* options,
+ float pixel_ratio)
+ : SbWindowPrivate(compositor, shell, options, pixel_ratio) {
+#if SB_CAN(USE_WAYLAND_VIDEO_WINDOW)
+ video_window = display;
+#else
+ video_window = elm_win_add(NULL, "Cobalt_Video", ELM_WIN_BASIC);
+ elm_win_title_set(video_window, "Cobalt_Video");
+ elm_win_autodel_set(video_window, EINA_TRUE);
+ evas_object_resize(video_window, width, height);
+ evas_object_hide(video_window);
+#endif
+ tz_policy = policy;
+ tz_visibility = tizen_policy_get_visibility(tz_policy, surface);
+ tizen_visibility_add_listener(tz_visibility, &tizen_visibility_listener,
+ this);
+ tizen_policy_activate(tz_policy, surface);
+}
+
+SbWindowPrivateTizen::~SbWindowPrivateTizen() {
+#if !SB_CAN(USE_WAYLAND_VIDEO_WINDOW)
+ evas_object_hide(video_window);
+#endif
+ video_window = NULL;
+ tizen_visibility_destroy(tz_visibility);
+}
+
+void SbWindowPrivateTizen::WindowRaise() {
+ SbWindowPrivate::WindowRaise();
+ if (tz_policy)
+ tizen_policy_raise(tz_policy, surface);
+}
diff --git a/src/starboard/contrib/tizen/shared/wayland/window_internal_tizen.h b/src/starboard/contrib/tizen/shared/wayland/window_internal_tizen.h
new file mode 100644
index 0000000..3375588
--- /dev/null
+++ b/src/starboard/contrib/tizen/shared/wayland/window_internal_tizen.h
@@ -0,0 +1,44 @@
+// Copyright 2018 Samsung Electronics. All Rights Reserved.
+//
+// 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.
+
+#ifndef STARBOARD_CONTRIB_TIZEN_SHARED_WAYLAND_WINDOW_INTERNAL_TIZEN_H_
+#define STARBOARD_CONTRIB_TIZEN_SHARED_WAYLAND_WINDOW_INTERNAL_TIZEN_H_
+
+#include <Elementary.h>
+#include <tizen-extension-client-protocol.h>
+
+#include "starboard/shared/wayland/window_internal.h"
+
+struct SbWindowPrivateTizen : SbWindowPrivate {
+ explicit SbWindowPrivateTizen(wl_display* display,
+ tizen_policy* policy,
+ wl_compositor* compositor,
+ wl_shell* shell,
+ const SbWindowOptions* options,
+ float pixel_ratio = 1.0);
+
+ ~SbWindowPrivateTizen();
+
+ void WindowRaise() override;
+
+ tizen_policy* tz_policy;
+ tizen_visibility* tz_visibility;
+#if SB_CAN(USE_WAYLAND_VIDEO_WINDOW)
+ wl_display* video_window;
+#else
+ Evas_Object* video_window;
+#endif
+};
+
+#endif // STARBOARD_CONTRIB_TIZEN_SHARED_WAYLAND_WINDOW_INTERNAL_TIZEN_H_
diff --git a/src/starboard/shared/wayland/application_wayland.cc b/src/starboard/shared/wayland/application_wayland.cc
index 06b2a28..51b93e2 100644
--- a/src/starboard/shared/wayland/application_wayland.cc
+++ b/src/starboard/shared/wayland/application_wayland.cc
@@ -17,75 +17,74 @@
#include <EGL/egl.h>
#include <poll.h>
#include <sys/eventfd.h>
+#include <string.h>
+#include <unistd.h>
#include "starboard/log.h"
#include "starboard/memory.h"
-#include "starboard/shared/wayland/dev_input.h"
+#include "starboard/shared/starboard/audio_sink/audio_sink_internal.h"
#include "starboard/shared/wayland/window_internal.h"
#include "starboard/time.h"
-// YouTube Technical Requirement 2018 (2016/11/1 - Initial draft)
-// 9.5 The device MUST dispatch the following key events, as appropriate:
-// * Window.keydown
-// * After a key is held down for 500ms, the Window.keydown event
-// MUST repeat every 50ms until a user stops holding the key down.
-// * Window.keyup
-static const SbTime kKeyHoldTime = 500 * kSbTimeMillisecond;
-static const SbTime kKeyRepeatTime = 50 * kSbTimeMillisecond;
-
namespace starboard {
namespace shared {
namespace wayland {
-// Tizen application engine using the generic queue and a tizen implementation.
+namespace {
+// registry_listener
+void GlobalObjectAvailable(void* data,
+ struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version) {
+ ApplicationWayland* app_wl = reinterpret_cast<ApplicationWayland*>(data);
+ SB_DCHECK(app_wl);
+ app_wl->OnGlobalObjectAvailable(registry, name, interface, version);
+}
+
+void GlobalObjectRemove(void*, struct wl_registry*, uint32_t) {}
+
+static struct wl_registry_listener registry_listener = {
+ &GlobalObjectAvailable,
+ &GlobalObjectRemove
+};
+
+}
+
+// Tizen application engine using the generic queue and a tizen implementation.
ApplicationWayland::ApplicationWayland(float video_pixel_ratio)
- : video_pixel_ratio_(video_pixel_ratio),
- seat_(NULL),
- keyboard_(NULL),
- key_repeat_event_id_(kSbEventIdInvalid),
- key_repeat_interval_(kKeyHoldTime),
- key_modifiers_(0) {}
+ : video_pixel_ratio_(video_pixel_ratio) {
+ SbAudioSinkPrivate::Initialize();
+}
+
+void ApplicationWayland::InjectInputEvent(SbInputData* data) {
+ Inject(new Event(kSbEventTypeInput, data,
+ &Application::DeleteDestructor<SbInputData>));
+}
+
+bool ApplicationWayland::OnGlobalObjectAvailable(struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version) {
+ if (strcmp(interface, "wl_compositor") == 0) {
+ compositor_ = static_cast<wl_compositor*>(
+ wl_registry_bind(registry, name, &wl_compositor_interface, 1));
+ return true;
+ }
+ if (strcmp(interface, "wl_shell") == 0) {
+ shell_ = static_cast<wl_shell*>(
+ wl_registry_bind(registry, name, &wl_shell_interface, 1));
+ return true;
+ }
+ return dev_input_.OnGlobalObjectAvailable(registry, name, interface, version);
+}
SbWindow ApplicationWayland::CreateWindow(const SbWindowOptions* options) {
SB_DLOG(INFO) << "CreateWindow";
- SbWindow window = new SbWindowPrivate(options, video_pixel_ratio_);
- window_ = window;
-
-// Video Plane
-#if SB_CAN(USE_WAYLAND_VIDEO_WINDOW)
- window->video_window = display_;
-#else
- window->video_window = elm_win_add(NULL, "Cobalt_Video", ELM_WIN_BASIC);
- elm_win_title_set(window->video_window, "Cobalt_Video");
- elm_win_autodel_set(window->video_window, EINA_TRUE);
- evas_object_resize(window->video_window, window->width, window->height);
- evas_object_hide(window->video_window);
-#endif
-
- // Graphics Plane
- window->surface = wl_compositor_create_surface(compositor_);
- window->shell_surface = wl_shell_get_shell_surface(shell_, window->surface);
- wl_shell_surface_add_listener(window->shell_surface, &shell_surface_listener,
- window);
-
- window->tz_visibility =
- tizen_policy_get_visibility(tz_policy_, window->surface);
- tizen_visibility_add_listener(window->tz_visibility,
- &tizen_visibility_listener, window);
- tizen_policy_activate(tz_policy_, window->surface);
- wl_shell_surface_set_title(window->shell_surface, "cobalt");
- WindowRaise();
-
- struct wl_region* region;
- region = wl_compositor_create_region(compositor_);
- wl_region_add(region, 0, 0, window->width, window->height);
- wl_surface_set_opaque_region(window->surface, region);
- wl_region_destroy(region);
-
- window->egl_window =
- wl_egl_window_create(window->surface, window->width, window->height);
-
+ SbWindow window =
+ new SbWindowPrivate(compositor_, shell_, options, video_pixel_ratio_);
+ dev_input_.SetSbWindow(window);
return window;
}
@@ -95,26 +94,13 @@
SB_DLOG(WARNING) << "wayland window destroy failed!!";
return false;
}
-
-// Video Plane
-#if !SB_CAN(USE_WAYLAND_VIDEO_WINDOW)
- evas_object_hide(window->video_window);
-#endif
- window->video_window = NULL;
-
- // Graphics Plane
- tizen_visibility_destroy(window->tz_visibility);
- wl_egl_window_destroy(window->egl_window);
- wl_shell_surface_destroy(window->shell_surface);
- wl_surface_destroy(window->surface);
-
+ dev_input_.SetSbWindow(kSbWindowInvalid);
+ delete window;
return true;
}
void ApplicationWayland::Initialize() {
SB_DLOG(INFO) << "Initialize";
- // Video Plane
- elm_policy_set(ELM_POLICY_QUIT, ELM_POLICY_QUIT_LAST_WINDOW_CLOSED);
// Graphics Plane
display_ = wl_display_connect(NULL);
@@ -133,13 +119,14 @@
void ApplicationWayland::Teardown() {
SB_DLOG(INFO) << "Teardown";
- DeleteRepeatKey();
+ dev_input_.DeleteRepeatKey();
TerminateEgl();
wl_display_flush(display_);
wl_display_disconnect(display_);
+ SbAudioSinkPrivate::TearDown();
// Close wakeup event
close(wakeup_fd_);
}
@@ -234,60 +221,6 @@
write(wakeup_fd_, &u, sizeof(uint64_t));
}
-void ApplicationWayland::CreateRepeatKey() {
- if (!key_repeat_state_) {
- return;
- }
-
- if (key_repeat_interval_) {
- key_repeat_interval_ = kKeyRepeatTime;
- }
-
- CreateKey(key_repeat_key_, key_repeat_state_, true);
-}
-
-void ApplicationWayland::DeleteRepeatKey() {
- if (key_repeat_event_id_ != kSbEventIdInvalid) {
- SbEventCancel(key_repeat_event_id_);
- key_repeat_event_id_ = kSbEventIdInvalid;
- }
-}
-
-void ApplicationWayland::CreateKey(int key, int state, bool is_repeat) {
- SbInputData* data = new SbInputData();
- SbMemorySet(data, 0, sizeof(*data));
- data->window = window_;
- data->type = (state == 0 ? kSbInputEventTypeUnpress : kSbInputEventTypePress);
- data->device_type = kSbInputDeviceTypeRemote;
- data->device_id = 1; // kKeyboardDeviceId;
- data->key = KeyCodeToSbKey(key);
- data->key_location = KeyCodeToSbKeyLocation(key);
- data->key_modifiers = key_modifiers_;
- Inject(new Event(kSbEventTypeInput, data,
- &Application::DeleteDestructor<SbInputData>));
-
- DeleteRepeatKey();
-
- if (is_repeat && state) {
- key_repeat_key_ = key;
- key_repeat_state_ = state;
- key_repeat_event_id_ = SbEventSchedule([](void* window) {
- ApplicationWayland* application =
- reinterpret_cast<ApplicationWayland*>(window);
- application->CreateRepeatKey();
- }, this, key_repeat_interval_);
- } else {
- key_repeat_interval_ = kKeyHoldTime;
- }
-}
-
-void ApplicationWayland::WindowRaise() {
- if (tz_policy_)
- tizen_policy_raise(tz_policy_, window_->surface);
- if (window_->shell_surface)
- wl_shell_surface_set_toplevel(window_->shell_surface);
-}
-
void ApplicationWayland::Pause(void* context, EventHandledCallback callback) {
Application::Pause(context, callback);
@@ -323,7 +256,7 @@
const size_t payload_size = strlen(payload) + 1;
char* copied_payload = new char[payload_size];
snprintf(copied_payload, payload_size, "%s", payload);
- Inject(new Event(kSbEventTypeLink, copiedPayload,
+ Inject(new Event(kSbEventTypeLink, copied_payload,
[](void* data) { delete[] reinterpret_cast<char*>(data); }));
}
diff --git a/src/starboard/shared/wayland/application_wayland.h b/src/starboard/shared/wayland/application_wayland.h
index 12e60ff..5bfb605 100644
--- a/src/starboard/shared/wayland/application_wayland.h
+++ b/src/starboard/shared/wayland/application_wayland.h
@@ -15,18 +15,19 @@
#ifndef STARBOARD_SHARED_WAYLAND_APPLICATION_WAYLAND_H_
#define STARBOARD_SHARED_WAYLAND_APPLICATION_WAYLAND_H_
-#include <tizen-extension-client-protocol.h>
#include <wayland-client.h>
#include <wayland-egl.h>
#include <deque>
#include "starboard/configuration.h"
+#include "starboard/event.h"
#include "starboard/input.h"
#include "starboard/mutex.h"
#include "starboard/shared/internal_only.h"
#include "starboard/shared/starboard/application.h"
#include "starboard/shared/starboard/queue_application.h"
+#include "starboard/shared/wayland/dev_input.h"
#include "starboard/types.h"
#include "starboard/window.h"
@@ -36,7 +37,7 @@
class ApplicationWayland : public shared::starboard::QueueApplication {
public:
- explicit ApplicationWayland(float video_pixel_ratio);
+ explicit ApplicationWayland(float video_pixel_ratio = 1.0f);
~ApplicationWayland() override{};
static ApplicationWayland* Get() {
@@ -44,35 +45,22 @@
shared::starboard::Application::Get());
}
- // window
- SbWindow CreateWindow(const SbWindowOptions* options);
- bool DestroyWindow(SbWindow window);
- void SetCompositor(wl_compositor* compositor) { compositor_ = compositor; }
- wl_compositor* GetCompositor() { return compositor_; }
- void SetShell(wl_shell* shell) { shell_ = shell; }
- wl_shell* GetShell() { return shell_; }
- void SetPolicy(tizen_policy* policy) { tz_policy_ = policy; }
- tizen_policy* GetPolicy() { return tz_policy_; }
- void WindowRaise();
+ // wl registry add listener
+ virtual bool OnGlobalObjectAvailable(struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version);
+
+ // display
wl_display* GetWLDisplay() { return display_; }
- // input devices
- void SetKeyboard(wl_keyboard* keyboard) { keyboard_ = keyboard; }
- wl_keyboard* GetKeyboard() { return keyboard_; }
- void SetSeat(wl_seat* seat) { seat_ = seat; }
- wl_seat* GetSeat() { return seat_; }
-
- // key event
- void UpdateKeyModifiers(unsigned int modifiers) {
- key_modifiers_ = modifiers;
- }
- void CreateRepeatKey();
- void DeleteRepeatKey();
- void CreateKey(int key, int state, bool is_repeat);
+ // window
+ virtual SbWindow CreateWindow(const SbWindowOptions* options);
+ bool DestroyWindow(SbWindow window);
// state change
- void Pause(void* context, EventHandledCallback callback) override;
- void Unpause(void* context, EventHandledCallback callback) override;
+ void Pause(void* context, EventHandledCallback callback);
+ void Unpause(void* context, EventHandledCallback callback);
// state change observer
class StateObserver {
@@ -88,6 +76,8 @@
// deeplink
void Deeplink(char* payload);
+ void InjectInputEvent(SbInputData* data);
+
protected:
// --- Application overrides ---
void Initialize() override;
@@ -101,26 +91,16 @@
Event* WaitForSystemEventWithTimeout(SbTime time) override;
void WakeSystemEventWait() override;
- private:
- void InitializeEgl();
- void TerminateEgl();
-
- // window
- SbWindow window_;
- float video_pixel_ratio_;
+ protected:
wl_display* display_;
wl_compositor* compositor_;
wl_shell* shell_;
- tizen_policy* tz_policy_;
+ DevInput dev_input_;
+ float video_pixel_ratio_;
- // input devices
- wl_seat* seat_;
- wl_keyboard* keyboard_;
- int key_repeat_key_;
- int key_repeat_state_;
- SbEventId key_repeat_event_id_;
- SbTime key_repeat_interval_;
- unsigned int key_modifiers_;
+ private:
+ void InitializeEgl();
+ void TerminateEgl();
// wakeup event
int wakeup_fd_;
diff --git a/src/starboard/shared/wayland/dev_input.cc b/src/starboard/shared/wayland/dev_input.cc
new file mode 100644
index 0000000..9df9f7c
--- /dev/null
+++ b/src/starboard/shared/wayland/dev_input.cc
@@ -0,0 +1,563 @@
+// Copyright 2018 Samsung Electronics. All Rights Reserved.
+//
+// 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.
+
+#include "starboard/shared/wayland/dev_input.h"
+
+#include <linux/input.h>
+#include <string.h>
+
+#include "starboard/input.h"
+#include "starboard/key.h"
+#include "starboard/log.h"
+#include "starboard/memory.h"
+#include "starboard/shared/starboard/application.h"
+#include "starboard/shared/wayland/application_wayland.h"
+
+namespace starboard {
+namespace shared {
+namespace wayland {
+
+namespace {
+
+// YouTube Technical Requirement 2018 (2016/11/1 - Initial draft)
+// 9.5 The device MUST dispatch the following key events, as appropriate:
+// * Window.keydown
+// * After a key is held down for 500ms, the Window.keydown event
+// MUST repeat every 50ms until a user stops holding the key down.
+// * Window.keyup
+const SbTime kKeyHoldTime = 500 * kSbTimeMillisecond;
+const SbTime kKeyRepeatTime = 50 * kSbTimeMillisecond;
+
+void SeatHandleCapabilities(void* data,
+ struct wl_seat* seat,
+ unsigned int caps) {
+ DevInput* dev_input = reinterpret_cast<DevInput*>(data);
+ SB_DCHECK(dev_input);
+ dev_input->OnSeatCapabilitiesChanged(seat, caps);
+}
+
+const struct wl_seat_listener seat_listener = {
+ &SeatHandleCapabilities,
+};
+
+#define KEY_INFO_BUTTON 0xbc
+
+// Converts an input_event code into an SbKey.
+SbKey KeyCodeToSbKey(uint16_t code) {
+ switch (code) {
+ case KEY_BACKSPACE:
+ return kSbKeyBack;
+ case KEY_DELETE:
+ return kSbKeyDelete;
+ case KEY_TAB:
+ return kSbKeyTab;
+ case KEY_LINEFEED:
+ case KEY_ENTER:
+ case KEY_KPENTER:
+ return kSbKeyReturn;
+ case KEY_CLEAR:
+ return kSbKeyClear;
+ case KEY_SPACE:
+ return kSbKeySpace;
+ case KEY_HOME:
+ return kSbKeyHome;
+ case KEY_END:
+ return kSbKeyEnd;
+ case KEY_PAGEUP:
+ return kSbKeyPrior;
+ case KEY_PAGEDOWN:
+ return kSbKeyNext;
+ case KEY_LEFT:
+ return kSbKeyLeft;
+ case KEY_RIGHT:
+ return kSbKeyRight;
+ case KEY_DOWN:
+ return kSbKeyDown;
+ case KEY_UP:
+ return kSbKeyUp;
+ case KEY_ESC:
+ return kSbKeyEscape;
+ case KEY_KATAKANA:
+ case KEY_HIRAGANA:
+ case KEY_KATAKANAHIRAGANA:
+ return kSbKeyKana;
+ case KEY_HANGEUL:
+ return kSbKeyHangul;
+ case KEY_HANJA:
+ return kSbKeyHanja;
+ case KEY_HENKAN:
+ return kSbKeyConvert;
+ case KEY_MUHENKAN:
+ return kSbKeyNonconvert;
+ case KEY_ZENKAKUHANKAKU:
+ return kSbKeyDbeDbcschar;
+ case KEY_A:
+ return kSbKeyA;
+ case KEY_B:
+ return kSbKeyB;
+ case KEY_C:
+ return kSbKeyC;
+ case KEY_D:
+ return kSbKeyD;
+ case KEY_E:
+ return kSbKeyE;
+ case KEY_F:
+ return kSbKeyF;
+ case KEY_G:
+ return kSbKeyG;
+ case KEY_H:
+ return kSbKeyH;
+ case KEY_I:
+ return kSbKeyI;
+ case KEY_J:
+ return kSbKeyJ;
+ case KEY_K:
+ return kSbKeyK;
+ case KEY_L:
+ return kSbKeyL;
+ case KEY_M:
+ return kSbKeyM;
+ case KEY_N:
+ return kSbKeyN;
+ case KEY_O:
+ return kSbKeyO;
+ case KEY_P:
+ return kSbKeyP;
+ case KEY_Q:
+ return kSbKeyQ;
+ case KEY_R:
+ return kSbKeyR;
+ case KEY_S:
+ return kSbKeyS;
+ case KEY_T:
+ return kSbKeyT;
+ case KEY_U:
+ return kSbKeyU;
+ case KEY_V:
+ return kSbKeyV;
+ case KEY_W:
+ return kSbKeyW;
+ case KEY_X:
+ return kSbKeyX;
+ case KEY_Y:
+ return kSbKeyY;
+ case KEY_Z:
+ return kSbKeyZ;
+
+ case KEY_0:
+ return kSbKey0;
+ case KEY_1:
+ return kSbKey1;
+ case KEY_2:
+ return kSbKey2;
+ case KEY_3:
+ return kSbKey3;
+ case KEY_4:
+ return kSbKey4;
+ case KEY_5:
+ return kSbKey5;
+ case KEY_6:
+ return kSbKey6;
+ case KEY_7:
+ return kSbKey7;
+ case KEY_8:
+ return kSbKey8;
+ case KEY_9:
+ return kSbKey9;
+
+ case KEY_NUMERIC_0:
+ case KEY_NUMERIC_1:
+ case KEY_NUMERIC_2:
+ case KEY_NUMERIC_3:
+ case KEY_NUMERIC_4:
+ case KEY_NUMERIC_5:
+ case KEY_NUMERIC_6:
+ case KEY_NUMERIC_7:
+ case KEY_NUMERIC_8:
+ case KEY_NUMERIC_9:
+ return static_cast<SbKey>(kSbKey0 + (code - KEY_NUMERIC_0));
+
+ case KEY_KP0:
+ return kSbKeyNumpad0;
+ case KEY_KP1:
+ return kSbKeyNumpad1;
+ case KEY_KP2:
+ return kSbKeyNumpad2;
+ case KEY_KP3:
+ return kSbKeyNumpad3;
+ case KEY_KP4:
+ return kSbKeyNumpad4;
+ case KEY_KP5:
+ return kSbKeyNumpad5;
+ case KEY_KP6:
+ return kSbKeyNumpad6;
+ case KEY_KP7:
+ return kSbKeyNumpad7;
+ case KEY_KP8:
+ return kSbKeyNumpad8;
+ case KEY_KP9:
+ return kSbKeyNumpad9;
+
+ case KEY_KPASTERISK:
+ return kSbKeyMultiply;
+ case KEY_KPDOT:
+ return kSbKeyDecimal;
+ case KEY_KPSLASH:
+ return kSbKeyDivide;
+ case KEY_KPPLUS:
+ case KEY_EQUAL:
+ return kSbKeyOemPlus;
+ case KEY_COMMA:
+ return kSbKeyOemComma;
+ case KEY_KPMINUS:
+ case KEY_MINUS:
+ return kSbKeyOemMinus;
+ case KEY_DOT:
+ return kSbKeyOemPeriod;
+ case KEY_SEMICOLON:
+ return kSbKeyOem1;
+ case KEY_SLASH:
+ return kSbKeyOem2;
+ case KEY_GRAVE:
+ return kSbKeyOem3;
+ case KEY_LEFTBRACE:
+ return kSbKeyOem4;
+ case KEY_BACKSLASH:
+ return kSbKeyOem5;
+ case KEY_RIGHTBRACE:
+ return kSbKeyOem6;
+ case KEY_APOSTROPHE:
+ return kSbKeyOem7;
+ case KEY_LEFTSHIFT:
+ case KEY_RIGHTSHIFT:
+ return kSbKeyShift;
+ case KEY_LEFTCTRL:
+ case KEY_RIGHTCTRL:
+ return kSbKeyControl;
+ case KEY_LEFTMETA:
+ case KEY_RIGHTMETA:
+ case KEY_LEFTALT:
+ case KEY_RIGHTALT:
+ return kSbKeyMenu;
+ case KEY_PAUSE:
+ return kSbKeyPause;
+ case KEY_CAPSLOCK:
+ return kSbKeyCapital;
+ case KEY_NUMLOCK:
+ return kSbKeyNumlock;
+ case KEY_SCROLLLOCK:
+ return kSbKeyScroll;
+ case KEY_SELECT:
+ return kSbKeySelect;
+ case KEY_PRINT:
+ return kSbKeyPrint;
+ case KEY_INSERT:
+ return kSbKeyInsert;
+ case KEY_HELP:
+ return kSbKeyHelp;
+ case KEY_MENU:
+ return kSbKeyApps;
+ case KEY_FN_F1:
+ case KEY_FN_F2:
+ case KEY_FN_F3:
+ case KEY_FN_F4:
+ case KEY_FN_F5:
+ case KEY_FN_F6:
+ case KEY_FN_F7:
+ case KEY_FN_F8:
+ case KEY_FN_F9:
+ case KEY_FN_F10:
+ case KEY_FN_F11:
+ case KEY_FN_F12:
+ return static_cast<SbKey>(kSbKeyF1 + (code - KEY_FN_F1));
+
+ // For supporting multimedia buttons on a USB keyboard.
+ case KEY_BACK:
+ return kSbKeyBrowserBack;
+ case KEY_FORWARD:
+ return kSbKeyBrowserForward;
+ case KEY_REFRESH:
+ return kSbKeyBrowserRefresh;
+ case KEY_STOP:
+ return kSbKeyBrowserStop;
+ case KEY_SEARCH:
+ return kSbKeyBrowserSearch;
+ case KEY_FAVORITES:
+ return kSbKeyBrowserFavorites;
+ case KEY_HOMEPAGE:
+ return kSbKeyBrowserHome;
+ case KEY_MUTE:
+ return kSbKeyVolumeMute;
+ case KEY_VOLUMEDOWN:
+ return kSbKeyVolumeDown;
+ case KEY_VOLUMEUP:
+ return kSbKeyVolumeUp;
+ case KEY_NEXTSONG:
+ return kSbKeyMediaNextTrack;
+ case KEY_PREVIOUSSONG:
+ return kSbKeyMediaPrevTrack;
+ case KEY_STOPCD:
+ return kSbKeyMediaStop;
+ case KEY_PLAYPAUSE:
+ return kSbKeyMediaPlayPause;
+ case KEY_MAIL:
+ return kSbKeyMediaLaunchMail;
+ case KEY_CALC:
+ return kSbKeyMediaLaunchApp2;
+ case KEY_WLAN:
+ return kSbKeyWlan;
+ case KEY_POWER:
+ return kSbKeyPower;
+ case KEY_BRIGHTNESSDOWN:
+ return kSbKeyBrightnessDown;
+ case KEY_BRIGHTNESSUP:
+ return kSbKeyBrightnessUp;
+
+ case KEY_INFO_BUTTON:
+ return kSbKeyF1;
+ }
+ SB_DLOG(WARNING) << "Unknown code: 0x" << std::hex << code;
+ return kSbKeyUnknown;
+} // NOLINT(readability/fn_size)
+
+// Get a SbKeyLocation from an input_event.code.
+SbKeyLocation KeyCodeToSbKeyLocation(uint16_t code) {
+ switch (code) {
+ case KEY_LEFTALT:
+ case KEY_LEFTCTRL:
+ case KEY_LEFTMETA:
+ case KEY_LEFTSHIFT:
+ return kSbKeyLocationLeft;
+ case KEY_RIGHTALT:
+ case KEY_RIGHTCTRL:
+ case KEY_RIGHTMETA:
+ case KEY_RIGHTSHIFT:
+ return kSbKeyLocationRight;
+ }
+
+ return kSbKeyLocationUnspecified;
+}
+
+void KeyboardHandleKeyMap(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t format,
+ int fd,
+ uint32_t size) {
+ DevInput* dev_input = reinterpret_cast<DevInput*>(data);
+ SB_DCHECK(dev_input);
+ dev_input->OnKeyboardHandleKeyMap(keyboard, format, fd, size);
+}
+
+void KeyboardHandleEnter(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface,
+ struct wl_array* keys) {
+ DevInput* dev_input = reinterpret_cast<DevInput*>(data);
+ SB_DCHECK(dev_input);
+ dev_input->OnKeyboardHandleEnter(keyboard, serial, surface, keys);
+}
+
+void KeyboardHandleLeave(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface) {
+ DevInput* dev_input = reinterpret_cast<DevInput*>(data);
+ SB_DCHECK(dev_input);
+ dev_input->OnKeyboardHandleLeave(keyboard, serial, surface);
+}
+
+void KeyboardHandleKey(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t key,
+ uint32_t state) {
+ DevInput* dev_input = reinterpret_cast<DevInput*>(data);
+ SB_DCHECK(dev_input);
+ dev_input->OnKeyboardHandleKey(keyboard, serial, time, key, state);
+}
+
+void KeyboardHandleModifiers(void* data,
+ struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t mods_depressed,
+ uint32_t mods_latched,
+ uint32_t mods_locked,
+ uint32_t group) {
+ DevInput* dev_input = reinterpret_cast<DevInput*>(data);
+ SB_DCHECK(dev_input);
+ dev_input->OnKeyboardHandleModifiers(keyboard, serial, mods_depressed,
+ mods_latched, mods_locked, group);
+}
+
+const struct wl_keyboard_listener keyboard_listener = {
+ &KeyboardHandleKeyMap,
+ &KeyboardHandleEnter,
+ &KeyboardHandleLeave,
+ &KeyboardHandleKey,
+ &KeyboardHandleModifiers,
+};
+
+}
+
+DevInput::DevInput()
+ : wl_seat_(NULL),
+ wl_keyboard_(NULL),
+ key_repeat_event_id_(kSbEventIdInvalid),
+ key_repeat_interval_(kKeyHoldTime),
+ key_modifiers_(0),
+ window_(kSbWindowInvalid) {}
+
+bool DevInput::OnGlobalObjectAvailable(struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version) {
+ if (strcmp(interface, "wl_seat") == 0) {
+ wl_seat_ = static_cast<wl_seat*>(
+ wl_registry_bind(registry, name, &wl_seat_interface, 1));
+ SB_DCHECK(wl_seat_);
+ wl_seat_add_listener(wl_seat_, &seat_listener, this);
+ return true;
+ }
+ return false;
+}
+
+void DevInput::OnSeatCapabilitiesChanged(struct wl_seat* seat,
+ unsigned int caps) {
+ SB_DLOG(INFO) << "[Key] seat_handle_capabilities caps: " << caps;
+ if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
+ wl_keyboard_ = static_cast<wl_keyboard*>(wl_seat_get_keyboard(seat));
+ if (wl_keyboard_)
+ wl_keyboard_add_listener(wl_keyboard_, &keyboard_listener, this);
+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
+ if (wl_keyboard_)
+ wl_keyboard_destroy(wl_keyboard_);
+ wl_keyboard_ = NULL;
+ }
+}
+
+void DevInput::OnKeyboardHandleKeyMap(struct wl_keyboard* keyboard,
+ uint32_t format,
+ int fd,
+ uint32_t size) {
+ SB_DLOG(INFO) << "[Key] Keyboard keymap";
+}
+
+void DevInput::OnKeyboardHandleEnter(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface,
+ struct wl_array* keys) {
+ SB_DLOG(INFO) << "[Key] Keyboard gained focus";
+}
+
+void DevInput::OnKeyboardHandleLeave(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface) {
+ SB_DLOG(INFO) << "[Key] Keyboard lost focus";
+ DeleteRepeatKey();
+}
+
+void DevInput::OnKeyboardHandleModifiers(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t mods_depressed,
+ uint32_t mods_latched,
+ uint32_t mods_locked,
+ uint32_t group) {
+ // Convert to SbKeyModifiers.
+ unsigned int modifiers = kSbKeyModifiersNone;
+
+ if (mods_depressed & 1)
+ modifiers |= kSbKeyModifiersShift;
+ if (mods_depressed & 4)
+ modifiers |= kSbKeyModifiersCtrl;
+ if (mods_depressed & 8)
+ modifiers |= kSbKeyModifiersAlt;
+
+ SB_DLOG(INFO) << "[Key] Modifiers depressed " << mods_depressed
+ << ", latched " << mods_latched << ", locked " << mods_locked
+ << ", group " << group << ", key modifiers " << modifiers;
+
+ key_modifiers_ = modifiers;
+}
+
+void DevInput::OnKeyboardHandleKey(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t key,
+ uint32_t state) {
+ bool repeatable = (key == KEY_LEFT || key == KEY_RIGHT || key == KEY_UP || key == KEY_DOWN);
+ SB_DLOG(INFO) << "[Key] Key :" << key << ", state:" << state << " repeatable " << repeatable
+ << " key_repeat_key_ " << key_repeat_key_ << " key_repeat_state_ " << key_repeat_state_;
+ if (state && repeatable && key == key_repeat_key_ && key_repeat_state_)
+ return;
+
+ if (repeatable) {
+ CreateKey(key, state, true);
+ } else {
+ CreateKey(key, state, false);
+ }
+}
+
+void DevInput::CreateRepeatKey() {
+ if (!key_repeat_state_) {
+ return;
+ }
+
+ if (key_repeat_interval_) {
+ key_repeat_interval_ = kKeyRepeatTime;
+ }
+
+ CreateKey(key_repeat_key_, key_repeat_state_, true);
+}
+
+void DevInput::CreateKey(int key, int state, bool is_repeat) {
+ SbInputData* data = new SbInputData();
+ SbMemorySet(data, 0, sizeof(*data));
+ data->window = window_;
+ data->type = (state == 0 ? kSbInputEventTypeUnpress : kSbInputEventTypePress);
+ data->device_type = kSbInputDeviceTypeRemote;
+ data->device_id = 1; // kKeyboardDeviceId;
+ data->key = KeyCodeToSbKey(key);
+ data->key_location = KeyCodeToSbKeyLocation(key);
+ data->key_modifiers = key_modifiers_;
+ ApplicationWayland::Get()->InjectInputEvent(data);
+
+ DeleteRepeatKey();
+
+ if (is_repeat && state) {
+ key_repeat_key_ = key;
+ key_repeat_state_ = state;
+ key_repeat_event_id_ = SbEventSchedule(
+ [](void* data) {
+ DevInput* dev_input = reinterpret_cast<DevInput*>(data);
+ dev_input->CreateRepeatKey();
+ },
+ this, key_repeat_interval_);
+ } else {
+ key_repeat_interval_ = kKeyHoldTime;
+ }
+}
+
+void DevInput::DeleteRepeatKey() {
+ key_repeat_state_ = 0;
+ if (key_repeat_event_id_ != kSbEventIdInvalid) {
+ SbEventCancel(key_repeat_event_id_);
+ key_repeat_event_id_ = kSbEventIdInvalid;
+ }
+}
+
+} // namespace wayland
+} // namespace shared
+} // namespace starboard
diff --git a/src/starboard/shared/wayland/dev_input.h b/src/starboard/shared/wayland/dev_input.h
index fbcbf11..a8538cf 100644
--- a/src/starboard/shared/wayland/dev_input.h
+++ b/src/starboard/shared/wayland/dev_input.h
@@ -15,491 +15,72 @@
#ifndef STARBOARD_SHARED_WAYLAND_DEV_INPUT_H_
#define STARBOARD_SHARED_WAYLAND_DEV_INPUT_H_
-#include <EGL/egl.h>
-#include <linux/input.h>
+#include <wayland-client.h>
-#include "starboard/input.h"
-#include "starboard/key.h"
-#include "starboard/log.h"
-#include "starboard/shared/wayland/application_wayland.h"
-#include "starboard/shared/wayland/window_internal.h"
+#include "starboard/event.h"
+#include "starboard/time.h"
+#include "starboard/window.h"
namespace starboard {
namespace shared {
namespace wayland {
-#define KEY_INFO_BUTTON 0xbc
+class DevInput {
+ public:
+ DevInput();
+ ~DevInput() {}
-// Converts an input_event code into an SbKey.
-static SbKey KeyCodeToSbKey(uint16_t code) {
- switch (code) {
- case KEY_BACKSPACE:
- return kSbKeyBack;
- case KEY_DELETE:
- return kSbKeyDelete;
- case KEY_TAB:
- return kSbKeyTab;
- case KEY_LINEFEED:
- case KEY_ENTER:
- case KEY_KPENTER:
- return kSbKeyReturn;
- case KEY_CLEAR:
- return kSbKeyClear;
- case KEY_SPACE:
- return kSbKeySpace;
- case KEY_HOME:
- return kSbKeyHome;
- case KEY_END:
- return kSbKeyEnd;
- case KEY_PAGEUP:
- return kSbKeyPrior;
- case KEY_PAGEDOWN:
- return kSbKeyNext;
- case KEY_LEFT:
- return kSbKeyLeft;
- case KEY_RIGHT:
- return kSbKeyRight;
- case KEY_DOWN:
- return kSbKeyDown;
- case KEY_UP:
- return kSbKeyUp;
- case KEY_ESC:
- return kSbKeyEscape;
- case KEY_KATAKANA:
- case KEY_HIRAGANA:
- case KEY_KATAKANAHIRAGANA:
- return kSbKeyKana;
- case KEY_HANGEUL:
- return kSbKeyHangul;
- case KEY_HANJA:
- return kSbKeyHanja;
- case KEY_HENKAN:
- return kSbKeyConvert;
- case KEY_MUHENKAN:
- return kSbKeyNonconvert;
- case KEY_ZENKAKUHANKAKU:
- return kSbKeyDbeDbcschar;
- case KEY_A:
- return kSbKeyA;
- case KEY_B:
- return kSbKeyB;
- case KEY_C:
- return kSbKeyC;
- case KEY_D:
- return kSbKeyD;
- case KEY_E:
- return kSbKeyE;
- case KEY_F:
- return kSbKeyF;
- case KEY_G:
- return kSbKeyG;
- case KEY_H:
- return kSbKeyH;
- case KEY_I:
- return kSbKeyI;
- case KEY_J:
- return kSbKeyJ;
- case KEY_K:
- return kSbKeyK;
- case KEY_L:
- return kSbKeyL;
- case KEY_M:
- return kSbKeyM;
- case KEY_N:
- return kSbKeyN;
- case KEY_O:
- return kSbKeyO;
- case KEY_P:
- return kSbKeyP;
- case KEY_Q:
- return kSbKeyQ;
- case KEY_R:
- return kSbKeyR;
- case KEY_S:
- return kSbKeyS;
- case KEY_T:
- return kSbKeyT;
- case KEY_U:
- return kSbKeyU;
- case KEY_V:
- return kSbKeyV;
- case KEY_W:
- return kSbKeyW;
- case KEY_X:
- return kSbKeyX;
- case KEY_Y:
- return kSbKeyY;
- case KEY_Z:
- return kSbKeyZ;
+ // wl registry add listener
+ bool OnGlobalObjectAvailable(struct wl_registry* registry,
+ uint32_t name,
+ const char* interface,
+ uint32_t version);
- case KEY_0:
- return kSbKey0;
- case KEY_1:
- return kSbKey1;
- case KEY_2:
- return kSbKey2;
- case KEY_3:
- return kSbKey3;
- case KEY_4:
- return kSbKey4;
- case KEY_5:
- return kSbKey5;
- case KEY_6:
- return kSbKey6;
- case KEY_7:
- return kSbKey7;
- case KEY_8:
- return kSbKey8;
- case KEY_9:
- return kSbKey9;
+ // wl seat add listener
+ void OnSeatCapabilitiesChanged(struct wl_seat* seat, unsigned int caps);
- case KEY_NUMERIC_0:
- case KEY_NUMERIC_1:
- case KEY_NUMERIC_2:
- case KEY_NUMERIC_3:
- case KEY_NUMERIC_4:
- case KEY_NUMERIC_5:
- case KEY_NUMERIC_6:
- case KEY_NUMERIC_7:
- case KEY_NUMERIC_8:
- case KEY_NUMERIC_9:
- return static_cast<SbKey>(kSbKey0 + (code - KEY_NUMERIC_0));
+ // wl keyboard add listener
+ void OnKeyboardHandleKeyMap(struct wl_keyboard* keyboard,
+ uint32_t format,
+ int fd,
+ uint32_t size);
+ void OnKeyboardHandleEnter(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface,
+ struct wl_array* keys);
+ void OnKeyboardHandleLeave(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ struct wl_surface* surface);
+ void OnKeyboardHandleKey(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t key,
+ uint32_t state);
+ void OnKeyboardHandleModifiers(struct wl_keyboard* keyboard,
+ uint32_t serial,
+ uint32_t mods_depressed,
+ uint32_t mods_latched,
+ uint32_t mods_locked,
+ uint32_t group);
- case KEY_KP0:
- return kSbKeyNumpad0;
- case KEY_KP1:
- return kSbKeyNumpad1;
- case KEY_KP2:
- return kSbKeyNumpad2;
- case KEY_KP3:
- return kSbKeyNumpad3;
- case KEY_KP4:
- return kSbKeyNumpad4;
- case KEY_KP5:
- return kSbKeyNumpad5;
- case KEY_KP6:
- return kSbKeyNumpad6;
- case KEY_KP7:
- return kSbKeyNumpad7;
- case KEY_KP8:
- return kSbKeyNumpad8;
- case KEY_KP9:
- return kSbKeyNumpad9;
+ // window
+ void SetSbWindow(SbWindow window) { window_ = window; }
- case KEY_KPASTERISK:
- return kSbKeyMultiply;
- case KEY_KPDOT:
- return kSbKeyDecimal;
- case KEY_KPSLASH:
- return kSbKeyDivide;
- case KEY_KPPLUS:
- case KEY_EQUAL:
- return kSbKeyOemPlus;
- case KEY_COMMA:
- return kSbKeyOemComma;
- case KEY_KPMINUS:
- case KEY_MINUS:
- return kSbKeyOemMinus;
- case KEY_DOT:
- return kSbKeyOemPeriod;
- case KEY_SEMICOLON:
- return kSbKeyOem1;
- case KEY_SLASH:
- return kSbKeyOem2;
- case KEY_GRAVE:
- return kSbKeyOem3;
- case KEY_LEFTBRACE:
- return kSbKeyOem4;
- case KEY_BACKSLASH:
- return kSbKeyOem5;
- case KEY_RIGHTBRACE:
- return kSbKeyOem6;
- case KEY_APOSTROPHE:
- return kSbKeyOem7;
- case KEY_LEFTSHIFT:
- case KEY_RIGHTSHIFT:
- return kSbKeyShift;
- case KEY_LEFTCTRL:
- case KEY_RIGHTCTRL:
- return kSbKeyControl;
- case KEY_LEFTMETA:
- case KEY_RIGHTMETA:
- case KEY_LEFTALT:
- case KEY_RIGHTALT:
- return kSbKeyMenu;
- case KEY_PAUSE:
- return kSbKeyPause;
- case KEY_CAPSLOCK:
- return kSbKeyCapital;
- case KEY_NUMLOCK:
- return kSbKeyNumlock;
- case KEY_SCROLLLOCK:
- return kSbKeyScroll;
- case KEY_SELECT:
- return kSbKeySelect;
- case KEY_PRINT:
- return kSbKeyPrint;
- case KEY_INSERT:
- return kSbKeyInsert;
- case KEY_HELP:
- return kSbKeyHelp;
- case KEY_MENU:
- return kSbKeyApps;
- case KEY_FN_F1:
- case KEY_FN_F2:
- case KEY_FN_F3:
- case KEY_FN_F4:
- case KEY_FN_F5:
- case KEY_FN_F6:
- case KEY_FN_F7:
- case KEY_FN_F8:
- case KEY_FN_F9:
- case KEY_FN_F10:
- case KEY_FN_F11:
- case KEY_FN_F12:
- return static_cast<SbKey>(kSbKeyF1 + (code - KEY_FN_F1));
+ void DeleteRepeatKey();
+ void CreateKey(int key, int state, bool is_repeat);
+ void CreateRepeatKey();
- // For supporting multimedia buttons on a USB keyboard.
- case KEY_BACK:
- return kSbKeyBrowserBack;
- case KEY_FORWARD:
- return kSbKeyBrowserForward;
- case KEY_REFRESH:
- return kSbKeyBrowserRefresh;
- case KEY_STOP:
- return kSbKeyBrowserStop;
- case KEY_SEARCH:
- return kSbKeyBrowserSearch;
- case KEY_FAVORITES:
- return kSbKeyBrowserFavorites;
- case KEY_HOMEPAGE:
- return kSbKeyBrowserHome;
- case KEY_MUTE:
- return kSbKeyVolumeMute;
- case KEY_VOLUMEDOWN:
- return kSbKeyVolumeDown;
- case KEY_VOLUMEUP:
- return kSbKeyVolumeUp;
- case KEY_NEXTSONG:
- return kSbKeyMediaNextTrack;
- case KEY_PREVIOUSSONG:
- return kSbKeyMediaPrevTrack;
- case KEY_STOPCD:
- return kSbKeyMediaStop;
- case KEY_PLAYPAUSE:
- return kSbKeyMediaPlayPause;
- case KEY_MAIL:
- return kSbKeyMediaLaunchMail;
- case KEY_CALC:
- return kSbKeyMediaLaunchApp2;
- case KEY_WLAN:
- return kSbKeyWlan;
- case KEY_POWER:
- return kSbKeyPower;
- case KEY_BRIGHTNESSDOWN:
- return kSbKeyBrightnessDown;
- case KEY_BRIGHTNESSUP:
- return kSbKeyBrightnessUp;
-
- case KEY_INFO_BUTTON:
- return kSbKeyF1;
- }
- SB_DLOG(WARNING) << "Unknown code: 0x" << std::hex << code;
- return kSbKeyUnknown;
-} // NOLINT(readability/fn_size)
-
-// Get a SbKeyLocation from an input_event.code.
-static SbKeyLocation KeyCodeToSbKeyLocation(uint16_t code) {
- switch (code) {
- case KEY_LEFTALT:
- case KEY_LEFTCTRL:
- case KEY_LEFTMETA:
- case KEY_LEFTSHIFT:
- return kSbKeyLocationLeft;
- case KEY_RIGHTALT:
- case KEY_RIGHTCTRL:
- case KEY_RIGHTMETA:
- case KEY_RIGHTSHIFT:
- return kSbKeyLocationRight;
- }
-
- return kSbKeyLocationUnspecified;
-}
-
-// keyboard_listener
-static void KeyboardHandleKeyMap(void* data,
- struct wl_keyboard* keyboard,
- uint32_t format,
- int fd,
- uint32_t size) {
- SB_DLOG(INFO) << "[Key] Keyboard keymap";
-}
-
-static void KeyboardHandleEnter(void* data,
- struct wl_keyboard* keyboard,
- uint32_t serial,
- struct wl_surface* surface,
- struct wl_array* keys) {
- SB_DLOG(INFO) << "[Key] Keyboard gained focus";
-}
-
-static void KeyboardHandleLeave(void* data,
- struct wl_keyboard* keyboard,
- uint32_t serial,
- struct wl_surface* surface) {
- SB_DLOG(INFO) << "[Key] Keyboard lost focus";
- ApplicationWayland* wayland_window_ =
- reinterpret_cast<ApplicationWayland*>(data);
- wayland_window_->DeleteRepeatKey();
-}
-
-static void KeyboardHandleKey(void* data,
- struct wl_keyboard* keyboard,
- uint32_t serial,
- uint32_t time,
- uint32_t key,
- uint32_t state) {
- SB_DLOG(INFO) << "[Key] Key :" << key << ", state:" << state;
- ApplicationWayland* wayland_window_ =
- reinterpret_cast<ApplicationWayland*>(data);
- if (key == KEY_LEFT || key == KEY_RIGHT || key == KEY_UP || key == KEY_DOWN) {
- wayland_window_->CreateKey(key, state, true);
- } else {
- wayland_window_->CreateKey(key, state, false);
- }
-}
-
-static void KeyboardHandleModifiers(void* data,
- struct wl_keyboard* keyboard,
- uint32_t serial,
- uint32_t mods_depressed,
- uint32_t mods_latched,
- uint32_t mods_locked,
- uint32_t group) {
- ApplicationWayland* wayland_window_ =
- reinterpret_cast<ApplicationWayland*>(data);
- // Convert to SbKeyModifiers.
- unsigned int modifiers = kSbKeyModifiersNone;
-
- if (mods_depressed & 1)
- modifiers |= kSbKeyModifiersShift;
- if (mods_depressed & 4)
- modifiers |= kSbKeyModifiersCtrl;
- if (mods_depressed & 8)
- modifiers |= kSbKeyModifiersAlt;
-
- SB_DLOG(INFO) << "[Key] Modifiers depressed " << mods_depressed
- << ", latched " << mods_latched << ", locked " << mods_locked
- << ", group " << group << ", key modifiers " << modifiers;
-
- wayland_window_->UpdateKeyModifiers(modifiers);
-}
-
-static const struct wl_keyboard_listener keyboard_listener_ = {
- &KeyboardHandleKeyMap, &KeyboardHandleEnter, &KeyboardHandleLeave,
- &KeyboardHandleKey, &KeyboardHandleModifiers,
+ private:
+ wl_seat* wl_seat_;
+ wl_keyboard* wl_keyboard_;
+ int key_repeat_key_;
+ int key_repeat_state_;
+ SbEventId key_repeat_event_id_;
+ SbTime key_repeat_interval_;
+ unsigned int key_modifiers_;
+ SbWindow window_;
};
-// seat_listener
-static void SeatHandleCapabilities(void* data,
- struct wl_seat* seat,
- unsigned int caps) {
- ApplicationWayland* wayland_window_ =
- reinterpret_cast<ApplicationWayland*>(data);
- if (!wayland_window_->GetKeyboard()) {
- SB_DLOG(INFO) << "[Key] seat_handle_capabilities caps: " << caps;
- if (caps & WL_SEAT_CAPABILITY_KEYBOARD) {
- SB_DLOG(INFO) << "[Key] wl_seat_get_keyboard";
- wayland_window_->SetKeyboard(wl_seat_get_keyboard(seat));
- wl_keyboard_add_listener(wayland_window_->GetKeyboard(),
- &keyboard_listener_, data);
- } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD)) {
- SB_DLOG(INFO) << "[Key] wl_keyboard_destroy";
- wl_keyboard_destroy(wayland_window_->GetKeyboard());
- wayland_window_->SetKeyboard(NULL);
- }
- }
-}
-
-static const struct wl_seat_listener seat_listener = {
- &SeatHandleCapabilities,
-};
-
-// registry_listener
-static void RegistryAddObject(void* data,
- struct wl_registry* registry,
- uint32_t name,
- const char* interface,
- uint32_t version) {
- ApplicationWayland* wayland_window_ =
- reinterpret_cast<ApplicationWayland*>(data);
- if (strcmp(interface, "wl_compositor") == 0) {
- wayland_window_->SetCompositor(static_cast<wl_compositor*>(
- wl_registry_bind(registry, name, &wl_compositor_interface, 1)));
- } else if (strcmp(interface, "wl_shell") == 0) {
- wayland_window_->SetShell(static_cast<wl_shell*>(
- wl_registry_bind(registry, name, &wl_shell_interface, 1)));
- } else if (strcmp(interface, "wl_seat") == 0) {
- wayland_window_->SetSeat(static_cast<wl_seat*>(
- wl_registry_bind(registry, name, &wl_seat_interface, 1)));
- wl_seat_add_listener(wayland_window_->GetSeat(), &seat_listener, data);
- } else if (!strcmp(interface, "tizen_policy")) {
- wayland_window_->SetPolicy(static_cast<tizen_policy*>(
- wl_registry_bind(registry, name, &tizen_policy_interface, 1)));
- }
-}
-
-static void RegistryRemoveObject(void*, struct wl_registry*, uint32_t) {}
-
-static struct wl_registry_listener registry_listener = {&RegistryAddObject,
- &RegistryRemoveObject};
-
-// shell_surface_listener
-static void ShellSurfacePing(void*,
- struct wl_shell_surface* shell_surface,
- uint32_t serial) {
- wl_shell_surface_pong(shell_surface, serial);
-}
-static void ShellSurfaceConfigure(void* data,
- struct wl_shell_surface*,
- uint32_t,
- int32_t width,
- int32_t height) {
- SB_DLOG(INFO) << "shell_surface_configure width(" << width << "), height("
- << height << ")";
- if (width && height) {
- SbWindowPrivate* window = reinterpret_cast<SbWindowPrivate*>(data);
- wl_egl_window_resize(window->egl_window, width, height, 0, 0);
- } else {
- SB_DLOG(INFO) << "width and height is 0. we don't resize that";
- }
-}
-
-static void ShellSurfacePopupDone(void*, struct wl_shell_surface*) {}
-
-static struct wl_shell_surface_listener shell_surface_listener = {
- &ShellSurfacePing, &ShellSurfaceConfigure, &ShellSurfacePopupDone};
-
-static void WindowCbVisibilityChange(void* data,
- struct tizen_visibility* tizen_visibility
- EINA_UNUSED,
- uint32_t visibility) {
-#if SB_HAS(LAZY_SUSPEND)
- if (visibility == TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED)
- ApplicationWayland::Get()->Pause(NULL, NULL);
- else
- ApplicationWayland::Get()->Unpause(NULL, NULL);
-#else
- if (visibility == TIZEN_VISIBILITY_VISIBILITY_FULLY_OBSCURED)
- shared::starboard::Application::Get()->Suspend(NULL, NULL);
- else
- shared::starboard::Application::Get()->Unpause(NULL, NULL);
-#endif
-}
-
-static const struct tizen_visibility_listener tizen_visibility_listener = {
- WindowCbVisibilityChange};
-
} // namespace wayland
} // namespace shared
} // namespace starboard
diff --git a/src/starboard/shared/wayland/egl_workaround.cc b/src/starboard/shared/wayland/egl_workaround.cc
new file mode 100644
index 0000000..24bd097
--- /dev/null
+++ b/src/starboard/shared/wayland/egl_workaround.cc
@@ -0,0 +1,25 @@
+// Copyright 2018 Samsung Electronics. All Rights Reserved.
+//
+// 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.
+
+#include "starboard/log.h"
+#include "cobalt/renderer/backend/egl/display.h"
+#include "starboard/shared/wayland/native_display_type.h"
+
+extern "C" EGLDisplay __real_eglGetDisplay(EGLNativeDisplayType native_display);
+extern "C" EGLDisplay __wrap_eglGetDisplay(EGLNativeDisplayType native_display);
+
+extern "C" EGLDisplay __wrap_eglGetDisplay(EGLNativeDisplayType native_display) {
+ SB_LOG(INFO) << " __wrap_eglGetDisplay ";
+ return __real_eglGetDisplay((EGLNativeDisplayType)WaylandNativeDisplayType());
+}
diff --git a/src/starboard/shared/wayland/native_display_type.cc b/src/starboard/shared/wayland/native_display_type.cc
new file mode 100644
index 0000000..03e118c
--- /dev/null
+++ b/src/starboard/shared/wayland/native_display_type.cc
@@ -0,0 +1,25 @@
+// Copyright 2018 Samsung Inc. All Rights Reserved.
+//
+// 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.
+
+#include "starboard/shared/wayland/native_display_type.h"
+
+#include "starboard/log.h"
+#include "starboard/shared/wayland/application_wayland.h"
+
+NativeDisplayType WaylandNativeDisplayType()
+{
+ wl_display* display = starboard::shared::wayland::ApplicationWayland::Get()->GetWLDisplay();
+ SB_LOG(INFO) << " SbNativeDisplayType() " << display;
+ return (NativeDisplayType)display;
+}
diff --git a/src/starboard/shared/wayland/native_display_type.h b/src/starboard/shared/wayland/native_display_type.h
new file mode 100644
index 0000000..4eef08c
--- /dev/null
+++ b/src/starboard/shared/wayland/native_display_type.h
@@ -0,0 +1,27 @@
+// Copyright 2018 Samsung Inc. All Rights Reserved.
+//
+// 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.
+
+#ifndef STARBOARD_SHARED_WAYLAND_NATIVE_DISPLAY_TYPE_H_
+#define STARBOARD_SHARED_WAYLAND_NATIVE_DISPLAY_TYPE_H_
+#include <EGL/egl.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+NativeDisplayType WaylandNativeDisplayType();
+
+#ifdef __cplusplus
+}
+#endif
+#endif //STARBOARD_SHARED_WAYLAND_NATIVE_DISPLAY_TYPE_H_
diff --git a/src/starboard/shared/wayland/window_internal.cc b/src/starboard/shared/wayland/window_internal.cc
index 1eb325a..bce7bc7 100644
--- a/src/starboard/shared/wayland/window_internal.cc
+++ b/src/starboard/shared/wayland/window_internal.cc
@@ -14,18 +14,81 @@
#include "starboard/shared/wayland/window_internal.h"
+#include "starboard/log.h"
+
namespace {
+
const int kWindowWidth = 1920;
const int kWindowHeight = 1080;
+
+// shell_surface_listener
+void ShellSurfacePing(void*,
+ struct wl_shell_surface* shell_surface,
+ uint32_t serial) {
+ wl_shell_surface_pong(shell_surface, serial);
}
-SbWindowPrivate::SbWindowPrivate(const SbWindowOptions* options,
+void ShellSurfaceConfigure(void* data,
+ struct wl_shell_surface*,
+ uint32_t,
+ int32_t width,
+ int32_t height) {
+ SB_DLOG(INFO) << "shell_surface_configure width(" << width << "), height("
+ << height << ")";
+ if (width && height) {
+ SbWindowPrivate* window = reinterpret_cast<SbWindowPrivate*>(data);
+ wl_egl_window_resize(window->egl_window, width, height, 0, 0);
+ } else {
+ SB_DLOG(INFO) << "width and height is 0. we don't resize that";
+ }
+}
+
+void ShellSurfacePopupDone(void*, struct wl_shell_surface*) {}
+
+struct wl_shell_surface_listener shell_surface_listener = {
+ &ShellSurfacePing,
+ &ShellSurfaceConfigure,
+ &ShellSurfacePopupDone
+};
+
+}
+
+SbWindowPrivate::SbWindowPrivate(wl_compositor* compositor,
+ wl_shell* shell,
+ const SbWindowOptions* options,
float pixel_ratio) {
width = kWindowWidth;
height = kWindowHeight;
video_pixel_ratio = pixel_ratio;
+
if (options && options->size.width > 0 && options->size.height > 0) {
width = options->size.width;
height = options->size.height;
}
+
+ surface = wl_compositor_create_surface(compositor);
+ shell_surface = wl_shell_get_shell_surface(shell, surface);
+ wl_shell_surface_add_listener(shell_surface, &shell_surface_listener, this);
+ wl_shell_surface_set_title(shell_surface, "cobalt");
+
+ struct wl_region* region;
+ region = wl_compositor_create_region(compositor);
+ wl_region_add(region, 0, 0, width, height);
+ wl_surface_set_opaque_region(surface, region);
+ wl_region_destroy(region);
+
+ egl_window = wl_egl_window_create(surface, width, height);
+
+ WindowRaise();
+}
+
+SbWindowPrivate::~SbWindowPrivate() {
+ wl_egl_window_destroy(egl_window);
+ wl_shell_surface_destroy(shell_surface);
+ wl_surface_destroy(surface);
+}
+
+void SbWindowPrivate::WindowRaise() {
+ if (shell_surface)
+ wl_shell_surface_set_toplevel(shell_surface);
}
diff --git a/src/starboard/shared/wayland/window_internal.h b/src/starboard/shared/wayland/window_internal.h
index 7d2c616..2677f9e 100644
--- a/src/starboard/shared/wayland/window_internal.h
+++ b/src/starboard/shared/wayland/window_internal.h
@@ -15,29 +15,23 @@
#ifndef STARBOARD_SHARED_WAYLAND_WINDOW_INTERNAL_H_
#define STARBOARD_SHARED_WAYLAND_WINDOW_INTERNAL_H_
-#include <Elementary.h>
-#include <string.h>
-#include <tizen-extension-client-protocol.h>
#include <wayland-client.h>
#include <wayland-egl.h>
#include "starboard/window.h"
struct SbWindowPrivate {
- explicit SbWindowPrivate(const SbWindowOptions* options,
+ explicit SbWindowPrivate(wl_compositor* compositor,
+ wl_shell* shell,
+ const SbWindowOptions* options,
float pixel_ratio = 1.0);
- ~SbWindowPrivate() {}
+ virtual ~SbWindowPrivate();
+
+ virtual void WindowRaise();
struct wl_surface* surface;
struct wl_shell_surface* shell_surface;
struct wl_egl_window* egl_window;
- struct tizen_visibility* tz_visibility;
-
-#if SB_CAN(USE_WAYLAND_VIDEO_WINDOW)
- wl_display* video_window;
-#else
- Evas_Object* video_window;
-#endif
// The width, height, pixel ratio of this window.
int width;