Thu, 15 Jan 2015 15:59:08 +0100
Implement a real Private Browsing Mode condition by changing the API/ABI;
This solves Tor bug #9701, complying with disk avoidance documented in
https://www.torproject.org/projects/torbrowser/design/#disk-avoidance.
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 "nsScreenWin.h" |
michael@0 | 7 | #include "nsCoord.h" |
michael@0 | 8 | #include "gfxWindowsPlatform.h" |
michael@0 | 9 | #include "nsIWidget.h" |
michael@0 | 10 | |
michael@0 | 11 | |
michael@0 | 12 | nsScreenWin :: nsScreenWin ( HMONITOR inScreen ) |
michael@0 | 13 | : mScreen(inScreen) |
michael@0 | 14 | { |
michael@0 | 15 | #ifdef DEBUG |
michael@0 | 16 | HDC hDCScreen = ::GetDC(nullptr); |
michael@0 | 17 | NS_ASSERTION(hDCScreen,"GetDC Failure"); |
michael@0 | 18 | NS_ASSERTION ( ::GetDeviceCaps(hDCScreen, TECHNOLOGY) == DT_RASDISPLAY, "Not a display screen"); |
michael@0 | 19 | ::ReleaseDC(nullptr,hDCScreen); |
michael@0 | 20 | #endif |
michael@0 | 21 | |
michael@0 | 22 | // nothing else to do. I guess we could cache a bunch of information |
michael@0 | 23 | // here, but we want to ask the device at runtime in case anything |
michael@0 | 24 | // has changed. |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | |
michael@0 | 28 | nsScreenWin :: ~nsScreenWin() |
michael@0 | 29 | { |
michael@0 | 30 | // nothing to see here. |
michael@0 | 31 | } |
michael@0 | 32 | |
michael@0 | 33 | |
michael@0 | 34 | NS_IMETHODIMP |
michael@0 | 35 | nsScreenWin :: GetRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight) |
michael@0 | 36 | { |
michael@0 | 37 | BOOL success = FALSE; |
michael@0 | 38 | if ( mScreen ) { |
michael@0 | 39 | MONITORINFO info; |
michael@0 | 40 | info.cbSize = sizeof(MONITORINFO); |
michael@0 | 41 | success = ::GetMonitorInfoW( mScreen, &info ); |
michael@0 | 42 | if ( success ) { |
michael@0 | 43 | *outLeft = info.rcMonitor.left; |
michael@0 | 44 | *outTop = info.rcMonitor.top; |
michael@0 | 45 | *outWidth = info.rcMonitor.right - info.rcMonitor.left; |
michael@0 | 46 | *outHeight = info.rcMonitor.bottom - info.rcMonitor.top; |
michael@0 | 47 | } |
michael@0 | 48 | } |
michael@0 | 49 | if (!success) { |
michael@0 | 50 | HDC hDCScreen = ::GetDC(nullptr); |
michael@0 | 51 | NS_ASSERTION(hDCScreen,"GetDC Failure"); |
michael@0 | 52 | |
michael@0 | 53 | *outTop = *outLeft = 0; |
michael@0 | 54 | *outWidth = ::GetDeviceCaps(hDCScreen, HORZRES); |
michael@0 | 55 | *outHeight = ::GetDeviceCaps(hDCScreen, VERTRES); |
michael@0 | 56 | |
michael@0 | 57 | ::ReleaseDC(nullptr, hDCScreen); |
michael@0 | 58 | } |
michael@0 | 59 | return NS_OK; |
michael@0 | 60 | |
michael@0 | 61 | } // GetRect |
michael@0 | 62 | |
michael@0 | 63 | |
michael@0 | 64 | NS_IMETHODIMP |
michael@0 | 65 | nsScreenWin :: GetAvailRect(int32_t *outLeft, int32_t *outTop, int32_t *outWidth, int32_t *outHeight) |
michael@0 | 66 | { |
michael@0 | 67 | BOOL success = FALSE; |
michael@0 | 68 | |
michael@0 | 69 | if ( mScreen ) { |
michael@0 | 70 | MONITORINFO info; |
michael@0 | 71 | info.cbSize = sizeof(MONITORINFO); |
michael@0 | 72 | success = ::GetMonitorInfoW( mScreen, &info ); |
michael@0 | 73 | if ( success ) { |
michael@0 | 74 | *outLeft = info.rcWork.left; |
michael@0 | 75 | *outTop = info.rcWork.top; |
michael@0 | 76 | *outWidth = info.rcWork.right - info.rcWork.left; |
michael@0 | 77 | *outHeight = info.rcWork.bottom - info.rcWork.top; |
michael@0 | 78 | } |
michael@0 | 79 | } |
michael@0 | 80 | if (!success) { |
michael@0 | 81 | RECT workArea; |
michael@0 | 82 | ::SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0); |
michael@0 | 83 | *outLeft = workArea.left; |
michael@0 | 84 | *outTop = workArea.top; |
michael@0 | 85 | *outWidth = workArea.right - workArea.left; |
michael@0 | 86 | *outHeight = workArea.bottom - workArea.top; |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | return NS_OK; |
michael@0 | 90 | |
michael@0 | 91 | } // GetAvailRect |
michael@0 | 92 | |
michael@0 | 93 | static double |
michael@0 | 94 | GetDPIScale() |
michael@0 | 95 | { |
michael@0 | 96 | double dpiScale= nsIWidget::DefaultScaleOverride(); |
michael@0 | 97 | if (dpiScale <= 0.0) { |
michael@0 | 98 | dpiScale = gfxWindowsPlatform::GetPlatform()->GetDPIScale(); |
michael@0 | 99 | } |
michael@0 | 100 | return dpiScale; |
michael@0 | 101 | } |
michael@0 | 102 | |
michael@0 | 103 | NS_IMETHODIMP |
michael@0 | 104 | nsScreenWin::GetRectDisplayPix(int32_t *outLeft, int32_t *outTop, |
michael@0 | 105 | int32_t *outWidth, int32_t *outHeight) |
michael@0 | 106 | { |
michael@0 | 107 | int32_t left, top, width, height; |
michael@0 | 108 | nsresult rv = GetRect(&left, &top, &width, &height); |
michael@0 | 109 | if (NS_FAILED(rv)) { |
michael@0 | 110 | return rv; |
michael@0 | 111 | } |
michael@0 | 112 | double scaleFactor = 1.0 / GetDPIScale(); |
michael@0 | 113 | *outLeft = NSToIntRound(left * scaleFactor); |
michael@0 | 114 | *outTop = NSToIntRound(top * scaleFactor); |
michael@0 | 115 | *outWidth = NSToIntRound(width * scaleFactor); |
michael@0 | 116 | *outHeight = NSToIntRound(height * scaleFactor); |
michael@0 | 117 | return NS_OK; |
michael@0 | 118 | } |
michael@0 | 119 | |
michael@0 | 120 | NS_IMETHODIMP |
michael@0 | 121 | nsScreenWin::GetAvailRectDisplayPix(int32_t *outLeft, int32_t *outTop, |
michael@0 | 122 | int32_t *outWidth, int32_t *outHeight) |
michael@0 | 123 | { |
michael@0 | 124 | int32_t left, top, width, height; |
michael@0 | 125 | nsresult rv = GetAvailRect(&left, &top, &width, &height); |
michael@0 | 126 | if (NS_FAILED(rv)) { |
michael@0 | 127 | return rv; |
michael@0 | 128 | } |
michael@0 | 129 | double scaleFactor = 1.0 / GetDPIScale(); |
michael@0 | 130 | *outLeft = NSToIntRound(left * scaleFactor); |
michael@0 | 131 | *outTop = NSToIntRound(top * scaleFactor); |
michael@0 | 132 | *outWidth = NSToIntRound(width * scaleFactor); |
michael@0 | 133 | *outHeight = NSToIntRound(height * scaleFactor); |
michael@0 | 134 | return NS_OK; |
michael@0 | 135 | } |
michael@0 | 136 | |
michael@0 | 137 | |
michael@0 | 138 | NS_IMETHODIMP |
michael@0 | 139 | nsScreenWin :: GetPixelDepth(int32_t *aPixelDepth) |
michael@0 | 140 | { |
michael@0 | 141 | //XXX not sure how to get this info for multiple monitors, this might be ok... |
michael@0 | 142 | HDC hDCScreen = ::GetDC(nullptr); |
michael@0 | 143 | NS_ASSERTION(hDCScreen,"GetDC Failure"); |
michael@0 | 144 | |
michael@0 | 145 | int32_t depth = ::GetDeviceCaps(hDCScreen, BITSPIXEL); |
michael@0 | 146 | if (depth == 32) { |
michael@0 | 147 | // If a device uses 32 bits per pixel, it's still only using 8 bits |
michael@0 | 148 | // per color component, which is what our callers want to know. |
michael@0 | 149 | // (Some devices report 32 and some devices report 24.) |
michael@0 | 150 | depth = 24; |
michael@0 | 151 | } |
michael@0 | 152 | *aPixelDepth = depth; |
michael@0 | 153 | |
michael@0 | 154 | ::ReleaseDC(nullptr, hDCScreen); |
michael@0 | 155 | return NS_OK; |
michael@0 | 156 | |
michael@0 | 157 | } // GetPixelDepth |
michael@0 | 158 | |
michael@0 | 159 | |
michael@0 | 160 | NS_IMETHODIMP |
michael@0 | 161 | nsScreenWin :: GetColorDepth(int32_t *aColorDepth) |
michael@0 | 162 | { |
michael@0 | 163 | return GetPixelDepth(aColorDepth); |
michael@0 | 164 | |
michael@0 | 165 | } // GetColorDepth |
michael@0 | 166 | |
michael@0 | 167 |