OLD | NEW |
| (Empty) |
1 // Copyright (c) 2011 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 "ui/aura/desktop_host_win.h" | |
6 | |
7 #include <windows.h> | |
8 | |
9 #include <algorithm> | |
10 | |
11 #include "base/message_loop.h" | |
12 #include "ui/aura/desktop.h" | |
13 #include "ui/aura/event.h" | |
14 | |
15 using std::max; | |
16 using std::min; | |
17 | |
18 namespace aura { | |
19 | |
20 namespace { | |
21 | |
22 const 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 | |
104 // static | |
105 DesktopHost* DesktopHost::Create(const gfx::Rect& bounds) { | |
106 return new DesktopHostWin(bounds); | |
107 } | |
108 | |
109 // static | |
110 gfx::Size DesktopHost::GetNativeScreenSize() { | |
111 return gfx::Size(GetSystemMetrics(SM_CXSCREEN), | |
112 GetSystemMetrics(SM_CYSCREEN)); | |
113 } | |
114 | |
115 DesktopHostWin::DesktopHostWin(const gfx::Rect& bounds) | |
116 : desktop_(NULL), | |
117 fullscreen_(false), | |
118 saved_window_style_(0), | |
119 saved_window_ex_style_(0) { | |
120 Init(NULL, bounds); | |
121 SetWindowText(hwnd(), L"aura::Desktop!"); | |
122 } | |
123 | |
124 DesktopHostWin::~DesktopHostWin() { | |
125 DestroyWindow(hwnd()); | |
126 } | |
127 | |
128 bool DesktopHostWin::Dispatch(const MSG& msg) { | |
129 TranslateMessage(&msg); | |
130 DispatchMessage(&msg); | |
131 return true; | |
132 } | |
133 | |
134 void DesktopHostWin::SetDesktop(Desktop* desktop) { | |
135 desktop_ = desktop; | |
136 } | |
137 | |
138 gfx::AcceleratedWidget DesktopHostWin::GetAcceleratedWidget() { | |
139 return hwnd(); | |
140 } | |
141 | |
142 void DesktopHostWin::Show() { | |
143 ShowWindow(hwnd(), SW_SHOWNORMAL); | |
144 } | |
145 | |
146 void DesktopHostWin::ToggleFullScreen() { | |
147 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 | |
178 gfx::Size DesktopHostWin::GetSize() const { | |
179 RECT r; | |
180 GetClientRect(hwnd(), &r); | |
181 return gfx::Rect(r).size(); | |
182 } | |
183 | |
184 void DesktopHostWin::SetSize(const gfx::Size& size) { | |
185 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)); | |
199 SetWindowPos( | |
200 hwnd(), | |
201 NULL, | |
202 0, | |
203 0, | |
204 window_rect.right - window_rect.left, | |
205 window_rect.bottom - window_rect.top, | |
206 SWP_NOMOVE | SWP_NOOWNERZORDER | SWP_NOREDRAW | SWP_NOREPOSITION); | |
207 } | |
208 | |
209 gfx::Point DesktopHostWin::GetLocationOnNativeScreen() const { | |
210 RECT r; | |
211 GetClientRect(hwnd(), &r); | |
212 return gfx::Point(r.left, r.top); | |
213 } | |
214 | |
215 | |
216 void DesktopHostWin::SetCursor(gfx::NativeCursor native_cursor) { | |
217 // 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)); | |
224 } | |
225 | |
226 gfx::Point DesktopHostWin::QueryMouseLocation() { | |
227 POINT pt; | |
228 GetCursorPos(&pt); | |
229 ScreenToClient(hwnd(), &pt); | |
230 const gfx::Size size = GetSize(); | |
231 return gfx::Point(max(0, min(size.width(), static_cast<int>(pt.x))), | |
232 max(0, min(size.height(), static_cast<int>(pt.y)))); | |
233 } | |
234 | |
235 void DesktopHostWin::PostNativeEvent(const base::NativeEvent& native_event) { | |
236 ::PostMessage( | |
237 hwnd(), native_event.message, native_event.wParam, native_event.lParam); | |
238 } | |
239 | |
240 void DesktopHostWin::OnClose() { | |
241 // TODO: this obviously shouldn't be here. | |
242 MessageLoopForUI::current()->Quit(); | |
243 } | |
244 | |
245 LRESULT DesktopHostWin::OnKeyEvent(UINT message, | |
246 WPARAM w_param, | |
247 LPARAM l_param) { | |
248 MSG msg = { hwnd(), message, w_param, l_param }; | |
249 KeyEvent keyev(msg, message == WM_CHAR); | |
250 SetMsgHandled(desktop_->DispatchKeyEvent(&keyev)); | |
251 return 0; | |
252 } | |
253 | |
254 LRESULT DesktopHostWin::OnMouseRange(UINT message, | |
255 WPARAM w_param, | |
256 LPARAM l_param) { | |
257 MSG msg = { hwnd(), message, w_param, l_param, 0, | |
258 { GET_X_LPARAM(l_param), GET_Y_LPARAM(l_param) } }; | |
259 MouseEvent event(msg); | |
260 bool handled = false; | |
261 if (!(event.flags() & ui::EF_IS_NON_CLIENT)) | |
262 handled = desktop_->DispatchMouseEvent(&event); | |
263 SetMsgHandled(handled); | |
264 return 0; | |
265 } | |
266 | |
267 void DesktopHostWin::OnPaint(HDC dc) { | |
268 desktop_->Draw(); | |
269 ValidateRect(hwnd(), NULL); | |
270 } | |
271 | |
272 void DesktopHostWin::OnSize(UINT param, const CSize& size) { | |
273 // Minimizing resizes the window to 0x0 which causes our layout to go all | |
274 // screwy, so we just ignore it. | |
275 if (param != SIZE_MINIMIZED) | |
276 desktop_->OnHostResized(gfx::Size(size.cx, size.cy)); | |
277 } | |
278 | |
279 } // namespace aura | |
OLD | NEW |