diff options
author | dnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-28 17:38:23 +0000 |
---|---|---|
committer | dnicoara@chromium.org <dnicoara@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-07-28 17:38:23 +0000 |
commit | 236754afe8615dfffebc8f5f4b0257c4cebcf137 (patch) | |
tree | c513216c90163f869ac0a925ad31e45ae3b57c2d /ui/wayland | |
parent | ffdd452063e25308a32c71944d17af3557b77f38 (diff) | |
download | chromium_src-236754afe8615dfffebc8f5f4b0257c4cebcf137.zip chromium_src-236754afe8615dfffebc8f5f4b0257c4cebcf137.tar.gz chromium_src-236754afe8615dfffebc8f5f4b0257c4cebcf137.tar.bz2 |
Adding a Wayland basic toolkit
This is essentially a OO wrapper over the Wayland library. It will be used to
add Wayland support for Chrome.
This was written with the intent of being as standalone as possible and it
should not require any external Chrome dependencies.
BUG=None
TEST=None
R=evan@chromium.org
Review URL: http://codereview.chromium.org/7457023
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94492 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui/wayland')
-rw-r--r-- | ui/wayland/events/wayland_event.h | 127 | ||||
-rw-r--r-- | ui/wayland/wayland.gyp | 42 | ||||
-rw-r--r-- | ui/wayland/wayland_buffer.cc | 15 | ||||
-rw-r--r-- | ui/wayland/wayland_buffer.h | 36 | ||||
-rw-r--r-- | ui/wayland/wayland_cursor.cc | 76 | ||||
-rw-r--r-- | ui/wayland/wayland_cursor.h | 42 | ||||
-rw-r--r-- | ui/wayland/wayland_display.cc | 158 | ||||
-rw-r--r-- | ui/wayland/wayland_display.h | 105 | ||||
-rw-r--r-- | ui/wayland/wayland_input_device.cc | 211 | ||||
-rw-r--r-- | ui/wayland/wayland_input_device.h | 123 | ||||
-rw-r--r-- | ui/wayland/wayland_message_pump.cc | 78 | ||||
-rw-r--r-- | ui/wayland/wayland_message_pump.h | 63 | ||||
-rw-r--r-- | ui/wayland/wayland_screen.cc | 78 | ||||
-rw-r--r-- | ui/wayland/wayland_screen.h | 79 | ||||
-rw-r--r-- | ui/wayland/wayland_shm_buffer.cc | 65 | ||||
-rw-r--r-- | ui/wayland/wayland_shm_buffer.h | 39 | ||||
-rw-r--r-- | ui/wayland/wayland_widget.h | 28 | ||||
-rw-r--r-- | ui/wayland/wayland_window.cc | 84 | ||||
-rw-r--r-- | ui/wayland/wayland_window.h | 87 |
19 files changed, 1536 insertions, 0 deletions
diff --git a/ui/wayland/events/wayland_event.h b/ui/wayland/events/wayland_event.h new file mode 100644 index 0000000..0c20361 --- /dev/null +++ b/ui/wayland/events/wayland_event.h @@ -0,0 +1,127 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_EVENTS_WAYLAND_EVENT_H_ +#define UI_WAYLAND_EVENTS_WAYLAND_EVENT_H_ + +#include <linux/input.h> +#include <stdint.h> + +// Wayland event information is being passed in as arguments to the callbacks. +// (See wayland_input_device.{h,cc} for information on the callbacks and how +// events are processed.) +// In order to provide a more generic look for events we wrap these arguments +// in specific event structs. Then define a WaylandEvent as a union of all +// types of events that Wayland will send. +// +// The following fields are common for most event types and their use is +// similar: +// - time: +// The time of the event. This should be monotonically increasing. +// - state: +// The value of the button event as given by evdev. This is 0 if button +// isn't pressed. +// - modifiers: +// Stores all the keyboard modifiers (Ctrl, Alt, Shift, ...) currently +// active. The modifiers are values as defined by xkbcommon. + +namespace ui { + +// Types of events Wayland will send +enum WaylandEventType { + WAYLAND_BUTTON, + WAYLAND_KEY, + WAYLAND_MOTION, + WAYLAND_POINTER_FOCUS, + WAYLAND_KEYBOARD_FOCUS, + WAYLAND_GEOMETRY_CHANGE, +}; + +// These are the mouse events expected. The event type Wayland sends is an +// evdev event. The following is the correct mapping from evdev to expected +// events type. +enum WaylandEventButtonType { + LEFT_BUTTON = BTN_LEFT, + MIDDLE_BUTTON = BTN_RIGHT, + RIGHT_BUTTON = BTN_MIDDLE, + SCROLL_UP = BTN_SIDE, + SCROLL_DOWN = BTN_EXTRA, +}; + +struct WaylandEventButton { + WaylandEventType type; + uint32_t time; + // WaylandEventButtonType defines some of the values button can take + uint32_t button; + uint32_t state; + uint32_t modifiers; + int32_t x; + int32_t y; +}; + +struct WaylandEventKey { + WaylandEventType type; + uint32_t time; + // The raw key value that evdev returns. + uint32_t key; + // The key symbol returned by processing the raw key using the xkbcommon + // library. + uint32_t sym; + uint32_t state; + uint32_t modifiers; +}; + +// Triggered when there is a motion event. The motion event is triggered +// only if there is a window under focus. +struct WaylandEventMotion { + WaylandEventType type; + uint32_t time; + uint32_t modifiers; + int32_t x; + int32_t y; +}; + +// Triggered when a window enters/exits pointer focus. The state tells us +// if the window lost focus (state == 0) or gained focus (state != 0). +struct WaylandEventPointerFocus { + WaylandEventType type; + uint32_t time; + uint32_t state; + int32_t x; + int32_t y; +}; + +// Triggered when a window enters/exits keyboard focus. The state tells us +// if the window lost focus (state == 0) or gained focus (state != 0). +struct WaylandEventKeyboardFocus { + WaylandEventType type; + uint32_t time; + uint32_t state; + uint32_t modifiers; +}; + +// Event triggered when a window's geometry changes. The event contains the +// position and dimensions of the window. +struct WaylandEventGeometryChange { + WaylandEventType type; + uint32_t time; + int32_t x; + int32_t y; + int32_t width; + int32_t height; +}; + +union WaylandEvent { + WaylandEventType type; + WaylandEventButton button; + WaylandEventKey key; + WaylandEventMotion motion; + WaylandEventPointerFocus pointer_focus; + WaylandEventKeyboardFocus keyboard_focus; + WaylandEventGeometryChange geometry_change; +}; + +} // namespace ui + +#endif // UI_WAYLAND_EVENTS_WAYLAND_EVENT_H_ diff --git a/ui/wayland/wayland.gyp b/ui/wayland/wayland.gyp new file mode 100644 index 0000000..72e456e --- /dev/null +++ b/ui/wayland/wayland.gyp @@ -0,0 +1,42 @@ +# Copyright (c) 2011 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. + +{ + 'targets': [ + { + 'target_name': 'wayland', + 'type': 'static_library', + 'dependencies': [ + '../../base/base.gyp:base', + '../../build/linux/system.gyp:wayland', + '../ui.gyp:ui', + ], + 'include_dirs': [ + '.', + '../..', + 'events', + ], + 'sources': [ + 'events/wayland_event.h', + 'wayland_buffer.cc', + 'wayland_buffer.h', + 'wayland_cursor.cc', + 'wayland_cursor.h', + 'wayland_display.cc', + 'wayland_display.h', + 'wayland_input_device.cc', + 'wayland_input_device.h', + 'wayland_message_pump.cc', + 'wayland_message_pump.h', + 'wayland_screen.cc', + 'wayland_screen.h', + 'wayland_shm_buffer.cc', + 'wayland_shm_buffer.h', + 'wayland_widget.h', + 'wayland_window.cc', + 'wayland_window.h', + ], + } + ], +} diff --git a/ui/wayland/wayland_buffer.cc b/ui/wayland/wayland_buffer.cc new file mode 100644 index 0000000..4fed8a18 --- /dev/null +++ b/ui/wayland/wayland_buffer.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2011 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_buffer.h" + +namespace ui { + +WaylandBuffer::WaylandBuffer() { +} + +WaylandBuffer::~WaylandBuffer() { +} + +} // namespace ui diff --git a/ui/wayland/wayland_buffer.h b/ui/wayland/wayland_buffer.h new file mode 100644 index 0000000..a5b84c5 --- /dev/null +++ b/ui/wayland/wayland_buffer.h @@ -0,0 +1,36 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_BUFFER_H_ +#define UI_WAYLAND_WAYLAND_BUFFER_H_ + +#include "base/basictypes.h" + +struct wl_buffer; + +namespace ui { + +// Wrapper around a wl_buffer. A wl_buffer is associated with a drawing +// surface. +// +// This class is a basic interface of what a buffer should be/provide. +// Implementations whould create and destroy the wl_buffer. +class WaylandBuffer { + public: + WaylandBuffer(); + virtual ~WaylandBuffer(); + + wl_buffer* buffer() const { return buffer_; } + + protected: + // Owned by this object and should be destroyed by this object. + wl_buffer* buffer_; + + private: + DISALLOW_COPY_AND_ASSIGN(WaylandBuffer); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_BUFFER_H_ diff --git a/ui/wayland/wayland_cursor.cc b/ui/wayland/wayland_cursor.cc new file mode 100644 index 0000000..54d915d --- /dev/null +++ b/ui/wayland/wayland_cursor.cc @@ -0,0 +1,76 @@ +// Copyright (c) 2011 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_cursor.h" + +#include <cairo.h> + +#include "base/logging.h" +#include "ui/wayland/wayland_display.h" +#include "ui/wayland/wayland_shm_buffer.h" + +namespace { + +struct PointerImage { + const char* filename; + int hotspot_x, hotspot_y; +}; + +// TODO(dnicoara) Add more pointer images and fix the path. +const PointerImage kPointerImages[] = { + {"left_ptr.png", 10, 5}, + {"hand.png", 10, 5}, +}; + +} // namespace + +namespace ui { + +WaylandCursor::WaylandCursor(WaylandDisplay* display) + : display_(display), + buffer_(NULL) { +} + +WaylandCursor::~WaylandCursor() { + if (buffer_) { + delete buffer_; + buffer_ = NULL; + } +} + +void WaylandCursor::ChangeCursor(Type type) { + const PointerImage& ptr = kPointerImages[type]; + + cairo_surface_t* ptr_surface = cairo_image_surface_create_from_png( + ptr.filename); + + if (!ptr_surface) { + LOG(ERROR) << "Failed to create cursor surface"; + return; + } + + int width = cairo_image_surface_get_width(ptr_surface); + int height = cairo_image_surface_get_height(ptr_surface); + + if (buffer_) { + delete buffer_; + buffer_ = NULL; + } + + // TODO(dnicoara) There should be a simpler way to create a wl_buffer for + // a cairo surface. Meantime we just copy the contents of the cairo surface + // created from file to the cairo surface created using a shm file. + buffer_ = new WaylandShmBuffer(display_, width, height); + cairo_surface_t* shared_surface = buffer_->data_surface(); + + cairo_t* cr = cairo_create(shared_surface); + cairo_set_source_surface(cr, ptr_surface, 0, 0); + cairo_rectangle(cr, 0, 0, width, height); + cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE); + cairo_fill(cr); + + display_->SetCursor(buffer_, ptr.hotspot_x, ptr.hotspot_y); +} + +} // namespace ui diff --git a/ui/wayland/wayland_cursor.h b/ui/wayland/wayland_cursor.h new file mode 100644 index 0000000..748252b --- /dev/null +++ b/ui/wayland/wayland_cursor.h @@ -0,0 +1,42 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_CURSOR_H_ +#define UI_WAYLAND_WAYLAND_CURSOR_H_ + +#include "base/basictypes.h" + +namespace ui { + +class WaylandDisplay; +class WaylandShmBuffer; + +// This class allows applications to change the currently displaying cursor. +class WaylandCursor { + public: + // Types of Wayland cursors supported + enum Type { + ARROW_CURSOR, + HAND_CURSOR, + }; + + explicit WaylandCursor(WaylandDisplay* display); + ~WaylandCursor(); + + // Used to change the current type to the type specified in 'type' + void ChangeCursor(Type type); + + private: + // Pointer to the current display. This is not owned by this class. + WaylandDisplay* display_; + // The currently set cursor image. + // This class should dispose of this on deletion. + WaylandShmBuffer* buffer_; + + DISALLOW_COPY_AND_ASSIGN(WaylandCursor); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_CURSOR_H_ diff --git a/ui/wayland/wayland_display.cc b/ui/wayland/wayland_display.cc new file mode 100644 index 0000000..3c7246c --- /dev/null +++ b/ui/wayland/wayland_display.cc @@ -0,0 +1,158 @@ +// Copyright (c) 2011 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_display.h" + +#include <string.h> +#include <wayland-client.h> + +#include "ui/wayland/wayland_buffer.h" +#include "ui/wayland/wayland_input_device.h" +#include "ui/wayland/wayland_screen.h" +#include "ui/wayland/wayland_window.h" + +namespace ui { + +// static +WaylandDisplay* WaylandDisplay::Connect(char* name) { + WaylandDisplay* display = new WaylandDisplay(name); + if (!display->display_) { + delete display; + return NULL; + } + + wl_display_set_user_data(display->display_, display); + // Register the display initialization handler and iterate over the initial + // connection events sent by the server. This is required since the display + // will send registration events needed to initialize everything else. This + // will create the compositor, visuals, etc.., which are required in creating + // a drawing context. + wl_display_add_global_listener(display->display_, + WaylandDisplay::DisplayHandleGlobal, + display); + wl_display_iterate(display->display_, WL_DISPLAY_READABLE); + + return display; +} + +// static +WaylandDisplay* WaylandDisplay::GetDisplay(wl_display* display) { + return static_cast<WaylandDisplay*>(wl_display_get_user_data(display)); +} + +WaylandDisplay::WaylandDisplay(char* name) : display_(NULL), + compositor_(NULL), + shell_(NULL), + shm_(NULL), + visual_(NULL) { + display_ = wl_display_connect(name); +} + +WaylandDisplay::~WaylandDisplay() { + if (display_) + wl_display_destroy(display_); + if (compositor_) + wl_compositor_destroy(compositor_); + if (visual_) + wl_visual_destroy(visual_); + if (shell_) + wl_shell_destroy(shell_); + if (shm_) + wl_shm_destroy(shm_); + for (std::list<WaylandInputDevice*>::iterator i = input_list_.begin(); + i != input_list_.end(); ++i) { + delete *i; + } + for (std::list<WaylandScreen*>::iterator i = screen_list_.begin(); + i != screen_list_.end(); ++i) { + delete *i; + } +} + +wl_surface* WaylandDisplay::CreateSurface() { + return wl_compositor_create_surface(compositor_); +} + +void WaylandDisplay::SetCursor(WaylandBuffer* buffer, + int32_t x, int32_t y) { + // Currently there is no way of knowing which input device should have the + // buffer attached, so we just attach to every input device. + for (std::list<WaylandInputDevice*>::iterator i = input_list_.begin(); + i != input_list_.end(); ++i) { + (*i)->Attach(buffer->buffer(), x, y); + } +} + +std::list<WaylandScreen*> WaylandDisplay::GetScreenList() const { + return screen_list_; +} + +// static +void WaylandDisplay::DisplayHandleGlobal(wl_display* display, + uint32_t id, + const char* interface, + uint32_t version, + void* data) { + WaylandDisplay* disp = static_cast<WaylandDisplay*>(data); + + static const wl_compositor_listener kCompositorListener = { + WaylandDisplay::CompositorHandleVisual, + }; + static const wl_shell_listener kShellListener = { + WaylandDisplay::ShellHandleConfigure, + }; + + if (strcmp(interface, "wl_compositor") == 0) { + disp->compositor_ = wl_compositor_create(display, id, 1); + wl_compositor_add_listener(disp->compositor_, + &kCompositorListener, + disp); + } else if (strcmp(interface, "wl_output") == 0) { + WaylandScreen* screen = new WaylandScreen(disp, id); + disp->screen_list_.push_back(screen); + } else if (strcmp(interface, "wl_input_device") == 0) { + WaylandInputDevice *input_device = new WaylandInputDevice(display, id); + disp->input_list_.push_back(input_device); + } else if (strcmp(interface, "wl_shell") == 0) { + disp->shell_ = wl_shell_create(display, id, 1); + wl_shell_add_listener(disp->shell_, &kShellListener, disp); + } else if (strcmp(interface, "wl_shm") == 0) { + disp->shm_ = wl_shm_create(display, id, 1); + } +} + +// static +void WaylandDisplay::CompositorHandleVisual(void* data, + wl_compositor* compositor, + uint32_t id, + uint32_t token) { + WaylandDisplay* display = static_cast<WaylandDisplay*>(data); + + // The compositor may support multiple types of visuals but we really only + // need one. + switch (token) { + case WL_COMPOSITOR_VISUAL_ARGB32: + break; + case WL_COMPOSITOR_VISUAL_PREMULTIPLIED_ARGB32: + display->visual_ = wl_visual_create(display->display_, id, 1); + break; + case WL_COMPOSITOR_VISUAL_XRGB32: + break; + } +} + +// static +void WaylandDisplay::ShellHandleConfigure(void* data, + wl_shell* shell, + uint32_t time, + uint32_t edges, + wl_surface* surface, + int32_t width, + int32_t height) { + WaylandWindow* window = static_cast<WaylandWindow*>( + wl_surface_get_user_data(surface)); + window->Configure(time, edges, 0, 0, width, height); +} + +} // namespace ui diff --git a/ui/wayland/wayland_display.h b/ui/wayland/wayland_display.h new file mode 100644 index 0000000..424c45c --- /dev/null +++ b/ui/wayland/wayland_display.h @@ -0,0 +1,105 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_DISPLAY_H_ +#define UI_WAYLAND_WAYLAND_DISPLAY_H_ + +#include <stdint.h> + +#include <list> + +#include "base/basictypes.h" + +struct wl_compositor; +struct wl_display; +struct wl_shell; +struct wl_shm; +struct wl_surface; +struct wl_visual; + +namespace ui { + +class WaylandBuffer; +class WaylandInputDevice; +class WaylandScreen; + +// WaylandDisplay is a wrapper around wl_display. Once we get a valid +// wl_display, the Wayland server will send different events to register +// the Wayland compositor, shell, visuals, screens, input devices, ... +class WaylandDisplay { + public: + // Attempt to create a connection to the display. If it fails this returns + // NULL + static WaylandDisplay* Connect(char* name); + + // Get the WaylandDisplay associated with the native Wayland display + static WaylandDisplay* GetDisplay(wl_display* display); + + ~WaylandDisplay(); + + // Creates a wayland surface. This is used to create a window surface. + // The returned pointer should be deleted by the caller. + wl_surface* CreateSurface(); + + // Sets the specified buffer as the surface for the cursor. (x, y) is + // the hotspot for the cursor. + void SetCursor(WaylandBuffer* buffer, int32_t x, int32_t y); + + // Returns a pointer to the wl_display. + wl_display* display() const { return display_; } + + // Returns a list of the registered screens. + std::list<WaylandScreen*> GetScreenList() const; + + wl_shell* shell() const { return shell_; } + + wl_shm* shm() const { return shm_; } + + wl_visual* visual() const { return visual_; } + + private: + WaylandDisplay(char* name); + + // This handler resolves all server events used in initialization. It also + // handles input device registration, screen registration. + static void DisplayHandleGlobal(wl_display* display, + uint32_t id, + const char* interface, + uint32_t version, + void* data); + + // Used by the compositor initialization to register the different visuals. + static void CompositorHandleVisual(void* data, + wl_compositor* compositor, + uint32_t id, + uint32_t token); + + // Used when the shell requires configuration. This is called when a + // window is configured and receives its size. + // TODO(dnicoara) Need to look if there is one shell per window. Then it + // makes more sense to move this into the WaylandWindow and it would keep + // track of the shell. + static void ShellHandleConfigure(void* data, + wl_shell* shell, + uint32_t time, + uint32_t edges, + wl_surface* surface, + int32_t width, + int32_t height); + + // WaylandDisplay manages the memory of all these pointers. + wl_display* display_; + wl_compositor* compositor_; + wl_shell* shell_; + wl_shm* shm_; + wl_visual* visual_; + std::list<WaylandScreen*> screen_list_; + std::list<WaylandInputDevice*> input_list_; + + DISALLOW_COPY_AND_ASSIGN(WaylandDisplay); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_DISPLAY_H_ diff --git a/ui/wayland/wayland_input_device.cc b/ui/wayland/wayland_input_device.cc new file mode 100644 index 0000000..05efd98 --- /dev/null +++ b/ui/wayland/wayland_input_device.cc @@ -0,0 +1,211 @@ +// Copyright (c) 2011 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/extensions/XKBcommon.h> +#include <wayland-client.h> + +#include "ui/wayland/events/wayland_event.h" +#include "ui/wayland/wayland_widget.h" +#include "ui/wayland/wayland_window.h" + +namespace ui { + +WaylandInputDevice::WaylandInputDevice( + wl_display* display, + uint32_t id) + : input_device_(wl_input_device_create(display, id, 1)), + pointer_focus_(NULL), + keyboard_focus_(NULL), + keyboard_modifiers_(0) { + + // List of callback functions for input device events. + static const struct wl_input_device_listener kInputDeviceListener = { + WaylandInputDevice::OnMotionNotify, + WaylandInputDevice::OnButtonNotify, + WaylandInputDevice::OnKeyNotify, + WaylandInputDevice::OnPointerFocus, + WaylandInputDevice::OnKeyboardFocus, + }; + + wl_input_device_add_listener(input_device_, &kInputDeviceListener, this); + wl_input_device_set_user_data(input_device_, this); + + struct xkb_rule_names names; + names.rules = "evdev"; + names.model = "pc105"; + names.layout = "us"; + names.variant = ""; + names.options = ""; + + xkb_ = xkb_compile_keymap_from_rules(&names); +} + +WaylandInputDevice::~WaylandInputDevice() { + if (input_device_) + wl_input_device_destroy(input_device_); +} + +void WaylandInputDevice::Attach(wl_buffer* buffer, int32_t x, int32_t y) { + wl_input_device_attach(input_device_, last_event_time_, buffer, x, y); +} + +void WaylandInputDevice::OnMotionNotify(void* data, + wl_input_device* input_device, + uint32_t time, + int32_t x, + int32_t y, + int32_t sx, + int32_t sy) { + WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data); + WaylandWindow* window = device->pointer_focus_; + + device->last_event_time_ = time; + device->global_position_.SetPoint(x, y); + 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; + + window->widget()->OnMotionNotify(event); +} + +void WaylandInputDevice::OnButtonNotify(void* data, + wl_input_device* input_device, + uint32_t time, + uint32_t button, + uint32_t state) { + WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data); + WaylandWindow* window = device->pointer_focus_; + + device->last_event_time_ = time; + + 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(); + + window->widget()->OnButtonNotify(event); +} + +void WaylandInputDevice::OnKeyNotify(void* data, + wl_input_device* input_device, + uint32_t time, + uint32_t key, + uint32_t state) { + WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data); + WaylandWindow* window = device->keyboard_focus_; + struct xkb_desc *xkb = device->xkb_; + + device->last_event_time_ = time; + + WaylandEvent event; + event.type = WAYLAND_KEY; + event.key.time = time; + event.key.key = key; + event.key.state = state; + + uint32_t code = key + xkb->min_key_code; + uint32_t level = 0; + if ((device->keyboard_modifiers_ & XKB_COMMON_SHIFT_MASK) && + XkbKeyGroupWidth(xkb, code, 0) > 1) { + level = 1; + } + + event.key.sym = XkbKeySymEntry(xkb, code, level, 0); + if (state) + device->keyboard_modifiers_ |= xkb->map->modmap[code]; + else + device->keyboard_modifiers_ &= ~xkb->map->modmap[code]; + + event.key.modifiers = device->keyboard_modifiers_; + + window->widget()->OnKeyNotify(event); +} + +void WaylandInputDevice::OnPointerFocus(void* data, + wl_input_device* input_device, + uint32_t time, + wl_surface* surface, + int32_t x, + int32_t y, + int32_t sx, + int32_t sy) { + WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data); + WaylandWindow* window = device->pointer_focus_; + + device->last_event_time_ = time; + + WaylandEvent event; + event.type = WAYLAND_POINTER_FOCUS; + event.pointer_focus.time = time; + event.pointer_focus.x = sx; + event.pointer_focus.y = sy; + + // If we have a window, then this means it loses focus + if (window) { + event.pointer_focus.state = 0; + device->pointer_focus_ = NULL; + window->widget()->OnPointerFocus(event); + } + + // If we have a surface, then a new window is in focus + if (surface) { + event.pointer_focus.state = 1; + window = static_cast<WaylandWindow*>(wl_surface_get_user_data(surface)); + device->pointer_focus_ = window; + window->widget()->OnPointerFocus(event); + } +} + +void WaylandInputDevice::OnKeyboardFocus(void* data, + wl_input_device* input_device, + uint32_t time, + wl_surface* surface, + wl_array* keys) { + WaylandInputDevice* device = static_cast<WaylandInputDevice*>(data); + WaylandWindow* window = device->keyboard_focus_; + struct xkb_desc* xkb = device->xkb_; + + device->last_event_time_ = time; + + WaylandEvent event; + event.type = WAYLAND_KEYBOARD_FOCUS; + event.keyboard_focus.time = time; + device->keyboard_modifiers_ = 0; + + uint32_t* codes = static_cast<uint32_t*>(keys->data); + int codes_size = keys->size / sizeof(uint32_t); + for (int i = 0; i < codes_size; i++) { + uint32_t code = codes[i] + xkb->min_key_code; + device->keyboard_modifiers_ |= xkb->map->modmap[code]; + } + event.keyboard_focus.modifiers = device->keyboard_modifiers_; + + // If there is a window, then it loses focus + if (window) { + event.keyboard_focus.state = 0; + device->keyboard_focus_ = NULL; + window->widget()->OnKeyboardFocus(event); + } + + // If we have a surface, then a window gains focus + if (surface) { + event.keyboard_focus.state = 1; + window = static_cast<WaylandWindow*>(wl_surface_get_user_data(surface)); + device->keyboard_focus_ = window; + window->widget()->OnKeyboardFocus(event); + } +} + +} // namespace ui diff --git a/ui/wayland/wayland_input_device.h b/ui/wayland/wayland_input_device.h new file mode 100644 index 0000000..3250463 --- /dev/null +++ b/ui/wayland/wayland_input_device.h @@ -0,0 +1,123 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_INPUT_DEVICE_H_ +#define UI_WAYLAND_WAYLAND_INPUT_DEVICE_H_ + +#include <stdint.h> + +#include "base/basictypes.h" +#include "ui/gfx/point.h" +#include "ui/wayland/wayland_widget.h" + +struct xkb_desc; +struct wl_array; +struct wl_buffer; +struct wl_display; +struct wl_input_device; +struct wl_input_device_listener; +struct wl_surface; + +namespace ui { + +class WaylandWindow; + +// This class represents an input device that was registered with Wayland. +// The purpose of this class is to parse and wrap events into generic +// WaylandEvent types and dispatch the event to the appropriate WaylandWindow. +// +// How Wayland events work: +// ------------------------ +// +// When the On*Focus events are triggered, the input device receives a +// reference to the surface that just received/lost focus. Each surface is +// associated with a unique WaylandWindow. When processing the focus events we +// keep track of the currently focused window such that when we receive +// different events (mouse button press or key press) we only send the event to +// the window in focus. +class WaylandInputDevice { + public: + WaylandInputDevice(wl_display* display, uint32_t id); + ~WaylandInputDevice(); + + // Used to change the surface of the input device (normally pointer image). + void Attach(wl_buffer* buffer, int32_t x, int32_t y); + + private: + // Input device callback functions. These will create 'WaylandEvent's and + // send them to the currently focused window. + // Args: + // - data: Pointer to the WaylandInputDevice object associated with the + // 'input_device' + // - input_device: + // The input device that sent the event + // - time: The time of the event. + static void OnMotionNotify(void* data, + wl_input_device* input_device, + uint32_t time, + int32_t x, + int32_t y, + int32_t sx, + int32_t sy); + + static void OnButtonNotify(void* data, + wl_input_device* input_device, + uint32_t time, + uint32_t button, + uint32_t state); + + static void OnKeyNotify(void* data, + wl_input_device* input_device, + uint32_t time, + uint32_t key, + uint32_t state); + + // On*Focus events also have a Wayland surface associated with them. If the + // surface is NULL, then the event signifies a loss of focus. Otherwise we + // use the surface to get the WaylandWindow that receives focus. + static void OnPointerFocus(void* data, + wl_input_device* input_device, + uint32_t time, + wl_surface *surface, + int32_t x, + int32_t y, + int32_t sx, + int32_t sy); + + static void OnKeyboardFocus(void* data, + wl_input_device* input_device, + uint32_t time, + wl_surface *surface, + wl_array* keys); + + wl_input_device* input_device_; + + // These keep track of the window that's currently under focus. NULL if no + // window is under focus. + WaylandWindow* pointer_focus_; + WaylandWindow* keyboard_focus_; + + // Keeps track of the currently active keyboard modifiers. We keep this + // since we want to advertise keyboard modifiers with mouse events. + uint32_t keyboard_modifiers_; + + // Keeps track of the last position for the motion event. We want to + // publish this with events such as button notify which doesn't have a + // position associated by default. + gfx::Point global_position_; + gfx::Point surface_position_; + + // Keep track of the time of last event. Useful when we get buffer Attach + // calls and the calls wouldn't have a way of getting an event time. + uint32_t last_event_time_; + + // keymap used to transform keyboard events. + xkb_desc* xkb_; + + DISALLOW_COPY_AND_ASSIGN(WaylandInputDevice); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_INPUT_DEVICE_H_ diff --git a/ui/wayland/wayland_message_pump.cc b/ui/wayland/wayland_message_pump.cc new file mode 100644 index 0000000..9e7e671 --- /dev/null +++ b/ui/wayland/wayland_message_pump.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2011 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_message_pump.h" + +#include <wayland-client.h> + +#include "ui/wayland/wayland_display.h" + +namespace ui { + +WaylandMessagePump::WaylandMessagePump(WaylandDisplay* display) + : display_(display) { + static GSourceFuncs kSourceHandlers = { + WaylandMessagePump::SourcePrepare, + WaylandMessagePump::SourceCheck, + WaylandMessagePump::SourceDispatch, + NULL + }; + + source_ = static_cast<WorkSource*>( + g_source_new(&kSourceHandlers, sizeof(WorkSource))); + source_->pump = this; + pfd_.fd = wl_display_get_fd(display_->display(), + WaylandMessagePump::SourceUpdate, + source_); + pfd_.events = G_IO_IN | G_IO_ERR; + g_source_add_poll(source_, &pfd_); + g_source_attach(source_, NULL); +} + +WaylandMessagePump::~WaylandMessagePump() { + g_source_destroy(source_); + g_source_unref(source_); +} + +int WaylandMessagePump::HandlePrepare() { + while (mask_ & WL_DISPLAY_WRITABLE) + wl_display_iterate(display_->display(), WL_DISPLAY_WRITABLE); + + return -1; +} + +bool WaylandMessagePump::HandleCheck() { + return pfd_.revents; +} + +void WaylandMessagePump::HandleDispatch() { + wl_display_iterate(display_->display(), WL_DISPLAY_READABLE); +} + +// static +gboolean WaylandMessagePump::SourcePrepare(GSource* source, gint* timeout) { + *timeout = static_cast<WorkSource*>(source)->pump->HandlePrepare(); + return FALSE; +} + +// static +gboolean WaylandMessagePump::SourceCheck(GSource* source) { + return static_cast<WorkSource*>(source)->pump->HandleCheck(); +} + +// static +gboolean WaylandMessagePump::SourceDispatch(GSource* source, + GSourceFunc callback, + gpointer data) { + static_cast<WorkSource*>(source)->pump->HandleDispatch(); + return TRUE; +} + +// static +int WaylandMessagePump::SourceUpdate(uint32_t mask, void* data) { + static_cast<WorkSource*>(data)->pump->mask_ = mask; + return 0; +} + +} // namespace ui diff --git a/ui/wayland/wayland_message_pump.h b/ui/wayland/wayland_message_pump.h new file mode 100644 index 0000000..8ae7a91 --- /dev/null +++ b/ui/wayland/wayland_message_pump.h @@ -0,0 +1,63 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_MESSAGE_PUMP_H_ +#define UI_WAYLAND_WAYLAND_MESSAGE_PUMP_H_ + +#include <glib.h> +#include <stdint.h> + +#include "base/basictypes.h" + +namespace ui { + +class WaylandDisplay; + +// The message pump handles Wayland specific event delivery. This message +// pump uses the default glib context, so running a glib main loop with the +// default context will allow looping through Wayland events. +class WaylandMessagePump { + public: + explicit WaylandMessagePump(WaylandDisplay* display); + virtual ~WaylandMessagePump(); + + protected: + // These are used to process the pump callbacks. + // HandlePrepare: is called during glib's prepare step and returns a timeout + // that will be passed to the poll. + // HandleCheck: called after HandlePrepare and returns whether + // HandleDispatch should be called. + // HandleDispatch:is called after HandleCheck returns true and it will + // dispatch a Wayland event. + virtual int HandlePrepare(); + virtual bool HandleCheck(); + virtual void HandleDispatch(); + + private: + struct WorkSource : public GSource { + WaylandMessagePump* pump; + }; + + // Actual callbacks for glib. These functions will just call the appropriate + // Handle* functions in a WaylandMessagePump object. + static gboolean SourcePrepare(GSource* source, gint* timeout); + static gboolean SourceCheck(GSource* source); + static gboolean SourceDispatch(GSource* source, + GSourceFunc callback, + gpointer data); + // Handles updates to the Wayland mask. This is used to signal when the + // compositor is done processing writable events. + static int SourceUpdate(uint32_t mask, void* data); + + WaylandDisplay* display_; + WorkSource* source_; + GPollFD pfd_; + uint32_t mask_; + + DISALLOW_COPY_AND_ASSIGN(WaylandMessagePump); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_MESSAGE_PUMP_H_ diff --git a/ui/wayland/wayland_screen.cc b/ui/wayland/wayland_screen.cc new file mode 100644 index 0000000..73a181b --- /dev/null +++ b/ui/wayland/wayland_screen.cc @@ -0,0 +1,78 @@ +// Copyright (c) 2011 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_screen.h" + +#include <wayland-client.h> + +#include "ui/wayland/wayland_display.h" + +namespace ui { + +WaylandScreen::WaylandScreen(WaylandDisplay* display, uint32_t id) + : output_(NULL), + display_(display) { + static const wl_output_listener kOutputListener = { + WaylandScreen::OutputHandleGeometry, + WaylandScreen::OutputHandleMode, + }; + + output_ = wl_output_create(display_->display(), id, 1); + wl_output_add_listener(output_, &kOutputListener, this); +} + +WaylandScreen::~WaylandScreen() { + if (output_) + wl_output_destroy(output_); +} + +gfx::Rect WaylandScreen::GetAllocation() const { + gfx::Rect allocation; + allocation.set_origin(position_); + + // Find the active mode and pass its dimensions. + for (Modes::const_iterator i = modes_.begin(); i != modes_.end(); ++i) { + if ((*i).flags & WL_OUTPUT_MODE_CURRENT) { + allocation.set_width((*i).width); + allocation.set_height((*i).height); + break; + } + } + + return allocation; +} + +// static +void WaylandScreen::OutputHandleGeometry(void* data, + wl_output* output, + int32_t x, + int32_t y, + int32_t physical_width, + int32_t physical_height, + int32_t subpixel, + const char* make, + const char* model) { + WaylandScreen* screen = static_cast<WaylandScreen*>(data); + screen->position_.SetPoint(x, y); +} + +// static +void WaylandScreen::OutputHandleMode(void* data, + wl_output* wl_output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh) { + WaylandScreen* screen = static_cast<WaylandScreen*>(data); + + Mode mode; + mode.width = width; + mode.height = height; + mode.refresh = refresh; + mode.flags = flags; + + screen->modes_.push_back(mode); +} + +} // namespace ui diff --git a/ui/wayland/wayland_screen.h b/ui/wayland/wayland_screen.h new file mode 100644 index 0000000..828762f --- /dev/null +++ b/ui/wayland/wayland_screen.h @@ -0,0 +1,79 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_SCREEN_H_ +#define UI_WAYLAND_WAYLAND_SCREEN_H_ + +#include <stdint.h> + +#include <list> + +#include "base/basictypes.h" +#include "ui/gfx/point.h" +#include "ui/gfx/rect.h" + +struct wl_output; + +namespace ui { + +class WaylandDisplay; + +// WaylandScreen objects keep track of the current outputs (screens/monitors) +// that are available to the application. +class WaylandScreen { + public: + WaylandScreen(WaylandDisplay* display, uint32_t id); + ~WaylandScreen(); + + // Returns the active allocation of the screen. + gfx::Rect GetAllocation() const; + + private: + // Used to store information regarding the available modes for the current + // screen. + // - (width, height): is the resolution of the screen + // - refresh: is the refresh rate of the screen under this mode + // - flags: contains extra information regarding the mode. The most important + // is the active mode flag. + struct Mode { + int32_t width, height, refresh, flags; + }; + typedef std::list<Mode> Modes; + + // Callback functions that allows the display to initialize the screen's + // position and available modes. + static void OutputHandleGeometry(void* data, + wl_output* output, + int32_t x, + int32_t y, + int32_t physical_width, + int32_t physical_height, + int32_t subpixel, + const char* make, + const char* model); + + static void OutputHandleMode(void* data, + wl_output* wl_output, + uint32_t flags, + int32_t width, + int32_t height, + int32_t refresh); + + // The Wayland output this object wraps + wl_output* output_; + // The display that the output is associated with + WaylandDisplay* display_; + // The position of the screen. This is important in multi monitor display + // since it provides the position of the screen in the virtual screen. + gfx::Point position_; + + // List of supported modes + Modes modes_; + + DISALLOW_COPY_AND_ASSIGN(WaylandScreen); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_SCREEN_H_ diff --git a/ui/wayland/wayland_shm_buffer.cc b/ui/wayland/wayland_shm_buffer.cc new file mode 100644 index 0000000..2cd59ac --- /dev/null +++ b/ui/wayland/wayland_shm_buffer.cc @@ -0,0 +1,65 @@ +// Copyright (c) 2011 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_shm_buffer.h" + +#include <cairo.h> +#include <fcntl.h> +#include <stdlib.h> +#include <sys/mman.h> +#include <unistd.h> +#include <wayland-client.h> + +#include "base/logging.h" +#include "ui/wayland/wayland_display.h" + +namespace ui { + +WaylandShmBuffer::WaylandShmBuffer(WaylandDisplay* display, + uint32_t width, + uint32_t height) + : data_surface_(NULL) { + int stride = cairo_format_stride_for_width(CAIRO_FORMAT_ARGB32, width); + int allocation = stride * height; + + char filename[] = "/tmp/wayland-shm-XXXXXX"; + int fd = mkstemp(filename); + if (fd < 0) { + PLOG(ERROR) << "Failed to open"; + return; + } + if (ftruncate(fd, allocation) < 0) { + PLOG(ERROR) << "Failed to ftruncate"; + close(fd); + return; + } + + unsigned char* data = static_cast<unsigned char*>( + mmap(NULL, allocation, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)); + unlink(filename); + + if (data == MAP_FAILED) { + PLOG(ERROR) << "Failed to mmap /dev/zero"; + close(fd); + return; + } + data_surface_ = cairo_image_surface_create_for_data( + data, CAIRO_FORMAT_ARGB32, width, height, stride); + buffer_ = wl_shm_create_buffer(display->shm(), fd, + width, height, stride, display->visual()); + close(fd); +} + +WaylandShmBuffer::~WaylandShmBuffer() { + if (buffer_) { + wl_buffer_destroy(buffer_); + buffer_ = NULL; + } + if (data_surface_) { + cairo_surface_destroy(data_surface_); + data_surface_ = NULL; + } +} + +} // namespace ui diff --git a/ui/wayland/wayland_shm_buffer.h b/ui/wayland/wayland_shm_buffer.h new file mode 100644 index 0000000..7712be3 --- /dev/null +++ b/ui/wayland/wayland_shm_buffer.h @@ -0,0 +1,39 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_SHM_BUFFER_H_ +#define UI_WAYLAND_WAYLAND_SHM_BUFFER_H_ + +#include <stdint.h> + +#include "base/basictypes.h" +#include "ui/wayland/wayland_buffer.h" + +typedef struct _cairo_surface cairo_surface_t; + +namespace ui { + +class WaylandDisplay; + +// A SHM implementation for the WaylandBuffer. +class WaylandShmBuffer : public WaylandBuffer { + public: + // Creates a Wayland buffer with the given width and height. + WaylandShmBuffer(WaylandDisplay* display, uint32_t width, uint32_t height); + virtual ~WaylandShmBuffer(); + + // Returns a pointer to the surface associated with the buffer. + // This object maintains ownership of the surface. + cairo_surface_t* data_surface() const { return data_surface_; } + + private: + // The surface associated with the Wayland buffer. + cairo_surface_t* data_surface_; + + DISALLOW_COPY_AND_ASSIGN(WaylandShmBuffer); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_SHM_BUFFER_H_ diff --git a/ui/wayland/wayland_widget.h b/ui/wayland/wayland_widget.h new file mode 100644 index 0000000..f274141 --- /dev/null +++ b/ui/wayland/wayland_widget.h @@ -0,0 +1,28 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_WIDGET_H_ +#define UI_WAYLAND_WAYLAND_WIDGET_H_ + +#include "ui/wayland/events/wayland_event.h" + +namespace ui { + +// WaylandWidget is an interface for processing Wayland events. +class WaylandWidget { + public: + virtual ~WaylandWidget() {} + + virtual void OnMotionNotify(WaylandEvent event) = 0; + virtual void OnButtonNotify(WaylandEvent event) = 0; + virtual void OnKeyNotify(WaylandEvent event) = 0; + virtual void OnPointerFocus(WaylandEvent event) = 0; + virtual void OnKeyboardFocus(WaylandEvent event) = 0; + + virtual void OnGeometryChange(WaylandEvent event) = 0; +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_WIDGET_H_ diff --git a/ui/wayland/wayland_window.cc b/ui/wayland/wayland_window.cc new file mode 100644 index 0000000..7199494 --- /dev/null +++ b/ui/wayland/wayland_window.cc @@ -0,0 +1,84 @@ +// Copyright (c) 2011 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_window.h" + +#include <wayland-egl.h> + +#include "ui/wayland/events/wayland_event.h" +#include "ui/wayland/wayland_display.h" +#include "ui/wayland/wayland_widget.h" + +namespace ui { + +WaylandWindow::WaylandWindow(WaylandWidget* widget, WaylandDisplay* display) + : widget_(widget), + display_(display), + parent_window_(NULL), + relative_position_(), + surface_(display->CreateSurface()), + fullscreen_(false) { + wl_surface_set_user_data(surface_, this); +} + +WaylandWindow::WaylandWindow( + WaylandWidget* widget, + WaylandDisplay* display, + WaylandWindow* parent, + int32_t x, + int32_t y) + : widget_(widget), + display_(display), + parent_window_(parent), + relative_position_(x, y), + surface_(display->CreateSurface()), + fullscreen_(false) { + wl_surface_set_user_data(surface_, this); +} + +WaylandWindow::~WaylandWindow() { + if (surface_) + wl_surface_destroy(surface_); +} + +void WaylandWindow::SetVisible(bool visible) { + if (visible) { + if (fullscreen_) { + wl_shell_set_fullscreen(display_->shell(), surface_); + } else if (!parent_window_) { + wl_shell_set_toplevel(display_->shell(), surface_); + } else { + wl_shell_set_transient(display_->shell(), + surface_, + parent_window_->surface(), + relative_position_.x(), + relative_position_.y(), + 0); + } + } else { + // TODO(dnicoara) What is the correct way of hiding a wl_surface? + } +} + +bool WaylandWindow::IsVisible() const { + return surface_ != NULL; +} + +void WaylandWindow::Configure(uint32_t time, + uint32_t edges, + int32_t x, + int32_t y, + int32_t width, + int32_t height) { + WaylandEvent event; + event.geometry_change.time = time; + event.geometry_change.x = x; + event.geometry_change.y = y; + event.geometry_change.width = width; + event.geometry_change.height = height; + + widget_->OnGeometryChange(event); +} + +} // namespace ui diff --git a/ui/wayland/wayland_window.h b/ui/wayland/wayland_window.h new file mode 100644 index 0000000..b3a6074 --- /dev/null +++ b/ui/wayland/wayland_window.h @@ -0,0 +1,87 @@ +// Copyright (c) 2011 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. + +#ifndef UI_WAYLAND_WAYLAND_WINDOW_H_ +#define UI_WAYLAND_WAYLAND_WINDOW_H_ + +#include <stdint.h> + +#include "base/basictypes.h" +#include "ui/gfx/point.h" + +struct wl_surface; + +namespace ui { + +class WaylandDisplay; +class WaylandWidget; + +// WaylandWindow wraps a wl_surface and some basic operations for the surface. +// WaylandWindow also keeps track of the WaylandWidget that will process all +// events related to the window. +class WaylandWindow { + public: + // Creates a toplevel window. + WaylandWindow(WaylandWidget* widget, WaylandDisplay* display); + // Creates a transient window with an offset of (x,y) from parent. + WaylandWindow(WaylandWidget* widget, + WaylandDisplay* display, + WaylandWindow* parent, + int32_t x, + int32_t y); + + ~WaylandWindow(); + + void SetVisible(bool visible); + bool IsVisible() const; + + // Sets the window to fullscreen if |fullscreen| is true. Otherwise it sets + // it as a normal window. + void set_fullscreen(bool fullscreen) { fullscreen_ = fullscreen; } + bool fullscreen() const { return fullscreen_; } + + // Returns a pointer to the parent window. NULL is this window doesn't have + // a parent. + WaylandWindow* parent_window() const { return parent_window_; } + + WaylandWidget* widget() const { return widget_; } + + // Returns the pointer to the surface associated with the window. + // The WaylandWindow object owns the pointer. + wl_surface* surface() const { return surface_; } + + void Configure(uint32_t time, uint32_t edges, int32_t x, int32_t y, + int32_t width, int32_t height); + + private: + // The widget that will process events for this window. This is not owned + // by the window. + WaylandWidget* widget_; + + // Pointer to the display this window is using. This doesn't own the pointer + // to the display. + WaylandDisplay* display_; + + // When creating a transient window, |parent_window_| is set to point to the + // parent of this window. We will then use |parent_window_| to align this + // window at the specified offset in |relative_position_|. + // |parent_window_| is not owned by this window. + WaylandWindow* parent_window_; + + // Position relative to parent window. This is only used by + // a transient window. + gfx::Point relative_position_; + + // The native wayland surface associated with this window. + wl_surface* surface_; + + // Whether the window is in fullscreen mode. + bool fullscreen_; + + DISALLOW_COPY_AND_ASSIGN(WaylandWindow); +}; + +} // namespace ui + +#endif // UI_WAYLAND_WAYLAND_WINDOW_H_ |