Upstream version 9.37.197.0
[platform/framework/web/crosswalk.git] / src / mojo / services / native_viewport / native_viewport_win.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "mojo/services/native_viewport/native_viewport.h"
6
7 #include "ui/events/event.h"
8 #include "ui/gfx/win/msg_util.h"
9 #include "ui/gfx/win/window_impl.h"
10
11 namespace mojo {
12 namespace services {
13 namespace {
14
15 gfx::Rect GetWindowBoundsForClientBounds(DWORD style, DWORD ex_style,
16                                          const gfx::Rect& bounds) {
17   RECT wr;
18   wr.left = bounds.x();
19   wr.top = bounds.y();
20   wr.right = bounds.x() + bounds.width();
21   wr.bottom = bounds.y() + bounds.height();
22   AdjustWindowRectEx(&wr, style, FALSE, ex_style);
23
24   // Make sure to keep the window onscreen, as AdjustWindowRectEx() may have
25   // moved part of it offscreen.
26   gfx::Rect window_bounds(wr.left, wr.top,
27                           wr.right - wr.left, wr.bottom - wr.top);
28   window_bounds.set_x(std::max(0, window_bounds.x()));
29   window_bounds.set_y(std::max(0, window_bounds.y()));
30   return window_bounds;
31 }
32
33 }
34
35 class NativeViewportWin : public gfx::WindowImpl,
36                           public NativeViewport {
37  public:
38   explicit NativeViewportWin(NativeViewportDelegate* delegate)
39       : delegate_(delegate) {
40   }
41   virtual ~NativeViewportWin() {
42     if (IsWindow(hwnd()))
43       DestroyWindow(hwnd());
44   }
45
46  private:
47   // Overridden from NativeViewport:
48   virtual void Init(const gfx::Rect& bounds) OVERRIDE {
49     gfx::Rect window_bounds = GetWindowBoundsForClientBounds(
50         WS_OVERLAPPEDWINDOW, window_ex_style(), bounds);
51     gfx::WindowImpl::Init(NULL, window_bounds);
52     SetWindowText(hwnd(), L"native_viewport::NativeViewportWin!");
53   }
54
55   virtual void Show() OVERRIDE {
56     ShowWindow(hwnd(), SW_SHOWNORMAL);
57   }
58
59   virtual void Hide() OVERRIDE {
60     ShowWindow(hwnd(), SW_HIDE);
61   }
62
63   virtual void Close() OVERRIDE {
64     DestroyWindow(hwnd());
65   }
66
67   virtual gfx::Size GetSize() OVERRIDE {
68     RECT cr;
69     GetClientRect(hwnd(), &cr);
70     return gfx::Size(cr.right - cr.left, cr.bottom - cr.top);
71   }
72
73   virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE {
74     gfx::Rect window_bounds = GetWindowBoundsForClientBounds(
75         GetWindowLong(hwnd(), GWL_STYLE),
76         GetWindowLong(hwnd(), GWL_EXSTYLE),
77         bounds);
78     SetWindowPos(hwnd(), NULL, window_bounds.x(), window_bounds.y(),
79                  window_bounds.width(), window_bounds.height(),
80                  SWP_NOREPOSITION);
81   }
82
83   virtual void SetCapture() OVERRIDE {
84     DCHECK(::GetCapture() != hwnd());
85     ::SetCapture(hwnd());
86   }
87
88   virtual void ReleaseCapture() OVERRIDE {
89     if (::GetCapture() == hwnd())
90       ::ReleaseCapture();
91   }
92
93   CR_BEGIN_MSG_MAP_EX(NativeViewportWin)
94     CR_MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange)
95
96     CR_MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyEvent)
97     CR_MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyEvent)
98     CR_MESSAGE_HANDLER_EX(WM_SYSKEYDOWN, OnKeyEvent)
99     CR_MESSAGE_HANDLER_EX(WM_SYSKEYUP, OnKeyEvent)
100     CR_MESSAGE_HANDLER_EX(WM_CHAR, OnKeyEvent)
101     CR_MESSAGE_HANDLER_EX(WM_SYSCHAR, OnKeyEvent)
102     CR_MESSAGE_HANDLER_EX(WM_IME_CHAR, OnKeyEvent)
103
104     CR_MSG_WM_CREATE(OnCreate)
105     CR_MSG_WM_DESTROY(OnDestroy)
106     CR_MSG_WM_PAINT(OnPaint)
107     CR_MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged)
108   CR_END_MSG_MAP()
109
110   LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) {
111     MSG msg = { hwnd(), message, w_param, l_param, 0,
112                 { CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param) } };
113     ui::MouseEvent event(msg);
114     SetMsgHandled(delegate_->OnEvent(&event));
115     return 0;
116   }
117   LRESULT OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param) {
118     MSG msg = { hwnd(), message, w_param, l_param };
119     ui::KeyEvent event(msg, message == WM_CHAR);
120     SetMsgHandled(delegate_->OnEvent(&event));
121     return 0;
122   }
123   LRESULT OnCreate(CREATESTRUCT* create_struct) {
124     delegate_->OnAcceleratedWidgetAvailable(hwnd());
125     return 0;
126   }
127   void OnDestroy() {
128     delegate_->OnDestroyed();
129   }
130   void OnPaint(HDC) {
131     RECT cr;
132     GetClientRect(hwnd(), &cr);
133
134     PAINTSTRUCT ps;
135     HDC dc = BeginPaint(hwnd(), &ps);
136     HBRUSH red_brush = CreateSolidBrush(RGB(255, 0, 0));
137     HGDIOBJ old_object = SelectObject(dc, red_brush);
138     Rectangle(dc, cr.left, cr.top, cr.right, cr.bottom);
139     SelectObject(dc, old_object);
140     DeleteObject(red_brush);
141     EndPaint(hwnd(), &ps);
142   }
143   void OnWindowPosChanged(WINDOWPOS* window_pos) {
144     if (!(window_pos->flags & SWP_NOSIZE) ||
145         !(window_pos->flags & SWP_NOMOVE)) {
146       RECT cr;
147       GetClientRect(hwnd(), &cr);
148       delegate_->OnBoundsChanged(
149           gfx::Rect(window_pos->x, window_pos->y,
150                     cr.right - cr.left, cr.bottom - cr.top));
151     }
152   }
153
154   NativeViewportDelegate* delegate_;
155
156   DISALLOW_COPY_AND_ASSIGN(NativeViewportWin);
157 };
158
159 // static
160 scoped_ptr<NativeViewport> NativeViewport::Create(
161     shell::Context* context,
162     NativeViewportDelegate* delegate) {
163   return scoped_ptr<NativeViewport>(new NativeViewportWin(delegate)).Pass();
164 }
165
166 }  // namespace services
167 }  // namespace mojo