Home | History | Annotate | Download | only in browser
      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