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 "chrome/browser/fullscreen.h"
6
7 #include <windows.h>
8 #include <shellapi.h>
9
10 #include "base/logging.h"
11 #include "base/sys_info.h"
12
IsPlatformFullScreenMode()13 static bool IsPlatformFullScreenMode() {
14 // SHQueryUserNotificationState is only available for Vista and above.
15 #if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_VISTA)
16 int32 major_version, minor_version, fix_version;
17 base::SysInfo::OperatingSystemVersionNumbers(&major_version,
18 &minor_version,
19 &fix_version);
20 if (major_version < 6)
21 return false;
22
23 typedef HRESULT(WINAPI *SHQueryUserNotificationStatePtr)(
24 QUERY_USER_NOTIFICATION_STATE* state);
25
26 HMODULE shell32_base = ::GetModuleHandle(L"shell32.dll");
27 if (!shell32_base) {
28 NOTREACHED();
29 return false;
30 }
31 SHQueryUserNotificationStatePtr query_user_notification_state_ptr =
32 reinterpret_cast<SHQueryUserNotificationStatePtr>
33 (::GetProcAddress(shell32_base, "SHQueryUserNotificationState"));
34 if (!query_user_notification_state_ptr) {
35 NOTREACHED();
36 return false;
37 }
38
39 QUERY_USER_NOTIFICATION_STATE state;
40 if (FAILED((*query_user_notification_state_ptr)(&state)))
41 return false;
42 return state == QUNS_RUNNING_D3D_FULL_SCREEN ||
43 state == QUNS_PRESENTATION_MODE;
44 #else
45 return false;
46 #endif
47 }
48
IsFullScreenWindowMode()49 static bool IsFullScreenWindowMode() {
50 // Get the foreground window which the user is currently working on.
51 HWND wnd = ::GetForegroundWindow();
52 if (!wnd)
53 return false;
54
55 // Get the monitor where the window is located.
56 RECT wnd_rect;
57 if (!::GetWindowRect(wnd, &wnd_rect))
58 return false;
59 HMONITOR monitor = ::MonitorFromRect(&wnd_rect, MONITOR_DEFAULTTONULL);
60 if (!monitor)
61 return false;
62 MONITORINFO monitor_info = { sizeof(monitor_info) };
63 if (!::GetMonitorInfo(monitor, &monitor_info))
64 return false;
65
66 // It should be the main monitor.
67 if (!(monitor_info.dwFlags & MONITORINFOF_PRIMARY))
68 return false;
69
70 // The window should be at least as large as the monitor.
71 if (!::IntersectRect(&wnd_rect, &wnd_rect, &monitor_info.rcMonitor))
72 return false;
73 if (!::EqualRect(&wnd_rect, &monitor_info.rcMonitor))
74 return false;
75
76 // At last, the window style should not have WS_DLGFRAME and WS_THICKFRAME and
77 // its extended style should not have WS_EX_WINDOWEDGE and WS_EX_TOOLWINDOW.
78 LONG style = ::GetWindowLong(wnd, GWL_STYLE);
79 LONG ext_style = ::GetWindowLong(wnd, GWL_EXSTYLE);
80 return !((style & (WS_DLGFRAME | WS_THICKFRAME)) ||
81 (ext_style & (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW)));
82 }
83
IsFullScreenConsoleMode()84 static bool IsFullScreenConsoleMode() {
85 // We detect this by attaching the current process to the console of the
86 // foreground window and then checking if it is in full screen mode.
87 DWORD pid = 0;
88 ::GetWindowThreadProcessId(::GetForegroundWindow(), &pid);
89 if (!pid)
90 return false;
91
92 if (!::AttachConsole(pid))
93 return false;
94
95 DWORD modes = 0;
96 ::GetConsoleDisplayMode(&modes);
97 ::FreeConsole();
98
99 return (modes & (CONSOLE_FULLSCREEN | CONSOLE_FULLSCREEN_HARDWARE)) != 0;
100 }
101
IsFullScreenMode()102 bool IsFullScreenMode() {
103 return IsPlatformFullScreenMode() ||
104 IsFullScreenWindowMode() ||
105 IsFullScreenConsoleMode();
106 }
107