blob: fbcbf115590cc0cc0be9a02966a3e30705fdd438 [file] [log] [blame]
// Copyright 2016 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_SHARED_WAYLAND_DEV_INPUT_H_
#define STARBOARD_SHARED_WAYLAND_DEV_INPUT_H_
#include <EGL/egl.h>
#include <linux/input.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"
namespace starboard {
namespace shared {
namespace wayland {
#define KEY_INFO_BUTTON 0xbc
// 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;
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.
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,
};
// 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
#endif // STARBOARD_SHARED_WAYLAND_DEV_INPUT_H_