Bug 473680. Stop crashtest 458637-1.html early (returning success) if it's running...
[mozilla-central.git] / layout / style / nsMediaFeatures.cpp
blobf8dca29626a31d4eb69a19dfc24c3363630cd199
1 /* vim: set shiftwidth=4 tabstop=8 autoindent cindent expandtab: */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is nsMediaFeatures.
17 * The Initial Developer of the Original Code is the Mozilla Foundation.
18 * Portions created by the Initial Developer are Copyright (C) 2008
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
22 * L. David Baron <dbaron@dbaron.org>, Mozilla Corporation (original author)
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 /* the features that media queries can test */
40 #include "nsMediaFeatures.h"
41 #include "nsGkAtoms.h"
42 #include "nsCSSKeywords.h"
43 #include "nsStyleConsts.h"
44 #include "nsPresContext.h"
45 #include "nsIDeviceContext.h"
46 #include "nsCSSValue.h"
47 #include "nsIDocShell.h"
48 #include "nsLayoutUtils.h"
50 static const PRInt32 kOrientationKeywords[] = {
51 eCSSKeyword_portrait, NS_STYLE_ORIENTATION_PORTRAIT,
52 eCSSKeyword_landscape, NS_STYLE_ORIENTATION_LANDSCAPE,
53 eCSSKeyword_UNKNOWN, -1
56 static const PRInt32 kScanKeywords[] = {
57 eCSSKeyword_progressive, NS_STYLE_SCAN_PROGRESSIVE,
58 eCSSKeyword_interlace, NS_STYLE_SCAN_INTERLACE,
59 eCSSKeyword_UNKNOWN, -1
62 // A helper for four features below
63 static nsSize
64 GetSize(nsPresContext* aPresContext)
66 nsSize size;
67 if (aPresContext->IsRootPaginatedDocument())
68 // We want the page size, including unprintable areas and margins.
69 size = aPresContext->GetPageSize();
70 else
71 size = aPresContext->GetVisibleArea().Size();
72 return size;
75 static nsresult
76 GetWidth(nsPresContext* aPresContext, nsCSSValue& aResult)
78 nsSize size = GetSize(aPresContext);
79 float pixelWidth = aPresContext->AppUnitsToFloatCSSPixels(size.width);
80 aResult.SetFloatValue(pixelWidth, eCSSUnit_Pixel);
81 return NS_OK;
84 static nsresult
85 GetHeight(nsPresContext* aPresContext, nsCSSValue& aResult)
87 nsSize size = GetSize(aPresContext);
88 float pixelHeight = aPresContext->AppUnitsToFloatCSSPixels(size.height);
89 aResult.SetFloatValue(pixelHeight, eCSSUnit_Pixel);
90 return NS_OK;
93 static nsIDeviceContext*
94 GetDeviceContextFor(nsPresContext* aPresContext)
96 // Do this dance rather than aPresContext->DeviceContext() to get
97 // things right in multi-monitor situations.
98 // (It's not clear if this is really needed for GetDepth and GetColor,
99 // but do it anyway.)
100 nsIDeviceContext* ctx = nsLayoutUtils::GetDeviceContextForScreenInfo(
101 nsCOMPtr<nsIDocShell>(do_QueryInterface(
102 nsCOMPtr<nsISupports>(aPresContext->GetContainer()))));
103 if (!ctx) {
104 ctx = aPresContext->DeviceContext();
106 return ctx;
109 // A helper for three features below.
110 static nsSize
111 GetDeviceSize(nsPresContext* aPresContext)
113 nsSize size;
114 if (aPresContext->IsRootPaginatedDocument())
115 // We want the page size, including unprintable areas and margins.
116 // XXX The spec actually says we want the "page sheet size", but
117 // how is that different?
118 size = aPresContext->GetPageSize();
119 else
120 GetDeviceContextFor(aPresContext)->
121 GetDeviceSurfaceDimensions(size.width, size.height);
122 return size;
125 static nsresult
126 GetDeviceWidth(nsPresContext* aPresContext, nsCSSValue& aResult)
128 nsSize size = GetDeviceSize(aPresContext);
129 float pixelWidth = aPresContext->AppUnitsToFloatCSSPixels(size.width);
130 aResult.SetFloatValue(pixelWidth, eCSSUnit_Pixel);
131 return NS_OK;
134 static nsresult
135 GetDeviceHeight(nsPresContext* aPresContext, nsCSSValue& aResult)
137 nsSize size = GetDeviceSize(aPresContext);
138 float pixelHeight = aPresContext->AppUnitsToFloatCSSPixels(size.height);
139 aResult.SetFloatValue(pixelHeight, eCSSUnit_Pixel);
140 return NS_OK;
143 static nsresult
144 GetOrientation(nsPresContext* aPresContext, nsCSSValue& aResult)
146 nsSize size = GetSize(aPresContext);
147 PRInt32 orientation;
148 if (size.width > size.height) {
149 orientation = NS_STYLE_ORIENTATION_LANDSCAPE;
150 } else {
151 // Per spec, square viewports should be 'portrait'
152 orientation = NS_STYLE_ORIENTATION_PORTRAIT;
155 aResult.SetIntValue(orientation, eCSSUnit_Enumerated);
156 return NS_OK;
159 // Helper for two features below
160 static nsresult
161 MakeArray(const nsSize& aSize, nsCSSValue& aResult)
163 nsRefPtr<nsCSSValue::Array> a = nsCSSValue::Array::Create(2);
164 NS_ENSURE_TRUE(a, NS_ERROR_OUT_OF_MEMORY);
166 a->Item(0).SetIntValue(aSize.width, eCSSUnit_Integer);
167 a->Item(1).SetIntValue(aSize.height, eCSSUnit_Integer);
169 aResult.SetArrayValue(a, eCSSUnit_Array);
170 return NS_OK;
173 static nsresult
174 GetAspectRatio(nsPresContext* aPresContext, nsCSSValue& aResult)
176 return MakeArray(GetSize(aPresContext), aResult);
179 static nsresult
180 GetDeviceAspectRatio(nsPresContext* aPresContext, nsCSSValue& aResult)
182 return MakeArray(GetDeviceSize(aPresContext), aResult);
186 static nsresult
187 GetColor(nsPresContext* aPresContext, nsCSSValue& aResult)
189 // FIXME: This implementation is bogus. nsThebesDeviceContext
190 // doesn't provide reliable information (should be fixed in bug
191 // 424386).
192 // FIXME: On a monochrome device, return 0!
193 nsIDeviceContext *dx = GetDeviceContextFor(aPresContext);
194 PRUint32 depth;
195 dx->GetDepth(depth);
196 // The spec says to use bits *per color component*, so divide by 3,
197 // and round down, since the spec says to use the smallest when the
198 // color components differ.
199 depth /= 3;
200 aResult.SetIntValue(PRInt32(depth), eCSSUnit_Integer);
201 return NS_OK;
204 static nsresult
205 GetColorIndex(nsPresContext* aPresContext, nsCSSValue& aResult)
207 // We should return zero if the device does not use a color lookup
208 // table. Stuart says that our handling of displays with 8-bit
209 // color is bad enough that we never change the lookup table to
210 // match what we're trying to display, so perhaps we should always
211 // return zero. Given that there isn't any better information
212 // exposed, we don't have much other choice.
213 aResult.SetIntValue(0, eCSSUnit_Integer);
214 return NS_OK;
217 static nsresult
218 GetMonochrome(nsPresContext* aPresContext, nsCSSValue& aResult)
220 // For color devices we should return 0.
221 // FIXME: On a monochrome device, return the actual color depth, not
222 // 0!
223 aResult.SetIntValue(0, eCSSUnit_Integer);
224 return NS_OK;
227 static nsresult
228 GetResolution(nsPresContext* aPresContext, nsCSSValue& aResult)
230 // Resolution values are in device pixels, not CSS pixels.
231 nsIDeviceContext *dx = GetDeviceContextFor(aPresContext);
232 float dpi = float(dx->AppUnitsPerInch()) / float(dx->AppUnitsPerDevPixel());
233 aResult.SetFloatValue(dpi, eCSSUnit_Inch);
234 return NS_OK;
237 static nsresult
238 GetScan(nsPresContext* aPresContext, nsCSSValue& aResult)
240 // Since Gecko doesn't support the 'tv' media type, the 'scan'
241 // feature is never present.
242 aResult.Reset();
243 return NS_OK;
246 static nsresult
247 GetGrid(nsPresContext* aPresContext, nsCSSValue& aResult)
249 // Gecko doesn't support grid devices (e.g., ttys), so the 'grid'
250 // feature is always 0.
251 aResult.SetIntValue(0, eCSSUnit_Integer);
252 return NS_OK;
256 * Adding new media features requires (1) adding the new feature to this
257 * array, with appropriate entries (and potentially any new code needed
258 * to support new types in these entries and (2) ensuring that either
259 * nsPresContext::MediaFeatureValuesChanged or
260 * nsPresContext::PostMediaFeatureValuesChangedEvent is called when the
261 * value that would be returned by the entry's mGetter changes.
264 /* static */ const nsMediaFeature
265 nsMediaFeatures::features[] = {
267 &nsGkAtoms::width,
268 nsMediaFeature::eMinMaxAllowed,
269 nsMediaFeature::eLength,
270 nsnull,
271 GetWidth
274 &nsGkAtoms::height,
275 nsMediaFeature::eMinMaxAllowed,
276 nsMediaFeature::eLength,
277 nsnull,
278 GetHeight
281 &nsGkAtoms::deviceWidth,
282 nsMediaFeature::eMinMaxAllowed,
283 nsMediaFeature::eLength,
284 nsnull,
285 GetDeviceWidth
288 &nsGkAtoms::deviceHeight,
289 nsMediaFeature::eMinMaxAllowed,
290 nsMediaFeature::eLength,
291 nsnull,
292 GetDeviceHeight
295 &nsGkAtoms::orientation,
296 nsMediaFeature::eMinMaxNotAllowed,
297 nsMediaFeature::eEnumerated,
298 kOrientationKeywords,
299 GetOrientation
302 &nsGkAtoms::aspectRatio,
303 nsMediaFeature::eMinMaxAllowed,
304 nsMediaFeature::eIntRatio,
305 nsnull,
306 GetAspectRatio
309 &nsGkAtoms::deviceAspectRatio,
310 nsMediaFeature::eMinMaxAllowed,
311 nsMediaFeature::eIntRatio,
312 nsnull,
313 GetDeviceAspectRatio
316 &nsGkAtoms::color,
317 nsMediaFeature::eMinMaxAllowed,
318 nsMediaFeature::eInteger,
319 nsnull,
320 GetColor
323 &nsGkAtoms::colorIndex,
324 nsMediaFeature::eMinMaxAllowed,
325 nsMediaFeature::eInteger,
326 nsnull,
327 GetColorIndex
330 &nsGkAtoms::monochrome,
331 nsMediaFeature::eMinMaxAllowed,
332 nsMediaFeature::eInteger,
333 nsnull,
334 GetMonochrome
337 &nsGkAtoms::resolution,
338 nsMediaFeature::eMinMaxAllowed,
339 nsMediaFeature::eResolution,
340 nsnull,
341 GetResolution
344 &nsGkAtoms::scan,
345 nsMediaFeature::eMinMaxNotAllowed,
346 nsMediaFeature::eEnumerated,
347 kScanKeywords,
348 GetScan
351 &nsGkAtoms::grid,
352 nsMediaFeature::eMinMaxNotAllowed,
353 nsMediaFeature::eBoolInteger,
354 nsnull,
355 GetGrid
357 // Null-mName terminator:
359 nsnull,
360 nsMediaFeature::eMinMaxAllowed,
361 nsMediaFeature::eInteger,
362 nsnull,
363 nsnull