Imported GNU Classpath 0.90
[official-gcc.git] / libjava / classpath / gnu / java / awt / peer / gtk / GtkToolkit.java
blob70e25a31957934be5b03d94f6477898a597d447e
1 /* GtkToolkit.java -- Implements an AWT Toolkit using GTK for peers
2 Copyright (C) 1998, 1999, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
5 This file is part of GNU Classpath.
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.
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.
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.
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.
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. */
40 package gnu.java.awt.peer.gtk;
42 import gnu.classpath.Configuration;
43 import gnu.java.awt.EmbeddedWindow;
44 import gnu.java.awt.peer.ClasspathFontPeer;
45 import gnu.java.awt.peer.ClasspathTextLayoutPeer;
46 import gnu.java.awt.peer.EmbeddedWindowPeer;
48 import java.awt.*;
49 import java.awt.datatransfer.Clipboard;
50 import java.awt.dnd.DragGestureEvent;
51 import java.awt.dnd.peer.DragSourceContextPeer;
52 import java.awt.font.FontRenderContext;
53 import java.awt.im.InputMethodHighlight;
54 import java.awt.image.BufferedImage;
55 import java.awt.image.ColorModel;
56 import java.awt.image.DirectColorModel;
57 import java.awt.image.ImageConsumer;
58 import java.awt.image.ImageObserver;
59 import java.awt.image.ImageProducer;
60 import java.awt.peer.*;
61 import java.io.InputStream;
62 import java.net.URL;
63 import java.text.AttributedString;
64 import java.util.HashMap;
65 import java.util.HashSet;
66 import java.util.Hashtable;
67 import java.util.Iterator;
68 import java.util.LinkedHashMap;
69 import java.util.Map;
70 import java.util.Properties;
72 import javax.imageio.spi.IIORegistry;
74 /* This class uses a deprecated method java.awt.peer.ComponentPeer.getPeer().
75 This merits comment. We are basically calling Sun's bluff on this one.
76 We think Sun has deprecated it simply to discourage its use as it is
77 bad programming style. However, we need to get at a component's peer in
78 this class. If getPeer() ever goes away, we can implement a hash table
79 that will keep up with every window's peer, but for now this is faster. */
81 /**
82 * This class accesses a system property called
83 * <tt>gnu.java.awt.peer.gtk.Graphics</tt>. If the property is defined and
84 * equal to "Graphics2D", the cairo-based GdkGraphics2D will be used in
85 * drawing contexts. Any other value will cause the older GdkGraphics
86 * object to be used.
88 public class GtkToolkit extends gnu.java.awt.ClasspathToolkit
90 Hashtable containers = new Hashtable();
91 static EventQueue q;
92 static boolean useGraphics2dSet;
93 static boolean useGraphics2d;
94 static Thread mainThread;
96 public static boolean useGraphics2D()
98 if (useGraphics2dSet)
99 return useGraphics2d;
100 useGraphics2d = System.getProperty("gnu.java.awt.peer.gtk.Graphics",
101 "Graphics").equals("Graphics2D");
102 useGraphics2dSet = true;
103 return useGraphics2d;
106 static native void gtkInit(int portableNativeSync);
108 static
110 if (Configuration.INIT_LOAD_LIBRARY)
111 System.loadLibrary("gtkpeer");
113 int portableNativeSync;
114 String portNatSyncProp =
115 System.getProperty("gnu.classpath.awt.gtk.portable.native.sync");
117 if (portNatSyncProp == null)
118 portableNativeSync = -1; // unset
119 else if (Boolean.valueOf(portNatSyncProp).booleanValue())
120 portableNativeSync = 1; // true
121 else
122 portableNativeSync = 0; // false
124 gtkInit(portableNativeSync);
126 mainThread = new Thread ("GTK main thread")
128 public void run ()
130 gtkMain ();
133 mainThread.start ();
136 public GtkToolkit ()
140 public native void beep();
141 private native void getScreenSizeDimensions(int[] xy);
143 public int checkImage (Image image, int width, int height,
144 ImageObserver observer)
146 int status = ImageObserver.ALLBITS
147 | ImageObserver.WIDTH
148 | ImageObserver.HEIGHT;
150 if (image instanceof GtkImage)
151 return ((GtkImage) image).checkImage (observer);
153 if (observer != null)
154 observer.imageUpdate (image, status,
155 -1, -1,
156 image.getWidth (observer),
157 image.getHeight (observer));
159 return status;
162 /**
163 * Helper to return either a Image -- the argument -- or a
164 * GtkImage with the errorLoading flag set if the argument is null.
166 private Image imageOrError(Image b)
168 if (b == null)
169 return GtkImage.getErrorImage();
170 else
171 return b;
174 public Image createImage (String filename)
176 if (filename.length() == 0)
177 return new GtkImage ();
179 Image image;
182 if (useGraphics2D())
183 image = GdkPixbufDecoder.createBufferedImage(filename);
184 else
185 image = new GtkImage(filename);
187 catch (IllegalArgumentException iae)
189 image = null;
191 return imageOrError(image);
194 public Image createImage (URL url)
196 Image image;
199 if (useGraphics2D())
200 image = GdkPixbufDecoder.createBufferedImage(url);
201 else
202 image = new GtkImage(url);
204 catch (IllegalArgumentException iae)
206 image = null;
208 return imageOrError(image);
211 public Image createImage (ImageProducer producer)
213 Image image;
216 if (useGraphics2D())
217 image = GdkPixbufDecoder.createBufferedImage(producer);
218 else
219 image = new GtkImage(producer);
221 catch (IllegalArgumentException iae)
223 image = null;
225 return imageOrError(image);
228 public Image createImage (byte[] imagedata, int imageoffset,
229 int imagelength)
231 Image image;
234 if (useGraphics2D())
235 image = GdkPixbufDecoder.createBufferedImage(imagedata,
236 imageoffset,
237 imagelength);
238 else
240 byte[] datacopy = new byte[imagelength];
241 System.arraycopy(imagedata, imageoffset, datacopy, 0, imagelength);
242 return new GtkImage(datacopy);
245 catch (IllegalArgumentException iae)
247 image = null;
249 return imageOrError(image);
253 * Creates an ImageProducer from the specified URL. The image is assumed
254 * to be in a recognised format.
256 * @param url URL to read image data from.
258 public ImageProducer createImageProducer(URL url)
260 return new GdkPixbufDecoder(url);
264 * Returns the native color model (which isn't the same as the default
265 * ARGB color model, but doesn't have to be).
267 public ColorModel getColorModel ()
269 /* Return the GDK-native ABGR format */
270 return new DirectColorModel(32,
271 0x000000FF,
272 0x0000FF00,
273 0x00FF0000,
274 0xFF000000);
277 public String[] getFontList ()
279 return (new String[] { "Dialog",
280 "DialogInput",
281 "Monospaced",
282 "Serif",
283 "SansSerif" });
286 private class LRUCache extends LinkedHashMap
288 int max_entries;
289 public LRUCache(int max)
291 super(max, 0.75f, true);
292 max_entries = max;
294 protected boolean removeEldestEntry(Map.Entry eldest)
296 return size() > max_entries;
300 private LRUCache fontCache = new LRUCache(50);
301 private LRUCache metricsCache = new LRUCache(50);
302 private LRUCache imageCache = new LRUCache(50);
304 public FontMetrics getFontMetrics (Font font)
306 synchronized (metricsCache)
308 if (metricsCache.containsKey(font))
309 return (FontMetrics) metricsCache.get(font);
312 FontMetrics m = new GdkFontMetrics (font);
313 synchronized (metricsCache)
315 metricsCache.put(font, m);
317 return m;
320 public Image getImage (String filename)
322 if (imageCache.containsKey(filename))
323 return (Image) imageCache.get(filename);
324 else
326 Image im = createImage(filename);
327 imageCache.put(filename, im);
328 return im;
332 public Image getImage (URL url)
334 if (imageCache.containsKey(url))
335 return (Image) imageCache.get(url);
336 else
338 Image im = createImage(url);
339 imageCache.put(url, im);
340 return im;
344 public PrintJob getPrintJob (Frame frame, String jobtitle, Properties props)
346 return null;
349 public native int getScreenResolution();
351 public Dimension getScreenSize ()
353 int dim[] = new int[2];
354 getScreenSizeDimensions(dim);
355 return new Dimension(dim[0], dim[1]);
358 public Clipboard getSystemClipboard()
360 SecurityManager secman = System.getSecurityManager();
361 if (secman != null)
362 secman.checkSystemClipboardAccess();
364 return GtkClipboard.getInstance();
368 * Prepares a GtkImage. For every other kind of Image it just
369 * assumes the image is already prepared for rendering.
371 public boolean prepareImage (Image image, int width, int height,
372 ImageObserver observer)
374 /* GtkImages are always prepared, as long as they're loaded. */
375 if (image instanceof GtkImage)
376 return ((((GtkImage)image).checkImage (observer) &
377 ImageObserver.ALLBITS) != 0);
379 /* Assume anything else is too */
380 return true;
383 public native void sync();
385 protected void setComponentState (Component c, GtkComponentPeer cp)
387 /* Make the Component reflect Peer defaults */
388 if (c.getForeground () == null)
389 c.setForeground (cp.getForeground ());
390 if (c.getBackground () == null)
391 c.setBackground (cp.getBackground ());
392 // if (c.getFont () == null)
393 // c.setFont (cp.getFont ());
395 /* Make the Peer reflect the state of the Component */
396 if (! (c instanceof Window))
398 cp.setCursor (c.getCursor ());
400 Rectangle bounds = c.getBounds ();
401 cp.setBounds (bounds.x, bounds.y, bounds.width, bounds.height);
402 cp.setVisible (c.isVisible ());
406 protected ButtonPeer createButton (Button b)
408 return new GtkButtonPeer (b);
411 protected CanvasPeer createCanvas (Canvas c)
413 return new GtkCanvasPeer (c);
416 protected CheckboxPeer createCheckbox (Checkbox cb)
418 return new GtkCheckboxPeer (cb);
421 protected CheckboxMenuItemPeer createCheckboxMenuItem (CheckboxMenuItem cmi)
423 return new GtkCheckboxMenuItemPeer (cmi);
426 protected ChoicePeer createChoice (Choice c)
428 return new GtkChoicePeer (c);
431 protected DialogPeer createDialog (Dialog d)
433 return new GtkDialogPeer (d);
436 protected FileDialogPeer createFileDialog (FileDialog fd)
438 return new GtkFileDialogPeer (fd);
441 protected FramePeer createFrame (Frame f)
443 return new GtkFramePeer (f);
446 protected LabelPeer createLabel (Label label)
448 return new GtkLabelPeer (label);
451 protected ListPeer createList (List list)
453 return new GtkListPeer (list);
456 protected MenuPeer createMenu (Menu m)
458 return new GtkMenuPeer (m);
461 protected MenuBarPeer createMenuBar (MenuBar mb)
463 return new GtkMenuBarPeer (mb);
466 protected MenuItemPeer createMenuItem (MenuItem mi)
468 return new GtkMenuItemPeer (mi);
471 protected PanelPeer createPanel (Panel p)
473 return new GtkPanelPeer (p);
476 protected PopupMenuPeer createPopupMenu (PopupMenu target)
478 return new GtkPopupMenuPeer (target);
481 protected ScrollPanePeer createScrollPane (ScrollPane sp)
483 return new GtkScrollPanePeer (sp);
486 protected ScrollbarPeer createScrollbar (Scrollbar sb)
488 return new GtkScrollbarPeer (sb);
491 protected TextAreaPeer createTextArea (TextArea ta)
493 return new GtkTextAreaPeer (ta);
496 protected TextFieldPeer createTextField (TextField tf)
498 return new GtkTextFieldPeer (tf);
501 protected WindowPeer createWindow (Window w)
503 return new GtkWindowPeer (w);
506 public EmbeddedWindowPeer createEmbeddedWindow (EmbeddedWindow w)
508 return new GtkEmbeddedWindowPeer (w);
511 /**
512 * @deprecated part of the older "logical font" system in earlier AWT
513 * implementations. Our newer Font class uses getClasspathFontPeer.
515 protected FontPeer getFontPeer (String name, int style) {
516 // All fonts get a default size of 12 if size is not specified.
517 return getFontPeer(name, style, 12);
521 * Private method that allows size to be set at initialization time.
523 private FontPeer getFontPeer (String name, int style, int size)
525 Map attrs = new HashMap ();
526 ClasspathFontPeer.copyStyleToAttrs (style, attrs);
527 ClasspathFontPeer.copySizeToAttrs (size, attrs);
528 return getClasspathFontPeer (name, attrs);
532 * Newer method to produce a peer for a Font object, even though Sun's
533 * design claims Font should now be peerless, we do not agree with this
534 * model, hence "ClasspathFontPeer".
537 public ClasspathFontPeer getClasspathFontPeer (String name, Map attrs)
539 Map keyMap = new HashMap (attrs);
540 // We don't know what kind of "name" the user requested (logical, face,
541 // family), and we don't actually *need* to know here. The worst case
542 // involves failure to consolidate fonts with the same backend in our
543 // cache. This is harmless.
544 keyMap.put ("GtkToolkit.RequestedFontName", name);
545 if (fontCache.containsKey (keyMap))
546 return (ClasspathFontPeer) fontCache.get (keyMap);
547 else
549 ClasspathFontPeer newPeer = new GdkFontPeer (name, attrs);
550 fontCache.put (keyMap, newPeer);
551 return newPeer;
555 public ClasspathTextLayoutPeer getClasspathTextLayoutPeer (AttributedString str,
556 FontRenderContext frc)
558 return new GdkTextLayout(str, frc);
561 protected EventQueue getSystemEventQueueImpl()
563 synchronized (GtkToolkit.class)
565 if (q == null)
567 q = new EventQueue();
570 return q;
573 protected native void loadSystemColors (int[] systemColors);
575 public DragSourceContextPeer createDragSourceContextPeer(DragGestureEvent e)
577 throw new Error("not implemented");
580 public Map mapInputMethodHighlight(InputMethodHighlight highlight)
582 throw new Error("not implemented");
585 public Rectangle getBounds()
587 int[] dims = new int[2];
588 getScreenSizeDimensions(dims);
589 return new Rectangle(0, 0, dims[0], dims[1]);
592 // ClasspathToolkit methods
594 public GraphicsEnvironment getLocalGraphicsEnvironment()
596 return new GdkGraphicsEnvironment();
599 public Font createFont(int format, InputStream stream)
601 throw new UnsupportedOperationException();
604 public RobotPeer createRobot (GraphicsDevice screen) throws AWTException
606 return new GdkRobotPeer (screen);
609 public void registerImageIOSpis(IIORegistry reg)
611 GdkPixbufDecoder.registerSpis(reg);
614 public static native void gtkMain();
615 } // class GtkToolkit