KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > swt > graphics > Device


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.swt.graphics;
12
13  
14 import org.eclipse.swt.internal.*;
15 import org.eclipse.swt.internal.gdip.*;
16 import org.eclipse.swt.internal.win32.*;
17 import org.eclipse.swt.*;
18
19 /**
20  * This class is the abstract superclass of all device objects,
21  * such as the Display device and the Printer device. Devices
22  * can have a graphics context (GC) created for them, and they
23  * can be drawn on by sending messages to the associated GC.
24  */

25 public abstract class Device implements Drawable {
26     
27     /* Debugging */
28     public static boolean DEBUG;
29     boolean debug = DEBUG;
30     boolean tracking = DEBUG;
31     Error JavaDoc [] errors;
32     Object JavaDoc [] objects;
33     
34     /**
35      * Palette
36      * (Warning: This field is platform dependent)
37      * <p>
38      * <b>IMPORTANT:</b> This field is <em>not</em> part of the SWT
39      * public API. It is marked public only so that it can be shared
40      * within the packages provided by SWT. It is not available on all
41      * platforms and should never be accessed from application code.
42      * </p>
43      */

44     public int hPalette = 0;
45     int [] colorRefCount;
46     
47     /* System Font */
48     int systemFont;
49
50     /* Font Enumeration */
51     int nFonts = 256;
52     LOGFONT [] logFonts;
53     TEXTMETRIC metrics;
54     int[] pixels;
55
56     /* Scripts */
57     int [] scripts;
58
59     /* Advanced Graphics */
60     int [] gdipToken;
61
62     boolean disposed;
63     
64     final static Object JavaDoc CREATE_LOCK = new Object JavaDoc();
65
66     /*
67     * TEMPORARY CODE. When a graphics object is
68     * created and the device parameter is null,
69     * the current Display is used. This presents
70     * a problem because SWT graphics does not
71     * reference classes in SWT widgets. The correct
72     * fix is to remove this feature. Unfortunately,
73     * too many application programs rely on this
74     * feature.
75     *
76     * This code will be removed in the future.
77     */

78     protected static Device CurrentDevice;
79     protected static Runnable JavaDoc DeviceFinder;
80     static {
81         try {
82             Class.forName ("org.eclipse.swt.widgets.Display"); //$NON-NLS-1$
83
} catch (Throwable JavaDoc e) {}
84     }
85
86 /*
87 * TEMPORARY CODE.
88 */

89 static synchronized Device getDevice () {
90     if (DeviceFinder != null) DeviceFinder.run();
91     Device device = CurrentDevice;
92     CurrentDevice = null;
93     return device;
94 }
95
96 /**
97  * Constructs a new instance of this class.
98  * <p>
99  * You must dispose the device when it is no longer required.
100  * </p>
101  *
102  * @see #create
103  * @see #init
104  *
105  * @since 3.1
106  */

107 public Device() {
108     this(null);
109 }
110
111 /**
112  * Constructs a new instance of this class.
113  * <p>
114  * You must dispose the device when it is no longer required.
115  * </p>
116  *
117  * @param data the DeviceData which describes the receiver
118  *
119  * @see #create
120  * @see #init
121  * @see DeviceData
122  */

123 public Device(DeviceData data) {
124     synchronized (CREATE_LOCK) {
125         if (data != null) {
126             debug = data.debug;
127             tracking = data.tracking;
128         }
129         create (data);
130         init ();
131         if (tracking) {
132             errors = new Error JavaDoc [128];
133             objects = new Object JavaDoc [128];
134         }
135         
136         /* Initialize the system font slot */
137         systemFont = getSystemFont().handle;
138     }
139 }
140
141 /**
142  * Throws an <code>SWTException</code> if the receiver can not
143  * be accessed by the caller. This may include both checks on
144  * the state of the receiver and more generally on the entire
145  * execution context. This method <em>should</em> be called by
146  * device implementors to enforce the standard SWT invariants.
147  * <p>
148  * Currently, it is an error to invoke any method (other than
149  * <code>isDisposed()</code> and <code>dispose()</code>) on a
150  * device that has had its <code>dispose()</code> method called.
151  * </p><p>
152  * In future releases of SWT, there may be more or fewer error
153  * checks and exceptions may be thrown for different reasons.
154  * <p>
155  *
156  * @exception SWTException <ul>
157  * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
158  * </ul>
159  */

160 protected void checkDevice () {
161     if (disposed) SWT.error(SWT.ERROR_DEVICE_DISPOSED);
162 }
163
164 void checkGDIP() {
165     if (gdipToken != null) return;
166     if (OS.IsWinCE) SWT.error(SWT.ERROR_NOT_IMPLEMENTED);
167     int oldErrorMode = OS.SetErrorMode (OS.SEM_FAILCRITICALERRORS);
168     try {
169         int [] token = new int [1];
170         GdiplusStartupInput input = new GdiplusStartupInput ();
171         input.GdiplusVersion = 1;
172         if (Gdip.GdiplusStartup (token, input, 0) == 0) {
173             gdipToken = token;
174         }
175     } catch (Throwable JavaDoc t) {
176         SWT.error (SWT.ERROR_NO_GRAPHICS_LIBRARY, t, " [GDI+ is required]"); //$NON-NLS-1$
177
} finally {
178         OS.SetErrorMode (oldErrorMode);
179     }
180 }
181
182 /**
183  * Creates the device in the operating system. If the device
184  * does not have a handle, this method may do nothing depending
185  * on the device.
186  * <p>
187  * This method is called before <code>init</code>.
188  * </p><p>
189  * Subclasses are supposed to reimplement this method and not
190  * call the <code>super</code> implementation.
191  * </p>
192  *
193  * @param data the DeviceData which describes the receiver
194  *
195  * @see #init
196  */

197 protected void create (DeviceData data) {
198 }
199
200 int computePixels(float height) {
201     int hDC = internal_new_GC (null);
202     int pixels = -(int)(0.5f + (height * OS.GetDeviceCaps(hDC, OS.LOGPIXELSY) / 72f));
203     internal_dispose_GC (hDC, null);
204     return pixels;
205 }
206
207 float computePoints(LOGFONT logFont, int hFont) {
208     int hDC = internal_new_GC (null);
209     int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY);
210     int pixels = 0;
211     if (logFont.lfHeight > 0) {
212         /*
213          * Feature in Windows. If the lfHeight of the LOGFONT structure
214          * is positive, the lfHeight measures the height of the entire
215          * cell, including internal leading, in logical units. Since the
216          * height of a font in points does not include the internal leading,
217          * we must subtract the internal leading, which requires a TEXTMETRIC.
218          */

219         int oldFont = OS.SelectObject(hDC, hFont);
220         TEXTMETRIC lptm = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA();
221         OS.GetTextMetrics(hDC, lptm);
222         OS.SelectObject(hDC, oldFont);
223         pixels = logFont.lfHeight - lptm.tmInternalLeading;
224     } else {
225         pixels = -logFont.lfHeight;
226     }
227     internal_dispose_GC (hDC, null);
228     return pixels * 72f / logPixelsY;
229 }
230
231 /**
232  * Destroys the device in the operating system and releases
233  * the device's handle. If the device does not have a handle,
234  * this method may do nothing depending on the device.
235  * <p>
236  * This method is called after <code>release</code>.
237  * </p><p>
238  * Subclasses are supposed to reimplement this method and not
239  * call the <code>super</code> implementation.
240  * </p>
241  *
242  * @see #dispose
243  * @see #release
244  */

245 protected void destroy () {
246 }
247
248 /**
249  * Disposes of the operating system resources associated with
250  * the receiver. After this method has been invoked, the receiver
251  * will answer <code>true</code> when sent the message
252  * <code>isDisposed()</code>.
253  *
254  * @see #release
255  * @see #destroy
256  * @see #checkDevice
257  */

258 public void dispose () {
259     if (isDisposed()) return;
260     checkDevice ();
261     release ();
262     destroy ();
263     disposed = true;
264     if (tracking) {
265         objects = null;
266         errors = null;
267     }
268 }
269
270 void dispose_Object (Object JavaDoc object) {
271     for (int i=0; i<objects.length; i++) {
272         if (objects [i] == object) {
273             objects [i] = null;
274             errors [i] = null;
275             return;
276         }
277     }
278 }
279
280 int EnumFontFamProc (int lpelfe, int lpntme, int FontType, int lParam) {
281     boolean isScalable = (FontType & OS.RASTER_FONTTYPE) == 0;
282     boolean scalable = lParam == 1;
283     if (isScalable == scalable) {
284         /* Add the log font to the list of log fonts */
285         if (nFonts == logFonts.length) {
286             LOGFONT [] newLogFonts = new LOGFONT [logFonts.length + 128];
287             System.arraycopy (logFonts, 0, newLogFonts, 0, nFonts);
288             logFonts = newLogFonts;
289             int[] newPixels = new int[newLogFonts.length];
290             System.arraycopy (pixels, 0, newPixels, 0, nFonts);
291             pixels = newPixels;
292         }
293         LOGFONT logFont = logFonts [nFonts];
294         if (logFont == null) logFont = OS.IsUnicode ? (LOGFONT)new LOGFONTW () : new LOGFONTA ();
295         OS.MoveMemory (logFont, lpelfe, LOGFONT.sizeof);
296         logFonts [nFonts] = logFont;
297         if (logFont.lfHeight > 0) {
298             /*
299              * Feature in Windows. If the lfHeight of the LOGFONT structure
300              * is positive, the lfHeight measures the height of the entire
301              * cell, including internal leading, in logical units. Since the
302              * height of a font in points does not include the internal leading,
303              * we must subtract the internal leading, which requires a TEXTMETRIC,
304              * which in turn requires font creation.
305              */

306             OS.MoveMemory(metrics, lpntme, TEXTMETRIC.sizeof);
307             pixels[nFonts] = logFont.lfHeight - metrics.tmInternalLeading;
308         } else {
309             pixels[nFonts] = -logFont.lfHeight;
310         }
311         nFonts++;
312     }
313     return 1;
314 }
315
316 /**
317  * Returns a rectangle describing the receiver's size and location.
318  *
319  * @return the bounding rectangle
320  *
321  * @exception SWTException <ul>
322  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
323  * </ul>
324  */

325 public Rectangle getBounds () {
326     checkDevice ();
327     int hDC = internal_new_GC (null);
328     int width = OS.GetDeviceCaps (hDC, OS.HORZRES);
329     int height = OS.GetDeviceCaps (hDC, OS.VERTRES);
330     internal_dispose_GC (hDC, null);
331     return new Rectangle (0, 0, width, height);
332 }
333
334 /**
335  * Returns a <code>DeviceData</code> based on the receiver.
336  * Modifications made to this <code>DeviceData</code> will not
337  * affect the receiver.
338  *
339  * @return a <code>DeviceData</code> containing the device's data and attributes
340  *
341  * @exception SWTException <ul>
342  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
343  * </ul>
344  *
345  * @see DeviceData
346  */

347 public DeviceData getDeviceData () {
348     checkDevice();
349     DeviceData data = new DeviceData ();
350     data.debug = debug;
351     data.tracking = tracking;
352     int count = 0, length = 0;
353     if (tracking) length = objects.length;
354     for (int i=0; i<length; i++) {
355         if (objects [i] != null) count++;
356     }
357     int index = 0;
358     data.objects = new Object JavaDoc [count];
359     data.errors = new Error JavaDoc [count];
360     for (int i=0; i<length; i++) {
361         if (objects [i] != null) {
362             data.objects [index] = objects [i];
363             data.errors [index] = errors [i];
364             index++;
365         }
366     }
367     return data;
368 }
369
370 /**
371  * Returns a rectangle which describes the area of the
372  * receiver which is capable of displaying data.
373  *
374  * @return the client area
375  *
376  * @exception SWTException <ul>
377  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
378  * </ul>
379  *
380  * @see #getBounds
381  */

382 public Rectangle getClientArea () {
383     return getBounds ();
384 }
385
386 /**
387  * Returns the bit depth of the screen, which is the number of
388  * bits it takes to represent the number of unique colors that
389  * the screen is currently capable of displaying. This number
390  * will typically be one of 1, 8, 15, 16, 24 or 32.
391  *
392  * @return the depth of the screen
393  *
394  * @exception SWTException <ul>
395  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
396  * </ul>
397  */

398 public int getDepth () {
399     checkDevice ();
400     int hDC = internal_new_GC (null);
401     int bits = OS.GetDeviceCaps (hDC, OS.BITSPIXEL);
402     int planes = OS.GetDeviceCaps (hDC, OS.PLANES);
403     internal_dispose_GC (hDC, null);
404     return bits * planes;
405 }
406
407 /**
408  * Returns a point whose x coordinate is the horizontal
409  * dots per inch of the display, and whose y coordinate
410  * is the vertical dots per inch of the display.
411  *
412  * @return the horizontal and vertical DPI
413  *
414  * @exception SWTException <ul>
415  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
416  * </ul>
417  */

418 public Point getDPI () {
419     checkDevice ();
420     int hDC = internal_new_GC (null);
421     int dpiX = OS.GetDeviceCaps (hDC, OS.LOGPIXELSX);
422     int dpiY = OS.GetDeviceCaps (hDC, OS.LOGPIXELSY);
423     internal_dispose_GC (hDC, null);
424     return new Point (dpiX, dpiY);
425 }
426
427 /**
428  * Returns <code>FontData</code> objects which describe
429  * the fonts that match the given arguments. If the
430  * <code>faceName</code> is null, all fonts will be returned.
431  *
432  * @param faceName the name of the font to look for, or null
433  * @param scalable if true only scalable fonts are returned, otherwise only non-scalable fonts are returned.
434  * @return the matching font data
435  *
436  * @exception SWTException <ul>
437  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
438  * </ul>
439  */

440 public FontData [] getFontList (String JavaDoc faceName, boolean scalable) {
441     checkDevice ();
442     
443     /* Create the callback */
444     Callback callback = new Callback (this, "EnumFontFamProc", 4); //$NON-NLS-1$
445
int lpEnumFontFamProc = callback.getAddress ();
446     if (lpEnumFontFamProc == 0) SWT.error (SWT.ERROR_NO_MORE_CALLBACKS);
447     
448     /* Initialize the instance variables */
449     metrics = OS.IsUnicode ? (TEXTMETRIC)new TEXTMETRICW() : new TEXTMETRICA();
450     pixels = new int[nFonts];
451     logFonts = new LOGFONT [nFonts];
452     for (int i=0; i<logFonts.length; i++) {
453         logFonts [i] = OS.IsUnicode ? (LOGFONT) new LOGFONTW () : new LOGFONTA ();
454     }
455     nFonts = 0;
456
457     /* Enumerate */
458     int offset = 0;
459     int hDC = internal_new_GC (null);
460     if (faceName == null) {
461         /* The user did not specify a face name, so they want all versions of all available face names */
462         OS.EnumFontFamilies (hDC, null, lpEnumFontFamProc, scalable ? 1 : 0);
463         
464         /**
465          * For bitmapped fonts, EnumFontFamilies only enumerates once for each font, regardless
466          * of how many styles are available. If the user wants bitmapped fonts, enumerate on
467          * each face name now.
468          */

469         offset = nFonts;
470         for (int i=0; i<offset; i++) {
471             LOGFONT lf = logFonts [i];
472             /**
473              * Bug in Windows 98. When EnumFontFamiliesEx is called with a specified face name, it
474              * should enumerate for each available style of that font. Instead, it only enumerates
475              * once. The fix is to call EnumFontFamilies, which works as expected.
476              */

477             if (OS.IsUnicode) {
478                 OS.EnumFontFamiliesW (hDC, ((LOGFONTW)lf).lfFaceName, lpEnumFontFamProc, scalable ? 1 : 0);
479             } else {
480                 OS.EnumFontFamiliesA (hDC, ((LOGFONTA)lf).lfFaceName, lpEnumFontFamProc, scalable ? 1 : 0);
481             }
482         }
483     } else {
484         /* Use the character encoding for the default locale */
485         TCHAR lpFaceName = new TCHAR (0, faceName, true);
486         /**
487          * Bug in Windows 98. When EnumFontFamiliesEx is called with a specified face name, it
488          * should enumerate for each available style of that font. Instead, it only enumerates
489          * once. The fix is to call EnumFontFamilies, which works as expected.
490          */

491         OS.EnumFontFamilies (hDC, lpFaceName, lpEnumFontFamProc, scalable ? 1 : 0);
492     }
493     int logPixelsY = OS.GetDeviceCaps(hDC, OS.LOGPIXELSY);
494     internal_dispose_GC (hDC, null);
495
496     /* Create the fontData from the logfonts */
497     int count = 0;
498     FontData [] result = new FontData [nFonts - offset];
499     for (int i=offset; i<nFonts; i++) {
500         FontData fd = FontData.win32_new (logFonts [i], pixels [i] * 72f / logPixelsY);
501         int j;
502         for (j = 0; j < count; j++) {
503             if (fd.equals (result [j])) break;
504         }
505         if (j == count) result [count++] = fd;
506     }
507     if (count != result.length) {
508         FontData [] newResult = new FontData [count];
509         System.arraycopy (result, 0, newResult, 0, count);
510         result = newResult;
511     }
512     
513     /* Clean up */
514     callback.dispose ();
515     logFonts = null;
516     pixels = null;
517     metrics = null;
518     return result;
519 }
520
521 String JavaDoc getLastError () {
522     int error = OS.GetLastError();
523     if (error == 0) return ""; //$NON-NLS-1$
524
return " [GetLastError=0x" + Integer.toHexString(error) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
525
}
526
527 String JavaDoc getLastErrorText () {
528     int error = OS.GetLastError();
529     if (error == 0) return ""; //$NON-NLS-1$
530
int[] buffer = new int[1];
531     int dwFlags = OS.FORMAT_MESSAGE_ALLOCATE_BUFFER | OS.FORMAT_MESSAGE_FROM_SYSTEM | OS.FORMAT_MESSAGE_IGNORE_INSERTS;
532     int length = OS.FormatMessage(dwFlags, 0, error, OS.LANG_USER_DEFAULT, buffer, 0, 0);
533     if (length == 0) return " [GetLastError=0x" + Integer.toHexString(error) + "]"; //$NON-NLS-1$ //$NON-NLS-2$
534
TCHAR buffer1 = new TCHAR(0, length);
535     OS.MoveMemory(buffer1, buffer[0], length * TCHAR.sizeof);
536     if (buffer[0] != 0) OS.LocalFree(buffer[0]);
537     return buffer1.toString(0, length);
538 }
539
540 /**
541  * Returns the matching standard color for the given
542  * constant, which should be one of the color constants
543  * specified in class <code>SWT</code>. Any value other
544  * than one of the SWT color constants which is passed
545  * in will result in the color black. This color should
546  * not be freed because it was allocated by the system,
547  * not the application.
548  *
549  * @param id the color constant
550  * @return the matching color
551  *
552  * @exception SWTException <ul>
553  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
554  * </ul>
555  *
556  * @see SWT
557  */

558 public Color getSystemColor (int id) {
559     checkDevice ();
560     int pixel = 0x00000000;
561     switch (id) {
562         case SWT.COLOR_WHITE: pixel = 0x00FFFFFF; break;
563         case SWT.COLOR_BLACK: pixel = 0x00000000; break;
564         case SWT.COLOR_RED: pixel = 0x000000FF; break;
565         case SWT.COLOR_DARK_RED: pixel = 0x00000080; break;
566         case SWT.COLOR_GREEN: pixel = 0x0000FF00; break;
567         case SWT.COLOR_DARK_GREEN: pixel = 0x00008000; break;
568         case SWT.COLOR_YELLOW: pixel = 0x0000FFFF; break;
569         case SWT.COLOR_DARK_YELLOW: pixel = 0x00008080; break;
570         case SWT.COLOR_BLUE: pixel = 0x00FF0000; break;
571         case SWT.COLOR_DARK_BLUE: pixel = 0x00800000; break;
572         case SWT.COLOR_MAGENTA: pixel = 0x00FF00FF; break;
573         case SWT.COLOR_DARK_MAGENTA: pixel = 0x00800080; break;
574         case SWT.COLOR_CYAN: pixel = 0x00FFFF00; break;
575         case SWT.COLOR_DARK_CYAN: pixel = 0x00808000; break;
576         case SWT.COLOR_GRAY: pixel = 0x00C0C0C0; break;
577         case SWT.COLOR_DARK_GRAY: pixel = 0x00808080; break;
578     }
579     return Color.win32_new (this, pixel);
580 }
581
582 /**
583  * Returns a reasonable font for applications to use.
584  * On some platforms, this will match the "default font"
585  * or "system font" if such can be found. This font
586  * should not be freed because it was allocated by the
587  * system, not the application.
588  * <p>
589  * Typically, applications which want the default look
590  * should simply not set the font on the widgets they
591  * create. Widgets are always created with the correct
592  * default font for the class of user-interface component
593  * they represent.
594  * </p>
595  *
596  * @return a font
597  *
598  * @exception SWTException <ul>
599  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
600  * </ul>
601  */

602 public Font getSystemFont () {
603     checkDevice ();
604     int hFont = OS.GetStockObject (OS.SYSTEM_FONT);
605     return Font.win32_new (this, hFont);
606 }
607
608 /**
609  * Returns <code>true</code> if the underlying window system prints out
610  * warning messages on the console, and <code>setWarnings</code>
611  * had previously been called with <code>true</code>.
612  *
613  * @return <code>true</code>if warnings are being handled, and <code>false</code> otherwise
614  *
615  * @exception SWTException <ul>
616  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
617  * </ul>
618  */

619 public boolean getWarnings () {
620     checkDevice ();
621     return false;
622 }
623
624 /**
625  * Initializes any internal resources needed by the
626  * device.
627  * <p>
628  * This method is called after <code>create</code>.
629  * </p><p>
630  * If subclasses reimplement this method, they must
631  * call the <code>super</code> implementation.
632  * </p>
633  *
634  * @see #create
635  */

636 protected void init () {
637     if (debug) {
638         if (!OS.IsWinCE) OS.GdiSetBatchLimit(1);
639     }
640
641     /* Initialize scripts list */
642     if (!OS.IsWinCE) {
643         int [] ppSp = new int [1];
644         int [] piNumScripts = new int [1];
645         OS.ScriptGetProperties (ppSp, piNumScripts);
646         scripts = new int [piNumScripts [0]];
647         OS.MoveMemory (scripts, ppSp [0], scripts.length * 4);
648     }
649     
650     /*
651      * If we're not on a device which supports palettes,
652      * don't create one.
653      */

654     int hDC = internal_new_GC (null);
655     int rc = OS.GetDeviceCaps (hDC, OS.RASTERCAPS);
656     int bits = OS.GetDeviceCaps (hDC, OS.BITSPIXEL);
657     int planes = OS.GetDeviceCaps (hDC, OS.PLANES);
658     
659     bits *= planes;
660     if ((rc & OS.RC_PALETTE) == 0 || bits != 8) {
661         internal_dispose_GC (hDC, null);
662         return;
663     }
664     
665     int numReserved = OS.GetDeviceCaps (hDC, OS.NUMRESERVED);
666     int numEntries = OS.GetDeviceCaps (hDC, OS.SIZEPALETTE);
667
668     if (OS.IsWinCE) {
669         /*
670         * Feature on WinCE. For some reason, certain 8 bit WinCE
671         * devices return 0 for the number of reserved entries in
672         * the system palette. Their system palette correctly contains
673         * the usual 20 system colors. The workaround is to assume
674         * there are 20 reserved system colors instead of 0.
675         */

676         if (numReserved == 0 && numEntries >= 20) numReserved = 20;
677     }
678
679     /* Create the palette and reference counter */
680     colorRefCount = new int [numEntries];
681
682     /* 4 bytes header + 4 bytes per entry * numEntries entries */
683     byte [] logPalette = new byte [4 + 4 * numEntries];
684     
685     /* 2 bytes = special header */
686     logPalette [0] = 0x00;
687     logPalette [1] = 0x03;
688     
689     /* 2 bytes = number of colors, LSB first */
690     logPalette [2] = 0;
691     logPalette [3] = 1;
692
693     /*
694     * Create a palette which contains the system entries
695     * as they are located in the system palette. The
696     * MSDN article 'Memory Device Contexts' describes
697     * where system entries are located. On an 8 bit
698     * display with 20 reserved colors, the system colors
699     * will be the first 10 entries and the last 10 ones.
700     */

701     byte[] lppe = new byte [4 * numEntries];
702     OS.GetSystemPaletteEntries (hDC, 0, numEntries, lppe);
703     /* Copy all entries from the system palette */
704     System.arraycopy (lppe, 0, logPalette, 4, 4 * numEntries);
705     /* Lock the indices corresponding to the system entries */
706     for (int i = 0; i < numReserved / 2; i++) {
707         colorRefCount [i] = 1;
708         colorRefCount [numEntries - 1 - i] = 1;
709     }
710     internal_dispose_GC (hDC, null);
711     hPalette = OS.CreatePalette (logPalette);
712 }
713 /**
714  * Invokes platform specific functionality to allocate a new GC handle.
715  * <p>
716  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
717  * API for <code>Device</code>. It is marked public only so that it
718  * can be shared within the packages provided by SWT. It is not
719  * available on all platforms, and should never be called from
720  * application code.
721  * </p>
722  *
723  * @param data the platform specific GC data
724  * @return the platform specific GC handle
725  */

726 public abstract int internal_new_GC (GCData data);
727
728 /**
729  * Invokes platform specific functionality to dispose a GC handle.
730  * <p>
731  * <b>IMPORTANT:</b> This method is <em>not</em> part of the public
732  * API for <code>Device</code>. It is marked public only so that it
733  * can be shared within the packages provided by SWT. It is not
734  * available on all platforms, and should never be called from
735  * application code.
736  * </p>
737  *
738  * @param hDC the platform specific GC handle
739  * @param data the platform specific GC data
740  */

741 public abstract void internal_dispose_GC (int hDC, GCData data);
742
743 /**
744  * Returns <code>true</code> if the device has been disposed,
745  * and <code>false</code> otherwise.
746  * <p>
747  * This method gets the dispose state for the device.
748  * When a device has been disposed, it is an error to
749  * invoke any other method using the device.
750  *
751  * @return <code>true</code> when the device is disposed and <code>false</code> otherwise
752  */

753 public boolean isDisposed () {
754     return disposed;
755 }
756
757 /**
758  * Loads the font specified by a file. The font will be
759  * present in the list of fonts available to the application.
760  *
761  * @param path the font file path
762  * @return whether the font was successfully loaded
763  *
764  * @exception SWTException <ul>
765  * <li>ERROR_NULL_ARGUMENT - if path is null</li>
766  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
767  * </ul>
768  *
769  * @see Font
770  *
771  * @since 3.3
772  */

773 public boolean loadFont (String JavaDoc path) {
774     checkDevice();
775     if (path == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
776     if (OS.IsWinNT && OS.WIN32_VERSION >= OS.VERSION (4, 10)) {
777         TCHAR lpszFilename = new TCHAR (0, path, true);
778         return OS.AddFontResourceEx (lpszFilename, OS.FR_PRIVATE, 0) != 0;
779     }
780     return false;
781 }
782
783 void new_Object (Object JavaDoc object) {
784     for (int i=0; i<objects.length; i++) {
785         if (objects [i] == null) {
786             objects [i] = object;
787             errors [i] = new Error JavaDoc ();
788             return;
789         }
790     }
791     Object JavaDoc [] newObjects = new Object JavaDoc [objects.length + 128];
792     System.arraycopy (objects, 0, newObjects, 0, objects.length);
793     newObjects [objects.length] = object;
794     objects = newObjects;
795     Error JavaDoc [] newErrors = new Error JavaDoc [errors.length + 128];
796     System.arraycopy (errors, 0, newErrors, 0, errors.length);
797     newErrors [errors.length] = new Error JavaDoc ();
798     errors = newErrors;
799 }
800
801 /**
802  * Releases any internal resources back to the operating
803  * system and clears all fields except the device handle.
804  * <p>
805  * When a device is destroyed, resources that were acquired
806  * on behalf of the programmer need to be returned to the
807  * operating system. For example, if the device allocated a
808  * font to be used as the system font, this font would be
809  * freed in <code>release</code>. Also,to assist the garbage
810  * collector and minimize the amount of memory that is not
811  * reclaimed when the programmer keeps a reference to a
812  * disposed device, all fields except the handle are zero'd.
813  * The handle is needed by <code>destroy</code>.
814  * </p>
815  * This method is called before <code>destroy</code>.
816  * </p><p>
817  * If subclasses reimplement this method, they must
818  * call the <code>super</code> implementation.
819  * </p>
820  *
821  * @see #dispose
822  * @see #destroy
823  */

824 protected void release () {
825     if (gdipToken != null) {
826         Gdip.GdiplusShutdown (gdipToken[0]);
827     }
828     gdipToken = null;
829     scripts = null;
830     if (hPalette != 0) OS.DeleteObject (hPalette);
831     hPalette = 0;
832     colorRefCount = null;
833     logFonts = null;
834     nFonts = 0;
835 }
836
837 /**
838  * If the underlying window system supports printing warning messages
839  * to the console, setting warnings to <code>false</code> prevents these
840  * messages from being printed. If the argument is <code>true</code> then
841  * message printing is not blocked.
842  *
843  * @param warnings <code>true</code>if warnings should be printed, and <code>false</code> otherwise
844  *
845  * @exception SWTException <ul>
846  * <li>ERROR_DEVICE_DISPOSED - if the receiver has been disposed</li>
847  * </ul>
848  */

849 public void setWarnings (boolean warnings) {
850     checkDevice ();
851 }
852
853 }
854
Popular Tags