OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / awt / Toolkit.java
1 /* Toolkit.java -- AWT Toolkit superclass
2    Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3    Free Software Foundation, Inc.
4
5 This file is part of GNU Classpath.
6
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301 USA.
21
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library.  Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module.  An independent module is a module which is not derived from
34 or based on this library.  If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so.  If you do not wish to do so, delete this
37 exception statement from your version. */
38
39
40 package java.awt;
41
42 import gnu.classpath.SystemProperties;
43 import gnu.java.awt.peer.GLightweightPeer;
44 import gnu.java.awt.peer.headless.HeadlessToolkit;
45
46 import java.awt.datatransfer.Clipboard;
47 import java.awt.dnd.DragGestureEvent;
48 import java.awt.dnd.DragGestureListener;
49 import java.awt.dnd.DragGestureRecognizer;
50 import java.awt.dnd.DragSource;
51 import java.awt.dnd.peer.DragSourceContextPeer;
52 import java.awt.event.AWTEventListener;
53 import java.awt.event.AWTEventListenerProxy;
54 import java.awt.event.KeyEvent;
55 import java.awt.font.TextAttribute;
56 import java.awt.im.InputMethodHighlight;
57 import java.awt.image.ColorModel;
58 import java.awt.image.ImageObserver;
59 import java.awt.image.ImageProducer;
60 import java.awt.peer.ButtonPeer;
61 import java.awt.peer.CanvasPeer;
62 import java.awt.peer.CheckboxMenuItemPeer;
63 import java.awt.peer.CheckboxPeer;
64 import java.awt.peer.ChoicePeer;
65 import java.awt.peer.DialogPeer;
66 import java.awt.peer.FileDialogPeer;
67 import java.awt.peer.FontPeer;
68 import java.awt.peer.FramePeer;
69 import java.awt.peer.LabelPeer;
70 import java.awt.peer.LightweightPeer;
71 import java.awt.peer.ListPeer;
72 import java.awt.peer.MenuBarPeer;
73 import java.awt.peer.MenuItemPeer;
74 import java.awt.peer.MenuPeer;
75 import java.awt.peer.MouseInfoPeer;
76 import java.awt.peer.PanelPeer;
77 import java.awt.peer.PopupMenuPeer;
78 import java.awt.peer.ScrollPanePeer;
79 import java.awt.peer.ScrollbarPeer;
80 import java.awt.peer.TextAreaPeer;
81 import java.awt.peer.TextFieldPeer;
82 import java.awt.peer.WindowPeer;
83 import java.beans.PropertyChangeListener;
84 import java.beans.PropertyChangeSupport;
85 import java.io.File;
86 import java.io.FileInputStream;
87 import java.net.URL;
88 import java.security.AccessController;
89 import java.security.PrivilegedAction;
90 import java.util.ArrayList;
91 import java.util.Hashtable;
92 import java.util.Map;
93 import java.util.Properties;
94 import java.util.StringTokenizer;
95
96 /**
97  * The AWT system uses a set of native peer objects to implement its
98  * widgets.  These peers are provided by a peer toolkit, that is accessed
99  * via a subclass of this superclass.  The system toolkit is retrieved
100  * by the static methods <code>getDefaultToolkit</code>.  This method
101  * determines the system toolkit by examining the system property
102  * <code>awt.toolkit</code>.  That property is set to the name of the
103  * <code>Toolkit</code> subclass for the specified peer set.  If the
104  * <code>awt.toolkit</code> property is not set, then the default
105  * toolkit <code>gnu.java.awt.peer.gtk.GtkToolkit</code> is used.  This
106  * toolkit creates its peers using the GTK+ toolkit.
107  *
108  * @author Aaron M. Renn (arenn@urbanophile.com)
109  */
110 public abstract class Toolkit
111 {
112   /** The default toolkit name. */
113   private static String default_toolkit_name
114     = gnu.classpath.Configuration.default_awt_peer_toolkit;
115
116   /**
117    * The toolkit in use.  Once we load it, we don't ever change it
118    * if the awt.toolkit property is set.
119    */
120   private static Toolkit toolkit;
121
122   /** The toolkit properties. */
123   private static Properties props = new Properties();
124
125   protected final Map<String,Object> desktopProperties = 
126     new Hashtable<String,Object>();
127
128   protected final PropertyChangeSupport desktopPropsSupport
129     = new PropertyChangeSupport(this);
130
131   /**
132    * All registered AWTEventListener objects. This is package private, so the
133    * event queue can efficiently access this list.
134    */
135   AWTEventListenerProxy[] awtEventListeners;
136
137   /**
138    * The shared peer for all lightweight components.
139    */
140   private GLightweightPeer lightweightPeer;
141
142   /**
143    * Default constructor for subclasses.
144    */
145   public Toolkit()
146   {
147     awtEventListeners = new AWTEventListenerProxy[0];
148   }
149
150   /**
151    * Creates a peer object for the specified <code>Button</code>.
152    *
153    * @param target The <code>Button</code> to create the peer for.
154    * 
155    * @return The peer for the specified <code>Button</code> object.
156    *
157    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
158    */
159   protected abstract ButtonPeer createButton(Button target);
160
161   /**
162    * Creates a peer object for the specified <code>TextField</code>.
163    *
164    * @param target The <code>TextField</code> to create the peer for.
165    *
166    * @return The peer for the specified <code>TextField</code> object.
167    *
168    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
169    */
170   protected abstract TextFieldPeer createTextField(TextField target);
171
172   /**
173    * Creates a peer object for the specified <code>Label</code>.
174    *
175    * @param target The <code>Label</code> to create the peer for.
176    *
177    * @return The peer for the specified <code>Label</code> object.
178    *
179    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
180    */
181   protected abstract LabelPeer createLabel(Label target);
182
183   /**
184    * Creates a peer object for the specified <code>List</code>.
185    *
186    * @param target The <code>List</code> to create the peer for.
187    *
188    * @return The peer for the specified <code>List</code> object.
189    *
190    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
191    */
192   protected abstract ListPeer createList(List target);
193
194   /**
195    * Creates a peer object for the specified <code>Checkbox</code>.
196    *
197    * @param target The <code>Checkbox</code> to create the peer for.
198    *
199    * @return The peer for the specified <code>Checkbox</code> object.
200    *
201    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
202    */
203   protected abstract CheckboxPeer createCheckbox(Checkbox target);
204
205   /**
206    * Creates a peer object for the specified <code>Scrollbar</code>.
207    *
208    * @param target The <code>Scrollbar</code> to create the peer for.
209    *
210    * @return The peer for the specified <code>Scrollbar</code> object.
211    *
212    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
213    */
214   protected abstract ScrollbarPeer createScrollbar(Scrollbar target);
215
216   /**
217    * Creates a peer object for the specified <code>ScrollPane</code>.
218    *
219    * @param target The <code>ScrollPane</code> to create the peer for.
220    *
221    * @return The peer for the specified <code>ScrollPane</code> object.
222    *
223    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
224    */
225   protected abstract ScrollPanePeer createScrollPane(ScrollPane target);
226
227   /**
228    * Creates a peer object for the specified <code>TextArea</code>.
229    *
230    * @param target The <code>TextArea</code> to create the peer for.
231    *
232    * @return The peer for the specified <code>TextArea</code> object.
233    *
234    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
235    */
236   protected abstract TextAreaPeer createTextArea(TextArea target);
237
238   /**
239    * Creates a peer object for the specified <code>Choice</code>.
240    *
241    * @param target The <code>Choice</code> to create the peer for.
242    *
243    * @return The peer for the specified <code>Choice</code> object.
244    *
245    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
246    */
247   protected abstract ChoicePeer createChoice(Choice target);
248
249   /**
250    * Creates a peer object for the specified <code>Frame</code>.
251    *
252    * @param target The <code>Frame</code> to create the peer for.
253    *
254    * @return The peer for the specified <code>Frame</code> object.
255    *
256    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
257    */
258   protected abstract FramePeer createFrame(Frame target);
259
260   /**
261    * Creates a peer object for the specified <code>Canvas</code>.
262    *
263    * @param target The <code>Canvas</code> to create the peer for.
264    *
265    * @return The peer for the specified <code>Canvas</code> object.
266    */
267   protected abstract CanvasPeer createCanvas(Canvas target);
268
269   /**
270    * Creates a peer object for the specified <code>Panel</code>.
271    *
272    * @param target The <code>Panel</code> to create the peer for.
273    *
274    * @return The peer for the specified <code>Panel</code> object.
275    */
276   protected abstract PanelPeer createPanel(Panel target);
277
278   /**
279    * Creates a peer object for the specified <code>Window</code>.
280    *
281    * @param target The <code>Window</code> to create the peer for.
282    *
283    * @return The peer for the specified <code>Window</code> object.
284    *
285    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
286    */
287   protected abstract WindowPeer createWindow(Window target);
288
289   /**
290    * Creates a peer object for the specified <code>Dialog</code>.
291    *
292    * @param target The dialog to create the peer for
293    *
294    * @return The peer for the specified font name.
295    *
296    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
297    */
298   protected abstract DialogPeer createDialog(Dialog target);
299
300   /**
301    * Creates a peer object for the specified <code>MenuBar</code>.
302    *
303    * @param target The <code>MenuBar</code> to create the peer for.
304    *
305    * @return The peer for the specified <code>MenuBar</code> object.
306    *
307    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
308    */
309   protected abstract MenuBarPeer createMenuBar(MenuBar target);
310
311   /**
312    * Creates a peer object for the specified <code>Menu</code>.
313    *
314    * @param target The <code>Menu</code> to create the peer for.
315    *
316    * @return The peer for the specified <code>Menu</code> object.
317    *
318    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
319    */
320   protected abstract MenuPeer createMenu(Menu target);
321
322   /**
323    * Creates a peer object for the specified <code>PopupMenu</code>.
324    *
325    * @param target The <code>PopupMenu</code> to create the peer for.
326    *
327    * @return The peer for the specified <code>PopupMenu</code> object.
328    *
329    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
330    */
331   protected abstract PopupMenuPeer createPopupMenu(PopupMenu target);
332
333   /**
334    * Creates a peer object for the specified <code>MenuItem</code>.
335    *
336    * @param target The <code>MenuItem</code> to create the peer for.
337    *
338    * @return The peer for the specified <code>MenuItem</code> object.
339    *
340    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
341    */
342   protected abstract MenuItemPeer createMenuItem(MenuItem target);
343
344   /**
345    * Returns a MouseInfoPeer. 
346    * The default implementation of this method throws
347    * UnsupportedOperationException.
348    *
349    * Toolkit implementations should overload this if possible, however.
350    */
351   protected MouseInfoPeer getMouseInfoPeer()
352   {
353     throw new UnsupportedOperationException("No mouse info peer.");
354   }
355
356   /**
357    * Creates a peer object for the specified <code>FileDialog</code>.
358    *
359    * @param target The <code>FileDialog</code> to create the peer for.
360    *
361    * @return The peer for the specified <code>FileDialog</code> object.
362    *
363    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
364    */
365   protected abstract FileDialogPeer createFileDialog(FileDialog target);
366
367   /**
368    * Creates a peer object for the specified <code>CheckboxMenuItem</code>.
369    *
370    * @param target The <code>CheckboxMenuItem</code> to create the peer for.
371    *
372    * @return The peer for the specified <code>CheckboxMenuItem</code> object.
373    *
374    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
375    */
376   protected abstract CheckboxMenuItemPeer
377     createCheckboxMenuItem(CheckboxMenuItem target);
378
379   /**
380    * Creates a peer object for the specified <code>Component</code>.  The
381    * peer returned by this method is not a native windowing system peer
382    * with its own native window.  Instead, this method allows the component
383    * to draw on its parent window as a "lightweight" widget.
384    *
385    * @param target The <code>Component</code> to create the peer for.
386    *
387    * @return The peer for the specified <code>Component</code> object.
388    */
389   protected LightweightPeer createComponent(Component target)
390   {
391     if (lightweightPeer == null)
392       lightweightPeer = new GLightweightPeer();
393     return lightweightPeer;
394   }
395
396   /**
397    * Creates a peer object for the specified font name.
398    *
399    * @param name The font to create the peer for.
400    * @param style The font style to create the peer for.
401    *
402    * @return The peer for the specified font name.
403    *
404    * @deprecated
405    */
406   protected abstract FontPeer getFontPeer(String name, int style);
407
408   /**
409    * Copies the current system colors into the specified array.  This is
410    * the interface used by the <code>SystemColor</code> class.  Although
411    * this method fills in the array with some default colors a real Toolkit
412    * should override this method and provide real system colors for the
413    * native GUI platform.
414    *
415    * @param systemColors The array to copy the system colors into.
416    * It must be at least 26 elements.
417    *
418    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
419    *
420    * @see java.awt.SystemColor
421    */
422   protected void loadSystemColors(int systemColors[])
423   {
424     systemColors[SystemColor.DESKTOP]                 = 0xFF005C5C;
425     systemColors[SystemColor.ACTIVE_CAPTION]          = 0xFF000080;
426     systemColors[SystemColor.ACTIVE_CAPTION_TEXT]     = 0xFFFFFFFF;
427     systemColors[SystemColor.ACTIVE_CAPTION_BORDER]   = 0xFFC0C0C0;
428     systemColors[SystemColor.INACTIVE_CAPTION]        = 0xFF808080;
429     systemColors[SystemColor.INACTIVE_CAPTION_TEXT]   = 0xFFC0C0C0;
430     systemColors[SystemColor.INACTIVE_CAPTION_BORDER] = 0xFFC0C0C0;
431     systemColors[SystemColor.WINDOW]                  = 0xFFFFFFFF;
432     systemColors[SystemColor.WINDOW_BORDER]           = 0xFF000000;
433     systemColors[SystemColor.WINDOW_TEXT]             = 0xFF000000;
434     systemColors[SystemColor.MENU]                    = 0xFFC0C0C0;
435     systemColors[SystemColor.MENU_TEXT]               = 0xFF000000;
436     systemColors[SystemColor.TEXT]                    = 0xFFC0C0C0;
437     systemColors[SystemColor.TEXT_TEXT]               = 0xFF000000;
438     systemColors[SystemColor.TEXT_HIGHLIGHT]          = 0xFF000090;
439     systemColors[SystemColor.TEXT_HIGHLIGHT_TEXT]     = 0xFFFFFFFF;
440     systemColors[SystemColor.TEXT_INACTIVE_TEXT]      = 0xFF808080;
441     systemColors[SystemColor.CONTROL]                 = 0xFFC0C0C0;
442     systemColors[SystemColor.CONTROL_TEXT]            = 0xFF000000;
443     systemColors[SystemColor.CONTROL_HIGHLIGHT]       = 0xFFFFFFFF;
444     systemColors[SystemColor.CONTROL_LT_HIGHLIGHT]    = 0xFFE0E0E0;
445     systemColors[SystemColor.CONTROL_SHADOW]          = 0xFF808080;
446     systemColors[SystemColor.CONTROL_DK_SHADOW]       = 0xFF000000;
447     systemColors[SystemColor.SCROLLBAR]               = 0xFFE0E0E0;
448     systemColors[SystemColor.INFO]                    = 0xFFE0E000;
449     systemColors[SystemColor.INFO_TEXT]               = 0xFF000000;
450   }
451
452   /**
453    * @since 1.4
454    *
455    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
456    */
457   public void setDynamicLayout(boolean dynamic)
458   {
459   }
460
461   /**
462    * @since 1.4
463    *
464    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
465    */
466   protected boolean isDynamicLayoutSet()
467   {
468     return false;
469   }
470
471   /**
472    * @since 1.4
473    *
474    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
475    */
476   public boolean isDynamicLayoutActive()
477   {
478     return false;
479   }
480
481   /**
482    * Returns the dimensions of the screen in pixels.
483    *
484    * @return The dimensions of the screen in pixels.
485    * 
486    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
487    */
488   public abstract Dimension getScreenSize();
489
490   /**
491    * Returns the screen resolution in dots per square inch.
492    *
493    * @return The screen resolution in dots per square inch.
494    *
495    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
496    */
497   public abstract int getScreenResolution();
498
499   /**
500    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
501    *
502    * @since 1.4
503    */
504   public Insets getScreenInsets(GraphicsConfiguration gc)
505   {
506     return new Insets(0, 0, 0, 0);
507   }
508
509   /**
510    * Returns the color model of the screen.
511    *
512    * @return The color model of the screen.
513    * 
514    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
515    */
516   public abstract ColorModel getColorModel();
517
518   /**
519    * Returns the names of the available fonts.
520    *
521    * @return The names of the available fonts.
522    *
523    * @deprecated
524    */
525   public abstract String[] getFontList();
526
527   /**
528    * Return the font metrics for the specified font
529    *
530    * @param name The name of the font to return metrics for.
531    *
532    * @return The requested font metrics.
533    *
534    * @deprecated
535    */
536   public abstract FontMetrics getFontMetrics(Font name);
537
538   /**
539    * Flushes any buffered data to the screen so that it is in sync with
540    * what the AWT system has drawn to it.
541    */
542   public abstract void sync();
543
544   /**
545    * Returns an instance of the default toolkit.  The default toolkit is
546    * the subclass of <code>Toolkit</code> specified in the system property
547    * <code>awt.toolkit</code>, or <code>gnu.java.awt.peer.gtk.GtkToolkit</code>
548    * if the property is not set.
549    *
550    * @return An instance of the system default toolkit.
551    *
552    * @throws AWTError If the toolkit cannot be loaded.
553    */
554   public static synchronized Toolkit getDefaultToolkit()
555   {
556     if (toolkit != null)
557       return toolkit;
558
559     String toolkit_name = SystemProperties.getProperty("awt.toolkit",
560                                                        default_toolkit_name);
561     try
562       {
563         ClassLoader cl;
564         cl = (ClassLoader) AccessController.doPrivileged
565         (new PrivilegedAction()
566           {
567             public Object run()
568               {
569                 return ClassLoader.getSystemClassLoader();
570               }
571           });
572         Class cls = Class.forName(toolkit_name, true, cl);
573         Object obj = cls.newInstance();
574         if (!(obj instanceof Toolkit))
575           throw new AWTError(toolkit_name + " is not a subclass of " +
576                              "java.awt.Toolkit");
577         toolkit = (Toolkit) obj;
578
579         initAccessibility();
580         return toolkit;
581       }
582     catch (ThreadDeath death)
583       {
584         throw death;
585       }
586     catch (Throwable t)
587       {
588         // Check for the headless property.
589         if (GraphicsEnvironment.isHeadless())
590           {
591             toolkit = new HeadlessToolkit();
592             return toolkit;
593           }
594         else
595           {
596             AWTError e = new AWTError("Cannot load AWT toolkit: "
597                                       + toolkit_name);
598             throw (AWTError) e.initCause(t);
599           }
600       }
601   }
602
603   /**
604    * Returns an image from the specified file, which must be in a
605    * recognized format.  Supported formats vary from toolkit to toolkit.
606    *
607    * @return name The name of the file to read the image from.
608    */
609   public abstract Image getImage(String name);
610
611   /**
612    * Returns an image from the specified URL, which must be in a
613    * recognized format.  Supported formats vary from toolkit to toolkit.
614    *
615    * @return url The URl to read the image from.
616    */
617   public abstract Image getImage(URL url);
618
619   public abstract Image createImage(String filename);
620
621   public abstract Image createImage(URL url);
622
623   /**
624    * Readies an image to be rendered on the screen.  The width and height
625    * values can be set to the default sizes for the image by passing -1
626    * in those parameters.
627    *
628    * @param image The image to prepare for rendering.
629    * @param width The width of the image.
630    * @param height The height of the image.
631    * @param observer The observer to receive events about the preparation
632    * process.
633    *
634    * @return <code>true</code> if the image is already prepared for rendering,
635    * <code>false</code> otherwise.
636    */
637   public abstract boolean prepareImage(Image image, int width, int height,
638                                        ImageObserver observer);
639
640   /**
641    * Checks the status of specified image as it is being readied for
642    * rendering.
643    *
644    * @param image The image to prepare for rendering.
645    * @param width The width of the image.
646    * @param height The height of the image.
647    * @param observer The observer to receive events about the preparation
648    * process.
649    *
650    * @return A union of the bitmasks from
651    * <code>java.awt.image.ImageObserver</code> that indicates the current
652    * state of the imaging readying process.
653    */
654   public abstract int checkImage(Image image, int width, int height,
655                                  ImageObserver observer);
656
657   /**
658    * Creates an image using the specified <code>ImageProducer</code>
659    *
660    * @param producer The <code>ImageProducer</code> to create the image from.
661    *
662    * @return The created image.
663    */
664   public abstract Image createImage(ImageProducer producer);
665
666   /**
667    * Creates an image from the specified byte array. The array must be in
668    * a recognized format.  Supported formats vary from toolkit to toolkit.
669    *
670    * @param data The raw image data.
671    *
672    * @return The created image.
673    */
674   public Image createImage(byte[] data)
675   {
676     return createImage(data, 0, data.length);
677   }
678
679   /**
680    * Creates an image from the specified portion of the byte array passed.
681    * The array must be in a recognized format.  Supported formats vary from
682    * toolkit to toolkit.
683    *
684    * @param data The raw image data.
685    * @param offset The offset into the data where the image data starts.
686    * @param len The length of the image data.
687    *
688    * @return The created image.
689    */
690   public abstract Image createImage(byte[] data, int offset, int len);
691
692   /**
693    * Returns a instance of <code>PrintJob</code> for the specified
694    * arguments.
695    *
696    * @param frame The window initiating the print job.
697    * @param title The print job title.
698    * @param props The print job properties.
699    *
700    * @return The requested print job, or <code>null</code> if the job
701    * was cancelled.
702    *
703    * @exception NullPointerException If frame is null,
704    * or GraphicsEnvironment.isHeadless() returns true.
705    * @exception SecurityException If this thread is not allowed to initiate
706    * a print job request.
707    */
708   public abstract PrintJob getPrintJob(Frame frame, String title,
709                                        Properties props);
710
711   /**
712    * Returns a instance of <code>PrintJob</code> for the specified
713    * arguments.
714    *
715    * @param frame The window initiating the print job.
716    * @param title The print job title.
717    * @param jobAttr A set of job attributes which will control the print job.
718    * @param pageAttr A set of page attributes which will control the print job.
719    *
720    * @exception NullPointerException If frame is null, and either jobAttr is null
721    * or jobAttr.getDialog() returns JobAttributes.DialogType.NATIVE.
722    * @exception IllegalArgumentException If pageAttrspecifies differing cross
723    * feed and feed resolutions, or when GraphicsEnvironment.isHeadless() returns
724    * true.
725    * @exception SecurityException If this thread is not allowed to initiate
726    * a print job request.
727    *
728    * @since 1.3
729    */
730   public PrintJob getPrintJob(Frame frame, String title,
731                               JobAttributes jobAttr, PageAttributes pageAttr)
732   {
733     // FIXME: it is possible this check may be removed
734     // if this method, when written, always delegates to
735     // getPrintJob(Frame, String, Properties).
736     SecurityManager sm;
737     sm = System.getSecurityManager();
738     if (sm != null)
739       sm.checkPrintJobAccess();
740
741     return null;
742   }
743
744   /**
745    * Causes a "beep" tone to be generated.
746    */
747   public abstract void beep();
748
749   /**
750    * Returns the system clipboard.
751    *
752    * @return THe system clipboard.
753    *
754    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
755    */
756   public abstract Clipboard getSystemClipboard();
757
758   /**
759    * Gets the singleton instance of the system selection as a
760    * Clipboard object. The system selection contains the selected text
761    * of the last component/widget that had focus and a text selection.
762    * The default implementation returns null.
763    *
764    * @return The Clipboard holding the system (text) selection or null
765    * if the Toolkit or system doesn't support a selection clipboard.
766    *
767    * @exception HeadlessException If GraphicsEnvironment.isHeadless()
768    * is true.
769    * @exception SecurityException If the current security manager
770    * checkSystemClipboardAccess() doesn't allow access.
771    *
772    * @since 1.4
773    */
774   public Clipboard getSystemSelection()
775   {
776     return null;
777   }
778
779   /**
780    * Returns the accelerator key mask for menu shortcuts. The default is
781    * <code>Event.CTRL_MASK</code>.  A toolkit must override this method
782    * to change the default.
783    *
784    * @return The key mask for the menu accelerator key.
785    *
786    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
787    */
788   public int getMenuShortcutKeyMask()
789   {
790     return Event.CTRL_MASK;
791   }
792
793   /**
794    * Returns whether the given locking key on the keyboard is currently in its
795    * "on" state.
796    *
797    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
798    * @exception IllegalArgumentException If keyCode is not one of the valid keys.
799    * @exception UnsupportedOperationException If the host system doesn't allow
800    * getting the state of this key programmatically, or if the keyboard doesn't
801    * have this key.
802    */
803   public boolean getLockingKeyState(int keyCode)
804   {
805     if (keyCode != KeyEvent.VK_CAPS_LOCK
806         && keyCode != KeyEvent.VK_NUM_LOCK
807         && keyCode != KeyEvent.VK_SCROLL_LOCK)
808       throw new IllegalArgumentException();
809     
810     throw new UnsupportedOperationException();
811   }
812
813   /**
814    * Sets the state of the given locking key on the keyboard.
815    *
816    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
817    * @exception IllegalArgumentException If keyCode is not one of the valid keys.
818    * @exception UnsupportedOperationException If the host system doesn't allow
819    * getting the state of this key programmatically, or if the keyboard doesn't
820    * have this key.
821    */
822   public void setLockingKeyState(int keyCode, boolean on)
823   {
824     if (keyCode != KeyEvent.VK_CAPS_LOCK
825         && keyCode != KeyEvent.VK_NUM_LOCK
826         && keyCode != KeyEvent.VK_SCROLL_LOCK)
827       throw new IllegalArgumentException();
828     
829     throw new UnsupportedOperationException();
830   }
831
832   /**
833    * Returns the native container object of the specified component.  This
834    * method is necessary because the parent component might be a lightweight
835    * component.
836    *
837    * @param component The component to fetch the native container for.
838    *
839    * @return The native container object for this component.
840    */
841   protected static Container getNativeContainer(Component component)
842   {
843     component = component.getParent();
844     while (true)
845       {
846         if (component == null)
847           return null;
848         if (! (component instanceof Container))
849           {
850             component = component.getParent();
851             continue;
852           }
853         if (component.getPeer() instanceof LightweightPeer)
854           {
855             component = component.getParent();
856             continue;
857           }
858         return (Container) component;
859       }
860   }
861
862   /**
863    * Creates a new custom cursor object.
864    *
865    * @exception IndexOutOfBoundsException If the hotSpot values are outside
866    * the bounds of the cursor.
867    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
868    */
869   public Cursor createCustomCursor(Image cursor, Point hotSpot, String name)
870   {
871     // Presumably the only reason this isn't abstract is for backwards
872     // compatibility? FIXME?
873     if (GraphicsEnvironment.isHeadless())
874       throw new HeadlessException("No custom cursor in an headless graphics "
875                                   + "environment.");
876     return null;
877   }
878
879   /**
880    * Returns the supported cursor dimension which is closest to the
881    * desired sizes.
882    *
883    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
884    */
885   public Dimension getBestCursorSize(int preferredWidth, int preferredHeight)
886   {
887     if (GraphicsEnvironment.isHeadless())
888       throw new HeadlessException("No best cursor size in an headless "
889                                   + "graphics environment.");
890     return new Dimension (0,0);
891   }
892
893   /**
894    * Returns the maximum number of colors the Toolkit supports in a custom
895    * cursor palette.
896    *
897    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
898    */
899   public int getMaximumCursorColors()
900   {
901     return 0;
902   }
903
904   /**
905    * Returns whether Toolkit supports this state for Frames.
906    *
907    * @exception HeadlessException If GraphicsEnvironment.isHeadless() is true.
908    * 
909    * @since 1.4
910    */
911   public boolean isFrameStateSupported(int state)
912   {
913     return false;
914   }
915
916   /**
917    * Returns the value of the property with the specified name, or the
918    * default value if the property does not exist.
919    *
920    * @param key The name of the property to retrieve.
921    * @param def The default value of the property.
922    */
923   public static String getProperty(String key, String def)
924   {
925     return props.getProperty(key, def);
926   }
927
928
929   /**
930    * Returns the event queue that is suitable for the calling context.
931    *
932    * <p>Despite the word &#x201c;System&#x201d; in the name of this
933    * method, a toolkit may provide different event queues for each
934    * applet. There is no guarantee that the same queue is shared
935    * system-wide.
936    *
937    * <p>The implementation first checks whether a
938    * SecurityManager has been installed. If so, its {@link
939    * java.lang.SecurityManager#checkAwtEventQueueAccess()} method gets
940    * called. The security manager will throw a SecurityException if it
941    * does not grant the permission to access the event queue.
942    *
943    * <p>Next, the call is delegated to {@link
944    * #getSystemEventQueueImpl()}.
945    *
946    * @return The event queue for this applet (or application).
947    *
948    * @throws SecurityException if a security manager has been
949    * installed, and it does not grant the permission to access the
950    * event queue.
951    */
952   public final EventQueue getSystemEventQueue()
953   {
954     SecurityManager sm;
955
956     sm = System.getSecurityManager();
957     if (sm != null)
958       sm.checkAwtEventQueueAccess();
959
960     return getSystemEventQueueImpl();
961   }
962
963
964   /**
965    * Returns the event queue that is suitable for the calling context.
966    *
967    * <p>Despite the word &#x201c;System&#x201d; in the name of this
968    * method, a toolkit may provide different event queues for each
969    * applet. There is no guarantee that the same queue is shared
970    * system-wide.
971    *
972    * <p>No security checks are performed, which is why this method
973    * may only be called by Toolkits.
974    *
975    * @see #getSystemEventQueue()
976    */
977   protected abstract EventQueue getSystemEventQueueImpl();
978
979
980   /**
981    * @since 1.3
982    */
983   public abstract DragSourceContextPeer
984     createDragSourceContextPeer(DragGestureEvent e);
985
986   /**
987    * @since 1.3
988    */
989   public <T extends DragGestureRecognizer> T
990     createDragGestureRecognizer(Class<T> recognizer, DragSource ds,
991                                 Component comp, int actions,
992                                 DragGestureListener l)
993   {
994     return null;
995   }
996
997   public final Object getDesktopProperty(String propertyName)
998   {
999     return desktopProperties.get(propertyName);
1000   }
1001
1002   protected final void setDesktopProperty(String name, Object newValue)
1003   {
1004     Object oldValue = getDesktopProperty(name);
1005     desktopProperties.put(name, newValue);
1006     desktopPropsSupport.firePropertyChange(name, oldValue, newValue);
1007   }
1008
1009   protected Object lazilyLoadDesktopProperty(String name)
1010   {
1011     // FIXME - what is this??
1012     return null;
1013   }
1014
1015   protected void initializeDesktopProperties()
1016   {
1017     // Overridden by toolkit implementation?
1018   }
1019
1020   public void addPropertyChangeListener(String name,
1021                                         PropertyChangeListener pcl)
1022   {
1023     desktopPropsSupport.addPropertyChangeListener(name, pcl);
1024   }
1025
1026   public void removePropertyChangeListener(String name,
1027                                            PropertyChangeListener pcl)
1028   {
1029     desktopPropsSupport.removePropertyChangeListener(name, pcl);
1030   }
1031
1032   /**
1033    * @since 1.4
1034    */
1035   public PropertyChangeListener[] getPropertyChangeListeners()
1036   {
1037     return desktopPropsSupport.getPropertyChangeListeners();
1038   }
1039
1040   /**
1041    * @since 1.4
1042    */
1043   public PropertyChangeListener[] getPropertyChangeListeners(String name)
1044   {
1045     return desktopPropsSupport.getPropertyChangeListeners(name);
1046   }
1047
1048   /**
1049    * Adds an AWTEventListener to this toolkit. This listener is informed about
1050    * all events that pass the eventqueue that match the specified
1051    * <code>evenMask</code>. The <code>eventMask</code> is an ORed combination
1052    * of event masks as defined in {@link AWTEvent}.
1053    *
1054    * If a security manager is installed, it is asked first if an
1055    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1056    * This may result in a <code>SecurityException</code> beeing thrown.
1057    *
1058    * It is not recommended to use this kind of notification for normal
1059    * applications. It is intended solely for the purpose of debugging and to
1060    * support special facilities.
1061    *
1062    * @param listener the listener to add
1063    * @param eventMask the event mask of event types which the listener is
1064    *        interested in
1065    *
1066    * @since 1.2
1067    *
1068    * @throws SecurityException if there is a <code>SecurityManager</code> that
1069    *         doesn't grant
1070    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1071    *
1072    * @see #getAWTEventListeners()
1073    * @see #getAWTEventListeners(long)
1074    * @see #removeAWTEventListener(AWTEventListener)
1075    */
1076   public void addAWTEventListener(AWTEventListener listener, long eventMask)
1077   {
1078     // First we must check the security permissions.
1079     SecurityManager s = System.getSecurityManager();
1080     if (s != null)
1081       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1082
1083     // Go through the list and check if the requested listener is already
1084     // registered.
1085     boolean found = false;
1086     for (int i = 0; i < awtEventListeners.length; ++i)
1087       {
1088         AWTEventListenerProxy proxy = awtEventListeners[i];
1089         if (proxy.getListener() == listener)
1090           {
1091             found = true;
1092             // Modify the proxies event mask to include the new event mask.
1093             AWTEventListenerProxy newProxy =
1094               new AWTEventListenerProxy(proxy.getEventMask() | eventMask,
1095                                         listener);
1096             awtEventListeners[i] = newProxy;
1097             break;
1098           }
1099       }
1100
1101     // If that listener was not found, then add it.
1102     if (! found)
1103       {
1104         AWTEventListenerProxy proxy =
1105           new AWTEventListenerProxy(eventMask, listener);
1106         AWTEventListenerProxy[] newArray =
1107           new AWTEventListenerProxy[awtEventListeners.length + 1];
1108         System.arraycopy(awtEventListeners, 0, newArray, 0,
1109                          awtEventListeners.length);
1110         newArray[newArray.length - 1] = proxy;
1111         awtEventListeners = newArray;
1112       }
1113   }
1114
1115   /**
1116    * Removes an AWT event listener from this toolkit. This listener is no
1117    * longer informed of any event types it was registered in.
1118    *
1119    * If a security manager is installed, it is asked first if an
1120    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1121    * This may result in a <code>SecurityException</code> beeing thrown.
1122    *
1123    * It is not recommended to use this kind of notification for normal
1124    * applications. It is intended solely for the purpose of debugging and to
1125    * support special facilities.
1126    *
1127    * @param listener the listener to remove
1128    *
1129    * @throws SecurityException if there is a <code>SecurityManager</code> that
1130    *         doesn't grant
1131    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1132    *
1133    * @since 1.2
1134    *
1135    * @see #addAWTEventListener(AWTEventListener, long)
1136    * @see #getAWTEventListeners()
1137    * @see #getAWTEventListeners(long)
1138    */
1139   public void removeAWTEventListener(AWTEventListener listener)
1140   {
1141     // First we must check the security permissions.
1142     SecurityManager s = System.getSecurityManager();
1143     if (s != null)
1144       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1145
1146
1147     // Find the index of the listener.
1148     int index = -1;
1149     for (int i = 0; i < awtEventListeners.length; ++i)
1150       {
1151         AWTEventListenerProxy proxy = awtEventListeners[i];
1152         if (proxy.getListener() == listener)
1153           {
1154             index = i;
1155             break;
1156           }
1157       }
1158
1159     // Copy over the arrays and leave out the removed element.
1160     if (index != -1)
1161       {
1162         AWTEventListenerProxy[] newArray =
1163           new AWTEventListenerProxy[awtEventListeners.length - 1];
1164         if (index > 0)
1165           System.arraycopy(awtEventListeners, 0, newArray, 0, index);
1166         if (index < awtEventListeners.length - 1)
1167           System.arraycopy(awtEventListeners, index + 1, newArray, index,
1168                            awtEventListeners.length - index - 1);
1169         awtEventListeners = newArray;
1170       }
1171   }
1172
1173   /**
1174    * Returns all registered AWT event listeners. This method returns a copy of
1175    * the listener array, so that application cannot trash the listener list.
1176    *
1177    * If a security manager is installed, it is asked first if an
1178    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1179    * This may result in a <code>SecurityException</code> beeing thrown.
1180    *
1181    * It is not recommended to use this kind of notification for normal
1182    * applications. It is intended solely for the purpose of debugging and to
1183    * support special facilities.
1184    *
1185    * @return all registered AWT event listeners
1186    *
1187    * @throws SecurityException if there is a <code>SecurityManager</code> that
1188    *         doesn't grant
1189    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1190    *
1191    * @since 1.4
1192    *
1193    * @see #addAWTEventListener(AWTEventListener, long)
1194    * @see #removeAWTEventListener(AWTEventListener)
1195    * @see #getAWTEventListeners(long)
1196    */
1197   public AWTEventListener[] getAWTEventListeners()
1198   {
1199     // First we must check the security permissions.
1200     SecurityManager s = System.getSecurityManager();
1201     if (s != null)
1202       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1203
1204     // Create a copy of the array.
1205     AWTEventListener[] copy = new AWTEventListener[awtEventListeners.length];
1206     System.arraycopy(awtEventListeners, 0, copy, 0, awtEventListeners.length);
1207     return copy;
1208   }
1209
1210   /**
1211    * Returns all registered AWT event listeners that listen for events with
1212    * the specified <code>eventMask</code>. This method returns a copy of
1213    * the listener array, so that application cannot trash the listener list.
1214    *
1215    * If a security manager is installed, it is asked first if an
1216    * <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code> is allowed.
1217    * This may result in a <code>SecurityException</code> beeing thrown.
1218    *
1219    * It is not recommended to use this kind of notification for normal
1220    * applications. It is intended solely for the purpose of debugging and to
1221    * support special facilities.
1222    *
1223    * @param mask the event mask
1224    *
1225    * @throws SecurityException if there is a <code>SecurityManager</code> that
1226    *         doesn't grant
1227    *         <code>AWTPermission(&quot;listenToAllAWTEvents&quot;)</code>
1228    *
1229    *
1230    * @since 1.4
1231    *
1232    * @see #addAWTEventListener(AWTEventListener, long)
1233    * @see #removeAWTEventListener(AWTEventListener)
1234    * @see #getAWTEventListeners()
1235    */
1236   public AWTEventListener[] getAWTEventListeners(long mask)
1237   {
1238     // First we must check the security permissions.
1239     SecurityManager s = System.getSecurityManager();
1240     if (s != null)
1241       s.checkPermission(new AWTPermission("listenToAllAWTEvents"));
1242
1243     // Create a copy of the array with only the requested listeners in it.
1244     ArrayList l = new ArrayList(awtEventListeners.length);
1245     for (int i = 0; i < awtEventListeners.length; ++i)
1246       {
1247         if ((awtEventListeners[i].getEventMask() & mask) != 0)
1248           l.add(awtEventListeners[i]);
1249       }
1250
1251     return (AWTEventListener[] ) l.toArray(new AWTEventListener[l.size()]);
1252   }
1253
1254
1255   /**
1256    * Dispatches events to listeners registered to this Toolkit. This is called
1257    * by {@link Component#dispatchEventImpl(AWTEvent)} in order to dispatch
1258    * events globally.
1259    *
1260    * @param ev the event to dispatch
1261    */
1262   void globalDispatchEvent(AWTEvent ev)
1263   {
1264     // We do not use the accessor methods here because they create new
1265     // arrays each time. We must be very efficient, so we access this directly.
1266     for (int i = 0; i < awtEventListeners.length; ++i)
1267       {
1268         AWTEventListenerProxy proxy = awtEventListeners[i];
1269         if ((proxy.getEventMask() & AWTEvent.eventIdToMask(ev.getID())) != 0)
1270           proxy.eventDispatched(ev);
1271       }
1272   }
1273
1274   /**
1275    * @since 1.3
1276    */
1277   public abstract Map<TextAttribute,?>
1278     mapInputMethodHighlight(InputMethodHighlight highlight);
1279
1280   /**
1281    * Initializes the accessibility framework. In particular, this loads the
1282    * properties javax.accessibility.screen_magnifier_present and
1283    * javax.accessibility.screen_reader_present and loads
1284    * the classes specified in javax.accessibility.assistive_technologies.
1285    */
1286   private static void initAccessibility()
1287   {
1288     AccessController.doPrivileged
1289     (new PrivilegedAction()
1290      {
1291        public Object run()
1292        {
1293          Properties props = new Properties();
1294          String sep = File.separator;
1295
1296          // Try the user configuration.
1297          try
1298            {
1299              File propsFile = new File(System.getProperty("user.home") + sep
1300                                        + ".accessibility.properties");
1301              FileInputStream in = new FileInputStream(propsFile);
1302              props.load(in);
1303              in.close();
1304            }
1305          catch (Exception ex)
1306            {
1307              // User configuration not present, ignore.
1308            }
1309
1310          // Try the system configuration if there was no user configuration.
1311          if (props.size() == 0)
1312            {
1313              try
1314                {
1315                  File propsFile =
1316                    new File(System.getProperty("gnu.classpath.home.url")
1317                             + sep + "accessibility.properties");
1318                  FileInputStream in = new FileInputStream(propsFile);
1319                  props.load(in);
1320                  in.close();
1321                }
1322              catch (Exception ex)
1323                {
1324                  // System configuration not present, ignore.
1325                }
1326            }
1327
1328        // Fetch the screen_magnifier_present property. Check systen properties
1329        // first, then fallback to the configuration file.
1330        String magPresent = SystemProperties.getProperty
1331                               ("javax.accessibility.screen_magnifier_present");
1332        if (magPresent == null)
1333          {
1334            magPresent = props.getProperty("screen_magnifier_present");
1335            if (magPresent != null)
1336              {
1337                SystemProperties.setProperty
1338                  ("javax.accessibility.screen_magnifier_present", magPresent);
1339              }
1340          }
1341
1342        // Fetch the screen_reader_present property. Check systen properties
1343        // first, then fallback to the configuration file.
1344        String readerPresent = SystemProperties.getProperty
1345                                 ("javax.accessibility.screen_reader_present");
1346        if (readerPresent == null)
1347          {
1348            readerPresent = props.getProperty("screen_reader_present");
1349            if (readerPresent != null)
1350              {
1351                SystemProperties.setProperty
1352                  ("javax.accessibility.screen_reader_present", readerPresent);
1353              }
1354          }
1355
1356        // Fetch the list of classes to be loaded.
1357        String classes = SystemProperties.getProperty
1358          ("javax.accessibility.assistive_technologies");
1359        if (classes == null)
1360          {
1361            classes = props.getProperty("assistive_technologies");
1362            if (classes != null)
1363              {
1364                SystemProperties.setProperty
1365                ("javax.accessibility.assistive_technologies", classes);
1366              }
1367          }
1368
1369        // Try to load the assisitive_technologies classes.
1370        if (classes != null)
1371          {
1372            ClassLoader cl = ClassLoader.getSystemClassLoader();
1373            StringTokenizer tokenizer = new StringTokenizer(classes, ",");
1374            while (tokenizer.hasMoreTokens())
1375              {
1376                String className = tokenizer.nextToken();
1377                try
1378                  {
1379                    Class atClass = cl.loadClass(className);
1380                    atClass.newInstance();
1381                  }
1382                catch (ClassNotFoundException ex)
1383                  {
1384                    AWTError err = new AWTError("Assistive Technology class not"
1385                                                + " found: " + className);
1386                    err.initCause(ex);
1387                    throw err;
1388                  }
1389                catch (InstantiationException ex)
1390                  {
1391                    AWTError err =
1392                      new AWTError("Assistive Technology class cannot be "
1393                                   + "instantiated: " + className);
1394                    err.initCause(ex);
1395                    throw err;
1396                  }
1397                catch (IllegalAccessException ex)
1398                  {
1399                    AWTError err =
1400                      new AWTError("Assistive Technology class cannot be "
1401                                   + "accessed: " + className);
1402                    err.initCause(err);
1403                    throw err;
1404                  }
1405              }
1406          }
1407        return null;
1408        }
1409      });
1410
1411   }
1412
1413 } // class Toolkit