blob: 868173c8b93f941083c7f88eef450e593c911ee6 [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]553dfa52012-02-23 17:35:3413#include "ui/aura/env.h"
[email protected]f94f0f12011-09-14 21:14:0114#include "ui/aura/event.h"
[email protected]81585f32011-07-29 19:32:0615
[email protected]9ba7ecf2011-10-19 18:39:3216using std::max;
17using std::min;
18
[email protected]81585f32011-07-29 19:32:0619namespace aura {
20
[email protected]9e591cb2011-10-17 18:14:3221namespace {
22
23const wchar_t* GetCursorId(gfx::NativeCursor native_cursor) {
24 switch (native_cursor) {
25 case kCursorNull:
26 return IDC_ARROW;
27 case kCursorPointer:
28 return IDC_ARROW;
29 case kCursorCross:
30 return IDC_CROSS;
31 case kCursorHand:
32 return IDC_HAND;
33 case kCursorIBeam:
34 return IDC_IBEAM;
35 case kCursorWait:
36 return IDC_WAIT;
37 case kCursorHelp:
38 return IDC_HELP;
39 case kCursorEastResize:
40 return IDC_SIZEWE;
41 case kCursorNorthResize:
42 return IDC_SIZENS;
43 case kCursorNorthEastResize:
44 return IDC_SIZENESW;
45 case kCursorNorthWestResize:
46 return IDC_SIZENWSE;
47 case kCursorSouthResize:
48 return IDC_SIZENS;
49 case kCursorSouthEastResize:
50 return IDC_SIZENWSE;
51 case kCursorSouthWestResize:
52 return IDC_SIZENESW;
53 case kCursorWestResize:
54 return IDC_SIZEWE;
55 case kCursorNorthSouthResize:
56 return IDC_SIZENS;
57 case kCursorEastWestResize:
58 return IDC_SIZEWE;
59 case kCursorNorthEastSouthWestResize:
60 return IDC_SIZENESW;
61 case kCursorNorthWestSouthEastResize:
62 return IDC_SIZENWSE;
63 case kCursorMove:
64 return IDC_SIZEALL;
65 case kCursorProgress:
66 return IDC_APPSTARTING;
67 case kCursorNoDrop:
68 return IDC_NO;
69 case kCursorNotAllowed:
70 return IDC_NO;
71 case kCursorColumnResize:
72 case kCursorRowResize:
73 case kCursorMiddlePanning:
74 case kCursorEastPanning:
75 case kCursorNorthPanning:
76 case kCursorNorthEastPanning:
77 case kCursorNorthWestPanning:
78 case kCursorSouthPanning:
79 case kCursorSouthEastPanning:
80 case kCursorSouthWestPanning:
81 case kCursorWestPanning:
82 case kCursorVerticalText:
83 case kCursorCell:
84 case kCursorContextMenu:
85 case kCursorAlias:
86 case kCursorCopy:
87 case kCursorNone:
88 case kCursorZoomIn:
89 case kCursorZoomOut:
90 case kCursorGrab:
91 case kCursorGrabbing:
92 case kCursorCustom:
93 // TODO(jamescook): Should we use WebKit glue resources for these?
94 // Or migrate those resources to someplace ui/aura can share?
95 NOTIMPLEMENTED();
96 return IDC_ARROW;
97 default:
98 NOTREACHED();
99 return IDC_ARROW;
100 }
101}
102
103} // namespace
104
[email protected]81585f32011-07-29 19:32:06105// static
[email protected]99f07e02011-12-07 00:02:59106RootWindowHost* RootWindowHost::Create(const gfx::Rect& bounds) {
107 return new RootWindowHostWin(bounds);
[email protected]81585f32011-07-29 19:32:06108}
109
[email protected]5978af5e2011-10-24 22:17:18110// static
[email protected]99f07e02011-12-07 00:02:59111gfx::Size RootWindowHost::GetNativeScreenSize() {
[email protected]5978af5e2011-10-24 22:17:18112 return gfx::Size(GetSystemMetrics(SM_CXSCREEN),
113 GetSystemMetrics(SM_CYSCREEN));
114}
115
[email protected]99f07e02011-12-07 00:02:59116RootWindowHostWin::RootWindowHostWin(const gfx::Rect& bounds)
117 : root_window_(NULL),
[email protected]8a1527b2011-11-03 15:47:16118 fullscreen_(false),
[email protected]759017e02012-02-11 20:46:11119 has_capture_(false),
[email protected]8a1527b2011-11-03 15:47:16120 saved_window_style_(0),
121 saved_window_ex_style_(0) {
[email protected]81585f32011-07-29 19:32:06122 Init(NULL, bounds);
[email protected]99f07e02011-12-07 00:02:59123 SetWindowText(hwnd(), L"aura::RootWindow!");
[email protected]81585f32011-07-29 19:32:06124}
125
[email protected]99f07e02011-12-07 00:02:59126RootWindowHostWin::~RootWindowHostWin() {
[email protected]81585f32011-07-29 19:32:06127 DestroyWindow(hwnd());
128}
129
[email protected]99f07e02011-12-07 00:02:59130void RootWindowHostWin::SetRootWindow(RootWindow* root_window) {
131 root_window_ = root_window;
[email protected]81585f32011-07-29 19:32:06132}
133
[email protected]99f07e02011-12-07 00:02:59134gfx::AcceleratedWidget RootWindowHostWin::GetAcceleratedWidget() {
[email protected]81585f32011-07-29 19:32:06135 return hwnd();
136}
137
[email protected]99f07e02011-12-07 00:02:59138void RootWindowHostWin::Show() {
[email protected]81585f32011-07-29 19:32:06139 ShowWindow(hwnd(), SW_SHOWNORMAL);
140}
141
[email protected]99f07e02011-12-07 00:02:59142void RootWindowHostWin::ToggleFullScreen() {
[email protected]8a1527b2011-11-03 15:47:16143 gfx::Rect target_rect;
144 if (!fullscreen_) {
145 fullscreen_ = true;
146 saved_window_style_ = GetWindowLong(hwnd(), GWL_STYLE);
147 saved_window_ex_style_ = GetWindowLong(hwnd(), GWL_EXSTYLE);
148 GetWindowRect(hwnd(), &saved_window_rect_);
149 SetWindowLong(hwnd(), GWL_STYLE,
150 saved_window_style_ & ~(WS_CAPTION | WS_THICKFRAME));
151 SetWindowLong(hwnd(), GWL_EXSTYLE,
152 saved_window_ex_style_ & ~(WS_EX_DLGMODALFRAME |
153 WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
154
155 MONITORINFO mi;
156 mi.cbSize = sizeof(mi);
157 GetMonitorInfo(MonitorFromWindow(hwnd(), MONITOR_DEFAULTTONEAREST), &mi);
158 target_rect = mi.rcMonitor;
159 } else {
160 fullscreen_ = false;
161 SetWindowLong(hwnd(), GWL_STYLE, saved_window_style_);
162 SetWindowLong(hwnd(), GWL_EXSTYLE, saved_window_ex_style_);
163 target_rect = saved_window_rect_;
164 }
165 SetWindowPos(hwnd(),
166 NULL,
167 target_rect.x(),
168 target_rect.y(),
169 target_rect.width(),
170 target_rect.height(),
171 SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
172}
173
[email protected]193b39d22012-03-16 20:56:28174gfx::Rect RootWindowHostWin::GetBounds() const {
[email protected]81585f32011-07-29 19:32:06175 RECT r;
176 GetClientRect(hwnd(), &r);
[email protected]193b39d22012-03-16 20:56:28177 return gfx::Rect(r);
[email protected]81585f32011-07-29 19:32:06178}
179
[email protected]193b39d22012-03-16 20:56:28180void RootWindowHostWin::SetBounds(const gfx::Rect& bounds) {
[email protected]71b6d572011-11-08 23:45:04181 if (fullscreen_) {
[email protected]193b39d22012-03-16 20:56:28182 saved_window_rect_.right = saved_window_rect_.left + bounds.width();
183 saved_window_rect_.bottom = saved_window_rect_.top + bounds.height();
[email protected]71b6d572011-11-08 23:45:04184 return;
185 }
186 RECT window_rect;
[email protected]193b39d22012-03-16 20:56:28187 window_rect.left = bounds.x();
188 window_rect.top = bounds.y();
189 window_rect.right = bounds.width();
190 window_rect.bottom = bounds.height();
[email protected]71b6d572011-11-08 23:45:04191 AdjustWindowRectEx(&window_rect,
192 GetWindowLong(hwnd(), GWL_STYLE),
193 FALSE,
194 GetWindowLong(hwnd(), GWL_EXSTYLE));
[email protected]970aa362011-08-30 20:03:34195 SetWindowPos(
196 hwnd(),
197 NULL,
198 0,
199 0,
[email protected]71b6d572011-11-08 23:45:04200 window_rect.right - window_rect.left,
201 window_rect.bottom - window_rect.top,
[email protected]970aa362011-08-30 20:03:34202 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOREPOSITION);
203}
204
[email protected]99f07e02011-12-07 00:02:59205gfx::Point RootWindowHostWin::GetLocationOnNativeScreen() const {
[email protected]ace7ca02011-11-22 21:34:17206 RECT r;
207 GetClientRect(hwnd(), &r);
208 return gfx::Point(r.left, r.top);
209}
210
211
[email protected]99f07e02011-12-07 00:02:59212void RootWindowHostWin::SetCursor(gfx::NativeCursor native_cursor) {
[email protected]9e591cb2011-10-17 18:14:32213 // Custom web cursors are handled directly.
214 if (native_cursor == kCursorCustom)
215 return;
216 const wchar_t* cursor_id = GetCursorId(native_cursor);
217 // TODO(jamescook): Support for non-system cursors will require finding
218 // the appropriate module to pass to LoadCursor().
219 ::SetCursor(LoadCursor(NULL, cursor_id));
[email protected]70ccf702011-09-22 18:15:58220}
221
[email protected]759017e02012-02-11 20:46:11222void RootWindowHostWin::SetCapture() {
223 if (!has_capture_) {
224 has_capture_ = true;
225 ::SetCapture(hwnd());
226 }
227}
228
229void RootWindowHostWin::ReleaseCapture() {
230 if (has_capture_) {
231 has_capture_ = false;
232 ::ReleaseCapture();
233 }
234}
235
[email protected]09a02fff2011-12-20 22:01:43236void RootWindowHostWin::ShowCursor(bool show) {
[email protected]c5e9c6ce2012-01-13 02:37:18237 // NOTIMPLEMENTED();
[email protected]09a02fff2011-12-20 22:01:43238}
239
[email protected]99f07e02011-12-07 00:02:59240gfx::Point RootWindowHostWin::QueryMouseLocation() {
[email protected]896728e2011-10-14 00:41:26241 POINT pt;
242 GetCursorPos(&pt);
243 ScreenToClient(hwnd(), &pt);
[email protected]193b39d22012-03-16 20:56:28244 const gfx::Size size = GetBounds().size();
[email protected]9ba7ecf2011-10-19 18:39:32245 return gfx::Point(max(0, min(size.width(), static_cast<int>(pt.x))),
246 max(0, min(size.height(), static_cast<int>(pt.y))));
[email protected]896728e2011-10-14 00:41:26247}
248
[email protected]e4243262012-01-19 18:59:25249bool RootWindowHostWin::ConfineCursorToRootWindow() {
250 RECT window_rect;
251 GetWindowRect(hwnd(), &window_rect);
252 return ClipCursor(&window_rect) != 0;
253}
254
255void RootWindowHostWin::UnConfineCursor() {
256 ClipCursor(NULL);
257}
258
[email protected]5922cb22012-01-17 21:53:12259void RootWindowHostWin::MoveCursorTo(const gfx::Point& location) {
260 POINT pt;
261 ClientToScreen(hwnd(), &pt);
262 SetCursorPos(pt.x, pt.y);
263}
264
[email protected]99f07e02011-12-07 00:02:59265void RootWindowHostWin::PostNativeEvent(const base::NativeEvent& native_event) {
[email protected]b5a18642011-11-18 22:45:36266 ::PostMessage(
267 hwnd(), native_event.message, native_event.wParam, native_event.lParam);
268}
269
[email protected]99f07e02011-12-07 00:02:59270void RootWindowHostWin::OnClose() {
[email protected]81585f32011-07-29 19:32:06271 // TODO: this obviously shouldn't be here.
272 MessageLoopForUI::current()->Quit();
273}
274
[email protected]99f07e02011-12-07 00:02:59275LRESULT RootWindowHostWin::OnKeyEvent(UINT message,
276 WPARAM w_param,
277 LPARAM l_param) {
[email protected]c94f8592011-09-02 20:12:13278 MSG msg = { hwnd(), message, w_param, l_param };
[email protected]593ddfa2011-10-20 21:51:43279 KeyEvent keyev(msg, message == WM_CHAR);
[email protected]99f07e02011-12-07 00:02:59280 SetMsgHandled(root_window_->DispatchKeyEvent(&keyev));
[email protected]c94f8592011-09-02 20:12:13281 return 0;
282}
283
[email protected]99f07e02011-12-07 00:02:59284LRESULT RootWindowHostWin::OnMouseRange(UINT message,
285 WPARAM w_param,
286 LPARAM l_param) {
[email protected]a83f0f22011-08-23 15:39:15287 MSG msg = { hwnd(), message, w_param, l_param, 0,
288 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } };
[email protected]e599f0132011-08-24 19:03:35289 MouseEvent event(msg);
290 bool handled = false;
291 if (!(event.flags() & ui::EF_IS_NON_CLIENT))
[email protected]99f07e02011-12-07 00:02:59292 handled = root_window_->DispatchMouseEvent(&event);
[email protected]e599f0132011-08-24 19:03:35293 SetMsgHandled(handled);
[email protected]a83f0f22011-08-23 15:39:15294 return 0;
295}
296
[email protected]759017e02012-02-11 20:46:11297LRESULT RootWindowHostWin::OnCaptureChanged(UINT message,
298 WPARAM w_param,
299 LPARAM l_param) {
300 if (has_capture_) {
301 has_capture_ = false;
302 root_window_->SetCapture(NULL);
303 }
304 return 0;
305}
306
[email protected]99f07e02011-12-07 00:02:59307void RootWindowHostWin::OnPaint(HDC dc) {
308 root_window_->Draw();
[email protected]81585f32011-07-29 19:32:06309 ValidateRect(hwnd(), NULL);
310}
311
[email protected]99f07e02011-12-07 00:02:59312void RootWindowHostWin::OnSize(UINT param, const CSize& size) {
[email protected]f4b96e202011-11-15 18:07:50313 // Minimizing resizes the window to 0x0 which causes our layout to go all
314 // screwy, so we just ignore it.
315 if (param != SIZE_MINIMIZED)
[email protected]99f07e02011-12-07 00:02:59316 root_window_->OnHostResized(gfx::Size(size.cx, size.cy));
[email protected]c94f8592011-09-02 20:12:13317}
318
[email protected]81585f32011-07-29 19:32:06319} // namespace aura