blob: 705cf9aab59ff0e7f48ab51fa06dcd64f2b882fe [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),
118 saved_window_style_(0),
119 saved_window_ex_style_(0) {
[email protected]81585f32011-07-29 19:32:06120 Init(NULL, bounds);
[email protected]99f07e02011-12-07 00:02:59121 SetWindowText(hwnd(), L"aura::RootWindow!");
[email protected]81585f32011-07-29 19:32:06122}
123
[email protected]99f07e02011-12-07 00:02:59124RootWindowHostWin::~RootWindowHostWin() {
[email protected]81585f32011-07-29 19:32:06125 DestroyWindow(hwnd());
126}
127
[email protected]99f07e02011-12-07 00:02:59128bool RootWindowHostWin::Dispatch(const MSG& msg) {
[email protected]b2d2ee82011-08-22 17:25:05129 TranslateMessage(&msg);
130 DispatchMessage(&msg);
[email protected]711d8a82011-08-22 16:01:19131 return true;
132}
133
[email protected]99f07e02011-12-07 00:02:59134void RootWindowHostWin::SetRootWindow(RootWindow* root_window) {
135 root_window_ = root_window;
[email protected]81585f32011-07-29 19:32:06136}
137
[email protected]99f07e02011-12-07 00:02:59138gfx::AcceleratedWidget RootWindowHostWin::GetAcceleratedWidget() {
[email protected]81585f32011-07-29 19:32:06139 return hwnd();
140}
141
[email protected]99f07e02011-12-07 00:02:59142void RootWindowHostWin::Show() {
[email protected]81585f32011-07-29 19:32:06143 ShowWindow(hwnd(), SW_SHOWNORMAL);
144}
145
[email protected]99f07e02011-12-07 00:02:59146void RootWindowHostWin::ToggleFullScreen() {
[email protected]8a1527b2011-11-03 15:47:16147 gfx::Rect target_rect;
148 if (!fullscreen_) {
149 fullscreen_ = true;
150 saved_window_style_ = GetWindowLong(hwnd(), GWL_STYLE);
151 saved_window_ex_style_ = GetWindowLong(hwnd(), GWL_EXSTYLE);
152 GetWindowRect(hwnd(), &saved_window_rect_);
153 SetWindowLong(hwnd(), GWL_STYLE,
154 saved_window_style_ & ~(WS_CAPTION | WS_THICKFRAME));
155 SetWindowLong(hwnd(), GWL_EXSTYLE,
156 saved_window_ex_style_ & ~(WS_EX_DLGMODALFRAME |
157 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
158
159 MONITORINFO mi;
160 mi.cbSize = sizeof(mi);
161 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST), &mi);
162 target_rect = mi.rcMonitor;
163 } else {
164 fullscreen_ = false;
165 SetWindowLong(hwnd(), GWL_STYLE, saved_window_style_);
166 SetWindowLong(hwnd(), GWL_EXSTYLE, saved_window_ex_style_);
167 target_rect = saved_window_rect_;
168 }
169 SetWindowPos(hwnd(),
170 NULL,
171 target_rect.x(),
172 target_rect.y(),
173 target_rect.width(),
174 target_rect.height(),
175 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
176}
177
[email protected]99f07e02011-12-07 00:02:59178gfx::Size RootWindowHostWin::GetSize() const {
[email protected]81585f32011-07-29 19:32:06179 RECT r;
180 GetClientRect(hwnd(), &r);
181 return gfx::Rect(r).size();
182}
183
[email protected]99f07e02011-12-07 00:02:59184void RootWindowHostWin::SetSize(const gfx::Size& size) {
[email protected]71b6d572011-11-08 23:45:04185 if (fullscreen_) {
186 saved_window_rect_.right = saved_window_rect_.left + size.width();
187 saved_window_rect_.bottom = saved_window_rect_.top + size.height();
188 return;
189 }
190 RECT window_rect;
191 window_rect.left = 0;
192 window_rect.top = 0;
193 window_rect.right = size.width();
194 window_rect.bottom = size.height();
195 AdjustWindowRectEx(&window_rect,
196 GetWindowLong(hwnd(), GWL_STYLE),
197 FALSE,
198 GetWindowLong(hwnd(), GWL_EXSTYLE));
[email protected]970aa362011-08-30 20:03:34199 SetWindowPos(
200 hwnd(),
201 NULL,
202 0,
203 0,
[email protected]71b6d572011-11-08 23:45:04204 window_rect.right - window_rect.left,
205 window_rect.bottom - window_rect.top,
[email protected]970aa362011-08-30 20:03:34206 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOREPOSITION);
207}
208
[email protected]99f07e02011-12-07 00:02:59209gfx::Point RootWindowHostWin::GetLocationOnNativeScreen() const {
[email protected]ace7ca02011-11-22 21:34:17210 RECT r;
211 GetClientRect(hwnd(), &r);
212 return gfx::Point(r.left, r.top);
213}
214
215
[email protected]99f07e02011-12-07 00:02:59216void RootWindowHostWin::SetCursor(gfx::NativeCursor native_cursor) {
[email protected]9e591cb2011-10-17 18:14:32217 // Custom web cursors are handled directly.
218 if (native_cursor == kCursorCustom)
219 return;
220 const wchar_t* cursor_id = GetCursorId(native_cursor);
221 // TODO(jamescook): Support for non-system cursors will require finding
222 // the appropriate module to pass to LoadCursor().
223 ::SetCursor(LoadCursor(NULL, cursor_id));
[email protected]70ccf702011-09-22 18:15:58224}
225
[email protected]09a02fff2011-12-20 22:01:43226void RootWindowHostWin::ShowCursor(bool show) {
[email protected]c5e9c6ce2012-01-13 02:37:18227 // NOTIMPLEMENTED();
[email protected]09a02fff2011-12-20 22:01:43228}
229
[email protected]99f07e02011-12-07 00:02:59230gfx::Point RootWindowHostWin::QueryMouseLocation() {
[email protected]896728e2011-10-14 00:41:26231 POINT pt;
232 GetCursorPos(&pt);
233 ScreenToClient(hwnd(), &pt);
[email protected]9ba7ecf2011-10-19 18:39:32234 const gfx::Size size = GetSize();
235 return gfx::Point(max(0, min(size.width(), static_cast<int>(pt.x))),
236 max(0, min(size.height(), static_cast<int>(pt.y))));
[email protected]896728e2011-10-14 00:41:26237}
238
[email protected]e4243262012-01-19 18:59:25239bool RootWindowHostWin::ConfineCursorToRootWindow() {
240 RECT window_rect;
241 GetWindowRect(hwnd(), &window_rect);
242 return ClipCursor(&window_rect) != 0;
243}
244
245void RootWindowHostWin::UnConfineCursor() {
246 ClipCursor(NULL);
247}
248
[email protected]5922cb22012-01-17 21:53:12249void RootWindowHostWin::MoveCursorTo(const gfx::Point& location) {
250 POINT pt;
251 ClientToScreen(hwnd(), &pt);
252 SetCursorPos(pt.x, pt.y);
253}
254
[email protected]99f07e02011-12-07 00:02:59255void RootWindowHostWin::PostNativeEvent(const base::NativeEvent& native_event) {
[email protected]b5a18642011-11-18 22:45:36256 ::PostMessage(
257 hwnd(), native_event.message, native_event.wParam, native_event.lParam);
258}
259
[email protected]99f07e02011-12-07 00:02:59260void RootWindowHostWin::OnClose() {
[email protected]81585f32011-07-29 19:32:06261 // TODO: this obviously shouldn't be here.
262 MessageLoopForUI::current()->Quit();
263}
264
[email protected]99f07e02011-12-07 00:02:59265LRESULT RootWindowHostWin::OnKeyEvent(UINT message,
266 WPARAM w_param,
267 LPARAM l_param) {
[email protected]c94f8592011-09-02 20:12:13268 MSG msg = { hwnd(), message, w_param, l_param };
[email protected]593ddfa2011-10-20 21:51:43269 KeyEvent keyev(msg, message == WM_CHAR);
[email protected]99f07e02011-12-07 00:02:59270 SetMsgHandled(root_window_->DispatchKeyEvent(&keyev));
[email protected]c94f8592011-09-02 20:12:13271 return 0;
272}
273
[email protected]99f07e02011-12-07 00:02:59274LRESULT RootWindowHostWin::OnMouseRange(UINT message,
275 WPARAM w_param,
276 LPARAM l_param) {
[email protected]a83f0f22011-08-23 15:39:15277 MSG msg = { hwnd(), message, w_param, l_param, 0,
278 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } };
[email protected]e599f0132011-08-24 19:03:35279 MouseEvent event(msg);
280 bool handled = false;
281 if (!(event.flags() & ui::EF_IS_NON_CLIENT))
[email protected]99f07e02011-12-07 00:02:59282 handled = root_window_->DispatchMouseEvent(&event);
[email protected]e599f0132011-08-24 19:03:35283 SetMsgHandled(handled);
[email protected]a83f0f22011-08-23 15:39:15284 return 0;
285}
286
[email protected]99f07e02011-12-07 00:02:59287void RootWindowHostWin::OnPaint(HDC dc) {
288 root_window_->Draw();
[email protected]81585f32011-07-29 19:32:06289 ValidateRect(hwnd(), NULL);
290}
291
[email protected]99f07e02011-12-07 00:02:59292void RootWindowHostWin::OnSize(UINT param, const CSize& size) {
[email protected]f4b96e202011-11-15 18:07:50293 // Minimizing resizes the window to 0x0 which causes our layout to go all
294 // screwy, so we just ignore it.
295 if (param != SIZE_MINIMIZED)
[email protected]99f07e02011-12-07 00:02:59296 root_window_->OnHostResized(gfx::Size(size.cx, size.cy));
[email protected]c94f8592011-09-02 20:12:13297}
298
[email protected]81585f32011-07-29 19:32:06299} // namespace aura