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