widget/windows/nsScreenManagerWin.cpp

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
michael@0 2 /* This Source Code Form is subject to the terms of the Mozilla Public
michael@0 3 * License, v. 2.0. If a copy of the MPL was not distributed with this
michael@0 4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
michael@0 5
michael@0 6 #include "nsScreenManagerWin.h"
michael@0 7 #include "nsScreenWin.h"
michael@0 8 #include "gfxWindowsPlatform.h"
michael@0 9 #include "nsIWidget.h"
michael@0 10
michael@0 11
michael@0 12 BOOL CALLBACK CountMonitors ( HMONITOR, HDC, LPRECT, LPARAM ioCount ) ;
michael@0 13
michael@0 14 nsScreenManagerWin :: nsScreenManagerWin ( )
michael@0 15 : mNumberOfScreens(0)
michael@0 16 {
michael@0 17 // nothing to do. I guess we could cache a bunch of information
michael@0 18 // here, but we want to ask the device at runtime in case anything
michael@0 19 // has changed.
michael@0 20 }
michael@0 21
michael@0 22
michael@0 23 nsScreenManagerWin :: ~nsScreenManagerWin()
michael@0 24 {
michael@0 25 }
michael@0 26
michael@0 27
michael@0 28 // addref, release, QI
michael@0 29 NS_IMPL_ISUPPORTS(nsScreenManagerWin, nsIScreenManager)
michael@0 30
michael@0 31
michael@0 32 //
michael@0 33 // CreateNewScreenObject
michael@0 34 //
michael@0 35 // Utility routine. Creates a new screen object from the given device handle
michael@0 36 //
michael@0 37 // NOTE: For this "single-monitor" impl, we just always return the cached primary
michael@0 38 // screen. This should change when a multi-monitor impl is done.
michael@0 39 //
michael@0 40 nsIScreen*
michael@0 41 nsScreenManagerWin :: CreateNewScreenObject ( HMONITOR inScreen )
michael@0 42 {
michael@0 43 nsIScreen* retScreen = nullptr;
michael@0 44
michael@0 45 // look through our screen list, hoping to find it. If it's not there,
michael@0 46 // add it and return the new one.
michael@0 47 for ( unsigned i = 0; i < mScreenList.Length(); ++i ) {
michael@0 48 ScreenListItem& curr = mScreenList[i];
michael@0 49 if ( inScreen == curr.mMon ) {
michael@0 50 NS_IF_ADDREF(retScreen = curr.mScreen.get());
michael@0 51 return retScreen;
michael@0 52 }
michael@0 53 } // for each screen.
michael@0 54
michael@0 55 retScreen = new nsScreenWin(inScreen);
michael@0 56 mScreenList.AppendElement ( ScreenListItem ( inScreen, retScreen ) );
michael@0 57
michael@0 58 NS_IF_ADDREF(retScreen);
michael@0 59 return retScreen;
michael@0 60 }
michael@0 61
michael@0 62
michael@0 63 //
michael@0 64 // ScreenForRect
michael@0 65 //
michael@0 66 // Returns the screen that contains the rectangle. If the rect overlaps
michael@0 67 // multiple screens, it picks the screen with the greatest area of intersection.
michael@0 68 //
michael@0 69 // The coordinates are in pixels (not twips) and in logical screen coordinates.
michael@0 70 //
michael@0 71 NS_IMETHODIMP
michael@0 72 nsScreenManagerWin :: ScreenForRect ( int32_t inLeft, int32_t inTop, int32_t inWidth, int32_t inHeight,
michael@0 73 nsIScreen **outScreen )
michael@0 74 {
michael@0 75 if ( !(inWidth || inHeight) ) {
michael@0 76 NS_WARNING ( "trying to find screen for sizeless window, using primary monitor" );
michael@0 77 *outScreen = CreateNewScreenObject ( nullptr ); // addrefs
michael@0 78 return NS_OK;
michael@0 79 }
michael@0 80
michael@0 81 // convert coordinates from logical to device pixels for MonitorFromRect
michael@0 82 double dpiScale = nsIWidget::DefaultScaleOverride();
michael@0 83 if (dpiScale <= 0.0) {
michael@0 84 dpiScale = gfxWindowsPlatform::GetPlatform()->GetDPIScale();
michael@0 85 }
michael@0 86 RECT globalWindowBounds = {
michael@0 87 NSToIntRound(dpiScale * inLeft),
michael@0 88 NSToIntRound(dpiScale * inTop),
michael@0 89 NSToIntRound(dpiScale * (inLeft + inWidth)),
michael@0 90 NSToIntRound(dpiScale * (inTop + inHeight))
michael@0 91 };
michael@0 92
michael@0 93 HMONITOR genScreen = ::MonitorFromRect( &globalWindowBounds, MONITOR_DEFAULTTOPRIMARY );
michael@0 94
michael@0 95 *outScreen = CreateNewScreenObject ( genScreen ); // addrefs
michael@0 96
michael@0 97 return NS_OK;
michael@0 98
michael@0 99 } // ScreenForRect
michael@0 100
michael@0 101
michael@0 102 //
michael@0 103 // GetPrimaryScreen
michael@0 104 //
michael@0 105 // The screen with the menubar/taskbar. This shouldn't be needed very
michael@0 106 // often.
michael@0 107 //
michael@0 108 NS_IMETHODIMP
michael@0 109 nsScreenManagerWin :: GetPrimaryScreen(nsIScreen** aPrimaryScreen)
michael@0 110 {
michael@0 111 *aPrimaryScreen = CreateNewScreenObject ( nullptr ); // addrefs
michael@0 112 return NS_OK;
michael@0 113
michael@0 114 } // GetPrimaryScreen
michael@0 115
michael@0 116
michael@0 117 //
michael@0 118 // CountMonitors
michael@0 119 //
michael@0 120 // Will be called once for every monitor in the system. Just
michael@0 121 // increments the parameter, which holds a ptr to a PRUin32 holding the
michael@0 122 // count up to this point.
michael@0 123 //
michael@0 124 BOOL CALLBACK
michael@0 125 CountMonitors ( HMONITOR, HDC, LPRECT, LPARAM ioParam )
michael@0 126 {
michael@0 127 uint32_t* countPtr = reinterpret_cast<uint32_t*>(ioParam);
michael@0 128 ++(*countPtr);
michael@0 129
michael@0 130 return TRUE; // continue the enumeration
michael@0 131
michael@0 132 } // CountMonitors
michael@0 133
michael@0 134
michael@0 135 //
michael@0 136 // GetNumberOfScreens
michael@0 137 //
michael@0 138 // Returns how many physical screens are available.
michael@0 139 //
michael@0 140 NS_IMETHODIMP
michael@0 141 nsScreenManagerWin :: GetNumberOfScreens(uint32_t *aNumberOfScreens)
michael@0 142 {
michael@0 143 if ( mNumberOfScreens )
michael@0 144 *aNumberOfScreens = mNumberOfScreens;
michael@0 145 else {
michael@0 146 uint32_t count = 0;
michael@0 147 BOOL result = ::EnumDisplayMonitors(nullptr, nullptr, (MONITORENUMPROC)CountMonitors, (LPARAM)&count);
michael@0 148 if (!result)
michael@0 149 return NS_ERROR_FAILURE;
michael@0 150 *aNumberOfScreens = mNumberOfScreens = count;
michael@0 151 }
michael@0 152
michael@0 153 return NS_OK;
michael@0 154
michael@0 155 } // GetNumberOfScreens
michael@0 156
michael@0 157 NS_IMETHODIMP
michael@0 158 nsScreenManagerWin::GetSystemDefaultScale(float *aDefaultScale)
michael@0 159 {
michael@0 160 *aDefaultScale = float(gfxWindowsPlatform::GetPlatform()->GetDPIScale());
michael@0 161 return NS_OK;
michael@0 162 }
michael@0 163
michael@0 164 NS_IMETHODIMP
michael@0 165 nsScreenManagerWin :: ScreenForNativeWidget(void *aWidget, nsIScreen **outScreen)
michael@0 166 {
michael@0 167 HMONITOR mon = MonitorFromWindow ((HWND) aWidget, MONITOR_DEFAULTTOPRIMARY);
michael@0 168 *outScreen = CreateNewScreenObject (mon);
michael@0 169 return NS_OK;
michael@0 170 }

mercurial