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.
5 #include "mojo/services/native_viewport/native_viewport.h"
7 #include "ui/events/event.h"
8 #include "ui/events/event_utils.h"
9 #include "ui/gfx/win/msg_util.h"
10 #include "ui/gfx/win/window_impl.h"
16 gfx::Rect
GetWindowBoundsForClientBounds(DWORD style
, DWORD ex_style
,
17 const gfx::Rect
& bounds
) {
21 wr
.right
= bounds
.x() + bounds
.width();
22 wr
.bottom
= bounds
.y() + bounds
.height();
23 AdjustWindowRectEx(&wr
, style
, FALSE
, ex_style
);
25 // Make sure to keep the window onscreen, as AdjustWindowRectEx() may have
26 // moved part of it offscreen.
27 gfx::Rect
window_bounds(wr
.left
, wr
.top
,
28 wr
.right
- wr
.left
, wr
.bottom
- wr
.top
);
29 window_bounds
.set_x(std::max(0, window_bounds
.x()));
30 window_bounds
.set_y(std::max(0, window_bounds
.y()));
36 class NativeViewportWin
: public gfx::WindowImpl
,
37 public NativeViewport
{
39 explicit NativeViewportWin(NativeViewportDelegate
* delegate
)
40 : delegate_(delegate
) {
42 virtual ~NativeViewportWin() {
44 DestroyWindow(hwnd());
48 // Overridden from NativeViewport:
49 virtual void Init(const gfx::Rect
& bounds
) OVERRIDE
{
50 gfx::Rect window_bounds
= GetWindowBoundsForClientBounds(
51 WS_OVERLAPPEDWINDOW
, window_ex_style(), bounds
);
52 gfx::WindowImpl::Init(NULL
, window_bounds
);
53 SetWindowText(hwnd(), L
"native_viewport::NativeViewportWin!");
56 virtual void Show() OVERRIDE
{
57 ShowWindow(hwnd(), SW_SHOWNORMAL
);
60 virtual void Hide() OVERRIDE
{
61 ShowWindow(hwnd(), SW_HIDE
);
64 virtual void Close() OVERRIDE
{
65 DestroyWindow(hwnd());
68 virtual gfx::Size
GetSize() OVERRIDE
{
70 GetClientRect(hwnd(), &cr
);
71 return gfx::Size(cr
.right
- cr
.left
, cr
.bottom
- cr
.top
);
74 virtual void SetBounds(const gfx::Rect
& bounds
) OVERRIDE
{
75 gfx::Rect window_bounds
= GetWindowBoundsForClientBounds(
76 GetWindowLong(hwnd(), GWL_STYLE
),
77 GetWindowLong(hwnd(), GWL_EXSTYLE
),
79 SetWindowPos(hwnd(), NULL
, window_bounds
.x(), window_bounds
.y(),
80 window_bounds
.width(), window_bounds
.height(),
84 virtual void SetCapture() OVERRIDE
{
85 DCHECK(::GetCapture() != hwnd());
89 virtual void ReleaseCapture() OVERRIDE
{
90 if (::GetCapture() == hwnd())
94 CR_BEGIN_MSG_MAP_EX(NativeViewportWin
)
95 CR_MESSAGE_RANGE_HANDLER_EX(WM_MOUSEFIRST
, WM_MOUSELAST
, OnMouseRange
)
97 CR_MESSAGE_HANDLER_EX(WM_KEYDOWN
, OnKeyEvent
)
98 CR_MESSAGE_HANDLER_EX(WM_KEYUP
, OnKeyEvent
)
99 CR_MESSAGE_HANDLER_EX(WM_SYSKEYDOWN
, OnKeyEvent
)
100 CR_MESSAGE_HANDLER_EX(WM_SYSKEYUP
, OnKeyEvent
)
101 CR_MESSAGE_HANDLER_EX(WM_CHAR
, OnKeyEvent
)
102 CR_MESSAGE_HANDLER_EX(WM_SYSCHAR
, OnKeyEvent
)
103 CR_MESSAGE_HANDLER_EX(WM_IME_CHAR
, OnKeyEvent
)
105 CR_MSG_WM_CREATE(OnCreate
)
106 CR_MSG_WM_DESTROY(OnDestroy
)
107 CR_MSG_WM_PAINT(OnPaint
)
108 CR_MSG_WM_WINDOWPOSCHANGED(OnWindowPosChanged
)
111 LRESULT
OnMouseRange(UINT message
, WPARAM w_param
, LPARAM l_param
) {
112 MSG msg
= { hwnd(), message
, w_param
, l_param
, 0,
113 { CR_GET_X_LPARAM(l_param
), CR_GET_Y_LPARAM(l_param
) } };
114 ui::MouseEvent
event(msg
);
115 if (ui::IsMouseEventFromTouch(message
))
116 event
.set_flags(event
.flags() | ui::EF_FROM_TOUCH
);
117 SetMsgHandled(delegate_
->OnEvent(&event
));
120 LRESULT
OnKeyEvent(UINT message
, WPARAM w_param
, LPARAM l_param
) {
121 MSG msg
= { hwnd(), message
, w_param
, l_param
};
122 ui::KeyEvent
event(msg
, message
== WM_CHAR
);
123 SetMsgHandled(delegate_
->OnEvent(&event
));
126 LRESULT
OnCreate(CREATESTRUCT
* create_struct
) {
127 delegate_
->OnAcceleratedWidgetAvailable(hwnd());
131 delegate_
->OnDestroyed();
135 GetClientRect(hwnd(), &cr
);
138 HDC dc
= BeginPaint(hwnd(), &ps
);
139 HBRUSH red_brush
= CreateSolidBrush(RGB(255, 0, 0));
140 HGDIOBJ old_object
= SelectObject(dc
, red_brush
);
141 Rectangle(dc
, cr
.left
, cr
.top
, cr
.right
, cr
.bottom
);
142 SelectObject(dc
, old_object
);
143 DeleteObject(red_brush
);
144 EndPaint(hwnd(), &ps
);
146 void OnWindowPosChanged(WINDOWPOS
* window_pos
) {
147 if (!(window_pos
->flags
& SWP_NOSIZE
) ||
148 !(window_pos
->flags
& SWP_NOMOVE
)) {
150 GetClientRect(hwnd(), &cr
);
151 delegate_
->OnBoundsChanged(
152 gfx::Rect(window_pos
->x
, window_pos
->y
,
153 cr
.right
- cr
.left
, cr
.bottom
- cr
.top
));
157 NativeViewportDelegate
* delegate_
;
159 DISALLOW_COPY_AND_ASSIGN(NativeViewportWin
);
163 scoped_ptr
<NativeViewport
> NativeViewport::Create(
164 shell::Context
* context
,
165 NativeViewportDelegate
* delegate
) {
166 return scoped_ptr
<NativeViewport
>(new NativeViewportWin(delegate
)).Pass();
169 } // namespace services