- add sources.
[platform/framework/web/crosswalk.git] / src / ui / gfx / screen_win.cc
1 // Copyright (c) 2012 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/gfx/screen_win.h"
6
7 #include <windows.h>
8
9 #include "base/hash.h"
10 #include "base/logging.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/win/win_util.h"
13 #include "ui/gfx/display.h"
14 #include "ui/gfx/win/dpi.h"
15
16 namespace {
17
18 MONITORINFOEX GetMonitorInfoForMonitor(HMONITOR monitor) {
19   MONITORINFOEX monitor_info;
20   ZeroMemory(&monitor_info, sizeof(MONITORINFOEX));
21   monitor_info.cbSize = sizeof(monitor_info);
22   base::win::GetMonitorInfoWrapper(monitor, &monitor_info);
23   return monitor_info;
24 }
25
26 gfx::Display GetDisplay(MONITORINFOEX& monitor_info) {
27   // TODO(oshima): Implement Observer.
28   int64 id = static_cast<int64>(base::Hash(WideToUTF8(monitor_info.szDevice)));
29   gfx::Rect bounds = gfx::Rect(monitor_info.rcMonitor);
30   gfx::Display display(id, bounds);
31   display.set_work_area(gfx::Rect(monitor_info.rcWork));
32   display.SetScaleAndBounds(gfx::win::GetDeviceScaleFactor(), bounds);
33   return display;
34 }
35
36 BOOL CALLBACK EnumMonitorCallback(HMONITOR monitor,
37                                   HDC hdc,
38                                   LPRECT rect,
39                                   LPARAM data) {
40   std::vector<gfx::Display>* all_displays =
41       reinterpret_cast<std::vector<gfx::Display>*>(data);
42   DCHECK(all_displays);
43
44   MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(monitor);
45   gfx::Display display = GetDisplay(monitor_info);
46   all_displays->push_back(display);
47   return TRUE;
48 }
49
50 }  // namespace
51
52 namespace gfx {
53
54 ScreenWin::ScreenWin() {
55 }
56
57 ScreenWin::~ScreenWin() {
58 }
59
60 bool ScreenWin::IsDIPEnabled() {
61   return IsInHighDPIMode();
62 }
63
64 gfx::Point ScreenWin::GetCursorScreenPoint() {
65   POINT pt;
66   GetCursorPos(&pt);
67   return gfx::Point(pt);
68 }
69
70 gfx::NativeWindow ScreenWin::GetWindowUnderCursor() {
71   POINT cursor_loc;
72   HWND hwnd = GetCursorPos(&cursor_loc) ? WindowFromPoint(cursor_loc) : NULL;
73   return GetNativeWindowFromHWND(hwnd);
74 }
75
76 gfx::NativeWindow ScreenWin::GetWindowAtScreenPoint(const gfx::Point& point) {
77   return GetNativeWindowFromHWND(WindowFromPoint(point.ToPOINT()));
78 }
79
80 int ScreenWin::GetNumDisplays() const {
81   return GetSystemMetrics(SM_CMONITORS);
82 }
83
84 std::vector<gfx::Display> ScreenWin::GetAllDisplays() const {
85   std::vector<gfx::Display> all_displays;
86   EnumDisplayMonitors(NULL, NULL, EnumMonitorCallback,
87                       reinterpret_cast<LPARAM>(&all_displays));
88   return all_displays;
89 }
90
91 gfx::Display ScreenWin::GetDisplayNearestWindow(gfx::NativeView window) const {
92   HWND window_hwnd = GetHWNDFromNativeView(window);
93   if (!window_hwnd) {
94     // When |window| isn't rooted to a display, we should just return the
95     // default display so we get some correct display information like the
96     // scaling factor.
97     return GetPrimaryDisplay();
98   }
99
100   MONITORINFOEX monitor_info;
101   monitor_info.cbSize = sizeof(monitor_info);
102   base::win::GetMonitorInfoWrapper(
103       MonitorFromWindow(window_hwnd, MONITOR_DEFAULTTONEAREST), &monitor_info);
104   return GetDisplay(monitor_info);
105 }
106
107 gfx::Display ScreenWin::GetDisplayNearestPoint(const gfx::Point& point) const {
108   POINT initial_loc = { point.x(), point.y() };
109   HMONITOR monitor = MonitorFromPoint(initial_loc, MONITOR_DEFAULTTONEAREST);
110   MONITORINFOEX mi;
111   ZeroMemory(&mi, sizeof(MONITORINFOEX));
112   mi.cbSize = sizeof(mi);
113   if (monitor && base::win::GetMonitorInfoWrapper(monitor, &mi)) {
114     return GetDisplay(mi);
115   }
116   return gfx::Display();
117 }
118
119 gfx::Display ScreenWin::GetDisplayMatching(const gfx::Rect& match_rect) const {
120   RECT other_bounds_rect = match_rect.ToRECT();
121   MONITORINFOEX monitor_info = GetMonitorInfoForMonitor(MonitorFromRect(
122       &other_bounds_rect, MONITOR_DEFAULTTONEAREST));
123   return GetDisplay(monitor_info);
124 }
125
126 gfx::Display ScreenWin::GetPrimaryDisplay() const {
127   MONITORINFOEX mi = GetMonitorInfoForMonitor(
128       MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY));
129   gfx::Display display = GetDisplay(mi);
130   // TODO(kevers|girard): Test if these checks can be reintroduced for high-DIP
131   // once more of the app is DIP-aware.
132   if (!IsInHighDPIMode()) {
133     DCHECK_EQ(GetSystemMetrics(SM_CXSCREEN), display.size().width());
134     DCHECK_EQ(GetSystemMetrics(SM_CYSCREEN), display.size().height());
135   }
136   return display;
137 }
138
139 void ScreenWin::AddObserver(DisplayObserver* observer) {
140   // TODO(oshima): crbug.com/122863.
141 }
142
143 void ScreenWin::RemoveObserver(DisplayObserver* observer) {
144   // TODO(oshima): crbug.com/122863.
145 }
146
147 HWND ScreenWin::GetHWNDFromNativeView(NativeView window) const {
148 #if defined(USE_AURA)
149   NOTREACHED();
150   return NULL;
151 #else
152   return window;
153 #endif  // USE_AURA
154 }
155
156 NativeWindow ScreenWin::GetNativeWindowFromHWND(HWND hwnd) const {
157 #if defined(USE_AURA)
158   NOTREACHED();
159   return NULL;
160 #else
161   return hwnd;
162 #endif  // USE_AURA
163 }
164
165 #if !defined(USE_AURA)
166 Screen* CreateNativeScreen() {
167   return new ScreenWin;
168 }
169 #endif  // !USE_AURA
170
171 }  // namespace gfx