Refine starboard shared wayland let wayland can compile on tizen and other wayland platform such as ubuntu 17.10. create ApplicationTizen inherit from ApplicationWayland, put all of the Tizen-specific code inside in it. create DevInput to handle all dev inputs handlers. create SbWindowPrivateTizen inherit from SbWindowPrivate, put all of the Tizen-specific code inside in it. Change-Id: I5247010a001258869ace8ae4588d8a9bb2152e5f
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/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;