blob: a4f60b6436c21512d0277b54a078eadc9af108c6 [file] [log] [blame]
[email protected]c5e9c6ce2012-01-13 02:37:181// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]81585f32011-07-29 19:32:062// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]99f07e02011-12-07 00:02:595#include "ui/aura/root_window_host_win.h"
[email protected]81585f32011-07-29 19:32:066
[email protected]896728e2011-10-14 00:41:267#include <windows.h>
8
[email protected]9ba7ecf2011-10-19 18:39:329#include <algorithm>
10
[email protected]81585f32011-07-29 19:32:0611#include "base/message_loop.h"
[email protected]99f07e02011-12-07 00:02:5912#include "ui/aura/root_window.h"
[email protected]f94f0f12011-09-14 21:14:0113#include "ui/aura/event.h"
[email protected]81585f32011-07-29 19:32:0614
[email protected]9ba7ecf2011-10-19 18:39:3215using std::max;
16using std::min;
17
[email protected]81585f32011-07-29 19:32:0618namespace aura {
19
[email protected]9e591cb2011-10-17 18:14:3220namespace {
21
22const wchar_t* GetCursorId(gfx::NativeCursor native_cursor) {
23 switch (native_cursor) {
24 case kCursorNull:
25 return IDC_ARROW;
26 case kCursorPointer:
27 return IDC_ARROW;
28 case kCursorCross:
29 return IDC_CROSS;
30 case kCursorHand:
31 return IDC_HAND;
32 case kCursorIBeam:
33 return IDC_IBEAM;
34 case kCursorWait:
35 return IDC_WAIT;
36 case kCursorHelp:
37 return IDC_HELP;
38 case kCursorEastResize:
39 return IDC_SIZEWE;
40 case kCursorNorthResize:
41 return IDC_SIZENS;
42 case kCursorNorthEastResize:
43 return IDC_SIZENESW;
44 case kCursorNorthWestResize:
45 return IDC_SIZENWSE;
46 case kCursorSouthResize:
47 return IDC_SIZENS;
48 case kCursorSouthEastResize:
49 return IDC_SIZENWSE;
50 case kCursorSouthWestResize:
51 return IDC_SIZENESW;
52 case kCursorWestResize:
53 return IDC_SIZEWE;
54 case kCursorNorthSouthResize:
55 return IDC_SIZENS;
56 case kCursorEastWestResize:
57 return IDC_SIZEWE;
58 case kCursorNorthEastSouthWestResize:
59 return IDC_SIZENESW;
60 case kCursorNorthWestSouthEastResize:
61 return IDC_SIZENWSE;
62 case kCursorMove:
63 return IDC_SIZEALL;
64 case kCursorProgress:
65 return IDC_APPSTARTING;
66 case kCursorNoDrop:
67 return IDC_NO;
68 case kCursorNotAllowed:
69 return IDC_NO;
70 case kCursorColumnResize:
71 case kCursorRowResize:
72 case kCursorMiddlePanning:
73 case kCursorEastPanning:
74 case kCursorNorthPanning:
75 case kCursorNorthEastPanning:
76 case kCursorNorthWestPanning:
77 case kCursorSouthPanning:
78 case kCursorSouthEastPanning:
79 case kCursorSouthWestPanning:
80 case kCursorWestPanning:
81 case kCursorVerticalText:
82 case kCursorCell:
83 case kCursorContextMenu:
84 case kCursorAlias:
85 case kCursorCopy:
86 case kCursorNone:
87 case kCursorZoomIn:
88 case kCursorZoomOut:
89 case kCursorGrab:
90 case kCursorGrabbing:
91 case kCursorCustom:
92 // TODO(jamescook): Should we use WebKit glue resources for these?
93 // Or migrate those resources to someplace ui/aura can share?
94 NOTIMPLEMENTED();
95 return IDC_ARROW;
96 default:
97 NOTREACHED();
98 return IDC_ARROW;
99 }
100}
101
102} // namespace
103
[email protected]81585f32011-07-29 19:32:06104// static
[email protected]99f07e02011-12-07 00:02:59105RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) {
106 return new RootWindowHostWin(bounds);
[email protected]81585f32011-07-29 19:32:06107}
108
[email protected]5978af5e2011-10-24 22:17:18109// static
[email protected]99f07e02011-12-07 00:02:59110gfx::Size RootWindowHost::GetNativeScreenSize() {
[email protected]5978af5e2011-10-24 22:17:18111 return gfx::Size(GetSystemMetrics(SM_CXSCREEN),
112 GetSystemMetrics(SM_CYSCREEN));
113}
114
[email protected]99f07e02011-12-07 00:02:59115RootWindowHostWin::RootWindowHostWin(const gfx::Rect& bounds)
116 : root_window_(NULL),
[email protected]8a1527b2011-11-03 15:47:16117 fullscreen_(false),
[email protected]759017e02012-02-11 20:46:11118 has_capture_(false),
[email protected]8a1527b2011-11-03 15:47:16119 saved_window_style_(0),
120 saved_window_ex_style_(0) {
[email protected]81585f32011-07-29 19:32:06121 Init(NULL, bounds);
[email protected]99f07e02011-12-07 00:02:59122 SetWindowText(hwnd(), L"aura::RootWindow!");
[email protected]81585f32011-07-29 19:32:06123}
124
[email protected]99f07e02011-12-07 00:02:59125RootWindowHostWin::~RootWindowHostWin() {
[email protected]81585f32011-07-29 19:32:06126 DestroyWindow(hwnd());
127}
128
[email protected]99f07e02011-12-07 00:02:59129bool RootWindowHostWin::Dispatch(const MSG& msg) {
[email protected]b2d2ee82011-08-22 17:25:05130 TranslateMessage(&msg);
131 DispatchMessage(&msg);
[email protected]711d8a82011-08-22 16:01:19132 return true;
133}
134
[email protected]99f07e02011-12-07 00:02:59135void RootWindowHostWin::SetRootWindow(RootWindow* root_window) {
136 root_window_ = root_window;
[email protected]81585f32011-07-29 19:32:06137}
138
[email protected]99f07e02011-12-07 00:02:59139gfx::AcceleratedWidget RootWindowHostWin::GetAcceleratedWidget() {
[email protected]81585f32011-07-29 19:32:06140 return hwnd();
141}
142
[email protected]99f07e02011-12-07 00:02:59143void RootWindowHostWin::Show() {
[email protected]81585f32011-07-29 19:32:06144 ShowWindow(hwnd(), SW_SHOWNORMAL);
145}
146
[email protected]99f07e02011-12-07 00:02:59147void RootWindowHostWin::ToggleFullScreen() {
[email protected]8a1527b2011-11-03 15:47:16148 gfx::Rect target_rect;
149 if (!fullscreen_) {
150 fullscreen_ = true;
151 saved_window_style_ = GetWindowLong(hwnd(), GWL_STYLE);
152 saved_window_ex_style_ = GetWindowLong(hwnd(), GWL_EXSTYLE);
153 GetWindowRect(hwnd(), &saved_window_rect_);
154 SetWindowLong(hwnd(), GWL_STYLE,
155 saved_window_style_ & ~(WS_CAPTION | WS_THICKFRAME));
156 SetWindowLong(hwnd(), GWL_EXSTYLE,
157 saved_window_ex_style_ & ~(WS_EX_DLGMODALFRAME |
158 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
159
160 MONITORINFO mi;
161 mi.cbSize = sizeof(mi);
162 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST), &mi);
163 target_rect = mi.rcMonitor;
164 } else {
165 fullscreen_ = false;
166 SetWindowLong(hwnd(), GWL_STYLE, saved_window_style_);
167 SetWindowLong(hwnd(), GWL_EXSTYLE, saved_window_ex_style_);
168 target_rect = saved_window_rect_;
169 }
170 SetWindowPos(hwnd(),
171 NULL,
172 target_rect.x(),
173 target_rect.y(),
174 target_rect.width(),
175 target_rect.height(),
176 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
177}
178
[email protected]99f07e02011-12-07 00:02:59179gfx::Size RootWindowHostWin::GetSize() const {
[email protected]81585f32011-07-29 19:32:06180 RECT r;
181 GetClientRect(hwnd(), &r);
182 return gfx::Rect(r).size();
183}
184
[email protected]99f07e02011-12-07 00:02:59185void RootWindowHostWin::SetSize(const gfx::Size& size) {
[email protected]71b6d572011-11-08 23:45:04186 if (fullscreen_) {
187 saved_window_rect_.right = saved_window_rect_.left + size.width();
188 saved_window_rect_.bottom = saved_window_rect_.top + size.height();
189 return;
190 }
191 RECT window_rect;
192 window_rect.left = 0;
193 window_rect.top = 0;
194 window_rect.right = size.width();
195 window_rect.bottom = size.height();
196 AdjustWindowRectEx(&window_rect,
197 GetWindowLong(hwnd(), GWL_STYLE),
198 FALSE,
199 GetWindowLong(hwnd(), GWL_EXSTYLE));
[email protected]970aa362011-08-30 20:03:34200 SetWindowPos(
201 hwnd(),
202 NULL,
203 0,
204 0,
[email protected]71b6d572011-11-08 23:45:04205 window_rect.right - window_rect.left,
206 window_rect.bottom - window_rect.top,
[email protected]970aa362011-08-30 20:03:34207 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOREPOSITION);
208}
209
[email protected]99f07e02011-12-07 00:02:59210gfx::Point RootWindowHostWin::GetLocationOnNativeScreen() const {
[email protected]ace7ca02011-11-22 21:34:17211 RECT r;
212 GetClientRect(hwnd(), &r);
213 return gfx::Point(r.left, r.top);
214}
215
216
[email protected]99f07e02011-12-07 00:02:59217void RootWindowHostWin::SetCursor(gfx::NativeCursor native_cursor) {
[email protected]9e591cb2011-10-17 18:14:32218 // Custom web cursors are handled directly.
219 if (native_cursor == kCursorCustom)
220 return;
221 const wchar_t* cursor_id = GetCursorId(native_cursor);
222 // TODO(jamescook): Support for non-system cursors will require finding
223 // the appropriate module to pass to LoadCursor().
224 ::SetCursor(LoadCursor(NULL, cursor_id));
[email protected]70ccf702011-09-22 18:15:58225}
226
[email protected]759017e02012-02-11 20:46:11227void RootWindowHostWin::SetCapture() {
228 if (!has_capture_) {
229 has_capture_ = true;
230 ::SetCapture(hwnd());
231 }
232}
233
234void RootWindowHostWin::ReleaseCapture() {
235 if (has_capture_) {
236 has_capture_ = false;
237 ::ReleaseCapture();
238 }
239}
240
[email protected]09a02fff2011-12-20 22:01:43241void RootWindowHostWin::ShowCursor(bool show) {
[email protected]c5e9c6ce2012-01-13 02:37:18242 // NOTIMPLEMENTED();
[email protected]09a02fff2011-12-20 22:01:43243}
244
[email protected]99f07e02011-12-07 00:02:59245gfx::Point RootWindowHostWin::QueryMouseLocation() {
[email protected]896728e2011-10-14 00:41:26246 POINT pt;
247 GetCursorPos(&pt);
248 ScreenToClient(hwnd(), &pt);
[email protected]9ba7ecf2011-10-19 18:39:32249 const gfx::Size size = GetSize();
250 return gfx::Point(max(0, min(size.width(), static_cast<int>(pt.x))),
251 max(0, min(size.height(), static_cast<int>(pt.y))));
[email protected]896728e2011-10-14 00:41:26252}
253
[email protected]e4243262012-01-19 18:59:25254bool RootWindowHostWin::ConfineCursorToRootWindow() {
255 RECT window_rect;
256 GetWindowRect(hwnd(), &window_rect);
257 return ClipCursor(&window_rect) != 0;
258}
259
260void RootWindowHostWin::UnConfineCursor() {
261 ClipCursor(NULL);
262}
263
[email protected]5922cb22012-01-17 21:53:12264void RootWindowHostWin::MoveCursorTo(const gfx::Point& location) {
265 POINT pt;
266 ClientToScreen(hwnd(), &pt);
267 SetCursorPos(pt.x, pt.y);
268}
269
[email protected]99f07e02011-12-07 00:02:59270void RootWindowHostWin::PostNativeEvent(const base::NativeEvent& native_event) {
[email protected]b5a18642011-11-18 22:45:36271 ::PostMessage(
272 hwnd(), native_event.message, native_event.wParam, native_event.lParam);
273}
274
[email protected]99f07e02011-12-07 00:02:59275void RootWindowHostWin::OnClose() {
[email protected]81585f32011-07-29 19:32:06276 // TODO: this obviously shouldn't be here.
277 MessageLoopForUI::current()->Quit();
278}
279
[email protected]99f07e02011-12-07 00:02:59280LRESULT RootWindowHostWin::OnKeyEvent(UINT message,
281 WPARAM w_param,
282 LPARAM l_param) {
[email protected]c94f8592011-09-02 20:12:13283 MSG msg = { hwnd(), message, w_param, l_param };
[email protected]593ddfa2011-10-20 21:51:43284 KeyEvent keyev(msg, message == WM_CHAR);
[email protected]99f07e02011-12-07 00:02:59285 SetMsgHandled(root_window_->DispatchKeyEvent(&keyev));
[email protected]c94f8592011-09-02 20:12:13286 return 0;
287}
288
[email protected]99f07e02011-12-07 00:02:59289LRESULT RootWindowHostWin::OnMouseRange(UINT message,
290 WPARAM w_param,
291 LPARAM l_param) {
[email protected]a83f0f22011-08-23 15:39:15292 MSG msg = { hwnd(), message, w_param, l_param, 0,
293 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } };
[email protected]e599f0132011-08-24 19:03:35294 MouseEvent event(msg);
295 bool handled = false;
296 if (!(event.flags() & ui::EF_IS_NON_CLIENT))
[email protected]99f07e02011-12-07 00:02:59297 handled = root_window_->DispatchMouseEvent(&event);
[email protected]e599f0132011-08-24 19:03:35298 SetMsgHandled(handled);
[email protected]a83f0f22011-08-23 15:39:15299 return 0;
300}
301
[email protected]759017e02012-02-11 20:46:11302LRESULT RootWindowHostWin::OnCaptureChanged(UINT message,
303 WPARAM w_param,
304 LPARAM l_param) {
305 if (has_capture_) {
306 has_capture_ = false;
307 root_window_->SetCapture(NULL);
308 }
309 return 0;
310}
311
[email protected]99f07e02011-12-07 00:02:59312void RootWindowHostWin::OnPaint(HDC dc) {
313 root_window_->Draw();
[email protected]81585f32011-07-29 19:32:06314 ValidateRect(hwnd(), NULL);
315}
316
[email protected]99f07e02011-12-07 00:02:59317void RootWindowHostWin::OnSize(UINT param, const CSize& size) {
[email protected]f4b96e202011-11-15 18:07:50318 // Minimizing resizes the window to 0x0 which causes our layout to go all
319 // screwy, so we just ignore it.
320 if (param != SIZE_MINIMIZED)
[email protected]99f07e02011-12-07 00:02:59321 root_window_->OnHostResized(gfx::Size(size.cx, size.cy));
[email protected]c94f8592011-09-02 20:12:13322}
323
[email protected]81585f32011-07-29 19:32:06324} // namespace aura