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