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 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 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 (!base::win::GetMonitorInfoWrapper(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 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 104 bool IsFullScreenMode() { 105 #if defined(USE_ASH) 106 if (chrome::GetActiveDesktop() == chrome::HOST_DESKTOP_TYPE_ASH) { 107 ash::internal::RootWindowController* controller = 108 ash::internal::RootWindowController::ForTargetRootWindow(); 109 return controller && controller->GetWindowForFullscreenMode(); 110 } 111 #endif 112 return IsPlatformFullScreenMode() || 113 IsFullScreenWindowMode() || 114 IsFullScreenConsoleMode(); 115 } 116