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
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.
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
64 GetSize(nsPresContext
* aPresContext
)
67 if (aPresContext
->IsRootPaginatedDocument())
68 // We want the page size, including unprintable areas and margins.
69 size
= aPresContext
->GetPageSize();
71 size
= aPresContext
->GetVisibleArea().Size();
76 GetWidth(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
78 nsSize size
= GetSize(aPresContext
);
79 float pixelWidth
= aPresContext
->AppUnitsToFloatCSSPixels(size
.width
);
80 aResult
.SetFloatValue(pixelWidth
, eCSSUnit_Pixel
);
85 GetHeight(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
87 nsSize size
= GetSize(aPresContext
);
88 float pixelHeight
= aPresContext
->AppUnitsToFloatCSSPixels(size
.height
);
89 aResult
.SetFloatValue(pixelHeight
, eCSSUnit_Pixel
);
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,
100 nsIDeviceContext
* ctx
= nsLayoutUtils::GetDeviceContextForScreenInfo(
101 nsCOMPtr
<nsIDocShell
>(do_QueryInterface(
102 nsCOMPtr
<nsISupports
>(aPresContext
->GetContainer()))));
104 ctx
= aPresContext
->DeviceContext();
109 // A helper for three features below.
111 GetDeviceSize(nsPresContext
* aPresContext
)
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();
120 GetDeviceContextFor(aPresContext
)->
121 GetDeviceSurfaceDimensions(size
.width
, size
.height
);
126 GetDeviceWidth(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
128 nsSize size
= GetDeviceSize(aPresContext
);
129 float pixelWidth
= aPresContext
->AppUnitsToFloatCSSPixels(size
.width
);
130 aResult
.SetFloatValue(pixelWidth
, eCSSUnit_Pixel
);
135 GetDeviceHeight(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
137 nsSize size
= GetDeviceSize(aPresContext
);
138 float pixelHeight
= aPresContext
->AppUnitsToFloatCSSPixels(size
.height
);
139 aResult
.SetFloatValue(pixelHeight
, eCSSUnit_Pixel
);
144 GetOrientation(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
146 nsSize size
= GetSize(aPresContext
);
148 if (size
.width
> size
.height
) {
149 orientation
= NS_STYLE_ORIENTATION_LANDSCAPE
;
151 // Per spec, square viewports should be 'portrait'
152 orientation
= NS_STYLE_ORIENTATION_PORTRAIT
;
155 aResult
.SetIntValue(orientation
, eCSSUnit_Enumerated
);
159 // Helper for two features below
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
);
174 GetAspectRatio(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
176 return MakeArray(GetSize(aPresContext
), aResult
);
180 GetDeviceAspectRatio(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
182 return MakeArray(GetDeviceSize(aPresContext
), aResult
);
187 GetColor(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
189 // FIXME: This implementation is bogus. nsThebesDeviceContext
190 // doesn't provide reliable information (should be fixed in bug
192 // FIXME: On a monochrome device, return 0!
193 nsIDeviceContext
*dx
= GetDeviceContextFor(aPresContext
);
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.
200 aResult
.SetIntValue(PRInt32(depth
), eCSSUnit_Integer
);
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
);
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
223 aResult
.SetIntValue(0, eCSSUnit_Integer
);
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
);
238 GetScan(nsPresContext
* aPresContext
, nsCSSValue
& aResult
)
240 // Since Gecko doesn't support the 'tv' media type, the 'scan'
241 // feature is never present.
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
);
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
[] = {
268 nsMediaFeature::eMinMaxAllowed
,
269 nsMediaFeature::eLength
,
275 nsMediaFeature::eMinMaxAllowed
,
276 nsMediaFeature::eLength
,
281 &nsGkAtoms::deviceWidth
,
282 nsMediaFeature::eMinMaxAllowed
,
283 nsMediaFeature::eLength
,
288 &nsGkAtoms::deviceHeight
,
289 nsMediaFeature::eMinMaxAllowed
,
290 nsMediaFeature::eLength
,
295 &nsGkAtoms::orientation
,
296 nsMediaFeature::eMinMaxNotAllowed
,
297 nsMediaFeature::eEnumerated
,
298 kOrientationKeywords
,
302 &nsGkAtoms::aspectRatio
,
303 nsMediaFeature::eMinMaxAllowed
,
304 nsMediaFeature::eIntRatio
,
309 &nsGkAtoms::deviceAspectRatio
,
310 nsMediaFeature::eMinMaxAllowed
,
311 nsMediaFeature::eIntRatio
,
317 nsMediaFeature::eMinMaxAllowed
,
318 nsMediaFeature::eInteger
,
323 &nsGkAtoms::colorIndex
,
324 nsMediaFeature::eMinMaxAllowed
,
325 nsMediaFeature::eInteger
,
330 &nsGkAtoms::monochrome
,
331 nsMediaFeature::eMinMaxAllowed
,
332 nsMediaFeature::eInteger
,
337 &nsGkAtoms::resolution
,
338 nsMediaFeature::eMinMaxAllowed
,
339 nsMediaFeature::eResolution
,
345 nsMediaFeature::eMinMaxNotAllowed
,
346 nsMediaFeature::eEnumerated
,
352 nsMediaFeature::eMinMaxNotAllowed
,
353 nsMediaFeature::eBoolInteger
,
357 // Null-mName terminator:
360 nsMediaFeature::eMinMaxAllowed
,
361 nsMediaFeature::eInteger
,