10f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
20f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
30f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// found in the LICENSE file.
40f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
56e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "mojo/services/native_viewport/platform_viewport.h"
60f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
7116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/command_line.h"
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/message_loop/message_loop.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "mojo/services/public/cpp/input_events/lib/mojo_extended_key_event_data.h"
10cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ui/events/event.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/events/event_utils.h"
12c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/platform/platform_event_dispatcher.h"
13c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch#include "ui/events/platform/platform_event_source.h"
14f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "ui/gfx/rect.h"
15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/platform_window/platform_window.h"
16116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/platform_window/platform_window_delegate.h"
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/platform_window/x11/x11_window.h"
18f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
190f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)namespace mojo {
200f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)class PlatformViewportX11 : public PlatformViewport,
226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                            public ui::PlatformWindowDelegate {
230f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) public:
246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  explicit PlatformViewportX11(Delegate* delegate) : delegate_(delegate) {
250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
26f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  virtual ~PlatformViewportX11() {
28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    // Destroy the platform-window while |this| is still alive.
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_.reset();
300f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
310f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) private:
336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Overridden from PlatformViewport:
345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Init(const gfx::Rect& bounds) OVERRIDE {
35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CHECK(!event_source_);
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    CHECK(!platform_window_);
37f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    event_source_ = ui::PlatformEventSource::CreateDefault();
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_.reset(new ui::X11Window(this));
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->SetBounds(bounds);
425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Show() OVERRIDE {
45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->Show();
465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
47f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void Hide() OVERRIDE {
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->Hide();
50f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  }
51f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
520f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  virtual void Close() OVERRIDE {
53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->Close();
540f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  }
550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual gfx::Size GetSize() OVERRIDE {
575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return bounds_.size();
585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE {
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->SetBounds(bounds);
625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void SetCapture() OVERRIDE {
65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->SetCapture();
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  virtual void ReleaseCapture() OVERRIDE {
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->ReleaseCapture();
70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // ui::PlatformWindowDelegate:
73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnBoundsChanged(const gfx::Rect& new_bounds) OVERRIDE {
74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    bounds_ = new_bounds;
75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnBoundsChanged(new_bounds);
76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnDamageRect(const gfx::Rect& damaged_region) OVERRIDE {
79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void DispatchEvent(ui::Event* event) OVERRIDE {
82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnEvent(event);
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // We want to emulate the WM_CHAR generation behaviour of Windows.
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // On Linux, we've previously inserted characters by having
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // InputMethodAuraLinux take all key down events and send a character event
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // to the TextInputClient. This causes a mismatch in code that has to be
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // shared between Windows and Linux, including blink code. Now that we're
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // trying to have one way of doing things, we need to standardize on and
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // emulate Windows character events.
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    //
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // This is equivalent to what we're doing in the current Linux port, but
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // done once instead of done multiple times in different places.
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (event->type() == ui::ET_KEY_PRESSED) {
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::KeyEvent* key_press_event = static_cast<ui::KeyEvent*>(event);
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ui::KeyEvent char_event(key_press_event->GetCharacter(),
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              key_press_event->key_code(),
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              key_press_event->flags());
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK_EQ(key_press_event->GetCharacter(), char_event.GetCharacter());
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK_EQ(key_press_event->key_code(), char_event.key_code());
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      DCHECK_EQ(key_press_event->flags(), char_event.flags());
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      char_event.SetExtendedKeyEventData(scoped_ptr<ui::ExtendedKeyEventData>(
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          new MojoExtendedKeyEventData(
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              key_press_event->GetLocatedWindowsKeyboardCode(),
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              key_press_event->GetText(),
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              key_press_event->GetUnmodifiedText())));
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      char_event.set_platform_keycode(key_press_event->platform_keycode());
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      delegate_->OnEvent(&char_event);
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    }
114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnCloseRequest() OVERRIDE {
117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    platform_window_->Close();
118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnClosed() OVERRIDE {
121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnDestroyed();
122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnWindowStateChanged(ui::PlatformWindowState state) OVERRIDE {
125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnLostCapture() OVERRIDE {
128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  virtual void OnAcceleratedWidgetAvailable(
131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      gfx::AcceleratedWidget widget) OVERRIDE {
132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    delegate_->OnAcceleratedWidgetAvailable(widget);
133c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  }
134c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  virtual void OnActivationChanged(bool active) OVERRIDE {}
1365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
137c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  scoped_ptr<ui::PlatformEventSource> event_source_;
138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_ptr<ui::PlatformWindow> platform_window_;
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  Delegate* delegate_;
140f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  gfx::Rect bounds_;
1410f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(PlatformViewportX11);
1430f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)};
1440f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1450f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)// static
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)scoped_ptr<PlatformViewport> PlatformViewport::Create(Delegate* delegate) {
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return scoped_ptr<PlatformViewport>(new PlatformViewportX11(delegate)).Pass();
1480f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}
1490f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)
1500f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)}  // namespace mojo
151