blob: a52b37cca61edcf54bbdf84ecd68ac515c13f7a6 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.awt;
27
28import java.awt.GraphicsDevice;
29import java.awt.GraphicsEnvironment;
30import java.awt.Toolkit;
31import java.io.File;
32import java.io.IOException;
33import java.lang.ref.WeakReference;
34import java.util.ArrayList;
35import java.util.ListIterator;
36import java.util.NoSuchElementException;
37import java.util.StringTokenizer;
38import sun.awt.DisplayChangedListener;
39import sun.awt.SunDisplayChanger;
40import sun.awt.windows.WFontConfiguration;
41import sun.awt.windows.WPrinterJob;
42import sun.awt.windows.WToolkit;
43import sun.font.FontManager;
44import sun.java2d.SunGraphicsEnvironment;
45import sun.java2d.windows.WindowsFlags;
46
47/**
48 * This is an implementation of a GraphicsEnvironment object for the
49 * default local GraphicsEnvironment used by the Java Runtime Environment
50 * for Windows.
51 *
52 * @see GraphicsDevice
53 * @see GraphicsConfiguration
54 */
55
56public class Win32GraphicsEnvironment
57 extends SunGraphicsEnvironment
58{
59 static {
60 // Ensure awt is loaded already. Also, this forces static init
61 // of WToolkit and Toolkit, which we depend upon
62 WToolkit.loadLibraries();
63 // setup flags before initializing native layer
64 WindowsFlags.initFlags();
65 initDisplayWrapper();
66 eudcFontFileName = getEUDCFontFile();
67 }
68
69 /**
70 * Noop function that just acts as an entry point for someone to force
71 * a static initialization of this class.
72 */
73 public static void init() {}
74
75 /**
76 * Initializes native components of the graphics environment. This
77 * includes everything from the native GraphicsDevice elements to
78 * the DirectX rendering layer.
79 */
80 private static native void initDisplay();
81
82 private static boolean displayInitialized; // = false;
83 public static void initDisplayWrapper() {
84 if (!displayInitialized) {
85 displayInitialized = true;
86 initDisplay();
87 }
88 }
89
90 public Win32GraphicsEnvironment() {
91 }
92
93 protected native int getNumScreens();
94 protected native int getDefaultScreen();
95
96 public GraphicsDevice getDefaultScreenDevice() {
97 return getScreenDevices()[getDefaultScreen()];
98 }
99
100 /**
101 * Returns the number of pixels per logical inch along the screen width.
102 * In a system with multiple display monitors, this value is the same for
103 * all monitors.
104 * @returns number of pixels per logical inch in X direction
105 */
106 public native int getXResolution();
107 /**
108 * Returns the number of pixels per logical inch along the screen height.
109 * In a system with multiple display monitors, this value is the same for
110 * all monitors.
111 * @returns number of pixels per logical inch in Y direction
112 */
113 public native int getYResolution();
114
115
116/*
117 * ----DISPLAY CHANGE SUPPORT----
118 */
119
120 // list of invalidated graphics devices (those which were removed)
121 private ArrayList<WeakReference<Win32GraphicsDevice>> oldDevices;
122 /*
123 * From DisplayChangeListener interface.
124 * Called from WToolkit and executed on the event thread when the
125 * display settings are changed.
126 */
127 @Override
128 public void displayChanged() {
129 // getNumScreens() will return the correct current number of screens
130 GraphicsDevice newDevices[] = new GraphicsDevice[getNumScreens()];
131 GraphicsDevice oldScreens[] = screens;
132 // go through the list of current devices and determine if they
133 // could be reused, or will have to be replaced
134 if (oldScreens != null) {
135 for (int i = 0; i < oldScreens.length; i++) {
136 if (!(screens[i] instanceof Win32GraphicsDevice)) {
137 // REMIND: can we ever have anything other than Win32GD?
138 assert (false) : oldScreens[i];
139 continue;
140 }
141 Win32GraphicsDevice gd = (Win32GraphicsDevice)oldScreens[i];
142 // devices may be invalidated from the native code when the
143 // display change happens (device add/removal also causes a
144 // display change)
145 if (!gd.isValid()) {
146 if (oldDevices == null) {
147 oldDevices =
148 new ArrayList<WeakReference<Win32GraphicsDevice>>();
149 }
150 oldDevices.add(new WeakReference<Win32GraphicsDevice>(gd));
151 } else if (i < newDevices.length) {
152 // reuse the device
153 newDevices[i] = gd;
154 }
155 }
156 oldScreens = null;
157 }
158 // create the new devices (those that weren't reused)
159 for (int i = 0; i < newDevices.length; i++) {
160 if (newDevices[i] == null) {
161 newDevices[i] = makeScreenDevice(i);
162 }
163 }
164 // install the new array of devices
165 // Note: no synchronization here, it doesn't matter if a thread gets
166 // a new or an old array this time around
167 screens = newDevices;
168 for (GraphicsDevice gd : screens) {
169 if (gd instanceof DisplayChangedListener) {
170 ((DisplayChangedListener)gd).displayChanged();
171 }
172 }
173 // re-invalidate all old devices. It's needed because those in the list
174 // may become "invalid" again - if the current default device is removed,
175 // for example. Also, they need to be notified about display
176 // changes as well.
177 if (oldDevices != null) {
178 int defScreen = getDefaultScreen();
179 for (ListIterator<WeakReference<Win32GraphicsDevice>> it =
180 oldDevices.listIterator(); it.hasNext();)
181 {
182 Win32GraphicsDevice gd = it.next().get();
183 if (gd != null) {
184 gd.invalidate(defScreen);
185 gd.displayChanged();
186 } else {
187 // no more references to this device, remove it
188 it.remove();
189 }
190 }
191 }
192 // Reset the static GC for the (possibly new) default screen
193 WToolkit.resetGC();
194
195 // notify SunDisplayChanger list (e.g. VolatileSurfaceManagers and
196 // CachingSurfaceManagers) about the display change event
197 displayChanger.notifyListeners();
198 // note: do not call super.displayChanged, we've already done everything
199 }
200
201
202/*
203 * ----END DISPLAY CHANGE SUPPORT----
204 */
205
206 /* Used on Windows to obtain from the windows registry the name
207 * of a file containing the system EUFC font. If running in one of
208 * the locales for which this applies, and one is defined, the font
209 * defined by this file is appended to all composite fonts as a
210 * fallback component.
211 */
212 private static native String getEUDCFontFile();
213
214 /**
215 * Whether registerFontFile expects absolute or relative
216 * font file names.
217 */
218 protected boolean useAbsoluteFontFileNames() {
219 return false;
220 }
221
222 /* Unlike the shared code version, this expects a base file name -
223 * not a full path name.
224 * The font configuration file has base file names and the FontConfiguration
225 * class reports these back to the GraphicsEnvironment, so these
226 * are the componentFileNames of CompositeFonts.
227 */
228 protected void registerFontFile(String fontFileName, String[] nativeNames,
229 int fontRank, boolean defer) {
230
231 // REMIND: case compare depends on platform
232 if (registeredFontFiles.contains(fontFileName)) {
233 return;
234 }
235 registeredFontFiles.add(fontFileName);
236
237 int fontFormat;
238 if (ttFilter.accept(null, fontFileName)) {
239 fontFormat = FontManager.FONTFORMAT_TRUETYPE;
240 } else if (t1Filter.accept(null, fontFileName)) {
241 fontFormat = FontManager.FONTFORMAT_TYPE1;
242 } else {
243 /* on windows we don't use/register native fonts */
244 return;
245 }
246
247 if (fontPath == null) {
248 fontPath = getPlatformFontPath(noType1Font);
249 }
250
251 /* Look in the JRE font directory first.
252 * This is playing it safe as we would want to find fonts in the
253 * JRE font directory ahead of those in the system directory
254 */
255 String tmpFontPath = jreFontDirName+File.pathSeparator+fontPath;
256 StringTokenizer parser = new StringTokenizer(tmpFontPath,
257 File.pathSeparator);
258
259 boolean found = false;
260 try {
261 while (!found && parser.hasMoreTokens()) {
262 String newPath = parser.nextToken();
263 File theFile = new File(newPath, fontFileName);
264 if (theFile.canRead()) {
265 found = true;
266 String path = theFile.getAbsolutePath();
267 if (defer) {
268 FontManager.registerDeferredFont(fontFileName, path,
269 nativeNames,
270 fontFormat, true,
271 fontRank);
272 } else {
273 FontManager.registerFontFile(path, nativeNames,
274 fontFormat, true,
275 fontRank);
276 }
277 break;
278 }
279 }
280 } catch (NoSuchElementException e) {
281 System.err.println(e);
282 }
283 if (!found) {
284 addToMissingFontFileList(fontFileName);
285 }
286 }
287
288 /* register only TrueType/OpenType fonts
289 * Because these need to be registed just for use when printing,
290 * we defer the actual registration and the static initialiser
291 * for the printing class makes the call to registerJREFontsForPrinting()
292 */
293 static String fontsForPrinting = null;
294 protected void registerJREFontsWithPlatform(String pathName) {
295 fontsForPrinting = pathName;
296 }
297
298 public static void registerJREFontsForPrinting() {
299 String pathName = null;
300 synchronized (Win32GraphicsEnvironment.class) {
301 GraphicsEnvironment.getLocalGraphicsEnvironment();
302 if (fontsForPrinting == null) {
303 return;
304 }
305 pathName = fontsForPrinting;
306 fontsForPrinting = null;
307 }
308 File f1 = new File(pathName);
309 String[] ls = f1.list(new TTFilter());
310 if (ls == null) {
311 return;
312 }
313 for (int i=0; i <ls.length; i++ ) {
314 File fontFile = new File(f1, ls[i]);
315 registerFontWithPlatform(fontFile.getAbsolutePath());
316 }
317 }
318
319 protected static native void registerFontWithPlatform(String fontName);
320
321 protected static native void deRegisterFontWithPlatform(String fontName);
322
323 protected GraphicsDevice makeScreenDevice(int screennum) {
324 return new Win32GraphicsDevice(screennum);
325 }
326
327 // Implements SunGraphicsEnvironment.createFontConfiguration.
328 protected FontConfiguration createFontConfiguration() {
329 return new WFontConfiguration(this);
330 }
331
332 public FontConfiguration createFontConfiguration(boolean preferLocaleFonts,
333 boolean preferPropFonts) {
334
335 return new WFontConfiguration(this, preferLocaleFonts,preferPropFonts);
336 }
337}