| 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 |