OSDN Git Service

2006-08-14 Mark Wielaard <mark@klomp.org>
[pf3gnuchains/gcc-fork.git] / libjava / classpath / gnu / java / awt / peer / x / XToolkit.java
1 /* XToolkit.java -- The central AWT Toolkit for the X peers
2    Copyright (C) 2006 Free Software Foundation, Inc.
3
4 This file is part of GNU Classpath.
5
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37
38
39 package gnu.java.awt.peer.x;
40
41 import java.awt.AWTException;
42 import java.awt.Button;
43 import java.awt.Canvas;
44 import java.awt.Checkbox;
45 import java.awt.CheckboxMenuItem;
46 import java.awt.Choice;
47 import java.awt.Component;
48 import java.awt.Dialog;
49 import java.awt.Dimension;
50 import java.awt.EventQueue;
51 import java.awt.FileDialog;
52 import java.awt.Font;
53 import java.awt.FontMetrics;
54 import java.awt.Frame;
55 import java.awt.GraphicsDevice;
56 import java.awt.GraphicsEnvironment;
57 import java.awt.Image;
58 import java.awt.Label;
59 import java.awt.List;
60 import java.awt.Menu;
61 import java.awt.MenuBar;
62 import java.awt.MenuItem;
63 import java.awt.Panel;
64 import java.awt.PopupMenu;
65 import java.awt.PrintJob;
66 import java.awt.ScrollPane;
67 import java.awt.Scrollbar;
68 import java.awt.TextArea;
69 import java.awt.TextField;
70 import java.awt.Transparency;
71 import java.awt.Window;
72 import java.awt.datatransfer.Clipboard;
73 import java.awt.dnd.DragGestureEvent;
74 import java.awt.dnd.peer.DragSourceContextPeer;
75 import java.awt.im.InputMethodHighlight;
76 import java.awt.image.BufferedImage;
77 import java.awt.image.ColorModel;
78 import java.awt.image.DirectColorModel;
79 import java.awt.image.ImageObserver;
80 import java.awt.image.ImageProducer;
81 import java.awt.peer.ButtonPeer;
82 import java.awt.peer.CanvasPeer;
83 import java.awt.peer.CheckboxMenuItemPeer;
84 import java.awt.peer.CheckboxPeer;
85 import java.awt.peer.ChoicePeer;
86 import java.awt.peer.DialogPeer;
87 import java.awt.peer.FileDialogPeer;
88 import java.awt.peer.FontPeer;
89 import java.awt.peer.FramePeer;
90 import java.awt.peer.LabelPeer;
91 import java.awt.peer.LightweightPeer;
92 import java.awt.peer.ListPeer;
93 import java.awt.peer.MenuBarPeer;
94 import java.awt.peer.MenuItemPeer;
95 import java.awt.peer.MenuPeer;
96 import java.awt.peer.PanelPeer;
97 import java.awt.peer.PopupMenuPeer;
98 import java.awt.peer.RobotPeer;
99 import java.awt.peer.ScrollPanePeer;
100 import java.awt.peer.ScrollbarPeer;
101 import java.awt.peer.TextAreaPeer;
102 import java.awt.peer.TextFieldPeer;
103 import java.awt.peer.WindowPeer;
104 import java.io.ByteArrayInputStream;
105 import java.io.File;
106 import java.io.IOException;
107 import java.io.InputStream;
108 import java.net.MalformedURLException;
109 import java.net.URL;
110 import java.util.HashMap;
111 import java.util.Map;
112 import java.util.Properties;
113 import java.util.WeakHashMap;
114
115 import javax.imageio.ImageIO;
116
117 import gnu.classpath.SystemProperties;
118 import gnu.java.awt.ClasspathToolkit;
119 import gnu.java.awt.EmbeddedWindow;
120 import gnu.java.awt.peer.ClasspathFontPeer;
121 import gnu.java.awt.peer.EmbeddedWindowPeer;
122 import gnu.java.awt.peer.swing.SwingCanvasPeer;
123 import gnu.java.awt.peer.swing.SwingLabelPeer;
124 import gnu.java.awt.peer.swing.SwingPanelPeer;
125
126 public class XToolkit
127   extends ClasspathToolkit
128 {
129
130   /**
131    * Set to true to enable debug output.
132    */
133   static boolean DEBUG = false;
134
135   /**
136    * Maps AWT colors to X colors.
137    */
138   HashMap colorMap = new HashMap();
139
140   /**
141    * The system event queue.
142    */
143   private EventQueue eventQueue;
144
145   /**
146    * The default color model of this toolkit.
147    */
148   private ColorModel colorModel;
149
150   /**
151    * Maps image URLs to Image instances.
152    */
153   private HashMap imageCache = new HashMap();
154
155   /**
156    * The cached fonts.
157    */
158   private WeakHashMap fontCache = new WeakHashMap();
159
160   public XToolkit()
161   {
162     SystemProperties.setProperty("gnu.javax.swing.noGraphics2D", "true");
163     SystemProperties.setProperty("java.awt.graphicsenv",
164                                  "gnu.java.awt.peer.x.XGraphicsEnvironment");
165   }
166
167   public GraphicsEnvironment getLocalGraphicsEnvironment()
168   {
169     return new XGraphicsEnvironment();
170   }
171
172   /**
173    * Returns the font peer for a font with the specified name and attributes.
174    *
175    * @param name the font name
176    * @param attrs the font attributes
177    *
178    * @return the font peer for a font with the specified name and attributes
179    */
180   public ClasspathFontPeer getClasspathFontPeer(String name, Map attrs)
181   {
182     String canonical = XFontPeer.encodeFont(name, attrs);
183     ClasspathFontPeer font;
184     if (!fontCache.containsKey(canonical))
185       {
186         String graphics2d =
187           SystemProperties.getProperty("gnu.xawt.graphics2d");
188         if (graphics2d != null && graphics2d.equals("gl"))
189           font = new XFontPeer2(name, attrs);
190         else
191           font = new XFontPeer(name, attrs);
192         fontCache.put(canonical, font);
193       }
194     else
195       {
196         font = (ClasspathFontPeer) fontCache.get(canonical);
197       }
198     return font;
199   }
200
201   public Font createFont(int format, InputStream stream)
202   {
203     return null;
204   }
205
206   public RobotPeer createRobot(GraphicsDevice screen) throws AWTException
207   {
208     // TODO: Implement this.
209     throw new UnsupportedOperationException("Not yet implemented.");
210   }
211
212   public EmbeddedWindowPeer createEmbeddedWindow(EmbeddedWindow w)
213   {
214     // TODO: Implement this.
215     throw new UnsupportedOperationException("Not yet implemented.");
216   }
217
218   protected ButtonPeer createButton(Button target)
219   {
220     // TODO: Implement this.
221     throw new UnsupportedOperationException("Not yet implemented.");
222   }
223
224   protected TextFieldPeer createTextField(TextField target)
225   {
226     // TODO: Implement this.
227     throw new UnsupportedOperationException("Not yet implemented.");
228   }
229
230   protected LabelPeer createLabel(Label target)
231   {
232     return new SwingLabelPeer(target);
233   }
234
235   protected ListPeer createList(List target)
236   {
237     // TODO: Implement this.
238     throw new UnsupportedOperationException("Not yet implemented.");
239   }
240
241   protected CheckboxPeer createCheckbox(Checkbox target)
242   {
243     // TODO: Implement this.
244     throw new UnsupportedOperationException("Not yet implemented.");
245   }
246
247   protected ScrollbarPeer createScrollbar(Scrollbar target)
248   {
249     // TODO: Implement this.
250     throw new UnsupportedOperationException("Not yet implemented.");
251   }
252
253   protected ScrollPanePeer createScrollPane(ScrollPane target)
254   {
255     // TODO: Implement this.
256     throw new UnsupportedOperationException("Not yet implemented.");
257   }
258
259   protected TextAreaPeer createTextArea(TextArea target)
260   {
261     // TODO: Implement this.
262     throw new UnsupportedOperationException("Not yet implemented.");
263   }
264
265   protected ChoicePeer createChoice(Choice target)
266   {
267     // TODO: Implement this.
268     throw new UnsupportedOperationException("Not yet implemented.");
269   }
270
271   protected FramePeer createFrame(Frame target)
272   {
273     XFramePeer frame = new XFramePeer(target);
274     return frame;
275   }
276
277   protected CanvasPeer createCanvas(Canvas target)
278   {
279     return new SwingCanvasPeer(target);
280   }
281
282   protected PanelPeer createPanel(Panel target)
283   {
284     return new SwingPanelPeer(target);
285   }
286
287   protected WindowPeer createWindow(Window target)
288   {
289     return new XWindowPeer(target);
290   }
291
292   protected DialogPeer createDialog(Dialog target)
293   {
294     return new XDialogPeer(target);
295   }
296
297   protected MenuBarPeer createMenuBar(MenuBar target)
298   {
299     // TODO: Implement this.
300     throw new UnsupportedOperationException("Not yet implemented.");
301   }
302
303   protected MenuPeer createMenu(Menu target)
304   {
305     // TODO: Implement this.
306     throw new UnsupportedOperationException("Not yet implemented.");
307   }
308
309   protected PopupMenuPeer createPopupMenu(PopupMenu target)
310   {
311     // TODO: Implement this.
312     throw new UnsupportedOperationException("Not yet implemented.");
313   }
314
315   protected MenuItemPeer createMenuItem(MenuItem target)
316   {
317     // TODO: Implement this.
318     throw new UnsupportedOperationException("Not yet implemented.");
319   }
320
321   protected FileDialogPeer createFileDialog(FileDialog target)
322   {
323     // TODO: Implement this.
324     throw new UnsupportedOperationException("Not yet implemented.");
325   }
326
327   protected CheckboxMenuItemPeer createCheckboxMenuItem(CheckboxMenuItem target)
328   {
329     // TODO: Implement this.
330     throw new UnsupportedOperationException("Not yet implemented.");
331   }
332
333   protected FontPeer getFontPeer(String name, int style)
334   {
335     // TODO: Implement this.
336     throw new UnsupportedOperationException("Not yet implemented.");
337   }
338
339   public Dimension getScreenSize()
340   {
341     // FIXME: This is only a hack to get some apps working.
342     return new Dimension(1024, 768);
343   }
344
345   public int getScreenResolution()
346   {
347     // TODO: Implement this.
348     throw new UnsupportedOperationException("Not yet implemented.");
349   }
350
351   /**
352    * Returns the color model used by this toolkit.
353    *
354    * @return the color model used by this toolkit
355    */
356   public ColorModel getColorModel()
357   {
358     // TODO: I assume 24 bit depth here, we can do this better.
359     if (colorModel == null)
360       colorModel = new DirectColorModel(24, 0xFF0000, 0xFF00, 0xFF);
361     return colorModel;
362   }
363
364   public String[] getFontList()
365   {
366     // TODO: Implement this.
367     throw new UnsupportedOperationException("Not yet implemented.");
368   }
369
370   public FontMetrics getFontMetrics(Font name)
371   {
372     ClasspathFontPeer peer = (ClasspathFontPeer) name.getPeer();
373     return peer.getFontMetrics(name);
374   }
375
376   public void sync()
377   {
378     // TODO: Implement this.
379     throw new UnsupportedOperationException("Not yet implemented.");
380   }
381
382   /**
383    * Returns an image that has its pixel data loaded from a file with the
384    * specified name. If that file doesn't exist, an empty or error image
385    * is returned instead.
386    *
387    * @param name the filename of the file that contains the pixel data
388    *
389    * @return the image
390    */
391   public Image getImage(String name)
392   {
393     Image image;
394     try
395       {
396         File file = new File(name);
397         image = getImage(file.toURL());
398       }
399     catch (MalformedURLException ex)
400       {
401         // TODO: Replace by a more meaningful error image instead.
402         image = null;
403       }
404     return image;
405   }
406
407   /**
408    * Returns an image that has its pixel data loaded from the specified URL.
409    * If the image cannot be loaded for some reason, an empty or error image
410    * is returned instead.
411    *
412    * @param url the URL to the image data
413    *
414    * @return the image
415    */
416   public Image getImage(URL url)
417   {
418     Image image;
419     if (imageCache.containsKey(url))
420       {
421         image = (Image) imageCache.get(url);
422       }
423     else
424       {
425         image = createImage(url);
426         imageCache.put(url, image);
427       }
428     return image;
429   }
430
431   /**
432    * Returns an image that has its pixel data loaded from a file with the
433    * specified name. If that file doesn't exist, an empty or error image
434    * is returned instead.
435    *
436    * @param filename the filename of the file that contains the pixel data
437    *
438    * @return the image
439    */
440   public Image createImage(String filename)
441   {
442     Image im;
443     try
444       {
445         File file = new File(filename);
446         URL url = file.toURL();
447         im = createImage(url);
448       }
449     catch (MalformedURLException ex)
450       {
451         im = createErrorImage();
452       }
453     return im;
454   }
455
456   /**
457    * Returns an image that has its pixel data loaded from the specified URL.
458    * If the image cannot be loaded for some reason, an empty or error image
459    * is returned instead.
460    *
461    * @param url the URL to the image data
462    *
463    * @return the image
464    */
465   public Image createImage(URL url)
466   {
467     Image image;
468     try
469       {
470         image = createImage(url.openStream());
471       }
472     catch (IOException ex)
473       {
474         image = createErrorImage();
475       }
476     return image;
477   }
478
479   /**
480    * Creates an image that is returned when calls to createImage() yields an
481    * error.
482    * 
483    * @return an image that is returned when calls to createImage() yields an
484    *         error
485    */
486   private Image createErrorImage()
487   {
488     // TODO: Create better error image.
489     return new XImage(1, 1);
490   }
491
492   public boolean prepareImage(Image image, int width, int height, ImageObserver observer)
493   {
494     // Images are loaded synchronously, so we don't bother and return true.
495     return true;
496   }
497
498   public int checkImage(Image image, int width, int height, ImageObserver observer)
499   {
500     // TODO: Implement this.
501     throw new UnsupportedOperationException("Not yet implemented.");
502   }
503
504   public Image createImage(ImageProducer producer)
505   {
506     ImageConverter conv = new ImageConverter();
507     producer.startProduction(conv);
508     Image image = conv.getXImage();
509     return image;
510   }
511
512   public Image createImage(byte[] data, int offset, int len)
513   {
514     Image image;
515     try
516       {
517         ByteArrayInputStream i = new ByteArrayInputStream(data, offset, len);
518         image = createImage(i);
519       }
520     catch (IOException ex)
521       {
522         image = createErrorImage();
523       }
524     return image;
525   }
526
527   private Image createImage(InputStream i)
528     throws IOException
529   {
530     Image image;
531     BufferedImage buffered = ImageIO.read(i);
532     // If the bufferedimage is opaque, then we can copy it over to an
533     // X Pixmap for faster drawing.
534     if (buffered != null && buffered.getTransparency() == Transparency.OPAQUE)
535       {
536         ImageProducer source = buffered.getSource();
537         image = createImage(source);
538       }
539     else if (buffered != null)
540       {
541         image = buffered;
542       }
543     else
544       {
545         image = createErrorImage();
546       }
547     return image;
548   }
549
550   public PrintJob getPrintJob(Frame frame, String title, Properties props)
551   {
552     // TODO: Implement this.
553     throw new UnsupportedOperationException("Not yet implemented.");
554   }
555
556   public void beep()
557   {
558     // TODO: Implement this.
559     throw new UnsupportedOperationException("Not yet implemented.");
560   }
561
562   public Clipboard getSystemClipboard()
563   {
564     // TODO: Implement this.
565     throw new UnsupportedOperationException("Not yet implemented.");
566   }
567
568   /**
569    * Returns the eventqueue used by the XLib peers.
570    *
571    * @return the eventqueue used by the XLib peers
572    */
573   protected EventQueue getSystemEventQueueImpl()
574   {
575     if (eventQueue == null)
576       eventQueue = new EventQueue();
577     return eventQueue;
578   }
579
580   public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e)
581   {
582     // TODO: Implement this.
583     throw new UnsupportedOperationException("Not yet implemented.");
584   }
585
586   public Map mapInputMethodHighlight(InputMethodHighlight highlight)
587   {
588     // TODO: Implement this.
589     throw new UnsupportedOperationException("Not yet implemented.");
590   }
591
592   /**
593    * Helper method to quickly fetch the default device (X Display).
594    *
595    * @return the default XGraphicsDevice
596    */
597   static XGraphicsDevice getDefaultDevice()
598   {
599     XGraphicsEnvironment env = (XGraphicsEnvironment)
600       XGraphicsEnvironment.getLocalGraphicsEnvironment();
601     return (XGraphicsDevice) env.getDefaultScreenDevice();
602   }
603
604   protected LightweightPeer createComponent(Component c)
605   {
606     return new XLightweightPeer(c);
607   }
608 }