Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(516)

Unified Diff: ui/wayland/wayland_input_device.cc

Issue 17265006: wayland patch for inspection Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ui/wayland/wayland_input_device.h ('k') | ui/wayland/wayland_input_method_event_filter.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ui/wayland/wayland_input_device.cc
diff --git a/ui/wayland/wayland_input_device.cc b/ui/wayland/wayland_input_device.cc
new file mode 100644
index 0000000000000000000000000000000000000000..250cded5d0fe3900575b2c76cfc035668c360276
--- /dev/null
+++ b/ui/wayland/wayland_input_device.cc
@@ -0,0 +1,541 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ui/wayland/wayland_input_device.h"
+
+#include <X11/X.h>
+#include <linux/input.h>
+#include <wayland-client.h>
+
+#include <wayland-egl.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
+#include <EGL/egl.h>
+#include <EGL/eglext.h>
+
+#include "base/wayland/wayland_event.h"
+#include "ui/wayland/wayland_delegate.h"
+#include "ui/wayland/wayland_window.h"
+#include "ui/base/events/event.h"
+#include "ui/base/events/event_constants.h"
+#include "ui/base/hit_test.h"
+#include "ui/base/ui_base_types.h"
+
+using namespace base::wayland;
+
+namespace ui {
+
+// static
+BoundsChangeType WaylandInputDevice::GetBoundsChangeForWindowComponent(int component)
+{
+ BoundsChangeType bounds_change = kBoundsChange_None;
+ switch (component) {
+ case HTCAPTION:
+ bounds_change = kBoundsChange_Repositions;
+ break;
+ case HTTOPLEFT:
+ case HTTOP:
+ case HTTOPRIGHT:
+ case HTLEFT:
+ case HTBOTTOMLEFT:
+ case HTRIGHT:
+ case HTBOTTOMRIGHT:
+ case HTBOTTOM:
+ //case HTGROWBOX:
+ bounds_change = kBoundsChange_Resizes;
+ break;
+ default:
+ break;
+ }
+ return bounds_change;
+}
+
+// static
+int WaylandInputDevice::GetPointerImageForWindowComponent(int component)
+{
+ WindowLocation location = WaylandInputDevice::GetLocationForWindowComponent(component);
+
+ switch (location) {
+ case WINDOW_RESIZING_TOP:
+ return CURSOR_TOP;
+ case WINDOW_RESIZING_BOTTOM:
+ return CURSOR_BOTTOM;
+ case WINDOW_RESIZING_LEFT:
+ return CURSOR_LEFT;
+ case WINDOW_RESIZING_RIGHT:
+ return CURSOR_RIGHT;
+ case WINDOW_RESIZING_TOP_LEFT:
+ return CURSOR_TOP_LEFT;
+ case WINDOW_RESIZING_TOP_RIGHT:
+ return CURSOR_TOP_RIGHT;
+ case WINDOW_RESIZING_BOTTOM_LEFT:
+ return CURSOR_BOTTOM_LEFT;
+ case WINDOW_RESIZING_BOTTOM_RIGHT:
+ return CURSOR_BOTTOM_RIGHT;
+ case WINDOW_EXTERIOR:
+ case WINDOW_TITLEBAR:
+ default:
+ return CURSOR_LEFT_PTR;
+ }
+}
+
+// static
+WindowLocation WaylandInputDevice::GetLocationForWindowComponent(int component)
+{
+ WindowLocation location = WINDOW_INTERIOR;
+ switch (component) {
+ case HTCAPTION:
+ location = WINDOW_TITLEBAR;
+ break;
+ case HTTOPLEFT:
+ location = WINDOW_RESIZING_TOP_LEFT;
+ break;
+ case HTTOP:
+ location = WINDOW_RESIZING_TOP;
+ break;
+ case HTTOPRIGHT:
+ location = WINDOW_RESIZING_TOP_RIGHT;
+ break;
+ case HTLEFT:
+ location = WINDOW_RESIZING_LEFT;
+ break;
+ case HTBOTTOMLEFT:
+ location = WINDOW_RESIZING_BOTTOM_LEFT;
+ break;
+ case HTRIGHT:
+ location = WINDOW_RESIZING_RIGHT;
+ break;
+ case HTBOTTOMRIGHT:
+ location = WINDOW_RESIZING_BOTTOM_RIGHT;
+ break;
+ case HTBOTTOM:
+ location = WINDOW_RESIZING_BOTTOM;
+ break;
+ default:
+ break;
+ }
+ return location;
+}
+
+WaylandInputDevice::WaylandInputDevice(WaylandDisplay* disp, uint32_t id)
+ : input_seat_(NULL),
+ display_(disp->display()),
+ current_pointer_image_(CURSOR_LEFT_PTR),
+ input_pointer_(NULL),
+ input_keyboard_(NULL),
+ pointer_focus_(NULL),
+ keyboard_focus_(NULL),
+ keyboard_modifiers_(0)
+{
+ static const struct wl_seat_listener kInputSeatListener = {
+ WaylandInputDevice::OnSeatCapabilities,
+ };
+
+ input_seat_ = static_cast<wl_seat*>(
+ wl_registry_bind(disp->registry(), id, &wl_seat_interface, 1));
+ wl_seat_add_listener(input_seat_, &kInputSeatListener, this);
+ wl_seat_set_user_data(input_seat_, this);
+
+ InitXKB();
+}
+
+WaylandInputDevice::~WaylandInputDevice()
+{
+ if (input_seat_)
+ wl_seat_destroy(input_seat_);
+
+ FiniXKB();
+}
+
+void WaylandInputDevice::InitXKB()
+{
+ // Initialize XKB
+ xkb_.names.rules = "evdev";
+ xkb_.names.model = "pc105";
+ xkb_.names.layout = "us";
+ xkb_.names.variant = "";
+ xkb_.names.options = "";
+
+ xkb_.context = xkb_context_new((xkb_context_flags)0);
+ if (!xkb_.context) {
+ return;
+ }
+
+ xkb_.keymap =
+ xkb_map_new_from_names(xkb_.context, &xkb_.names, (xkb_map_compile_flags)0);
+ if (!xkb_.keymap) {
+ return;
+ }
+
+ xkb_.state = xkb_state_new(xkb_.keymap);
+ if (!xkb_.state) {
+ return;
+ }
+
+ xkb_.control_mask =
+ 1 << xkb_map_mod_get_index(xkb_.keymap, "Control");
+ xkb_.alt_mask =
+ 1 << xkb_map_mod_get_index(xkb_.keymap, "Mod1");
+ xkb_.shift_mask =
+ 1 << xkb_map_mod_get_index(xkb_.keymap, "Shift");
+}
+
+void WaylandInputDevice::FiniXKB()
+{
+ xkb_state_unref(xkb_.state);
+ xkb_map_unref(xkb_.keymap);
+ xkb_context_unref(xkb_.context);
+}
+
+void WaylandInputDevice::OnSeatCapabilities(void *data, wl_seat *seat, uint32_t caps)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+
+ static const struct wl_pointer_listener kInputPointerListener = {
+ WaylandInputDevice::OnPointerEnter,
+ WaylandInputDevice::OnPointerLeave,
+ WaylandInputDevice::OnMotionNotify,
+ WaylandInputDevice::OnButtonNotify,
+ WaylandInputDevice::OnAxisNotify,
+ };
+
+ if ((caps & WL_SEAT_CAPABILITY_POINTER) && !device->input_pointer_) {
+ device->input_pointer_ = wl_seat_get_pointer(seat);
+ wl_pointer_set_user_data(device->input_pointer_, device);
+ wl_pointer_add_listener(device->input_pointer_, &kInputPointerListener,
+ device);
+ } else if (!(caps & WL_SEAT_CAPABILITY_POINTER) && device->input_pointer_) {
+ wl_pointer_destroy(device->input_pointer_);
+ device->input_pointer_ = NULL;
+ }
+
+ static const struct wl_keyboard_listener kInputKeyboardListener = {
+ WaylandInputDevice::OnKeyboardKeymap,
+ WaylandInputDevice::OnKeyboardEnter,
+ WaylandInputDevice::OnKeyboardLeave,
+ WaylandInputDevice::OnKeyNotify,
+ WaylandInputDevice::OnKeyModifiers,
+ };
+
+ if ((caps & WL_SEAT_CAPABILITY_KEYBOARD) && !device->input_keyboard_) {
+ device->input_keyboard_ = wl_seat_get_keyboard(seat);
+ wl_keyboard_set_user_data(device->input_keyboard_, device);
+ wl_keyboard_add_listener(device->input_keyboard_, &kInputKeyboardListener,
+ device);
+ } else if (!(caps & WL_SEAT_CAPABILITY_KEYBOARD) && device->input_keyboard_) {
+ wl_keyboard_destroy(device->input_keyboard_);
+ device->input_keyboard_ = NULL;
+ }
+}
+
+void WaylandInputDevice::OnMotionNotify(void* data,
+ wl_pointer* input_pointer,
+ uint32_t time,
+ wl_fixed_t sx_w,
+ wl_fixed_t sy_w)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window = device->pointer_focus_;
+ GLfloat sx = wl_fixed_to_double(sx_w);
+ GLfloat sy = wl_fixed_to_double(sy_w);
+
+ device->surface_position_.SetPoint(sx, sy);
+
+ WaylandEvent event;
+ event.type = WAYLAND_MOTION;
+ event.motion.time = time;
+ event.motion.modifiers = device->keyboard_modifiers_;
+ event.motion.x = sx;
+ event.motion.y = sy;
+
+ if (!window->delegate())
+ return;
+
+ gfx::Point pt(event.motion.x, event.motion.y);
+ int component = window->delegate()->GetNonClientComponent(pt);
+ BoundsChangeType type = WaylandInputDevice::GetBoundsChangeForWindowComponent(component);
+
+ switch(type)
+ {
+ case kBoundsChange_Resizes:
+ WaylandDisplay::GetDisplay(device->display_)->SetPointerImage(
+ device, time, WaylandInputDevice::GetPointerImageForWindowComponent(component));
+ break;
+ case kBoundsChange_Repositions:
+ default:
+ WaylandDisplay::GetDisplay(device->display_)->SetPointerImage(
+ device, time, CURSOR_LEFT_PTR);
+ break;
+ }
+
+ if(type == kBoundsChange_None)
+ window->delegate()->OnMouseEvent(&event);
+}
+
+void WaylandInputDevice::OnAxisNotify(void* data,
+ wl_pointer* input_pointer,
+ uint32_t time,
+ uint32_t axis,
+ int32_t value)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window = device->pointer_focus_;
+
+ WaylandEvent event;
+ event.type = WAYLAND_BUTTON;
+ event.button.time = time;
+ event.button.button = value > 0 ? BTN_SIDE : BTN_EXTRA;
+ event.button.state = 1;
+ event.button.modifiers = device->keyboard_modifiers_;
+ event.button.x = device->surface_position_.x();
+ event.button.y = device->surface_position_.y();
+
+ if (!window->delegate())
+ return;
+
+ window->delegate()->OnMouseEvent(&event);
+}
+
+void WaylandInputDevice::OnButtonNotify(void* data,
+ wl_pointer* input_pointer,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t button,
+ uint32_t state)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window = device->pointer_focus_;
+
+ WaylandDisplay::GetDisplay(device->display_)->SetSerial(serial);
+
+ WaylandEvent event;
+ event.type = WAYLAND_BUTTON;
+ event.button.time = time;
+ event.button.button = button;
+ event.button.state = state;
+ event.button.modifiers = device->keyboard_modifiers_;
+ event.button.x = device->surface_position_.x();
+ event.button.y = device->surface_position_.y();
+
+ if (!window->delegate())
+ return;
+
+ gfx::Point pt(event.button.x, event.button.y);
+ int component = window->delegate()->GetNonClientComponent(pt);
+ BoundsChangeType type = WaylandInputDevice::GetBoundsChangeForWindowComponent(component);
+
+ if(WaylandDisplay::GetDisplay(device->display_)->shell() &&
+ button == BTN_LEFT && state == WL_POINTER_BUTTON_STATE_PRESSED)
+ {
+ switch(type)
+ {
+ case kBoundsChange_Repositions:
+ if(!window->shell_surface())
+ break;
+
+ WaylandDisplay::GetDisplay(device->display_)->SetPointerImage(
+ device, time, CURSOR_DRAGGING);
+ wl_shell_surface_move(window->shell_surface(), device->input_seat_, serial);
+ break;
+ case kBoundsChange_Resizes:
+ if(!window->shell_surface())
+ break;
+
+ wl_shell_surface_resize(window->shell_surface(), device->input_seat_, serial,
+ WaylandInputDevice::GetLocationForWindowComponent(component));
+ break;
+ default:
+ break;
+ }
+ }
+
+ if(type == kBoundsChange_None)
+ window->delegate()->OnMouseEvent(&event);
+}
+
+void WaylandInputDevice::OnKeyNotify(void* data,
+ wl_keyboard* input_keyboard,
+ uint32_t serial,
+ uint32_t time,
+ uint32_t key,
+ uint32_t state)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window = device->keyboard_focus_;
+ uint32_t code, num_syms;
+ const xkb_keysym_t *syms;
+ xkb_keysym_t sym;
+ xkb_mod_mask_t mask;
+
+ WaylandDisplay::GetDisplay(device->display_)->SetSerial(serial);
+
+ WaylandEvent event;
+ event.type = WAYLAND_KEY;
+ event.key.time = time;
+ event.key.key = key;
+ event.key.state = state;
+
+ code = key + 8;
+ num_syms = xkb_key_get_syms(device->xkb_.state, code, &syms);
+
+ mask = xkb_state_serialize_mods(device->xkb_.state,
+ (xkb_state_component)(XKB_STATE_DEPRESSED | XKB_STATE_LATCHED));
+ device->keyboard_modifiers_ = 0;
+ if (mask & device->xkb_.control_mask)
+ device->keyboard_modifiers_ |= MOD_CONTROL_MASK;
+ if (mask & device->xkb_.alt_mask)
+ device->keyboard_modifiers_ |= MOD_ALT_MASK;
+ if (mask & device->xkb_.shift_mask)
+ device->keyboard_modifiers_ |= MOD_SHIFT_MASK;
+
+ if(num_syms == 1)
+ event.key.sym = syms[0];
+ else
+ event.key.sym = NoSymbol;
+ event.key.modifiers = device->keyboard_modifiers_;
+
+ if (!window->delegate())
+ return;
+
+ // TODO: Add key processing
+ //
+ window->delegate()->OnKeyNotify(&event);
+}
+
+void WaylandInputDevice::OnKeyModifiers(void *data, wl_keyboard *keyboard,
+ uint32_t serial, uint32_t mods_depressed, uint32_t mods_latched,
+ uint32_t mods_locked, uint32_t group)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+
+ xkb_state_update_mask(device->xkb_.state, mods_depressed, mods_latched,
+ mods_locked, 0, 0, group);
+}
+
+void WaylandInputDevice::OnPointerEnter(void* data,
+ wl_pointer* input_pointer,
+ uint32_t serial,
+ wl_surface* surface,
+ wl_fixed_t sx_w,
+ wl_fixed_t sy_w)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window;
+
+ GLfloat sx = wl_fixed_to_double(sx_w);
+ GLfloat sy = wl_fixed_to_double(sy_w);
+
+ WaylandDisplay::GetDisplay(device->display_)->SetSerial(serial);
+ device->pointer_enter_serial_ = serial;
+
+ WaylandEvent event;
+ event.type = WAYLAND_POINTER_FOCUS;
+ event.pointer_focus.serial = serial;
+ event.pointer_focus.x = (int32_t)sx;
+ event.pointer_focus.y = (int32_t)sy;
+
+ // If we have a surface, then a new window is in focus
+ event.pointer_focus.state = 1;
+ window = static_cast<WaylandWindow*>(wl_surface_get_user_data(surface));
+ device->pointer_focus_ = window;
+
+ if (!window->delegate())
+ return;
+
+ window->delegate()->OnMouseEnter(&event);
+}
+
+void WaylandInputDevice::OnPointerLeave(void* data,
+ wl_pointer* input_pointer,
+ uint32_t serial,
+ wl_surface* surface)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window = device->pointer_focus_;
+
+ WaylandDisplay::GetDisplay(device->display_)->SetSerial(serial);
+
+ WaylandEvent event;
+ event.type = WAYLAND_POINTER_FOCUS;
+ event.pointer_focus.serial = serial;
+
+ // If we have a window, then this means it loses focus
+ if (window) {
+ if(!WaylandDisplay::GetDisplay(device->display_)->IsWindow(window))
+ return;
+
+ event.pointer_focus.state = 0;
+ device->pointer_focus_ = NULL;
+ device->current_pointer_image_ = POINTER_UNSET;
+
+ if (!window->delegate())
+ return;
+
+ window->delegate()->OnMouseLeave(&event);
+ }
+}
+
+void WaylandInputDevice::OnKeyboardKeymap(void *data,
+ struct wl_keyboard *keyboard,
+ uint32_t format, int fd, uint32_t size)
+{
+}
+
+void WaylandInputDevice::OnKeyboardEnter(void* data,
+ wl_keyboard* input_keyboard,
+ uint32_t serial,
+ wl_surface* surface,
+ wl_array* keys)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window;
+
+ WaylandDisplay::GetDisplay(device->display_)->SetSerial(serial);
+ window = device->keyboard_focus_ =
+ static_cast<WaylandWindow*>(wl_surface_get_user_data(surface));
+
+ WaylandEvent event;
+ event.type = WAYLAND_KEYBOARD_FOCUS;
+ event.keyboard_focus.serial = serial;
+ device->keyboard_modifiers_ = 0;
+ event.keyboard_focus.modifiers = device->keyboard_modifiers_;
+ event.keyboard_focus.state = 1;
+
+ if (!window->delegate())
+ return;
+
+ window->delegate()->OnKeyboardEnter(&event);
+}
+
+void WaylandInputDevice::OnKeyboardLeave(void* data,
+ wl_keyboard* input_keyboard,
+ uint32_t serial,
+ wl_surface* surface)
+{
+ WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data);
+ WaylandWindow* window = device->keyboard_focus_;
+
+ WaylandDisplay::GetDisplay(device->display_)->SetSerial(serial);
+
+ WaylandEvent event;
+ event.type = WAYLAND_KEYBOARD_FOCUS;
+ event.keyboard_focus.serial = serial;
+ device->keyboard_modifiers_ = 0;
+
+ // If there is a window, then it loses focus
+ if (window) {
+ if(!WaylandDisplay::GetDisplay(device->display_)->IsWindow(window))
+ return;
+
+ event.keyboard_focus.state = 0;
+ device->keyboard_focus_ = NULL;
+
+ if (!window->delegate())
+ return;
+
+ window->delegate()->OnKeyboardLeave(&event);
+ }
+}
+
+} // namespace ui
« no previous file with comments | « ui/wayland/wayland_input_device.h ('k') | ui/wayland/wayland_input_method_event_filter.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698