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/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