172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file. 472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/fullscreen.h" 672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <windows.h> 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <shellapi.h> 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/logging.h" 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "base/sys_info.h" 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool IsPlatformFullScreenMode() { 1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // SHQueryUserNotificationState is only available for Vista and above. 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#if defined(NTDDI_VERSION) && (NTDDI_VERSION >= NTDDI_VISTA) 1672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int32 major_version, minor_version, fix_version; 1772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen base::SysInfo::OperatingSystemVersionNumbers(&major_version, 1872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &minor_version, 1972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen &fix_version); 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (major_version < 6) 2172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen typedef HRESULT(WINAPI *SHQueryUserNotificationStatePtr)( 2472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen QUERY_USER_NOTIFICATION_STATE* state); 2572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 2672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HMODULE shell32_base = ::GetModuleHandle(L"shell32.dll"); 2772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!shell32_base) { 2872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NOTREACHED(); 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen SHQueryUserNotificationStatePtr query_user_notification_state_ptr = 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen reinterpret_cast<SHQueryUserNotificationStatePtr> 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen (::GetProcAddress(shell32_base, "SHQueryUserNotificationState")); 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!query_user_notification_state_ptr) { 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen NOTREACHED(); 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen } 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen QUERY_USER_NOTIFICATION_STATE state; 4072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (FAILED((*query_user_notification_state_ptr)(&state))) 4172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 4272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return state == QUNS_RUNNING_D3D_FULL_SCREEN || 4372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen state == QUNS_PRESENTATION_MODE; 4472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#else 4572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 4672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif 4772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 4972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool IsFullScreenWindowMode() { 5072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Get the foreground window which the user is currently working on. 5172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HWND wnd = ::GetForegroundWindow(); 5272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!wnd) 5372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 5472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 5572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Get the monitor where the window is located. 5672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen RECT wnd_rect; 5772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!::GetWindowRect(wnd, &wnd_rect)) 5872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 5972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen HMONITOR monitor = ::MonitorFromRect(&wnd_rect, MONITOR_DEFAULTTONULL); 6072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!monitor) 6172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 6272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen MONITORINFO monitor_info = { sizeof(monitor_info) }; 6372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!::GetMonitorInfo(monitor, &monitor_info)) 6472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 6572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 6672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // It should be the main monitor. 6772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!(monitor_info.dwFlags & MONITORINFOF_PRIMARY)) 6872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 6972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // The window should be at least as large as the monitor. 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!::IntersectRect(&wnd_rect, &wnd_rect, &monitor_info.rcMonitor)) 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!::EqualRect(&wnd_rect, &monitor_info.rcMonitor)) 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // At last, the window style should not have WS_DLGFRAME and WS_THICKFRAME and 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // its extended style should not have WS_EX_WINDOWEDGE and WS_EX_TOOLWINDOW. 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG style = ::GetWindowLong(wnd, GWL_STYLE); 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen LONG ext_style = ::GetWindowLong(wnd, GWL_EXSTYLE); 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return !((style & (WS_DLGFRAME | WS_THICKFRAME)) || 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen (ext_style & (WS_EX_WINDOWEDGE | WS_EX_TOOLWINDOW))); 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenstatic bool IsFullScreenConsoleMode() { 8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // We detect this by attaching the current process to the console of the 8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // foreground window and then checking if it is in full screen mode. 8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD pid = 0; 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::GetWindowThreadProcessId(::GetForegroundWindow(), &pid); 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!pid) 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen if (!::AttachConsole(pid)) 9372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return false; 9472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DWORD modes = 0; 9672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::GetConsoleDisplayMode(&modes); 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ::FreeConsole(); 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return (modes & (CONSOLE_FULLSCREEN | CONSOLE_FULLSCREEN_HARDWARE)) != 0; 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 10172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 10272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenbool IsFullScreenMode() { 10372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen return IsPlatformFullScreenMode() || 10472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IsFullScreenWindowMode() || 10572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen IsFullScreenConsoleMode(); 10672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen} 107