86e7ce9a53e7c0186e8be2a2ac437613d1f8154b
[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   return gfx::Rect(wr.left, wr.top, wr.right - wr.left, wr.bottom - wr.top);
24 }
25
26 }
27
28 class NativeViewportWin : public gfx::WindowImpl,
29                           public NativeViewport {
30  public:
31   explicit NativeViewportWin(NativeViewportDelegate* delegate)
32       : delegate_(delegate) {
33   }
34   virtual ~NativeViewportWin() {
35     if (IsWindow(hwnd()))
36       DestroyWindow(hwnd());
37   }
38
39  private:
40   // Overridden from NativeViewport:
41   virtual void Init(const gfx::Rect& bounds) OVERRIDE {
42     gfx::Rect window_bounds = GetWindowBoundsForClientBounds(
43         WS_OVERLAPPEDWINDOW, window_ex_style(), bounds);
44     gfx::WindowImpl::Init(NULL, window_bounds);
45     SetWindowText(hwnd(), L"native_viewport::NativeViewportWin!");
46   }
47
48   virtual void Show() OVERRIDE {
49     ShowWindow(hwnd(), SW_SHOWNORMAL);
50   }
51
52   virtual void Hide() OVERRIDE {
53     ShowWindow(hwnd(), SW_HIDE);
54   }
55
56   virtual void Close() OVERRIDE {
57     DestroyWindow(hwnd());
58   }
59
60   virtual gfx::Size GetSize() OVERRIDE {
61     RECT cr;
62     GetClientRect(hwnd(), &cr);
63     return gfx::Size(cr.right - cr.left, cr.bottom - cr.top);
64   }
65
66   virtual void SetBounds(const gfx::Rect& bounds) OVERRIDE {
67     gfx::Rect window_bounds = GetWindowBoundsForClientBounds(
68         GetWindowLong(hwnd(), GWL_STYLE),
69         GetWindowLong(hwnd(), GWL_EXSTYLE),
70         bounds);
71     SetWindowPos(hwnd(), NULL, window_bounds.x(), window_bounds.y(),
72                  window_bounds.width(), window_bounds.height(),
73                  SWP_NOREPOSITION);
74   }
75
76   virtual void SetCapture() OVERRIDE {
77     DCHECK(::GetCapture() != hwnd());
78     ::SetCapture(hwnd());
79   }
80
81   virtual void ReleaseCapture() OVERRIDE {
82     if (::GetCapture() == hwnd())
83       ::ReleaseCapture();
84   }
85
86   CR_BEGIN_MSG_MAP_EX(NativeViewportWin)
87     CR_MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseRange)
88
89     CR_MESSAGE_HANDLER_EX(WM_KEYDOWN, OnKeyEvent)
90     CR_MESSAGE_HANDLER_EX(WM_KEYUP, OnKeyEvent)
91     CR_MESSAGE_HANDLER_EX(WM_SYSKEYDOWN, OnKeyEvent)
92     CR_MESSAGE_HANDLER_EX(WM_SYSKEYUP, OnKeyEvent)
93     CR_MESSAGE_HANDLER_EX(WM_CHAR, OnKeyEvent)
94     CR_MESSAGE_HANDLER_EX(WM_SYSCHAR, OnKeyEvent)
95     CR_MESSAGE_HANDLER_EX(WM_IME_CHAR, OnKeyEvent)
96
97     CR_MSG_WM_CREATE(OnCreate)
98     CR_MSG_WM_DESTROY(OnDestroy)
99     CR_MSG_WM_PAINT(OnPaint)
100     CR_MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged)
101   CR_END_MSG_MAP()
102
103   LRESULT OnMouseRange(UINT message, WPARAM w_param, LPARAM l_param) {
104     MSG msg = { hwnd(), message, w_param, l_param, 0,
105                 { CR_GET_X_LPARAM(l_param), CR_GET_Y_LPARAM(l_param) } };
106     ui::MouseEvent event(msg);
107     SetMsgHandled(delegate_->OnEvent(&event));
108     return 0;
109   }
110   LRESULT OnKeyEvent(UINT message, WPARAM w_param, LPARAM l_param) {
111     MSG msg = { hwnd(), message, w_param, l_param };
112     ui::KeyEvent event(msg, message == WM_CHAR);
113     SetMsgHandled(delegate_->OnEvent(&event));
114     return 0;
115   }
116   LRESULT OnCreate(CREATESTRUCT* create_struct) {
117     delegate_->OnAcceleratedWidgetAvailable(hwnd());
118     return 0;
119   }
120   void OnDestroy() {
121     delegate_->OnDestroyed();
122   }
123   void OnPaint(HDC) {
124     RECT cr;
125     GetClientRect(hwnd(), &cr);
126
127     PAINTSTRUCT ps;
128     HDC dc = BeginPaint(hwnd(), &ps);
129     HBRUSH red_brush = CreateSolidBrush(RGB(255, 0, 0));
130     HGDIOBJ old_object = SelectObject(dc, red_brush);
131     Rectangle(dc, cr.left, cr.top, cr.right, cr.bottom);
132     SelectObject(dc, old_object);
133     DeleteObject(red_brush);
134     EndPaint(hwnd(), &ps);
135   }
136   void OnWindowPosChanged(WINDOWPOS* window_pos) {
137     if (!(window_pos->flags & SWP_NOSIZE) ||
138         !(window_pos->flags & SWP_NOMOVE)) {
139       delegate_->OnBoundsChanged(gfx::Rect(window_pos->x, window_pos->y,
140                                            window_pos->cx, window_pos->cy));
141     }
142   }
143
144   NativeViewportDelegate* delegate_;
145
146   DISALLOW_COPY_AND_ASSIGN(NativeViewportWin);
147 };
148
149 // static
150 scoped_ptr<NativeViewport> NativeViewport::Create(
151     shell::Context* context,
152     NativeViewportDelegate* delegate) {
153   return scoped_ptr<NativeViewport>(new NativeViewportWin(delegate)).Pass();
154 }
155
156 }  // namespace services
157 }  // namespace mojo